PCM转Wav(添加wav头)

 

在做Android上传声音到服务器时,涉及到PCM转Wav的问题,其实就是为Wav添加wav头信息,代码如下

 
   BinaryWriter binaryWriter;
        FileStream fileStream;
 /// 
        /// PCM to wav
        /// 添加Wav头文件
        /// 参考资料:http://blog.csdn.net/bluesoal/article/details/932395
        /// 
        private void CreateSoundFile(string path)
        {

            try
            {
                fileStream = new FileStream(path, FileMode.Create);
            }
            catch (Exception ex)
            {
                TxtLogger.DumpException(ex);
                //mWaveFile = new FileStream(System.DateTime.Now.ToString("yyyyMMddHHmmss") + "test2.wav", FileMode.Create);
            }

            binaryWriter = new BinaryWriter(fileStream);

            //Set up file with RIFF chunk info. 每个WAVE文件的头四个字节便是“RIFF”。
            char[] ChunkRiff = { 'R', 'I', 'F', 'F' };
            char[] ChunkType = { 'W', 'A', 'V', 'E' };
            char[] ChunkFmt = { 'f', 'm', 't', ' ' };
            char[] ChunkData = { 'd', 'a', 't', 'a' };

            short shPad = 1;                // File padding

            int nFormatChunkLength = 0x10; // Format chunk length.

            int nLength = 0;                // File length, minus first 8 bytes of RIFF description. This will be filled in later.

            short shBytesPerSample = 0;     // Bytes per sample.

            short BitsPerSample = 16; //每个采样需要的bit数  

            //这里需要注意的是有的值是short类型,有的是int,如果错了,会导致占的字节长度过长or过短
            short channels = 1;//声道数目,1-- 单声道;2-- 双声道

            // 一个样本点的字节数目
            shBytesPerSample = 2;

            // RIFF 块
            binaryWriter.Write(ChunkRiff);
            binaryWriter.Write(nLength);
            binaryWriter.Write(ChunkType);

            // WAVE块
            binaryWriter.Write(ChunkFmt);
            binaryWriter.Write(nFormatChunkLength);
            binaryWriter.Write(shPad);


            binaryWriter.Write(channels); // Mono,声道数目,1-- 单声道;2-- 双声道
            binaryWriter.Write(16000);// 16KHz 采样频率                   
            binaryWriter.Write(32000); //每秒所需字节数
            binaryWriter.Write(shBytesPerSample);//数据块对齐单位(每个采样需要的字节数)
            binaryWriter.Write(BitsPerSample);  // 16Bit,每个采样需要的bit数  

            // 数据块
            binaryWriter.Write(ChunkData);
            binaryWriter.Write((int)0);   // The sample length will be written in later.
        }
  /// 
        /// 获取完整的wav流
        /// 
        /// PCM流
        /// wav流
        private byte[] GetAudioByte(HttpPostedFileBase soundBytes)
        {
            try
            {
                string tempPath = string.Format(@"{0}\{1}.wav", AppDomain.CurrentDomain.BaseDirectory, Guid.NewGuid().ToString("n"));
                //添加wav文件头
                CreateSoundFile(tempPath);

                byte[] bytes = new byte[soundBytes.InputStream.Length];
                soundBytes.InputStream.Read(bytes, 0, bytes.Length);
                binaryWriter.Write(bytes, 0, bytes.Length);
                binaryWriter.Seek(4, SeekOrigin.Begin);
                binaryWriter.Write((int)(bytes.Length + 36));   // 写文件长度
                binaryWriter.Seek(40, SeekOrigin.Begin);
                binaryWriter.Write(bytes.Length);
                fileStream.Close();

                byte[] audioBytes = ConvertToBinary(tempPath);
                //删除文件
                if (System.IO.File.Exists(tempPath))
                {
                    FileInfo fi = new FileInfo(tempPath);
                    if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1)
                        fi.Attributes = FileAttributes.Normal;
                    System.IO.File.Delete(tempPath);
                }
                return audioBytes;
            }
            catch (Exception ex)
            {
                TxtLogger.DumpException(ex);
                return null;
            }
            finally
            {
                if (fileStream != null)
                {
                    fileStream.Close();
                }
            }
        }

ok,注意传过来的PCM流中的参数值。

 

你可能感兴趣的:(Tool)