Я пытаюсь передать файл MS ADPCM с помощью XAudio2 (в C ++, но эта проблема не связана с языком).
Файл закодирован с помощью ADPCMEncode.exe, это дает файл WAV с тегом формата WAVE_FORMAT_ADPCM.
Как и в любом потоке, я создаю IXAudio2SourceVoice (с полным ADPCMWAVEFORMAT от начала файла) и подаю в него буферы с выравниванием блоков, когда они их запрашивают. Похоже, что данные воспроизводятся нормально, пока не наступит время цикла.
Считывающее устройство циклическое, как и следовало ожидать: если происходит короткое чтение, верните смещение в начало и выполните другое чтение, чтобы заполнить оставшуюся часть буфера. Хорошо для PCM, но для MS ADPCM иногда голос останавливается. Похоже, он перестает просить больше буферов, и поэтому заканчивается и останавливается.
Время ошибки меняется. Иногда это происходит, как только данные зацикливаются, иногда после зацикливания несколько раз. Очевидно, есть некоторая дополнительная информация, которую мне нужно передать через XAUDIO2_BUFFER, но я не могу найти никаких документов, рассказывающих мне, что.
Кто-нибудь может указать мне правильное направление?
Еще раз, жертва достоинства в Интернете приносит свои плоды. 😉
Я понял, что неправильно использовал 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 / Length элемента XAUDIO2_BUFFER, если точки цикла не точно выровнены, но при условии, что вы правильно выровняете их в исходном WAV (как вы это сделали бы для любого другого варианта ADPCM) Вам это не понадобится, выравнивания блоков представленных сжатых данных будет достаточно.