gpt4 book ai didi

c++ - 流式传输和循环 MS ADPCM (WAVE_FORMAT_ADPCM)

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:49:54 31 4
gpt4 key购买 nike

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

该文件使用 ADPCMEncode.exe 进行编码,这将生成一个格式标记为 WAVE_FORMAT_ADPCM 的 WAV 文件。

与任何流一样,我创建了一个 IXAudio2SourceVoice(从文件的开头开始使用完整的 ADPCMWAVEFORMAT)并在它请求时将其提供给 block 对齐的缓冲区。在循环之前,数据似乎运行良好。

循环读取器正如您所期望的那样:如果发生短读取,则将偏移量返回到开始位置并进行另一次读取以填充缓冲区的其余部分。 PCM 没问题,但 MS ADPCM 有时声音会停止。它似乎停止请求更多缓冲区,因此用完并停止。

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

谁能指出我正确的方向?

最佳答案

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

我意识到我错误地为 ADPCM 使用了示例循环 WAV 片段。它仍然是样本而不是字节,所以它需要转换成字节(因为 ADPCM 大约是 25% 的压缩,而立体声样本是 4 字节,这两个值是相似的,这就是愚弄我的原因>__<)。

每个 block 的样本很容易从 block 对齐中计算出来:

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)你不需要它,提交的压缩数据的 block 对齐就足够了。

关于c++ - 流式传输和循环 MS ADPCM (WAVE_FORMAT_ADPCM),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31029775/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com