2016-12-14 3 views
0

У меня есть две функции, записанные для записи и записи в волновой файл с использованием NAudio. Я не могу найти тактику, чтобы остановить первую функцию без выполнения последней строки и выхода из локальной области.Запись звука с помощью NAudio и запись в файл при поступлении звука на микрофон

метод audio_Rec вызывается из основной функции и 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 функция

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(); 
     } 
    } 

Свободное игнорировать алгоритмы в второй функции. Их можно пренебречь. Любая помощь очень ценится. Благодаря

ответ

0

Вы можете попробовать следующее:

  • Ручка RecordingStopped события из устройства NAudio волны.
  • Создайте Event или Semaphore или какой-либо другой примитив синхронизации на уровне класса.
  • Когда срабатывает обработчик RecordingStopped, отпустите примитив синхронизации.
  • Прежде чем вы выйдете из основного метода, просто выполните WaitOne() на этом примитиве.

Ваш StopRecording вызов в DataAvailable обработчика результатов в вызове Stopped обработчик, который запускает семафор, который затем будит ваш основной поток так, что он может выйти.

Пример (я неравнодушен к семафоров, так это то, что я использую):

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(); 
} 
+0

Спасибо за помощь. Я понял способ, используя цикл while. Я только что добавил цикл while (! Flag) в конце последней строки (Console.Write («Запись начинается ... \ n»);), которая постоянно проверяет флажок «true?». И я добавил «flag = true» после строки «Запись остановлена». Теперь он работает гладко. –