SoundsEngine.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. #ifndef _SoundsEngine_h_
  2. #define _SoundsEngine_h_
  3. #include "ISoundEditorAccessor.h"
  4. #include <Xaudio2.h>
  5. #include "FxPremaster.h"
  6. #include "FxScene.h"
  7. #include "FxVoice.h"
  8. class SoundsEngine
  9. {
  10. public:
  11. //Константы
  12. enum Consts
  13. {
  14. //Максимально допустимое количество:
  15. c_soundChannels = 64, //звуковых каналов
  16. c_reserveChannels = 32, //каналов, доигрывающих звук с фейдом после замены
  17. c_totalSoundChannels = c_soundChannels + c_reserveChannels,
  18. //Время фейда в милисекундах при принудительной смене каналов
  19. c_replaceFadeTimeInMs = 800,
  20. };
  21. //Режимы вывода отладочной информации
  22. enum DebugStates
  23. {
  24. dbg_drawlevel_min = 0x1,
  25. dbg_drawlevel_max = 0x2,
  26. dbg_drawlevel_mask = 0xf,
  27. dbg_draw3d = 0x100,
  28. dbg_draw2d = 0x200,
  29. dbg_drawlistener = 0x400,
  30. dbg_logout = 0x10000,
  31. dbg_snd_off = 0x20000,
  32. dbg_tracecreates = 0x40000,
  33. dbg_mask = 0xfffff,
  34. };
  35. public:
  36. //Мастер сцены, применяющий к её звукам эффекты
  37. class SceneMaster
  38. {
  39. friend class SoundsEngine;
  40. enum Consts
  41. {
  42. flags_isActive = 1,
  43. flags_isInitFx = 2,
  44. flags_isPause = 4,
  45. };
  46. protected:
  47. SceneMaster();
  48. ~SceneMaster();
  49. HRESULT Init();
  50. public:
  51. //Использовать этот мастер сцены, если возможно
  52. bool Alloc();
  53. //Удалить
  54. void Release();
  55. //Запустить работу мастера
  56. void Resume();
  57. //Остановить работу мастера
  58. void Stop();
  59. //Установить параметры серды окружения
  60. void SetEnvironment(const FxScene::EnvParams & params);
  61. private:
  62. IXAudio2SubmixVoice * voice;
  63. IXAudio2SourceVoice * silence;
  64. FxScene fxScene;
  65. dword flags;
  66. };
  67. friend class SceneMaster;
  68. class SoundChannel;
  69. //Звуковой канал
  70. class SoundChannel
  71. {
  72. friend class SoundsEngine;
  73. protected:
  74. enum Consts
  75. {
  76. state_isPlay = 0x100, //Играеться канал
  77. state_fadeoutProcess = 0x200, //Фэйд канала перед остановкой
  78. state_isPause = 0x400, //Пауза канала
  79. state_buffersForStopMask = 0xff, //Если в очереди осталось столько буферов, то считаем что канал не играет
  80. };
  81. protected:
  82. SoundChannel();
  83. ~SoundChannel();
  84. void Release();
  85. //Управление каналом
  86. public:
  87. //Запустить источник звука на проигрывание
  88. void Play();
  89. //Приостоновить буффер не освобождая канала
  90. void Pause(bool isPause);
  91. //Плавно увеличить громкость с текущего значения до максимума
  92. void FadeIn(float time);
  93. //Плавно уменьшить громкость с текущего значения до нуля
  94. void FadeOut(float time);
  95. //Установить позицию в 3D (включает позиционирование звука)
  96. void SetLocators(const FxVoice::Locator * locs, dword count);
  97. //Установить громкость канала
  98. void SetVolume(float volume);
  99. //Установить режим низчайшего приоритета, при котором можно сразу вытеснять канал
  100. void SetLowPriority(bool isLowPriority);
  101. //Изменить текущую громкость волны (редактор)
  102. void FixWaveVolume(float volume);
  103. //Состояния канала
  104. public:
  105. //Активен ли канал для данного владельца
  106. bool IsLost(void * uniqPtr);
  107. //На паузе ли буфер
  108. bool IsPause();
  109. //Играет ли звук
  110. bool IsPlay();
  111. //Получить позицию проигрывания в сэмплах
  112. bool GetPlayPosition(dword & playPosition);
  113. //Получить текущую громкость канала
  114. float DebugGetCurrentVolume();
  115. private:
  116. //Остановить канал
  117. void Stop();
  118. //Получить логическое время
  119. long GetTime();
  120. float GetTailTime();
  121. private:
  122. //Интерфейсы, с которыми взаимодействуем
  123. IXAudio2SourceVoice * voice;
  124. IXAudio2SubmixVoice * fxVoice;
  125. FxVoice fxProcessor;
  126. //Системные поля
  127. dword states; //Состояние канала
  128. dword lowPrtCounter; //Счётчик низкого приоритета
  129. dword mode; //Режим в котором играет канал
  130. dword format; //Формат проигрываемого буфера
  131. float waveVolume; //Громкость волны
  132. float pickAmp; //Пиковая амплитуда в волне
  133. float tailTime; //Время малозначительного хвоста волны
  134. float fadeOutTime; //Время фейда в 0
  135. array<UINT32> xWmaBuffer; //Буфер для xWma волны
  136. long time; //Логическое время создания канала
  137. dword samplesCount; //Количество выборок в проигрываемом буфере
  138. UINT64 startPlayPosition; //Позиция войса с которой было начато проигрывание
  139. UINT64 continuePosition; //Позиция буфера с которой продолжели проигрывание
  140. void * currentUniqPtr; //Привязка к хозяину
  141. };
  142. public:
  143. SoundsEngine();
  144. virtual ~SoundsEngine();
  145. //Инициализировать
  146. bool Init();
  147. //Освободить ресурсы
  148. void Release();
  149. //Обновить состояние
  150. void Update();
  151. //Приостановить проигрывание звуков
  152. void SetPause(bool isSetPause);
  153. //Загрузить звуковой банк
  154. bool LoadSoundBank(const char * path);
  155. //Удалить звуковой банк
  156. void ReleaseSoundBank(const char * path);
  157. //Создать мастер сцены
  158. SceneMaster * CreateSceneMaster();
  159. //Попытаться получить доступный звуковой канал
  160. SoundChannel * GetSoundChannel(SoundBankFileSound & sbfs, SoundBankFileWaveInfo * selWave, dword startPosition, SceneMaster & scene, void * uniqPtr);
  161. //Освободить звуковой канал
  162. void ReleaseSoundChannel(SoundChannel * ch, void * uniqPtr);
  163. //Получить количество активных каналов
  164. dword GetPlayChannels();
  165. //Получить максимальное количество каналов
  166. dword GetMaxChannels();
  167. //Получить количество активных каналов для доигрывания
  168. dword GetPlayReservedChannels();
  169. //Получить максимальное количество каналов для доигрывания
  170. dword GetMaxReservedChannels();
  171. #ifdef _XBOX
  172. //Получить объект XAudio
  173. IXAudio2 * GetXAudio();
  174. #endif
  175. public:
  176. #ifndef NO_TOOLS
  177. //Запустить волну на проигрывание 16бит (для звукового редактора)
  178. bool EditPrewiewPlay(const dword userId[4], EditPrewiewWaveParams * mainWave, EditPrewiewWaveParams * mirrorWave, bool isMirror);
  179. //Переключить волну на зеркальную или оригинальную
  180. bool EditPrewiewSwitch(const dword userId[4], bool isMirror);
  181. //Играет ли волна на прослушивании (для звукового редактора), userId[4] == 0 игнорировать его
  182. bool EditPrewiewIsPlay(const dword userId[4], dword * samplesCount = null, bool * playWithMirror = null);
  183. //Остановить прослушивание волны, userId[4] == 0 игнорировать его
  184. void EditPrewiewStop(const dword userId[4]);
  185. //Установить громкость прослушиваемой волны, userId[4] == 0 игнорировать его
  186. void EditPrewiewSetVolume(float volume, const dword userId[4]);
  187. //Установить громкость мастера предпрослушивания
  188. void EditPrewiewSetMasterVolume(float volume);
  189. #endif
  190. private:
  191. //Обновить состояние музыкального канала в зависимости от состояния проигрывателя
  192. void UpdateMusicState();
  193. //Выбрать канал для замещения
  194. static long ChannelSelector(SoundChannel ** ch, long count, long priority, long time);
  195. //Поменять местами каналы
  196. static void ExchangeChannels(SoundChannel * & ch1, SoundChannel * & ch2);
  197. public:
  198. //Получить частоту для канала эфектов
  199. static dword GetFxMixFreq();
  200. //Получить частоту для канала музыки
  201. static dword GetMusMixFreq();
  202. private:
  203. //Звуковая библиотека
  204. IXAudio2 * pXAudio2;
  205. //Мастер задающий общую громкость
  206. IXAudio2MasteringVoice * masteringVoice;
  207. //Премастер канала эффектов
  208. IXAudio2SubmixVoice * fxPremasteringVoice;
  209. FxPremaster fxPremaster;
  210. //Премастер музыкального канала
  211. IXAudio2SubmixVoice * musicPremasteringVoice;
  212. //Премастера сцен
  213. array<SceneMaster *> sceneMasters;
  214. //Массив звуковых каналов для эффектов
  215. SoundChannel * sound[c_soundChannels];
  216. dword soundCount;
  217. //Массив каналов, находящихся на доигрывании
  218. SoundChannel * reserved[c_reserveChannels];
  219. dword reservedCount;
  220. //Общий массив каналов, используемых системой
  221. SoundChannel soundChannels[c_totalSoundChannels];
  222. //Счётчик создаваемых звуков
  223. long creationCounter;
  224. //Движёк на паузе
  225. long isPause;
  226. //Нотификация изменения состояния проигрывателя пользователя (xbox)
  227. HANDLE notificationListenerForXbox;
  228. //Буфер для проигрывания зацикленной тишины
  229. XAUDIO2_BUFFER silenceBuffer;
  230. byte silenceLoop[4096];
  231. private:
  232. static SoundsEngine * engine;
  233. private:
  234. #ifndef NO_TOOLS
  235. //Звук для прослушивания
  236. IXAudio2SubmixVoice * previewMaster;
  237. float previewMasterVolume;
  238. IXAudio2SourceVoice * previewVoice;
  239. IXAudio2SourceVoice * previewVoiceMirror;
  240. dword previewUserId[4];
  241. #endif
  242. };
  243. #endif