2015-06-24 5 views
2

Я пытаюсь передать файл MS ADPCM с помощью XAudio2 (на C++, но эта проблема не связана с языком).Поток и петля MS ADPCM (WAVE_FORMAT_ADPCM)

Файл закодирован с помощью ADPCMEncode.exe, это дает WAV-файл с тегом формата WAVE_FORMAT_ADPCM.

Как и любой поток, я создаю IXAudio2SourceVoice (с полным ADPCMWAVEFORMAT с начала файла) и подаю его буферизированные по блоку буферы по мере их запроса. Кажется, что данные воспроизводятся нормально, пока не наступит время.

Циклический считыватель как и следовало ожидать: если короткое чтение происходит, верните смещение в начало и сделайте еще одно чтение, чтобы заполнить остальную часть буфера. Отлично подходит для PCM, но для MS ADPCM иногда голос останавливается. Кажется, что перестает запрашивать больше буферов, и поэтому заканчивается и останавливается.

Время ошибки варьируется. Иногда это происходит, как только циклы данных, иногда после цикла несколько раз. Очевидно, есть какая-то дополнительная информация, которую мне нужно передать через XAUDIO2_BUFFER, но я не могу найти ни одного документа, рассказывающего мне что.

Может ли кто-нибудь указать мне в правильном направлении?

ответ

0

Еще раз, жертва достоинства в Интернете приносит плоды. ;)

Я понял, что неправильно использовал сегмент WAV контура выборки для ADPCM. Он по-прежнему находится в SAMPLES, а не в байтах, поэтому ему необходимо преобразовать в байты (поскольку ADPCM составляет примерно 25% сжатия, а стереокадр - 4 байта, эти два значения похожи, и это меня обмануло> __ <).

Образцы на блок легко обрабатываются из блока выравнивания:

unsigned int samplesPerBlock = m_format.nBlockAlign - 12; 

unsigned int startBlock = sampleLoop.start/samplesPerBlock; 
unsigned int startBlockOffset = sampleLoop.start % samplesPerBlock; 

unsigned int endBlock = sampleLoop.end/samplesPerBlock; 
unsigned int endBlockOffset = sampleLoop.end % samplesPerBlock; 

unsigned int loopStart = startBlock * m_format.nBlockAlign; 
unsigned int loopLength = (endBlock - startBlock) * m_format.nBlockAlign; 

Там какая-то дополнительная пустячный вы можете сделать с членами Play/LoopBegin/длина XAUDIO2_BUFFER, если точки цикла не точно совпадают, но до тех пор, пока вы должным образом выровняете их в исходном WAV (как и для любого другого аромата ADPCM), вам это не понадобится, будет достаточно выравнивания блоков для предоставленных сжатых данных.