C# 中使用DirectSound录音

一,声卡录音的基本原理

为了实现一个录音的基本过程,至少需要以下对象的支持:

1.录音设备,对我们的PC设备就是声卡。这个录音设备可以进行的操作应该有开始和关闭。

2.缓冲区,也就是我们录制的声音放在哪里的问题。

二,DirectSound对录音的描述模型

1.DirectSound对录音的支持类

Capture,设备对象,可以看作是声卡的描述。

CaptureBuffer,缓冲区对象,存放录入的音频数据。

Notify,事件通知对象,由于录音是一个长时间的过程,因此使用一个缓冲队列(多个缓冲区)接受数据,每当一个缓冲区满的时候,系统使用这个对象通知应用程序取走这个缓冲区,并继续录音。

以上三个对象是进行录音操作的主要对象,由于在C++中队DirectSound的操作DirectX帮助文档中已经有很详细的说明,这里就不再赘述了。本文主要是针对Managed Code。除了以上三个主要的DirectSound类,还需要以下几个辅助类。

WaveFormat,描述了进行录制的声音波形的格式,例如采样率,单声道还是立体声,每个采样点的长度等等。

Thread,线程类,由于录音的过程是需要不断处理缓冲区满的事件,因此新建一个线程对此进行单独处理。

AutoResetEvent,通知的事件,当缓冲区满的时候,使用该事件作为通知事件。

三,代码解析(SoundRecord类)

1.需要引用的程序集

using System;

using System.Windows.Forms;

using System.Threading;

using System.IO;

//对DirectSound的支持

using Microsoft.DirectX;

using Microsoft.DirectX.DirectSound;

2.SoundRecord的成员数据

        public const int cNotifyNum = 16;       // 缓冲队列的数目
        private int mNextCaptureOffset = 0;      // 该次录音缓冲区的起始点

        private int mSampleCount = 0;            // 录制的样本数目
        private int mNotifySize = 0;             // 每次通知大小

        private int mBufferSize = 0;             // 缓冲队列大小

        private string mFileName = string.Empty;     // 文件名

        private FileStream mWaveFile = null;         // 文件流

        private BinaryWriter mWriter = null;         // 写文件
        private Capture mCapDev = null;              // 音频捕捉设备

        private CaptureBuffer mRecBuffer = null;     // 缓冲区对象

        private Notify mNotify = null;               // 消息通知对象
        private WaveFormat mWavFormat;                       // 录音的格式

        private Thread mNotifyThread = null;                 // 处理缓冲区消息的线程

        private AutoResetEvent mNotificationEvent = null;    // 通知事件

 

3.对外操作的函数

        /// <summary>
        /// 构造函数,设定录音设备,设定录音格式
        /// </summary>
        public SoundRecord1()
        {
            //初始化录音设备
            InitCaptureDevice();

            //设定录音格式
            mWavFormat = CreateWaveFormat();
        }

 

        /// <summary>
        /// 设定录音结束后保存的文件,包括路径
        /// </summary>
        /// <param name="filename"></param>
        public void SetFileName(string filename)
        {
            mFileName = filename;
        }

 

        /// <summary>
        /// 开始录音
        /// </summary>
        public void RecStart()
        {
            //创建录音文件
            CreateSoundFile();

            //创建一个录音缓冲区,并开始录音
            CreateCaptureBuffe