Computing formants using parselmouth

355 views
Skip to first unread message

manjot gill

unread,
Sep 2, 2023, 1:33:01 PM9/2/23
to Parselmouth
Hello

I am trying to compute formants using the following code , but getting all values as NaN. Tried the code for both mono (16khz) and stereo (44.1khz) files. the output is NaN. 
When i executed code for pitch, intensity, vowel onset point, the wav file worked well and gave correct output, only problem lies while computing formants. so i am sharing code for formants computation. 

import parselmouth

def extract_formants(audio_path):
    try:
        # Load the audio using parselmouth
        sound = parselmouth.Sound(audio_path)
       
        # Extract formants
        formants = sound.to_formant_burg()

        # Extract F1, F2, F3 frequencies
        f1_freqs = formants.get_value_at_time(1, 0)  # First formant frequency
        f2_freqs = formants.get_value_at_time(2, 0)  # Second formant frequency
        f3_freqs = formants.get_value_at_time(3, 0)  # Third formant frequency
       
        return f1_freqs, f2_freqs, f3_freqs
    except Exception as e:
        print(f"Error processing {audio_path}: {str(e)}")
        return None, None, None

# Example usage:
audio_path = 'C:/Users/m.wav'
f1, f2, f3 = extract_formants(audio_path)

if f1 is not None and f2 is not None and f3 is not None:
    print(f"F1: {f1} Hz, F2: {f2} Hz, F3: {f3} Hz")
else:
    print("Formant extraction failed.")


Inputs are welcomed;

yannick...@gmail.com

unread,
Sep 2, 2023, 4:50:27 PM9/2/23
to Parselmouth
Hi

You're querying the formant values at time 0, so that's most likely outside of the analysis range of Praat, since it works with sliding windows and the first window's center is at a later time step than 0 seconds.
I checked this with a file in Praat, and the value returned is also NaN, so Parselmouth is consistent with Praat here.

The same goes for querying Pitch at time 0, so I don't know what you did there:
```
>>> import parselmouth
>>> import numpy as np
>>> sound = parselmouth.Sound(np.sin(np.arange(48000) / 48000 * 2 * np.pi * 200), 48000)
>>> pitch = sound.to_pitch()
>>> pitch.get_value_at_time(0)
nan
>>> pitch.get_value_at_time(0.1)
200.00468483404

```

You can try out these things interactively in the Praat GUI, and read up in the Praat documentation about the algorithm and interpolation, etc:

"If Time is not within half a frame width of any frame centre, or if Formant number is greater than the number of formants in the frame, the value is undefined;"


Kind regards
Yannick Jadoul

manjot gill

unread,
Sep 6, 2023, 9:59:14 AM9/6/23
to Parselmouth
Thanks a lot dear........ I struggled with the code and after posting here tried options like changing 0 to 0.1 or 0.2 .... and got the results.
But your inputs confirmed that 0.1 onwards values will work.

Thanks once again

yannick...@gmail.com

unread,
Sep 6, 2023, 10:56:10 AM9/6/23
to Parselmouth
Great, that makes sense indeed.
Thanks for the update, and good luck with the rest of the project! If there's anything regarding Parselmouth, you know where to find me.

Yannick
Reply all
Reply to author
Forward
0 new messages