How do we determine the duration of a fundamental frequency using the DFT (or FFT)?

303 Views Asked by At

I'm still in the process of learning the details of the DFT (and FFT) and I've just made a test .wav file in Audacity by joining 3 one-second sine waves together.

.wav file 1 = 440 Hz, sample rate = 44100, samplecount = 44100, 16-bit
.wav file 2 = 495 Hz, sample rate = 44100, samplecount = 44100, 16-bit
.wav file 3 = 495 Hz, sample rate = 44100, samplecount = 44100, 16-bit

VB TEST code:

Private Sub DFT()

Dim N As Integer  
Dim k As Integer  
Dim i As Integer  
Dim mReal() As Double  
Dim mImaginary() As Double  
Dim mPhase() As Double  
Dim mMagnitude() As Double  

N = NumberOfSamples

ReDim mSample(N - 1)  
ReDim mReal(N / 2) As Double  
ReDim mImaginary(N / 2) As Double  
ReDim mPhase(N / 2) As Double  
ReDim mMagnitude(N / 2) As Double  


'Call GenerateWaveSamples(hsbAmplitude.Value, cbo_MIDI_127_Frequencies.Text, lstSampleRate.Text, N, vsb_Number_of_Samples_Forward.Value)  

Call LoadWaveSamples 'Audacity  

For k = 0 To N / 2  
   mReal(k) = 0  
   mImaginary(k) = 0  
Next k  

For k = 0 To N / 2  
   For i = 0 To N - 1  
      mReal(k) = mReal(k) + mSample(i) * Cos(2 * Pi * k * i / N)  
      mImaginary(k) = mImaginary(k) - mSample(i) * Sin(2 * Pi * k * i / N)  
   Next i  
Next k  


For k = 0 To N / 2  
   mMagnitude(k) = Sqr((mReal(k) ^ 2) + (mImaginary(k) ^ 2))  
   mPhase(k) = Atn(mImaginary(k) / mReal(k))  
Next k  
End Sub  

I already have a rough idea how to read the samples and calculate the real and imaginary values, frequencies, magnitudes and phases using both DFT and FFT but how would we determine the DURATION of the fundamental frequencies or notes or pitches programatically or mathematically? Any additional info regarding this would be appreciated.

1

There are 1 best solutions below

1
On

The FT analyses the entire signal - to look at parts of it, scan over the signal with an appropriate window function.

E.g. (using rectangular window)

Take the first 100ms, transform, identify fundamental.

Then take 100ms from 50ms offset and transform, analyse...

Then 100ms from a 100ms offset...

keep analyzing overlapping regions of the signal and look for where the fundamental changes between slices.

When you have mapped times where the fundamental changes, you can easily calculate the duration of each fundamental.

It is generally useful to set a threshold for identifying fundamentals - as a fraction of the signal's RMS. This prevents noise from resulting in fake notes being reported.

The fundamental in a given slice is therefore the frequency with the highest amplitude which is also above the threshold value.