如何使用NAudio的MediaFoundationResampler获取正确大小的重采样PCM字节数组
问题根因
你当前输出大小异常的核心原因是读取流时没有正确处理Read方法的返回值:conversionStream.Read(readBuffer, 0, readBuffer.Length)的返回值代表本次读取操作实际拿到的有效字节数,你原有代码不管实际读取到多少字节,都将整个缓冲区的内容全部写入内存流,缓冲区末尾未被填满的部分会以0值填充到输出中,最终导致输出大小超出预期,且会随缓冲区大小变化。
修正后实现代码
internal byte[] WavChangeFrequency(byte[] rawPcmData, int frequency, int bits, int channels, int newFrequency) { // 先计算理论预期的重采样后PCM长度,用于提前分配内存减少性能损耗 long expectedByteCount = (long)rawPcmData.Length * newFrequency / frequency; // 按位深、声道对齐,确保长度是采样帧的整数倍 int frameSize = bits / 8 * channels; expectedByteCount = expectedByteCount / frameSize * frameSize; using (MemoryStream audioSample = new MemoryStream(rawPcmData)) using (RawSourceWaveStream original = new RawSourceWaveStream(audioSample, new WaveFormat(frequency, bits, channels))) // 显式指定输出WaveFormat,避免重载默认参数导致的位深、声道不匹配 using (MediaFoundationResampler conversionStream = new MediaFoundationResampler(original, new WaveFormat(newFrequency, bits, channels))) using (MemoryStream wavData = new MemoryStream((int)expectedByteCount)) { byte[] readBuffer = new byte[4096]; int readCount; // 仅写入实际读取到的有效字节数 while ((readCount = conversionStream.Read(readBuffer, 0, readBuffer.Length)) > 0) { wavData.Write(readBuffer, 0, readCount); } // 对长度精度要求极高时可截断到理论预期长度(MediaFoundation输出偏差通常在1个帧以内) if (wavData.Length > expectedByteCount) { return wavData.GetBuffer().AsSpan(0, (int)expectedByteCount).ToArray(); } return wavData.ToArray(); } }
效果验证
你提供的测试场景中,修正后的代码输出大小将和Audition、Audacity的结果一致,为923162字节,同时保留MediaFoundationResampler的高品质重采样效果,不会出现WaveFormatConversionStream的音质不佳问题。
内容的提问来源于stack exchange,提问作者jms2505
相关产品推荐
相关产品推荐

