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ń.
Widziałeś tego posta: http://stackoverflow.com/questions/15009084/implementing-fftpitchdetector-in-c-sharp? –
@DavidTansey Nie mam. Przyjrzy się temu i złoży raport. –
@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? –