Microsoft WASAPI:不同音频格式是否需要不同的缓冲区数据?
WASAPI音频缓冲区采样值格式差异说明
答案很明确:不是所有格式都用-1到1的采样值,不同格式的取值范围和数据类型完全不同,必须针对格式编写对应的缓冲区写入逻辑。
具体差异如下:
IEEE Float格式
这是你当前使用的场景,确实直接用-1.0到1.0的32位浮点数值即可。WASAPI会自动将这些浮点值映射到音频硬件的动态范围,不需要额外转换。整数PCM格式
这类格式的采样值是有符号整数,不同位深的取值范围完全不同:- 16位PCM:取值范围为
-32768到32767(对应C++的int16_t类型) - 24位PCM:取值范围为
-8388608到8388607 - 32位整数PCM:取值范围为
-2147483648到2147483647
你需要把生成的-1到1浮点正弦波值,按比例转换为对应位深的整数。比如16位PCM的转换公式是:浮点值 * 32767(注意边界处理,比如1.0要转换为32767,-1.0转换为-32768)。
- 16位PCM:取值范围为
关键结论
你必须根据初始化AudioClient时指定的音频格式,编写不同的缓冲区写入代码。如果格式不匹配(比如给整数PCM格式写入浮点值),会导致播放杂音、无声,甚至直接触发API调用失败。
举个简单的代码示例(C++):
// 生成的正弦波浮点采样值(范围-1.0~1.0) float floatSample = sin(2 * M_PI * freq * time); // 根据音频格式写入缓冲区 if (audioFormat.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) { float* buffer = static_cast<float*>(pData); buffer[sampleIndex] = floatSample; } else if (audioFormat.wFormatTag == WAVE_FORMAT_PCM && audioFormat.wBitsPerSample == 16) { int16_t* buffer = static_cast<int16_t*>(pData); buffer[sampleIndex] = static_cast<int16_t>(floatSample * 32767.0f); }
内容的提问来源于stack exchange,提问作者Mike64
相关产品推荐
相关产品推荐

