2017-02-15 8 views
6

мне удалось успешно получить поток аудиоданных, идущих на устройство вывода (динамик) с помощью NAudio:конвертировать аудио поток с частотой

private void OnDataAvailable(object sender, WaveInEventArgs e) 
     { 
      var buffer = e.Buffer; 
      var bytesRecorded = e.BytesRecorded; 
      Debug.WriteLine($"Bytes {bytesRecorded}"); 

И выход образца:

Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 23040 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 
Bytes 19200 

Я тогда преобразование (FFT), чтобы это х и у значений с помощью https://stackoverflow.com/a/20414331:

var buffer = e.Buffer; 
      var bytesRecorded = e.BytesRecorded; 
      //Debug.WriteLine($"Bytes {bytesRecorded}"); 
      var bufferIncrement = _waveIn.WaveFormat.BlockAlign; 

      for (var index = 0; index < bytesRecorded; index += bufferIncrement) 
      { 
       var sample32 = BitConverter.ToSingle(buffer, index); 
       _sampleAggregator.Add(sample32); 
      } 

с выходом образца:

x: -9.79634E-05, y: -9.212703E-05 
x: 6.897306E-05, y: 2.489315E-05 
x: 0.0002080683, y: 0.0004317867 
x: -0.0001720883, y: -6.681971E-05 
x: -0.0001245111, y: 0.0002880402 
x: -0.0005751926, y: -0.0002682915 
x: -5.280507E-06, y: 7.297558E-05 
x: -0.0001143928, y: -0.0001156801 
x: 0.0005231025, y: -0.000153206 
x: 0.0001011164, y: 7.681748E-05 
x: 0.000330695, y: 0.0002293986 

Не уверен, если это вообще возможно, или если я просто недоразумение, что поток возвращается, но я хотел бы получить частоту звукового потока для того, чтобы сделать некоторые вещи с Philips Hue. Значения x, y выше являются малыми для использования в цветовом пространстве CIE. Я делаю что-то неправильно или я полностью не понимаю, что данные находятся в буфере в OnDataAvailable?

Спасибо!

Edit:

Я изменил мой OnDataAvailable код на основе комментариев и учебник по программе автонастройки быть ниже:

private void OnDataAvailable(object sender, WaveInEventArgs e) 
     { 
      var buffer = e.Buffer; 
      float sample32 = 0; 

      for (var index = buffer.Length > 1024 ? buffer.Length - 1024 : buffer.Length; index < e.BytesRecorded; index += 2) 
      { 
       var sample = (short) ((buffer[index + 1] << 8) | buffer[index + 0]); 
       sample32 = sample/32768f; 
       Debug.WriteLine(sample32); 
       LightsController.SetLights(Convert.ToByte(Math.Abs(sample32) * 255)); 
       _sampleAggregator.Add(sample32); 
      } 
      var floats = BytesToFloats(buffer); 

      if (sample32 != 0.0f) 
      { 
       var pitchDetect = new FftPitchDetector(sample32); 
       var pitch = pitchDetect.DetectPitch(floats, floats.Length); 
       Debug.WriteLine($"Pitch {pitch}"); 
      } 
     } 

Надежда состоит в том, что я использую только последний набор элементов из буфера, поскольку он, кажется, не очищается, и меня интересует только последний набор данных, доступных для получения частоты текущего аудио. Тем не менее, я все равно получаю исключение индекса, когда вызывается метод DetectPitch. Где я иду не так? Я надеялся использовать частоту, чтобы изменить цвет и яркость цветовых оттенков.

+1

Вы видели этот пост: http://stackoverflow.com/questions/15009084/implementing-fftpitchdetector-in-c-sharp? –

+0

@DavidTansey У меня нет. Посмотрите на него и отчитайтесь. –

+0

@DavidTansey Я изменил свой код OnDataAvailable, чтобы соответствовать и передавать «floats» и «floats.Length» в pitchDetect.DetectPitch, но я получаю исключение индекса за пределами диапазона в 'SmbPitchShift.smbFft (fftBuffer, frames, -1);' и если закомментирован, в 'float real = fftBuffer [bin * 2];'. Есть идеи? –

ответ

1

Использование

fPeak = SamplingRate * BinNumberOfPeak/FFTLength ;

+0

Что такое "BinNumberOfPeak"? А где «FFTLength»? Вы отвечаете не очень подробно. Я хотел бы понять, что возвращает данные NAudio, а также как получить частоту (и) из данных? –

+0

Длина FFT = 4096 (= N число точек вычислений), а номер бина - индекс в массиве FFT 0, 1, 2 .. Вычисление пиков по частоте является сложным на основе односторонних или двухсторонних спектров. Вы должны следовать [пункт 4 здесь] (http://www.gaussianwaves.com/2014/07/how-to-plot-fft-using-matlab-fft-of-basic-signals-sine-and-cosine-waves /) для понимания достоверных вычислений. – SACn

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