2017-02-15 36 views
6

udało mi się z powodzeniem uzyskać strumień danych audio udających się do urządzenia wyjściowego (głośników) za pomocą NAudio:Konwersja strumienia audio do częstotliwości

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

a wyjście próbki:

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 

następnie przetwarza (FFT) w tym do X i y z użyciem 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); 
      } 

z wyjściem próbki:

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 

Nie jestem pewien, czy jest to w ogóle możliwe lub jeśli mam tylko nieporozumienie co strumień wraca, ale chciałbym, aby uzyskać częstotliwość strumienia audio, aby zrobić kilka rzeczy z Philips Hue. Powyższe wartości x, y są zbyt małe, aby można je było wykorzystać w przestrzeni kolorów CIE. Czy robię coś złego, czy też całkowicie nie rozumiem, jakie dane znajdują się w buforze w OnDataAvailable?

Dzięki!

Edit:

I zostały zmodyfikowane mój OnDataAvailable kodu na podstawie uwag i samouczek dla programu Autotune być poniżej:

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

Jest nadzieja, że ​​używam tylko ostatni zestaw elementy z bufora, ponieważ nie wydaje się, aby się oczyścić i interesuje mnie tylko najnowszy zestaw dostępnych danych, aby uzyskać częstotliwość bieżącego dźwięku. Jednak nadal otrzymuję wyjątek indeksu podczas wywoływania metody DetectPitch. Gdzie się mylę? Miałem nadzieję, że wykorzystam częstotliwość, aby zmienić kolor i jasność żarówek odcień.

+1

Widziałeś tego posta: http://stackoverflow.com/questions/15009084/implementing-fftpitchdetector-in-c-sharp? –

+0

@DavidTansey Nie mam. Przyjrzy się temu i złoży raport. –

+0

@DavidTansey I zmodyfikowałem mój kod OnDataAvailable, aby dopasować i przekazać w "floats" i "floats.Length" do pitchDetect.DetectPitch, ale otrzymuję wyjątek poza zakresem w 'SmbPitchShift.smbFft (fftBuffer, frames, -1);' i jeśli skomentował, w 'float real = fftBuffer [bin * 2];'. Jakieś pomysły? –

Odpowiedz

1

Zastosowanie

fPeak = SamplingRate * BinNumberOfPeak/FFTLength ;

+0

Co to jest "BinNumberOfPeak"? A gdzie jest "FFTLength"? Twoja odpowiedź nie dostarcza zbyt wielu szczegółów. Chciałbym zrozumieć, co zwraca dane w NAudio, a także jak uzyskać częstotliwość (częstotliwości) z danych? –

+0

FFT Length = 4096 (= liczba N punktów obliczeniowych) i Bin number jest indeksem w tablicy FFT 0, 1, 2 .. Obliczanie szczytowej częstotliwości jest trudne w oparciu o jednostronne lub dwustronne widma. Musisz przestrzegać [punkt 4 tutaj] (http://www.gaussianwaves.com/2014/07/how-to-plot-fft-using-matlab-fft-of-basic-signals-sine-and-cosine-waves /) dla zrozumienia autentycznych obliczeń. – SACn