2016-05-10 7 views
1

Я студент-химик, пытающийся использовать NAudio на C# для сбора данных с микрофона моего компьютера (планирование перехода на аудио-порт позже, в случае, если это уместно ответил). Я понимаю, что такое исходные потоки, и как NAudio использует обработчик событий, чтобы узнать, следует ли начинать считывать информацию из указанного потока, но я не понимаю, когда дело доходит до работы с данными, которые были прочитаны из потока. Насколько я понимаю, буферный массив заполняется либо в байтах, либо в формате WAV из исходного потока (с помощью команды AddSamples). Пока что все, что я пытаюсь сделать, это заполнить буфер и написать его содержимое на консоли или сделать простую визуализацию. Я не могу получить мои значения из буфера, и я пробовал рассматривать его как как WAV, так и байтовый массив. Может ли кто-нибудь дать мне понять, как работает NAudio, и как извлекать данные из буфера и хранить его в более удобном формате (т. Е. Удваивается)? Вот код, который я до сих пор для обработки NAudio и все, что происходит с ним:Попытка понять буферы относительно NAudio в C#

public NAudio.Wave.BufferedWaveProvider waveBuffer = null; // clears buffer 

NAudio.Wave.WaveIn sourceStream = null; // clears source stream 

public void startRecording(int samplingFrequency, int deviceNumber, string fileName) 
{  
    sourceStream = new NAudio.Wave.WaveIn(); // initializes incoming audio stream 
    sourceStream.DeviceNumber = deviceNumber; // specifies microphone device number 
    sourceStream.WaveFormat = new NAudio.Wave.WaveFormat(samplingFrequency, NAudio.Wave.WaveIn.GetCapabilities(deviceNumber).Channels); // specifies sampling frequency, channels 

    waveBuffer = new NAudio.Wave.BufferedWaveProvider(sourceStream.WaveFormat); // initializes buffer 

    sourceStream.DataAvailable += new EventHandler<NAudio.Wave.WaveInEventArgs>(sourceStream_DataAvailable); // event handler for when incoming audio is available 

    sourceStream.StartRecording(); 

    PauseForMilliSeconds(500); // delay before recording is stopped   

    sourceStream.StopRecording(); // terminates recording 
    sourceStream.Dispose(); 
    sourceStream = null; 
} 

void sourceStream_DataAvailable(object sender, NAudio.Wave.WaveInEventArgs e) 
{ 
    waveBuffer.AddSamples(e.Buffer, 0, e.BytesRecorded); // populate buffer with audio stream 
    waveBuffer.DiscardOnBufferOverflow = true; 
} 
+0

Добро пожаловать в SO. Пожалуйста, дважды проверьте форматирование кода. –

+0

Попробуйте увеличить паузу в 500 мс и произнести звуки во время паузы. Источник 'WaveIn' запускает только' sourceStream_DataAvailable() ', когда он фактически записывает некоторые звуки. Когда микрофон ничего не записывает, обработчик события не будет вызываться. Кроме того, как вы читаете данные из «BufferedWaveProvider»? Вы сказали, что пытаетесь распечатать/отобразить аудиоданные, но вы не показываете код, который это делает. –

+0

@Abbondanza Я пробовал задерживать серию различных временных интервалов (более 500 мс), и я могу видеть, как считывается некоторая форма данных. Я писал на консоль из метода исходного потока (последний фрагмент кода, который я опубликовал); Я удалил это с тех пор, но это была простая команда 'Debug.WriteLine()'. Главный вопрос, который у меня есть, - это: Как читать данные из буфера/использовать буфер вообще? Я пробовал 'Array.Copy' и' BlockCopy' для отдельного временного массива, но мне не удалось получить ничего согласованного. – Ruvim

ответ

1

Отказ от ответственности: У меня не так много опыта работы с NAudio.


Это отчасти зависит от того, что вы хотите сделать с аудиоданных.

Если вы просто хотите сохранить или сбросить данные (будь то файл цели или просто консоль), то вам не нужен BufferedWaveProvider. Просто делайте то, что вы хотите сделать непосредственно в обработчике событий sourceStream_DataAvailable(). Но имейте в виду, что вы получите данные в качестве исходных байтов, то есть, сколько байтов фактически составляют один кадр (так называемый образец) записанного звука зависит от формата волны:

var bytesPerFrame = sourceStream.WaveFormat.BitsPerSample/8 
        * sourceStream.WaveFormat.Channels 

Если вы хотите, чтобы проанализировать данные (например, анализ Фурье с БПФ), то я предлагаю использовать NASO ISampleProvider. Этот интерфейс скрывает все необработанные байты, бит-глубину и позволяет легко обращаться к кадрам данных.

Сначала создайте ISampleProvider из вашей BufferedWaveProvider так:

var samples = waveBuffer.ToSampleProvider(); 

Вы можете получить доступ к кадру образца с методом Read(). Убедитесь в том, чтобы проверить, если данные на самом деле доступны с BufferedBytes собственности на вашем BufferedWaveProvider:

while (true) 
{ 
    var bufferedFrames = waveBuffer.BufferedBytes/bytesPerFrame;   

    if (bufferedFrames < 1) 
     continue; 

    var frames = new float[bufferedFrames]; 
    samples.Read(frames, 0, bufferedFrames); 

    DoSomethingWith(frames); 
} 

Потому что вы хотите сделать две вещи сразу - записи и анализа звуковых данных одновременно - вы должны использовать два отдельных потока для это.

Для DTMF-анализа записанных аудиоданных имеется small GitHub project that uses NAudio. Вы можете взглянуть на некоторые идеи, как собрать все это вместе. Хороший отправной точкой является файл DtmfDetector\Program.cs.


Для быстрого запуска, который должен дать вам «более последовательной» выход попробуйте следующее:

Добавьте это поле в класс:

ISampleProvider samples; 

Добавить эту строку в метод startRecording():

samples = waveBuffer.ToSampleProvider(); 

Продлить sourceStream_DataAvailable() так:

void sourceStream_DataAvailable(object sender, NAudio.Wave.WaveInEventArgs e) 
{ 
    waveBuffer.AddSamples(e.Buffer, 0, e.BytesRecorded); 
    waveBuffer.DiscardOnBufferOverflow = true; 

    var bytesPerFrame = sourceStream.WaveFormat.BitsPerSample/8 
         * sourceStream.WaveFormat.Channels 
    var bufferedFrames = waveBuffer.BufferedBytes/bytesPerFrame; 

    var frames = new float[bufferedFrames]; 
    samples.Read(frames, 0, bufferedFrames); 

    foreach (var frame in frames) 
     Debug.WriteLine(frame); 
} 
Смежные вопросы