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

时间:2016-03-06 08:42:53

标签: c# audio naudio memorystream

我需要将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");
        }
    }

2 个答案:

答案 0 :(得分:1)

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

    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 :(得分:1)

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

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

(2个额外字节位于数据子块[d,a,t,a,大小< 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 at line 310中的NAudio src来检查这一点,而不是16字节,而fmt chunck 18 + extra是保留的(+ extra因为有些wav文件甚至包含比46更大的标题但是NAudio似乎总是写46个字节的标题而不是44个(MS标准)。还可以注意到,事实上NAudio能够读取44个字节的标题(WaveFormat.cs中的第210行)