Audio.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. //// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. //// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. //// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. //// PARTICULAR PURPOSE.
  5. ////
  6. //// Copyright (c) Microsoft Corporation. All rights reserved
  7. // For licensing information relating to this distribution please see Third Party Notices file.
  8. #pragma once
  9. #include <wrl.h>
  10. #include <d3d11_1.h>
  11. #include <agile.h>
  12. #include <DirectXMath.h>
  13. #include <memory>
  14. #define XAUDIO2_HELPER_FUNCTIONS 1
  15. #include <xaudio2.h>
  16. #include <map>
  17. static const int STREAMING_BUFFER_SIZE = 65536;
  18. static const int MAX_BUFFER_COUNT = 3;
  19. #define UNUSED_PARAM(unusedparam) (void)unusedparam
  20. struct SoundEffectData
  21. {
  22. unsigned int m_soundID;
  23. IXAudio2SourceVoice* m_soundEffectSourceVoice;
  24. XAUDIO2_BUFFER m_audioBuffer;
  25. byte* m_soundEffectBufferData;
  26. size_t m_soundEffectBufferLength;
  27. uint32 m_soundEffectSampleRate;
  28. bool m_soundEffectStarted;
  29. bool m_soundEffectPaused;
  30. };
  31. class Audio;
  32. class AudioEngineCallbacks: public IXAudio2EngineCallback
  33. {
  34. private:
  35. Audio *m_audio;
  36. public :
  37. AudioEngineCallbacks(){};
  38. void Initialize(Audio* audio);
  39. // Called by XAudio2 just before an audio processing pass begins.
  40. void _stdcall OnProcessingPassStart(){};
  41. // Called just after an audio processing pass ends.
  42. void _stdcall OnProcessingPassEnd(){};
  43. // Called in the event of a critical system error which requires XAudio2
  44. // to be closed down and restarted. The error code is given in Error.
  45. void _stdcall OnCriticalError(HRESULT Error);
  46. };
  47. struct StreamingVoiceContext : public IXAudio2VoiceCallback
  48. {
  49. STDMETHOD_(void, OnVoiceProcessingPassStart)(UINT32){}
  50. STDMETHOD_(void, OnVoiceProcessingPassEnd)(){}
  51. STDMETHOD_(void, OnStreamEnd)(){}
  52. STDMETHOD_(void, OnBufferStart)(void*)
  53. {
  54. ResetEvent(hBufferEndEvent);
  55. }
  56. STDMETHOD_(void, OnBufferEnd)(void* pContext)
  57. {
  58. //Trigger the event for the music stream.
  59. if (pContext == 0) {
  60. SetEvent(hBufferEndEvent);
  61. }
  62. }
  63. STDMETHOD_(void, OnLoopEnd)(void*){}
  64. STDMETHOD_(void, OnVoiceError)(void*, HRESULT){}
  65. HANDLE hBufferEndEvent;
  66. StreamingVoiceContext() : hBufferEndEvent(CreateEventEx(NULL, FALSE, FALSE, NULL))
  67. {
  68. }
  69. virtual ~StreamingVoiceContext()
  70. {
  71. CloseHandle(hBufferEndEvent);
  72. }
  73. };
  74. class Audio
  75. {
  76. private:
  77. IXAudio2* m_musicEngine;
  78. IXAudio2* m_soundEffectEngine;
  79. IXAudio2MasteringVoice* m_musicMasteringVoice;
  80. IXAudio2MasteringVoice* m_soundEffectMasteringVoice;
  81. StreamingVoiceContext m_voiceContext;
  82. typedef std::map<unsigned int, SoundEffectData> EffectList;
  83. typedef std::pair<unsigned int, SoundEffectData> Effect;
  84. EffectList m_soundEffects;
  85. unsigned int m_backgroundID;
  86. std::string m_backgroundFile;
  87. bool m_backgroundLoop;
  88. float m_soundEffctVolume;
  89. float m_backgroundMusicVolume;
  90. bool m_engineExperiencedCriticalError;
  91. AudioEngineCallbacks m_musicEngineCallback;
  92. AudioEngineCallbacks m_soundEffectEngineCallback;
  93. unsigned int Hash(const char* key);
  94. public:
  95. Audio();
  96. void Initialize();
  97. void CreateResources();
  98. void ReleaseResources();
  99. void Start();
  100. void Render();
  101. // This flag can be used to tell when the audio system is experiencing critical errors.
  102. // XAudio2 gives a critical error when the user unplugs their headphones, and a new
  103. // speaker configuration is generated.
  104. void SetEngineExperiencedCriticalError()
  105. {
  106. m_engineExperiencedCriticalError = true;
  107. }
  108. bool HasEngineExperiencedCriticalError()
  109. {
  110. return m_engineExperiencedCriticalError;
  111. }
  112. void PlayBackgroundMusic(const char* pszFilePath, bool bLoop);
  113. void StopBackgroundMusic(bool bReleaseData);
  114. void PauseBackgroundMusic();
  115. void ResumeBackgroundMusic();
  116. void RewindBackgroundMusic();
  117. bool IsBackgroundMusicPlaying();
  118. void SetBackgroundVolume(float volume);
  119. float GetBackgroundVolume();
  120. void SetSoundEffectVolume(float volume);
  121. float GetSoundEffectVolume();
  122. void PlaySoundEffect(const char* pszFilePath, bool bLoop, unsigned int& sound, bool isMusic = false);
  123. void PlaySoundEffect(unsigned int sound);
  124. bool IsSoundEffectStarted(unsigned int sound);
  125. bool IsSoundEffectPaused(unsigned int sound);
  126. void StopSoundEffect(unsigned int sound);
  127. void PauseSoundEffect(unsigned int sound);
  128. void ResumeSoundEffect(unsigned int sound);
  129. void RewindSoundEffect(unsigned int sound);
  130. void PauseAllSoundEffects();
  131. void ResumeAllSoundEffects();
  132. void StopAllSoundEffects(bool bReleaseData);
  133. void PreloadSoundEffect(const char* pszFilePath, bool isMusic = false);
  134. void UnloadSoundEffect(const char* pszFilePath);
  135. void UnloadSoundEffect(unsigned int sound);
  136. private:
  137. void RemoveFromList(unsigned int sound);
  138. };