parallel operations with audio stream c#

荒凉一梦 提交于 2019-12-12 05:58:22

问题


I record sound in c#(wpf) and when data from sound card is available it calls this event:

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
    }

As you can see I push every sample from the recorded buffer to a queue that is declared like that:

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

As you can see inside the event after the for loop I want to do some processing on the Queue. I worry that while processing the data, a new samples will come from the sound card and my processing will got lost.

  1. What is the right approach to make that?
  2. Is the processing that I call from the event is a static method/non-static?

回答1:


Given the fact you can buffer the samples and process them later, consider using BlockingCollection. BlockingCollection is an excellent solution for producer-consumer pattern, which to my understanding, is your case. On one side you have myWaveIn_DataAvailable() method as a producer adding samples to the collection, and on the other end you have another consuming thread (it doesn't have to be another thread, though) collecting the samples and processing them. There are various ways the consumer can be implemented, and they are well documented in MSDN.

EDIT: See the following example, I did not test it but it should give you a start point:

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) { }
        }
    }
}


来源:https://stackoverflow.com/questions/31427289/parallel-operations-with-audio-stream-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!