我要将pcm数据流写成wav文件,文件头部分如下:
 private byte[] GetWavHead(long len)
        {
            byte[] riffB = new byte[] { 0x52, 0x49, 0x46, 0x46 };//RIFF标志            byte[] lenB = new byte[4];//文件长度
            lenB = BitConverter.GetBytes(len + 48);            byte[] waveB = new byte[] { 0x57, 0x41, 0x56, 0x45 };//wave标志            byte[] fmtB = new byte[] { 0x66, 0x6D, 0x74, 0x20 };//fmt标志            byte[] fmtLen = new byte[] { 0x12, 0x00, 0x00, 0x00 };//块长度            byte[] codeB = new byte[] { 0x10, 0x00 };//编码方式 wFormatTag            byte[] numB = new byte[] { 0x01, 0x00 };//声道数目 wChannels            byte[] sampB = new byte[4];//{ 0x80, 0x3E, 0x00, 0x00 };//采样频率 dwSamplesPerSec
            sampB = BitConverter.GetBytes(44100);            byte[] avgB = new byte[4];//{ 0x00, 0x7D, 0x00, 0x00 };//每秒所需字节数 dwAvgBytesPerSec
            avgB = BitConverter.GetBytes(88200);            byte[] blockB = new byte[] { 0x02, 0x00 };//每个样本需要的字节数 wBlockAlign            byte[] bitB = new byte[] { 0x08, 0x00 };//每个样本需要的位数 wBitsPerSample            byte[] factB = new byte[] { 0x66, 0x61, 0x63, 0x74 };//fact标志            byte[] factLen = new byte[] { 0x04, 0x00, 0x00, 0x00 };//fact长度            byte[] temp = new byte[] { 0x00, 0xBE, 0x00, 0x00 };//            byte[] dataB = new byte[] { 0x64, 0x61, 0x74, 0x61 };//data标志            byte[] dataLen = new byte[4];//数据长度
            dataLen = BitConverter.GetBytes(len);            byte[] AllByte = new byte[]{riffB[0],riffB[1],riffB[2],riffB[3],lenB[0],lenB[1],lenB[2],lenB[3],waveB[0],waveB[1],waveB[2],waveB[3],
                fmtB[0],fmtB[1],fmtB[2],fmtB[3],fmtLen[0],fmtLen[1],fmtLen[2],fmtLen[3],codeB[0],codeB[1],numB[0],numB[1],
                sampB[0],sampB[1],sampB[2],sampB[3],avgB[0],avgB[1],avgB[2],avgB[3],blockB[0],blockB[1],bitB[0],bitB[1],
                factB[0],factB[1],factB[2],factB[3],factLen[0],factLen[1],factLen[2],factLen[3],temp[0],temp[1],temp[2],temp[3],
                dataB[0],dataB[1],dataB[2],dataB[3],dataLen[0],dataLen[1],dataLen[2],dataLen[3]};
            return AllByte;
        }我这个方法传入的参数是pcm数据流的长度,但转换后的wav文件不能播放,不知是什么原因,哪位知道的告诉我一下,非常感谢!

