I've been trying to implement FFT into my music program. I thought everything went great until I finished and saw the results...
To try it for the first time I rendered a Sine-wave in the C5 note (523.25Hz), too see if I got the correct results back from the program. But nope, I got a really weird frequency: -0.01171875Hz
.
I must have done something wrong! But I don't know what.
Here are some functions related to the whole FFT-implementation:
// Initializing the whole playing-part
waveOut = new WaveOutEvent();
audioFileReader = new AudioFileReader(file);
nsp = new NotifyingSampleProvider(audioFileReader.ToSampleProvider());
nsp.Sample += nsp_Sample;
FadeInOut = new FadeInOutSampleProvider(nsp);
waveOut.Init(new SampleToWaveProvider(FadeInOut));
aggregator = new SampleAggregator();
aggregator.NotificationCount = audioFileReader.WaveFormat.SampleRate / 1000;
aggregator.PerformFFT = true;
aggregator.FftCalculated += (s, a) => OnFftCalculated(a);
PlaySource = Filetype.MP3;
I assume I don't have to post the SampleAggregator-class. But if I do, tell me!
void nsp_Sample(object sender, SampleEventArgs e)
{
aggregator.Add(e.Left); // Only tried with Left sample first.
}
Here's where the FFT-data comes back and I start to process it.
protected virtual void OnFftCalculated(FftEventArgs e)
{
float[] magnitudes = new float[data.Length / 2];
for (int i = 0; i < data.Length / 2; i++)
magnitudes[i] = ((float)Math.Sqrt((data[i].X * data[i].X) + (data[i].Y * data[i].Y)));
float max_mag = float.MinValue;
float max_index = -1;
for (int i = 0; i < data.Length / 2; i++)
if (magnitudes[i] > max_mag)
{
max_mag = magnitudes[i];
max_index = i;
}
var frequency = max_index * CurrentSamplerate / 1024; // CurrentSamplerate gets set dynamically incase some tracks have a different samplerate.
Dispatcher.Invoke(new Action(() =>
{
Plswork.Text = frequency.ToString() + "Hz";
}));
}
Yep, that's all.
I assume I've must have made some rookie mistake, but I really don't know what. So any help would be appreciated.
Thank you.
Oh, also: Where I add samples to the aggregator, how do I feed both left and right channel at the same time?