You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 08:06:03