解决方案 »

  1.   

    找个能播放的wav文件,读出数据,用你的方法写,然后比较写好的wav与原来的有什么差别
      

  2.   


    获取wav文件文件头信息
    如下:
    using System;using System.IO;using System.Text; namespace WAV{    /// <summary>    /// Summary description for Wav.    /// </summary>    public class Wav    {        public Wav()        {            //            // TODO: Add constructor logic here            //        }         [STAThread]        static void Main(string[] args)        {            //            // TODO: Add code to start application here            //            string strpath=@"C:\Documents and Settings\Administrator\桌面\trojan\怀念战友.wav";//=@"F:\Music";            if(args.Length>0)            {                strpath=args[0].Trim();            }            if(File.Exists(strpath))            {                GetWavInfo(strpath);                Console.WriteLine("GetWavInfo Successfully!");                //Console.WriteLine("");            }            else            {                Console.Write("Please Enter the write filepath!\n");                Console.Write("用法: WAV [Full Path Of Your WAV filepath]");            }        }         public struct WavInfo        {            public string groupid;            public string rifftype;            public long filesize;            public string chunkid;            public long chunksize;             public short wformattag; //记录着此声音的格式代号,例如WAVE_FORMAT_PCM,WAVE_F0RAM_ADPCM等等。            public ushort wchannels; //记录声音的频道数。            public ulong  dwsamplespersec;//记录每秒取样数。            public ulong  dwavgbytespersec;//记录每秒的数据量。            public ushort wblockalign;//记录区块的对齐单位。            public ushort wbitspersample;//记录每个取样所需的位元数。             public string datachunkid;            public long datasize;         }         public static void GetWavInfo(string strpath)        {            WavInfo wavInfo = new WavInfo();            FileInfo fi = new FileInfo(strpath);            System.IO.FileStream fs=fi.OpenRead();            if(fs.Length>=44)            {                byte[] bInfo=new byte[44];                fs.Read(bInfo,0,44);                                System.Text.Encoding.Default.GetString(bInfo,0,4);                if(System.Text.Encoding.Default.GetString(bInfo,0,4)=="RIFF"&&System.Text.Encoding.Default.GetString(bInfo,8,4)=="WAVE"&&System.Text.Encoding.Default.GetString(bInfo,12,4)=="fmt ")                {                    wavInfo.groupid = System.Text.Encoding.Default.GetString(bInfo,0,4);                    System.BitConverter.ToInt32(bInfo,4);                    wavInfo.filesize = System.BitConverter.ToInt32(bInfo,4);                                            //wavInfo.filesize = Convert.ToInt64(System.Text.Encoding.Default.GetString(bInfo,4,4));                    wavInfo.rifftype = System.Text.Encoding.Default.GetString(bInfo,8,4);                    wavInfo.chunkid = System.Text.Encoding.Default.GetString(bInfo,12,4);                    wavInfo.chunksize = System.BitConverter.ToInt32(bInfo,16);                    wavInfo.wformattag = System.BitConverter.ToInt16(bInfo,20);                    wavInfo.wchannels = System.BitConverter.ToUInt16(bInfo,22);                    wavInfo.dwsamplespersec = System.BitConverter.ToUInt32(bInfo,24);                    wavInfo.dwavgbytespersec = System.BitConverter.ToUInt32(bInfo,28);                    wavInfo.wblockalign = System.BitConverter.ToUInt16(bInfo,32);                    wavInfo.wbitspersample = System.BitConverter.ToUInt16(bInfo,34);                    wavInfo.datachunkid = System.Text.Encoding.Default.GetString(bInfo,36,4);                    wavInfo.datasize = System.BitConverter.ToInt32(bInfo,40);                     System.Console.WriteLine("groupid:"+wavInfo.groupid);                    System.Console.WriteLine("filesize:"+wavInfo.filesize);                    System.Console.WriteLine("rifftype:"+wavInfo.rifftype);                    System.Console.WriteLine("chunkid:"+wavInfo.chunkid);                    System.Console.WriteLine("chunksize:"+wavInfo.chunksize);                    System.Console.WriteLine("wformattag:"+wavInfo.wformattag);                    System.Console.WriteLine("wchannels:"+wavInfo.wchannels);                    System.Console.WriteLine("dwsamplespersec:"+wavInfo.dwsamplespersec);                    System.Console.WriteLine("dwavgbytespersec:"+wavInfo.dwavgbytespersec);                    System.Console.WriteLine("wblockalign:"+wavInfo.wblockalign);                    System.Console.WriteLine("wbitspersample:"+wavInfo.wbitspersample);                    System.Console.WriteLine("datachunkid:"+wavInfo.datachunkid);                    System.Console.WriteLine("datasize:"+wavInfo.datasize);                 }            }        }    }}
      

  3.   

    但不同的PCM数据,它的[编码方式 声道数目 采样频率 每秒所需字节数]等是不同的吧,如何得到这些数据呢?
      

  4.   

    只知道读头文件.PCM就没弄过了
    好像可以直接查看wav文件的内容的,用记事本开就是全是二进制的,根据位数来区分
    具体打开方法忘了,可以找一下
      

  5.   

    用UltraEdit就可以看文件的16進制編碼,按位对应就知道是哪的问题了
      

  6.   

                byte[] blockB = new byte[] { 0x02, 0x00 };//每个样本需要的字节数 wBlockAlign        int 的顺序有问题,倒反存放
      

  7.   


    byte[] lenB = new byte[4];//文件长度 
    lenB = BitConverter.GetBytes(len + 48);
    你初始定义了4字节的长度。但接下来的那句话又重新定义了个实例给lenB。也就说,你的len不同,可能造成lenB长度不为4
      

  8.   

    前面我指出的地方,不是问题的根源。
    我测了一下你的代码。不明白你为什么用byte而不是用char
    既然你严格按照wave头来写文件就应该使用char类型我将len = 100作为参数传入后
    lenB = byte[]{148, 0, 0, 0};
    把lenB转成char[]写入文件的时候将变成char[]{0xc2, 0x94, 0, 0, 0}
    长度变成了5
      

  9.   

    你初始定义了4字节的长度。但接下来的那句话又重新定义了个实例给lenB。也就说,你的len不同,可能造成lenB长度不为4