麦克风输入静音时,使用NAudio录制音频并写入文件

时间:2016-12-14 08:38:07

标签: c# audio-recording naudio

我编写了这两个函数来记录并使用NAudio写入波形文件。我没有找到一个策略来停止第一个函数而不执行最后一行并离开本地范围。

audio_Rec 方法从main函数调用, audioSource_DataAvailable 函数在 WaveInEvent 中缓冲数据时执行。我认为, audioSource_DataAvailable 功能仅在 audio_Rec 方法的范围内运行,当代码到达 audio_Rec 的最后一行时(在线下) ,

Console.Write("Recording Starts...\n");

它超出范围,主要功能的下一行执行。 (主要没有提到)。我想要一种方法在录制音频时支持 audio_Rec 方法,直到在 audioSource_DataAvailable 函数中的给定条件下停止录制。

计数 求和是公共成员变量。

audio_Rec方法

    public void audio_Rec()
    {
        audioSource = new WaveInEvent();
        audioSource.DeviceNumber = 0;
        audioSource.WaveFormat = new WaveFormat(16000, 16, 1);

        audioSource.DataAvailable += new EventHandler<WaveInEventArgs>(audioSource_DataAvailable);
        waveFile = new WaveFileWriter(@"d:/dev/csharp/wspeechrec/new_wave.wav", audioSource.WaveFormat);

        audioSource.StartRecording();
        Console.Write("Recording Starts...\n");

        //Thread.Sleep(7000);
    }

audioSource_DataAvailable function

    void audioSource_DataAvailable(object sender, WaveInEventArgs e)
    {
        count++;
        if (count%5 == 0)
        {
            if (summation < 150000) {
                audioSource.StopRecording();
                Console.Write("Recording Stopped!");
            }
            Console.WriteLine(count * 100 + "ms :"+summation);
            summation = 0;
        }

        Console.WriteLine(count+" "+summation);
        byte[] buf = new byte[e.BytesRecorded];
        buf = e.Buffer;
        int[] Ints = new int[e.BytesRecorded / 2]; 

        for(int i=0;i<buf.Length;i+=2)
        {
            Ints[i/2] = BitConverter.ToInt16(buf, i);
        }

        int[] newInts = Ints.Select(x => Math.Abs(x)).ToArray();
        summation = newInts.Sum();

        if (waveFile != null)
        {
            waveFile.Write(e.Buffer, 0, e.BytesRecorded);
            waveFile.Flush();
        }
    }

可以在第二个功能中自由忽略算法。他们可以被忽视。 任何帮助都非常感谢。感谢

1 个答案:

答案 0 :(得分:0)

您可以尝试以下操作:

  • 处理来自NAudio wave设备的RecordingStopped事件。
  • 在班级创建EventSemaphore或其他同步原语。
  • 触发RecordingStopped处理程序时,启动同步原语。
  • 在main方法退出之前,只需对该原语执行WaitOne()

StopRecording处理程序中的DataAvailable调用导致调用Stopped处理程序,该处理程序触发信号量,然后信号量会唤醒主线程以便它可以退出。 / p>

示例(我偏爱信号量,所以我正在使用它):

using System.Threading;

Semaphore AudioSync = new Semaphore(0, int.MaxValue);

public void audio_Rec()
{
    audioSource = new WaveInEvent();
    audioSource.DeviceNumber = 0;
    audioSource.WaveFormat = new WaveFormat(16000, 16, 1);

    // Register for the 'RecordingStopped' event.
    audioSource.PlaybackStopped += this.audioSource_PlaybackStopped;

    audioSource.DataAvailable += new EventHandler<WaveInEventArgs>(audioSource_DataAvailable);
    waveFile = new WaveFileWriter(@"d:/dev/csharp/wspeechrec/new_wave.wav", audioSource.WaveFormat);

    audioSource.StartRecording();
    Console.Write("Recording Starts...\n");

    // Now just wait for the "PlaybackStopped" event handler to signal completion.
    AudioSync.WaitOne();   // <-------------------------------------
}

Stopped事件处理程序:

void audioSource_PlaybackStopped( object sender, StoppedEventArgs e )
{
    // Wakes up the main thread.
    AudioSync.Release();
}