首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >流和循环MS ADPCM (WAVE_FORMAT_ADPCM)

流和循环MS ADPCM (WAVE_FORMAT_ADPCM)
EN

Stack Overflow用户
提问于 2015-06-24 22:47:34
回答 1查看 726关注 0票数 2

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

该文件是用WAV编码的,这给出了一个格式标记为WAVE_FORMAT_ADPCM的ADPCMEncode.exe文件。

与任何流一样,我创建一个IXAudio2SourceVoice (从文件的开头开始包含完整的ADPCMWAVEFORMAT ),并在它请求时向其提供与块对齐的缓冲区。数据看起来运行得很好,直到循环的时候。

循环读取器与您预期的一样:如果发生短时间读取,则将偏移量返回到起始位置,并执行另一次读取以填满缓冲区的其余部分。对于PCM可以,但对于MS ADPCM有时声音会停止。它似乎不再请求更多的缓冲区,因此会用完并停止。

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

有谁能告诉我正确的方向吗?

EN

回答 1

Stack Overflow用户

发布于 2015-06-24 23:58:14

再一次,对互联网尊严的牺牲结出了果实。;)

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

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

代码语言:javascript
复制
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一样),你就不需要这样做,提交的压缩数据的块对齐就足够了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31029775

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档