MME 音频输出缓冲区大小

Posted

技术标签:

【中文标题】MME 音频输出缓冲区大小【英文标题】:MME Audio Output Buffer Size 【发布时间】:2013-05-05 14:30:56 【问题描述】:

我目前正在尝试通过旧的 MME API(waveOutXxx 函数)输出 FP32 样本。我遇到的问题是,如果我提供的缓冲区长度不能平均划分采样率,则音频流中会出现某些可听见的咔嗒声;记录时,看起来有些样本丢失了(我正在为测试生成一个正弦波)。目前,我使用每个缓冲区 2205 个样本的“魔术”值来实现 44100 采样率。

问题是,有人知道这些丢失的原因吗?是否有一些神奇的公式可以提供一种计算“正确”缓冲区大小的方法?

【问题讨论】:

那么究竟是什么阻止了您分配正确对齐的缓冲区? 其实没什么。只是这个要求没有在 MSDN 的任何地方指定。因此,问题。如果您碰巧有一个正确记录此行为的链接 - 请分享它。 【参考方案1】:

数据缓冲区的安全对齐是nBlockAlign 的值WAVEFORMATEX 结构。

软件必须同时处理多个 nBlockAlign 字节的数据 时间。 写入和读取设备的数据必须始终从 块的开头。 例如,开始播放 样本中间的 PCM 数据(即在非块对齐 边界)。

对于 PCM 格式,这是所有通道中单个样本的字节数。非 PCM 格式有自己的对齐方式,通常等于格式特定块的长度,例如20 毫秒。

waveOutXxx 是音频的主要 API 的时候,携带未对齐的字节对 API 来说是不合理的负担和不必要的性能开销。现在这个 API 是其他音频 API 之上的一个兼容层,我认为未对齐的字节只是被剥离以仍然播放其余内容,否则由于这个小故障而被完全拒绝,这可能只是一个较小且非致命的调用者的错误。

【讨论】:

在复制缓冲区数据导致故障时看起来像一个错误。感谢您的帮助!【参考方案2】:

如果你用正弦样本​​填充音频缓冲区并循环播放,它很容易会点击,除非缓冲区长度不是频率的倍数,正如你所说......听到的点击实际上是不连续的波浪...一种先进的技术是动态地填充缓冲区,也就是说,您应该在缓冲区指针前进时设置回调通知,并在适当的偏移量处用适当的数据填充缓冲区。我会使用更大的缓冲区,因为 2205 太短而无法获得异步通知、计算数据和写入缓冲区,所有这些都在播放时进行,但这取决于 cpu 功率

【讨论】:

我确实动态填充缓冲区,因此缓冲区会不断重新填充,并且数据中不应存在不连续性。我使用了三个缓冲区,所以系统数据用完应该没有问题。 我会将 wav 数据保存到文件中,然后使用一些工具将 .wav 可视化,以找出点击发生在缓冲区长度等方面的位置

以上是关于MME 音频输出缓冲区大小的主要内容,如果未能解决你的问题,请参考以下文章

为啥缓冲区大小会影响音频数据?

iOS,音频队列:缓冲区大小不是恒定的

您如何找到音频延迟? (Windows/OSX)

Android:java.lang.IllegalArgumentException:无效的音频缓冲区大小

捕获从端口音频写入输出音频设备的音频输出

没有流或缓冲区的 C# 音频输出