Click here to Skip to main content
15,889,877 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I am using NAudio library to capture the audio signal and do the FFT.

It sort of working. It can captured audio and do the frequency analysis. but what I want is :

playing a tune for 5 seconds, during a second, capture raw data and do FFT. and then check fundamental frequency. and repeat the step.

However, when I play the the tone and use thread.sleep(5000) to make sure the sound played at least 5 secs. and the audio capture events did not trigger until thread.sleep(5000) done. it did not capture anything during this 1 second time.

Please see the code:

first I initialize the instance while the form load:
C#
private void Form1_Load(object sender, EventArgs e)
{

    IWaveIn waveIn = new WaveIn();
    waveIn.DataAvailable += waveIn_DataAvailable;

    sampleAggregator.PerformFFT = true;
    waveIn.DataAvailable += waveIn_DataAvailable;
    sampleAggregator.FftCalculated += new EventHandler<FftEventArgs>(FftCalculated);
}


second write the event handler function for capture raw audio data
C#
void waveIn_DataAvailable(object sender, WaveInEventArgs e)
{
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new EventHandler<WaveInEventArgs>(waveIn_DataAvailable),    sender, e);
            }
            else
            {
                byte[] buffer = e.Buffer;
                int bytesRecorded = e.BytesRecorded;
                int bufferIncrement = waveIn.WaveFormat.BlockAlign;

                for (int index = 0; index < e.BytesRecorded; index += bufferIncrement)
                {
                    short sample = (short)((buffer[index + 1] << 8) |
                                            buffer[index + 0]);
                    float sample32 = sample / 32767f;
                    sampleAggregator.Add(sample32);   // will trigger FFT function
                }
            }
}


and then, FFT trigger event handler:
C#
void FftCalculated(object sender, FftEventArgs e)
{

    int length = 0;
    int i;
    float[] Amp = new float[16384];
    float AmpMax = 0;
    int AmpMaxIndex = 0;

    FftBuffer = e.Result;

    length = FftBuffer.Length / 2;

    for (i = 0; i < length; i++)
    {
        Amp[i] = AmplitudeCalc(FftBuffer[i].X, FftBuffer[i].Y);
        if (Amp[i] > AmpMax)
        {
            AmpMax = Amp[i];
            AmpMaxIndex = i;
        }
    }

    frequency = AmpMaxIndex * 8000 / fftLength;
    //Debug.WriteLine("frequency: " + frequency);


}


and in my main function to play audio for a second.
C#
OnekHz_L.PlayLooping();
waveIn.StartRecording();


Thread.Sleep(5000);

OnekHz_L.Stop();
Stop();

if (frequency < 1050 && frequency > 950)
{
    // do sth.
}
else
{
    // do sth.
}


the problem is during thread.sleep(5000) period, it never trigger waveIn_DataAvailable(object sender, WaveInEventArgs e) and FftCalculated(object sender, FftEventArgs e) two events.

How do I fix it?

Please help
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900