20 декабря 2011 / Sashasan
Озвучка игр средствами XAudio2
В прошлой статье Трехмерная игра на DirectX 9 (3D Game) было рассмотрено, как сделать несложную 3d игру похожую на те, что радовали нас на приставках типа денди, но какой интересной и динамичной игра бы не была, без звука она будет унылой. Хорошая озвучка четверть
успеха игры. Скачав пример из этой статьи, и сравнив его с тем что был ранее, вы сможете сравнить и оценить значимость звука.
Чем воспроизводить звук
Для воспроизведения и обработки звука компания Microsoft в своем DirectX предоставляет широкий набор API это и DirectSound и XAudio2 и XACT. Что же выбрать в итоге?
DirectSound – является устаревшим АПИ. Преимущество использования в том, что работает на любой системе, начиная с win98 - win7 (win8 возможно тоже поддерживает в целях совместимости со старыми приложениями). Недостатком можно назвать то, что начиная с Windows Vista, он поддерживает только программное ускорение, т.е. работает software. Так же можно сказать, что он не поддерживает современные средства обработки звука. Как воспользоваться DirectSound вы можете почитать, скачав DirectX 9.0 Pack for MASM32 со странички http://extcode.com/data/tool_4.html.
XAudio2 – замена DirectSound. Является самым продвинутым и новым низкоуровневым АПИ для обработки и воспроизведения звука.
XACT – АПИ использующее как основу XAudio2. Специально для упрощения работы программистов игровых приложений кроме XAudio2 для игр было сделано высокоуровневое API XACT. Поэтому все требования к XAudio2 одинаковы и к XACT.
На мой взгляд, самым интересным было б описать работу с XAudio2 о чем и пойдет речь в статье.
XAudio2
Системные требования:
- XACT и XAudio2 поддерживаются на Xbox 360 и на PC.
- PC должны иметь ЦПУ с поддержкой SIMD (SSE) (при наличии поддержки более новой версии SSE используется более новая версия).
- Операционная система должны быть клиентской версии Windows XP или более поздней. (на WinXP 64бит не работает)
Примечания: XACT и XAudio2 не поддерживаются на системах Windows Server.
Для того чтобы начать программировать понадобится подключить заголовочный файл xaudio2.inc (это конвертированная MASM32 версия xaudio2.h, находится в архиве вместе с примером к статье). На момент создания примера в DX SDK за июнь 2010 последней версией было XAudio 2.7 (XAudio 2.8 встроена в win8) .
Итак к делу:
- Инициализация XAudio2 экземпляра устройства.
- Грузим файл Wav заполняя структуры WAVEFORMATEX и XAUDIO2_BUFFER.
- Создаем голосовой источник SourceVoice.
- Играем звук, используя XAudio2.
Инициализация XAudio2 экземпляра устройства
Для инициализации нужно выполнить две функции:
invoke XAudio2Create,addr pXAudio2,NULL,XAUDIO2_DEFAULT_PROCESSOR
xaudio2 CreateMasteringVoice,pXAudio2,addr pMasterVoice, \
XAUDIO2_DEFAULT_CHANNELS,XAUDIO2_DEFAULT_SAMPLERATE,NULL,NULL,NULL
Грузим файл Wav заполняя структуры WAVEFORMATEX и XAUDIO2_BUFFER
Чтобы загрузить файл Wav можно использовать те же функции, что и в примере для DirectSound. Хотя в примерах XAudio2 из DX SDK за июнь 2010 для загрузки Wav используются функции, что и в примере DirectX 9.0 Pack for MASM32 под DS, в MSDN все же рекомендуется делать загрузку своими силами и предлагают примерный пример как это сделать. Следуя этой рекомендации, пишем две функции.
invoke FindChunk,hFile,fourccRIFF,addr dwChunkSize,addr dwChunkPosition
invoke ReadChunkData,hFile,addr filetype,sizeof(DWORD),dwChunkPosition
Для того чтобы понять как работают эти две функции нужно понять из чего сделан файл Wav. Wav это формат файла обмена ресурсами (RIFF) из которого будут загружены аудиоданные для XAudio2. Файл формата Wav состоит из блоков RIFF, от ноля или больше блоков.
Блок RIFF имеет структуру: 'RIFF', fileSize, fileType, data. Где:
- RIFF - буквенный код FOURCC 'RIFF' 4 байта
- fileSize - 4-ех байтовое значение, размер данных в файле. Значение fileSize включает размер данных, не включая код FOURCC и 4 байта значения размера (короче не включая 8 байт)
- fileType - FOURCC, который идентифицирует тип файла 4 байта.
- data - состоит из блоков в любом порядке.
У блоков data есть следующая форма: chunkID, chunkSize, данные
- chunkID - FOURCC идентифицирует данные, содержавшиеся в блоке.
- chunkSize - 4-байтовое значение, дающее размер раздела данных блока (минус 8 байт). Значение нуль или больше. Размер данных всегда дополняются к самой близкой границе WORD.
Итак самый простой Wav файл выглядит: RIFF, размер, WAVE, fmt , размер, WAVEFORMATEX, data, размер, аудио данные.
Из всей кучи данных для создания SourceVoice и последующего воспроизведения звука нам нужна структура WAVEFORMATEX и аудио данные для заполнения структуры XAUDIO2_BUFFER. В принципе можно не использовать функции FindChunk и ReadChunkData, а просто от начала файла отступить 4+4+4+4+4=20байт и считать WAVEFORMATEX в буфер размером равным этой структуре, а затем отступить от начала файла 20+sizeof(WAVEFORMATEX)+4+4 и считать все аудио данные в буфер размером этих данных и передать адрес этого буфера в XAUDIO2_BUFFER структуру.
Создаем голосовой источник SourceVoice
Вызываем метод CreateSourceVoice из интерфейса экземпляра устройства XAudio2 для создания голосового источника pSourceVoice.
xaudio2 CreateSourceVoice,pXAudio2,addr pSourceVoice,addr Wfx,NULL,MaxFR,NULL,NULL,NULL
Где: Wfx адрес указывающий на структуру WAVEFORMATEX. Теперь нужно установить XAUDIO2_BUFFER к нужному источнику вызвав метод SubmitSourceBuffer из интерфейса SourceVoice.
Играем звук, используя XAudio2
xaudio2sv SubmitSourceBuffer,pSourceVoice4,addr Xaudio2Buf4,NULL ; Прикрепляем буфер к источнику
xaudio2sv Start,pSourceVoice4,NULL,XAUDIO2_COMMIT_NOW ; Воспроизводим источник звука.
xaudio2sv Stop,pSourceVoice3,NULL,XAUDIO2_COMMIT_NOW ; Для остановки
Здесь есть два нюанса, если остановить, а затем снова воспроизвести источник голоса? то воспроизведение пойдет не с начала, а с места остановки и количество воспроизведений должно равняться количеству остановок. Для того чтобы воспроизведение пошло с начала вызываем метод FlushSourceBuffers из интерфейса SourceVoice.
xaudio2sv FlushSourceBuffers,pSourceVoice4
Вот на этом можно и закончить данную статью и как всегда успехов!!! А и не забудьте сравнить пример к статье, игру со звуком и эту игру без звука, о которой упоминалось в начале статьи. :)
Примеры к статье
xaudio2
Sashasan молодец. Прикрутил к ассемблеру XAudio2.Хорошая работа. Спасибо.