我正在尝试使用XAudio2 (在C++中,但这个问题似乎与语言无关)流式传输MS文件。
该文件是用WAV编码的,这给出了一个格式标记为WAVE_FORMAT_ADPCM的ADPCMEncode.exe文件。
与任何流一样,我创建一个IXAudio2SourceVoice (从文件的开头开始包含完整的ADPCMWAVEFORMAT ),并在它请求时向其提供与块对齐的缓冲区。数据看起来运行得很好,直到循环的时候。
循环读取器与您预期的一样:如果发生短时间读取,则将偏移量返回到起始位置,并执行另一次读取以填满缓冲区的其余部分。对于PCM可以,但对于MS ADPCM有时声音会停止。它似乎不再请求更多的缓冲区,因此会用完并停止。
错误的时间会有所不同。有时它会在数据循环后立即发生,有时会在多次循环之后发生。很明显,我需要通过XAUDIO2_BUFFER传递一些额外的信息,但是我找不到任何文档来告诉我是什么。
有谁能告诉我正确的方向吗?
发布于 2015-06-24 23:58:14
再一次,对互联网尊严的牺牲结出了果实。;)
我意识到我错误地使用了ADPCM的样本环路WAV段。它仍然是样本,而不是字节,所以它需要转换成字节(因为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一样),你就不需要这样做,提交的压缩数据的块对齐就足够了。
https://stackoverflow.com/questions/31029775
复制相似问题