繁体   English   中英

流和循环MS ADPCM(WAVE_FORMAT_ADPCM)

[英]Stream and loop MS ADPCM (WAVE_FORMAT_ADPCM)

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

该文件使用ADPCMEncode.exe编码,这将提供一个WAV文件,其格式标记为WAVE_FORMAT_ADPCM。

像任何流一样,我创建一个IXAudio2SourceVoice(从文件的开头开始是完整的ADPCMWAVEFORMAT),并在请求它们时将其以块对齐的形式提供给缓冲区。 数据看起来运行良好,直到时间到了。

循环读取器是您所期望的:如果发生短读取,则将偏移量返回到起始位置,然后再进行一次读取以填充缓冲区的其余部分。 适用于PCM,但适用于MS ADPCM,有时声音会停止。 它似乎不再需要更多的缓冲区,因此用完并停止。

错误的时间会有所不同。 有时,它在数据循环后立即发生,有时在循环几次后发生。 很显然,我还需要通过XAUDIO2_BUFFER传递一些其他信息,但是我找不到任何文档可以告诉我什么。

有人能指出我正确的方向吗?

再次,对互联网的尊严牺牲取得了成果。 ;)

我意识到我为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风格所做的那样)您将不需要,提交的压缩数据的块对齐就足够了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM