在网上找了很多类似录音教程效果都不好,或根本不能录音,代码由网上借鉴修改(完整实现录音播放功能)

NAudio

NAudio为.NET平台下的开源库,采用ML-PL协议,开源地址:https://github.com/naudio/NAudio。

NAudio功能强大,且其入门容易。 强大在于:它支持许多音频操作,可实现多种API播放与录制、多种不同音频格式、音频格式转换(重采样、位深、声道等)、音频编码、多通道播放、音频效果处理等等(详细介绍可以看Github readme)。

基本使用

基本代码示例

// 创建WaveIn实例 它将用于录制音频。你可以指定音频的采样率、通道数和位深度。
var waveIn = new WaveIn();

// 设置录音参数
waveIn.WaveFormat = new WaveFormat(44100, 16, 1);

// 设置录音事件处理函数
waveIn.DataAvailable += OnDataAvailable;

// 创建WaveFileWriter实例 它将用于将录制的音频写入文件
var writer = new WaveFileWriter("output.wav", waveIn.WaveFormat);

// 开始录音
waveIn.StartRecording();

// 停止录音
waveIn.StopRecording();
writer.Close();

// 录音事件处理函数
private void OnDataAvailable(object sender, WaveInEventArgs e)
{
    writer.Write(e.Buffer, 0, e.BytesRecorded);
}

实例

新建一个类

RecordController.cs

public class RecordController
{
  public WaveIn mWavIn;
  public WaveFileWriter mWavWriter;
  /// <summary>
  /// 开始录音
  /// </summary>
  /// <param name="filePath">录音文件路径</param>
  public void StartRecord(string filePath)
    {
      //录音文件路径
      mWavIn = new WaveIn();
      // 添加DataAvailable事件处理程序
      mWavIn.DataAvailable += MWavIn_DataAvailable;
      // mWavIn.RecordingStopped += MWavIn_RecordingStopped; 有冲突
      // 创建WaveFileWriter对象
      mWavWriter = new WaveFileWriter(filePath, mWavIn.WaveFormat);
      // 开始录音
      mWavIn.StartRecording();
    }
    /// <summary>
    /// 停止录音
    /// </summary>
  public void StopRecord()
    {
      // 停止录音
      mWavIn ? .StopRecording();
      // 释放WaveIn对象
      mWavIn ? .Dispose();
      mWavIn = null;
      // 关闭WaveFileWriter对象
      mWavWriter ? .Close();
      mWavWriter = null;
    }
    // 这个方法在调用关闭时会有冲突,暂时注释掉
    //private void MWavIn_RecordingStopped(object sender, StoppedEventArgs e)
    //{
    //    mWavIn?.Dispose();
    //    mWavIn = null;
    //    mWavWriter?.Close();
    //    mWavWriter = null;
    //}
    /// <summary>
    /// DataAvailable事件处理程序
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
  private void MWavIn_DataAvailable(object sender, WaveInEventArgs e)
  {
    // 写入录音数据
    mWavWriter.Write(e.Buffer, 0, e.BytesRecorded);
    // 计算已录制的秒数
    int secondsRecorded = (int) mWavWriter.Length / mWavWriter.WaveFormat.AverageBytesPerSecond;
  }
}

在StartRecord方法中,创建了WaveIn对象和WaveFileWriter对象,分别用于录制音频数据和将音频数据写入文件。添加了DataAvailable事件处理程序,用于在录音过程中将音频数据写入文件。在StopRecord方法中,停止录音并释放WaveIn对象和WaveFileWriter对象。

在MWavIn_DataAvailable方法中,将音频数据写入文件,并计算已录制的秒数。注释中说明了MWavIn_RecordingStopped方法存在冲突,暂时注释掉了该方法

方法调用

RecordController record = new RecordController();
/// <summary>
/// 测试
/// </summary>
/// <param name="i"></param>
public void Sidetone(int i)
{
  // 获取ListView中的行
  string[] row = getlistviewitem(i);
  // 开始录音
  record.StartRecord("e:\rec.wav");
    
  // 如果用户选择不播放录音,则停止录音并将错误标志设置为false
  if(MessageBox.Show("正在录音,点击是播放录音", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No)
  {
    record.StopRecord();
    ErrorFlag = false;
    row[6] = "FAIL";
  }
  else
  {
    // 停止录音并播放录音
    record.StopRecord();
    string path = "e:\rec.wav";
    //.wav音频文件路径
    System.Media.SoundPlayer player = new System.Media.SoundPlayer(path);
    player.Play();
      
    // 如果用户选择没有录音,则将错误标志设置为false
    if(MessageBox.Show("是否有录音", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No)
    {
      ErrorFlag = false;
      row[6] = "FAIL";
    }
    else
    {
      // 如果用户选择有录音,则将错误标志设置为true,并将行的第5列设置为“OK”,第6列设置为“PASS”
      ErrorFlag = true;
      row[5] = "OK";
      row[6] = "PASS";
    }
  }
  // 更新ListView中的行
  listupdate(row, i);
}

Sidetone的函数,它接受一个整数参数i,用于录音并播放录音,然后根据用户的响应更新ListView控件中指定索引位置的行数据。