0

я запись звука в C# (WPF) и когда данные из звуковой карты доступна она называет это событие:параллельные операции с аудио потоком C#

void myWaveIn_DataAvailable(object sender, WaveInEventArgs e) 
    { 
     for (int index = 0; index < e.BytesRecorded; index += 2)//Here I convert in a loop the stream into floating number samples 
     { 

      short sample = (short)((e.Buffer[index + 1] << 8) | 
            e.Buffer[index + 0]); 
      samples32Queue.Enqueue(sample/32768f); 
     } 
     //***Do some Processing with data inside Queue 
    } 

Как вы можете видеть, я нажимаю каждую пробу из записанного буфера очередь, объявленная так:

Queue<float> samples32Queue = new Queue<float>(); 

Как вы можете видеть внутри события после for loop я хочу сделать некоторую обработку очереди. Я волнуюсь, что при обработке данных новые звуковые карты будут получены из звуковой карты, и моя обработка будет потеряна.

  1. Каков правильный подход к этому?
  2. Является ли обработка, которую я вызываю из события, является статическим методом/нестационарным?
+0

ли это система RT? Если нет, вы можете буферизовать образцы и обрабатывать их позже. Если да, то у вас нет выбора - вы должны убедиться, что ваша функция обработки «быстрее», а затем входящие образцы. –

+0

Привет, я пытаюсь сделать это RT – axcelenator

+0

Выполняется ли обработка каждого образца ** ** до того, как придет новый образец? Или можно смоделировать дизайн производителя - потребителя? –

ответ

2

Учитывая тот факт, что вы можете буферизовать образцы и обрабатывать их позже, рассмотрите возможность использования BlockingCollection. BlockingCollection - отличное решение для шаблона производителя-потребителя, которое, насколько я понимаю, является вашим делом. С одной стороны у вас есть метод myWaveIn_DataAvailable() как производитель, добавляющий образцы в коллекцию, а с другой стороны у вас есть другой потребляющий поток (он не должен быть другим потоком), собирая образцы и обрабатывая их. Существуют различные способы реализации потребителя, и они хорошо документированы в MSDN.

EDIT: Смотрите следующий пример, я не проверял, но это должно дать вам начальную точку:

class ProducerConsumerExample 
{ 
    BlockingCollection<float> samples32Collection; 
    Thread consumer; 
    public ProducerConsumerExample() 
    { 
     samples32Collection = new BlockingCollection<float>(); 
     consumer = new Thread(() => LaunchConsumer()); 
     consumer.Start(); //you don't have to luanch the consumer here... 
    } 
    void Terminate() //Call this to terminate the consumer 
    { 
     consumer.Abort(); 
    } 
    void myWaveIn_DataAvailable(object sender, WaveInEventArgs e) 
    { 
     for (int index = 0; index < e.BytesRecorded; index += 2)//Here I convert in a loop the stream into floating number samples 
     { 

      short sample = (short)((e.Buffer[index + 1] << 8) | 
            e.Buffer[index + 0]); 
      samples32Collection.Add(sample/32768f); 
     } 
    } 

    void LaunchConsumer() 
    { 
     while (true /* insert your abort condition here*/) 
     { 
      try 
      { 
       var sample = samples32Collection.Take(); //this thread will wait here until the producer add new item(s) to the collection 
       Process(sample); //in the meanwhile, more samples could be added to the collection 
            //but they will not be processed until this thread is done with Process(sample) 
      } 
      catch (InvalidOperationException) { } 
     } 
    } 
} 
+0

Здравствуйте, в предыдущей ссылке msdn, есть пример с Tasks. Если мой продюсер - это событие, как я могу сделать его как задачу? Как должен выглядеть мой потребитель? Извините за беспокойство, я очень новичок в C# и параллельном программировании ... – axcelenator

+0

@axcelenator см. Мое последнее редактирование. –

 Смежные вопросы

  • Нет связанных вопросов^_^