C# DirectSound 实现录音:原理与代码解析

4星 · 超过85%的资源 需积分: 33 64 下载量 15 浏览量 更新于2024-09-18 收藏 108KB DOC 举报
在C#中实现录音功能,关键在于理解声卡的基本原理和利用DirectSound库提供的功能。首先,录音涉及到的主要组件包括声卡设备、缓冲区以及事件通知机制。声卡作为录音的基础设备,负责音频的捕捉;缓冲区用于存储录音数据,通过多个缓冲区构成一个队列,当一个缓冲区满时,会触发事件通知应用程序进行数据处理;Notify类则作为事件通知的核心,确保录音过程的连续性。 在C#中,具体到Managed Code,我们需要用到以下关键类: 1. **DirectSound类**:如Capture、CaptureBuffer和Notify,它们分别代表声卡描述、音频数据缓冲区和事件通知。DirectX文档提供了详细的API说明,这里不再赘述。 2. **WaveFormat类**:用来描述声音的波形格式,包括采样率、声道数和采样点长度等参数。 3. **Thread类**:创建一个新的线程来专门处理音频缓冲区满的事件,确保录音的实时性。 4. **AutoResetEvent类**:作为事件通知的载体,当缓冲区满了时,通过这个类来触发应用程序的处理。 代码实现部分,首先需要引用必要的程序集,如Windows Forms API、System.Threading、System.IO以及Microsoft.DirectX相关库。然后,定义SoundRecord类,其中包含了缓冲队列的配置,如缓冲区数量、当前录音的位置、已记录的样本数、每次通知的大小和总缓冲区大小。此外,还定义了一个字符串变量mFileName用于存储录音文件的路径。 在类内部,通过这些数据成员和引用的类,我们可以构建一个基本的录音框架。实例化SoundRecord对象后,可以通过调用相应的成员方法开始录音,例如设置录音格式、初始化缓冲区、启动新线程监听缓冲区状态变化,以及在缓冲区满时将数据写入文件等步骤。 值得注意的是,在实际开发过程中,可能需要处理错误和异常情况,比如设备可用性检查、音频格式转换、文件I/O错误等。此外,为了提供更好的用户体验,可能还需要添加停止录音、暂停和恢复等功能。 C#中实现录音功能涉及到了音频处理的基础概念和DirectSound库的高级用法,通过合理的类设计和事件驱动编程,可以高效地实现稳定的录音功能。
2019-03-07 上传
录音程序,可在DEC++或vc++6.0编译环境下成功运行 部分代码: int main() { creat_file(); //新建文件,原文件数据被删除 RecordWave(); //录音函数 simplest_pcm16le_to_wave("NocturneNo2inEflat_44.1k_s16le.pcm", 1, 44100, "output_nocture.wav"); //将二进制录音信息从内存中提取,并生成 wav 文件 测控 1602 DEV C ++ 环境下 控制台应用程序 善解人意 成员:王帅、赵永玻、侯雅茹 3 return 0; } void RecordWave() { int count = waveInGetNumDevs(); //检测录音设备 printf("\n 音频输入数量:%d\n", count); WAVEINCAPS waveIncaps; MMRESULT mmResult = waveInGetDevCaps(0, &waveIncaps;, sizeof(WAVEINCAPS)); printf("\n 音频输入设备:%s\n", waveIncaps.szPname); if (MMSYSERR_NOERROR == mmResult) { //HWAVEIN phwi; WAVEFORMATEX pwfx; //录音格式指针 WaveInitFormat (&pwfx;, //波形声音的格式,单声道双声道使用 WAVE_FORMAT_PCM.当包含在 WAVEFORMATEXTENSIBLE 结构中时,使用 WAVE_FORMAT_EXTENSIBLE 1, //声道数量 44100, //采样率 16 // 采样位数 ); printf("\n 正在打开音频输入设备"); printf("\n 采样参数:声道 44.1kHz 16bit\n"); mmResult = waveInOpen( &phwi;, WAVE_MAPPER, &pwfx;, (DWORD)(MicCallback), NULL, CALLBACK_FUNCTION );//3 if (MMSYSERR_NOERROR == mmResult) { //WAVEHDR pwh1; char buffer1[10240]; pwh1.lpData = buffer1; pwh1.dwBufferLength = 10240; pwh1.dwUser = 1; pwh1.dwFlags = 0; 测控 1602 DEV C ++ 环境下 控制台应用程序 善解人意 成员:王帅、赵永玻、侯雅茹 4 mmResult = waveInPrepareHeader(phwi, &pwh1;, sizeof(WAVEHDR));//为波形输 入设备准备缓冲区 printf("\n 准备缓冲区 1"); //WAVEHDR pwh2; char buffer2[10240]; pwh2.lpData = buffer2; pwh2.dwBufferLength = 10240; pwh2.dwUser = 2; pwh2.dwFlags = 0; mmResult = waveInPrepareHeader(phwi, &pwh2;, sizeof(WAVEHDR));//为波形输 入设备准备缓冲区 printf("\n 准备缓冲区 2\n"); // WAVEHDR pwh3; char buffer3[10240]; pwh3.lpData = buffer3; pwh3.dwBufferLength = 10240; pwh3.dwUser = 3; pwh3.dwFlags = 0; mmResult = waveInPrepareHeader(phwi, &pwh3;, sizeof(WAVEHDR));//为波形输 入设备准备缓冲区 printf("准备缓冲区 3\n"); if (MMSYSERR_NOERROR == mmResult) { mmResult = waveInAddBuffer(phwi, &pwh1;, sizeof(WAVEHDR));//给输入设 备增加一个缓存 printf("\n 将缓冲区 1 加入音频输入设备"); mmResult = waveInAddBuffer(phwi, &pwh2;, sizeof(WAVEHDR));//给输入设 备增加一个缓存 printf("\n 将缓冲区 2 加入音频输入设备\n"); mmResult = waveInAddBuffer(phwi, &pwh3;, sizeof(WAVEHDR));//给输入设 备增加一个缓存 printf("将缓冲区 3 加入音频输入设备\n");