简体   繁体   English

流和循环MS ADPCM(WAVE_FORMAT_ADPCM)

[英]Stream and loop MS ADPCM (WAVE_FORMAT_ADPCM)

I'm trying to stream an MS ADPCM file using XAudio2 (in C++, but this problem doesn't appear to be language related). 我正在尝试使用XAudio2流式传输MS ADPCM文件(在C ++中,但是此问题似乎与语言无关)。

The file is encoded with ADPCMEncode.exe, this gives a WAV file with a format tag of WAVE_FORMAT_ADPCM. 该文件使用ADPCMEncode.exe编码,这将提供一个WAV文件,其格式标记为WAVE_FORMAT_ADPCM。

Like any stream, I create a IXAudio2SourceVoice (with the full ADPCMWAVEFORMAT from the start of the file) and feed it block-aligned buffers as it requests them. 像任何流一样,我创建一个IXAudio2SourceVoice(从文件的开头开始是完整的ADPCMWAVEFORMAT),并在请求它们时将其以块对齐的形式提供给缓冲区。 The data appears to be playing fine, until the time comes to loop. 数据看起来运行良好,直到时间到了。

The looping reader is as you would expect: If a short read happens, return the offset to the start and do another read to fill up the rest of the buffer. 循环读取器是您所期望的:如果发生短读取,则将偏移量返回到起始位置,然后再进行一次读取以填充缓冲区的其余部分。 Fine for PCM, but for MS ADPCM sometimes the voice will stop. 适用于PCM,但适用于MS ADPCM,有时声音会停止。 It appears to stop asking for more buffers, and so runs out and stops. 它似乎不再需要更多的缓冲区,因此用完并停止。

The timing of the error varies. 错误的时间会有所不同。 Sometimes it happens as soon as the data loops, sometimes after looping several times. 有时,它在数据循环后立即发生,有时在循环几次后发生。 There's obviously some additional information I need to pass via the XAUDIO2_BUFFER, but I can't find any docs telling me what. 很显然,我还需要通过XAUDIO2_BUFFER传递一些其他信息,但是我找不到任何文档可以告诉我什么。

Can anybody point me in the right direction? 有人能指出我正确的方向吗?

Once again, the sacrifice of dignity to the internet bears fruit. 再次,对互联网的尊严牺牲取得了成果。 ;) ;)

I realised I was using the sample loop WAV segment wrongly for ADPCM. 我意识到我为ADPCM错误地使用了示例循环WAV段。 It's still in SAMPLES not bytes, so it needs converting into bytes (as ADPCM is roughly 25% compression and a stereo sample is 4 bytes the two values are similar and that's what fooled me >__<). 它仍然位于SAMPLES中而不是字节中,因此它需要转换为字节(由于ADPCM大约有25%的压缩率,而立体声采样为4字节,所以两个值相似,这就是让我> __ <愚弄的)。

Samples per block are easily worked out from the block align: 通过块对齐可轻松计算出每个块的样本:

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;

There's some extra fiddling you can do with the Play/LoopBegin/Length members of XAUDIO2_BUFFER if the loop points don't exactly align, but as long as you properly align them in the original WAV (like you would for any other flavour of ADPCM) you won't need that, block alignment of the submitted compressed data will be enough. 如果循环点未完全对齐,则可以使用XAUDIO2_BUFFER的Play / LoopBegin / Length成员进行一些额外的摆弄,但前提是您将它​​们正确地对齐在原始WAV中(就像您对其他ADPCM风格所做的那样)您将不需要,提交的压缩数据的块对齐就足够了。

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

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