C# 保存声音 录音

C#winform中保存设备返回的PCM音频。自己写文件,而不是调用其他的方法。


文中参考了这篇博文  http://blog.csdn.net/woaixiaozhe/article/details/7852824

原文是对声卡进行录音,这里是直接将录音改为一个类,直接调用就好了


录音类:

using System.IO;

    /// 
    /// 生成录音文件
    /// BY SUMC
    /// 2015-10-16
    /// 
    public class rec
    {
        private WaveFormat mWavFormat;
        private int mSampleCount = 0;

        private string mFileName = "";
        private FileStream mWaveFile = null;
        private BinaryWriter mWriter = null;

        public rec(string audioFileName)
        {
            // 设定录音格式  
            this.mFileName = audioFileName;
            mWavFormat = CreateWaveFormat();
        }

        private WaveFormat CreateWaveFormat()
        {
            WaveFormat format = new WaveFormat();
            format.SamplesPerSecond = 32000;
            format.BitsPerSample = 16; 
            format.Channels = 1;
            format.BlockAlign = (short)(format.Channels * (format.BitsPerSample / 8));   
            format.AverageBytesPerSecond = format.BlockAlign * format.SamplesPerSecond;
            return format;
        }

        public void RecStop()
        {
            // 写WAV文件尾  
            mWriter.Seek(4, SeekOrigin.Begin);
            mWriter.Write((int)(mSampleCount + 36));
            mWriter.Seek(40, SeekOrigin.Begin);
            mWriter.Write(mSampleCount);

            mWriter.Close();
            mWaveFile.Close();
            mWriter = null;
            mWaveFile = null;
        }

        ///   
        /// 创建保存的波形文件,并写入必要的文件头.  
        ///   
        public void CreateSoundFile()
        {
            // Open up the wave file for writing.  
            mWaveFile = new FileStream(mFileName, FileMode.Create);
            mWriter = new BinaryWriter(mWaveFile);
            /**************************************************************************  
               Here is where the file will be created. A  
               wave file is a RIFF file, which has chunks  
               of data that describe what the file contains.  
               A wave RIFF file is put together like this:  
               The 12 byte RIFF chunk is constructed like this:  
               Bytes 0 - 3 :  'R' 'I' 'F' 'F'  
               Bytes 4 - 7 :  Length of file, minus the first 8 bytes of the RIFF description.  
                                 (4 bytes for "WAVE" + 24 bytes for format chunk length +  
                                 8 bytes for data chunk description + actual sample data size.)  
                Bytes 8 - 11: 'W' 'A' 'V' 'E'  
                The 24 byte FORMAT chunk is constructed like this:  
                Bytes 0 - 3 : 'f' 'm' 't' ' '  
                Bytes 4 - 7 : The format chunk length. This is always 16.  
                Bytes 8 - 9 : File padding. Always 1.  
                Bytes 10- 11: Number of channels. Either 1 for mono,  or 2 for stereo.  
                Bytes 12- 15: Sample rate.  
                Bytes 16- 19: Number of bytes per second.  
                Bytes 20- 21: Bytes per sample. 1 for 8 bit mono, 2 for 8 bit stereo or  16 bit mono, 4 for 16 bit stereo.  
                Bytes 22- 23: Number of bits per sample.  
                The DATA chunk is constructed like this:  
                Bytes 0 - 3 : 'd' 'a' 't' 'a'  
                Bytes 4 - 7 : Length of data, in bytes.  
                Bytes 8 -: Actual sample data.  
              ***************************************************************************/
            // Set up file with RIFF chunk info.  
            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.  

            // 一个样本点的字节数目  
            if (8 == mWavFormat.BitsPerSample && 1 == mWavFormat.Channels)
                shBytesPerSample = 1;
            else if ((8 == mWavFormat.BitsPerSample && 2 == mWavFormat.Channels) || (16 == mWavFormat.BitsPerSample && 1 == mWavFormat.Channels))
                shBytesPerSample = 2;
            else if (16 == mWavFormat.BitsPerSample && 2 == mWavFormat.Channels)
                shBytesPerSample = 4;

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

            // WAVE块  
            mWriter.Write(ChunkFmt);
            mWriter.Write(nFormatChunkLength);
            mWriter.Write(shPad);
            mWriter.Write(mWavFormat.Channels);
            mWriter.Write(mWavFormat.SamplesPerSecond);
            mWriter.Write(mWavFormat.AverageBytesPerSecond);
            mWriter.Write(shBytesPerSample);
            mWriter.Write(mWavFormat.BitsPerSample);

            // 数据块  
            mWriter.Write(ChunkData);
            mWriter.Write((int)0);   // The sample length will be written in later.
        }

        public void writeData(byte[] data)
        {
            mWriter.Write(data,0,data.Length);
            mSampleCount += data.Length;
        }
    }

    public class WaveFormat
    {
        public int SamplesPerSecond;        // 采样率  int
        public short BitsPerSample;              // 采样位数 short
        public short Channels;                    // 声道:Mono  short
        public short BlockAlign;  // 单位采样点的字节数    short
        public int AverageBytesPerSecond;  //每秒平均码率 int
    }



外部调用:

//声明录音对象
private rec audioRec = null;

//需要录音的时候实例化录音对象,生成文件名
string audioFileName = Application.StartupPath + "\\" + DateTime.Now.ToString("yyyyMMddhhmmssffff") + ".wav";
audioRec = new rec(audioFileName);
audioRec.CreateSoundFile();

//将得到的音频原始流写入录音文件,循环着一帧一帧写
audioRec.writeData(WaveStream);//WaveStream 采集到的音频文件

//结束录音,重要,一定要调用结束
audioRec.RecStop();
//音频文件生成完成



你可能感兴趣的:(桌面应用)