2

我正在尝试使用 XAudio2 流式传输 MS ADPCM 文件(在 C++ 中,但这个问题似乎与语言无关)。

该文件使用 ADPCMEncode.exe 进行编码,这给出了一个带有 WAVE_FORMAT_ADPCM 格式标记的 WAV 文件。

像任何流一样,我创建了一个 IXAudio2SourceVoice(从文件开头使用完整的 ADPCMWAVEFORMAT),并在它请求时为其提供块对齐缓冲区。数据似乎可以正常播放,直到循环播放。

循环读取器如您所料:如果发生短读取,则将偏移量返回到开头并执行另一次读取以填满缓冲区的其余部分。PCM 很好,但 MS ADPCM 有时声音会停止。它似乎停止要求更多缓冲区,因此用完并停止。

错误发生的时间各不相同。有时它会在数据循环时立即发生,有时在循环数次后发生。显然,我需要通过 XAUDIO2_BUFFER 传递一些额外的信息,但我找不到任何文档告诉我什么。

谁能指出我正确的方向?

4

1 回答 1

0

再次,为互联网牺牲尊严的成果。;)

我意识到我对 ADPCM 错误地使用了示例循环 WAV 段。它仍然是 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;

如果循环点不完全对齐,您可以对 XAUDIO2_BUFFER 的 Play/LoopBegin/Length 成员进行一些额外的操作,但只要您在原始 WAV 中正确对齐它们(就像您对任何其他风格的 ADPCM 一样)你不需要那个,提交的压缩数据的块对齐就足够了。

于 2015-06-24T15:58:13.783 回答