0

According to this article I'm able to capture FFT Result of a wave in sound file. My sampleRate is given by

using (var reader = new WaveFileReader(soundFile))
using (wc = new WaveChannel32(reader) { PadWithZeroes = false })
using (audioOutput = new DirectSoundOut())
{
    wc.Volume = 100;
    sampleRate = reader.WaveFormat.SampleRate;   //<== sampleRate
    averageBytePerSecond = waveIn.WaveFormat.AverageBytesPerSecond; 
    audioOutput.Init(wc);
    try
    {
      audioOutput.Play();

      while (audioOutput.PlaybackState != PlaybackState.Stopped)
      {
        Thread.Sleep(20);
      }

      audioOutput.Stop();
    }
    catch (Exception e)
    {
      Debug.WriteLine(e.Message);
    }
}

I Use the method below to detect the main frequency of my sample (FftLenth is fixed to 8192):

 void FftCalculated(object sender, FftEventArgs e)
{       
    float maxVal = 0;
    int maxIndex = -1;
    for (int i = 0; i < FftLenth / 2; i++)
    {
        float v = e.Result[i].X * e.Result[i].X + e.Result[i].Y * e.Result[i].Y;
        if (v > maxVal)
        {
            maxVal = v;
            maxIndex = i;
        }
    }

    var frequency = maxIndex * (sampleRate / FftLenth);
}

Now I have my frequency, but how can I find the duration of this frequency? (How long the frequency is played.)

Community
  • 1
  • 1
Simon Mardiné
  • 510
  • 2
  • 7
  • 23
  • If you want to measure duration then you'll need compute overlapping FFTs, e.g. advance the window by say 10 ms on each iteration to determine the onset and offset times and then get the difference. This is a horribly inefficient way to measure things like the duration of a tone though. – Paul R Mar 06 '17 at 19:13
  • HI, thanks for your idea, the problem is the audio sample is catch in real time, so how could i "advance the window by say 10 ms" ? What do you mean by "determine the onset and offset times and then get the difference"? Again, thanks for your help :) – Simon Mardiné Mar 07 '17 at 07:32
  • You would need to buffer the audio in order to be able to overlap successive windows. I have no idea whether that is easily doable with NAudio however. As I said above though, this is a horribly inefficient way to try and determine the duration of tones or musical notes - you should probably do some more research into more appropriate algorithms for whatever problem it is that you are trying to solve. – Paul R Mar 07 '17 at 07:42

1 Answers1

0

If you know the frequency and bandwidth of your main signal, you can use a band pass filter and an envelope tracker. You will also need to estimate some sort of amplitude threshold for the envelope onset and decay.

A Goertzel filter is one common combined bandpass filter with an amplitude output. A sliding Goertzel filter can be used to localize time domain events.

hotpaw2
  • 70,107
  • 14
  • 90
  • 153
  • Hi, i start to work around the Goertzel filter. Do you think the filter has to be applied to input signal or to the FFT transformed signal? – Simon Mardiné Mar 09 '17 at 08:23
  • 1
    @SimonMardiné: a Goertzel filter works in the time domain - you don't need an FFT for this. (A useful way to think of a Goertzel filter is that it's effectively the same as a DFT evaluated at just one output bin.) – Paul R Mar 09 '17 at 18:33