C# 将wav文件转换为8000Hz 16位单声道wav

C# 将wav文件转换为8000Hz 16位单声道wav,c#,audio,naudio,memorystream,C#,Audio,Naudio,Memorystream,我需要将wav文件转换为8000Hz 16位单声道wav。我已经有了一个代码,可以很好地使用NAudio库,但我想使用MemoryStream而不是临时文件 using System.IO; using NAudio.Wave; static void Main() { var input = File.ReadAllBytes("C:/input.wav"); var output = ConvertWavTo8000Hz16BitMonoWa

我需要将wav文件转换为8000Hz 16位单声道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");
        }
    }

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

    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();
                        }   
                    }
                }
            }
        }
    }

它可能会被添加,很抱歉,由于缺少分数,我还不能发表评论。NAudio总是写入46字节的头文件,在某些情况下会导致崩溃。我想添加这一点,以防有人在搜索naudio wav文件为什么只开始崩溃某些程序的线索时遇到这一点

我遇到了这个问题,在弄清楚如何转换和/或采样wav与NAudio和被困后2天了,现在只有解决了它与十六进制编辑器

(2个额外字节位于数据子块[d,a,t,a,size]前面的字节37和38处。


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

您可以使用
WaveFileWriter
的一个构造函数,该构造函数接受一个流作为参数。取自@bob1024,我已经尝试过了,但是转换器没有参数……或者可能我缺少一些东西。您可以指定
WaveFormat
变量中的速率、位和通道,并将其传递给
WaveFile的构造函数Writer
@bob1024,是的,我可以,就像使用(var mem=newmemoryStream(inArray)){var waveilewriter=newwaveilewriter(mem,newwaveformat(8000,16,1));}但是下一步是什么呢?我想你可以用
waveilereader.ReadNextSampleFrame
waveilewriter.WriteSample
将音频样本从读卡器传输到写卡器。我看不到其他方法。