将 wav 文件转换为 8000Hz 16Bit Mono Wav

问题描述 投票:0回答:3

我需要将 wav 文件转换为 8000Hz 16Bit Mono Wav。我已经有一个代码,它可以很好地与 NAudio 库配合使用,但我想使用 MemoryStream 而不是临时文件。

using System.IO;
using NAudio.Wave;

    static void Main()
    {
        var input = File.ReadAllBytes("C:/input.wav");
        var output = ConvertWavTo8000Hz16BitMonoWav(input);
        File.WriteAllBytes("C:/output.wav", output);
    }

    public static byte[] ConvertWavTo8000Hz16BitMonoWav(byte[] inArray)
    {
        using (var mem = new MemoryStream(inArray))
        using (var reader = new WaveFileReader(mem))
        using (var converter = WaveFormatConversionStream.CreatePcmStream(reader))
        using (var upsampler = new WaveFormatConversionStream(new WaveFormat(8000, 16, 1), converter))
        {
            // todo: without saving to file using MemoryStream or similar
            WaveFileWriter.CreateWaveFile("C:/tmp_pcm_8000_16_mono.wav", upsampler);
            return File.ReadAllBytes("C:/tmp_pcm_8000_16_mono.wav");
        }
    }
c# audio naudio memorystream
3个回答
3
投票

不确定这是否是最佳方法,但它有效......

    public static byte[] ConvertWavTo8000Hz16BitMonoWav(byte[] inArray)
    {
        using (var mem = new MemoryStream(inArray))
        {
            using (var reader = new WaveFileReader(mem))
            {
                using (var converter = WaveFormatConversionStream.CreatePcmStream(reader))
                {
                    using (var upsampler = new WaveFormatConversionStream(new WaveFormat(8000, 16, 1), converter))
                    {
                        byte[] data;
                        using (var m = new MemoryStream())
                        {
                            upsampler.CopyTo(m);
                            data = m.ToArray();
                        }
                        using (var m = new MemoryStream())
                        {
                            // to create a propper WAV header (44 bytes), which begins with RIFF 
                            var w = new WaveFileWriter(m, upsampler.WaveFormat);
                            // append WAV data body
                            w.Write(data,0,data.Length);
                            return m.ToArray();
                        }   
                    }
                }
            }
        }
    }

1
投票

可能会添加,抱歉,由于缺乏积分,我还无法发表评论。 NAudio ALWAYS 写入 46 字节标头,这在某些情况下可能会导致崩溃。我想添加这个,以防有人在寻找为什么 naudio wav 文件只会开始崩溃某些程序的线索时遇到这个问题。

在弄清楚如何使用 NAudio 转换和/或采样 wav 后,我遇到了这个问题,并且被困了 2 天,只能用十六进制编辑器解决。

(2 个额外字节位于数据子块 [d,a,t,a,size<4bytes>] 之前的字节 37 和 38。 Here is a comparison of two wave file headers left is saved by NAudio 46 bytes; right by Audacity 44 bytes

您可以通过查看 WaveFormat.cs 中第 310 行的 NAudio src 来检查这一点,其中保留了 18+extra 的 fmt chunk,而不是 16 个字节(+extra 是因为有些 wav 文件甚至包含比46 字节),但 NAudio 似乎总是写入 46 字节标头,而不是 44(MS 标准)。还值得注意的是,事实上 NAudio 能够读取 44 字节标头(WaveFormat.cs 中的第 210 行)


0
投票
这对我有用(2024 年),阅读 NAudio 的文档

public void ConvertWav(String waveFilePath, String toWaveFilePath) { int outRate = 8000; using (var reader = new WaveFileReader(waveFilePath)) { var outFormat = new WaveFormat(outRate, 16, 1); using (var resampler = new MediaFoundationResampler(reader, outFormat)) { WaveFileWriter.CreateWaveFile(toWaveFilePath, resampler); } } }
并像这样修改你的程序:

static void Main() { ConvertWav("C:/input.wav","C:/output.wav"); }
    
© www.soinside.com 2019 - 2024. All rights reserved.