0

I'm super new to praat parselmouth in python and I am a big fan, as it enables analyzes without Praat. So my struggle is, that I need formants in a specific sampling rate but I cant change it here. If I change the time_step (and also time window), length of the formant list is not changing. I am mainly using this code: # http://blog.syntheticspeech.de/2021/03/10/how-to-extract-formant-tracks-with-praat-and-python/

and it looks like that

f0min= 75
f0max=300
pointProcess = praat.call(sound, "To PointProcess (periodic, cc)", f0min, f0max)

time_step = 0.01          # or 0.002 see picture
max_formant_num = 5
max_formant_freq = 5000   # men 5000, women 5500
window_length =  0.01      # or 0.002 see picture   
preemphasis = 50

formants = praat.call(sound, "To Formant (burg)", time_step, max_formant_num, max_formant_freq, window_length, preemphasis) 

numPoints = praat.call(pointProcess, "Get number of points")
print(numPoints)
f1_list = []
f2_list = []
f3_list = []
for point in range(0, numPoints):
    point += 1
    t = praat.call(pointProcess, "Get time from index", point)
    f1 = praat.call(formants, "Get value at time", 1, t, 'Hertz', 'Linear')
    f2 = praat.call(formants, "Get value at time", 2, t, 'Hertz', 'Linear')
    f3 = praat.call(formants, "Get value at time", 3, t, 'Hertz', 'Linear')
    f1_list.append(f1)
    f2_list.append(f2)
    f3_list.append(f3)

I can not get the sample rate I'd like (eg 30 Hz). Can someone help?

here I am plotting f1 for both time_steps, but it is still the same length (323) and timepoints

2 Answers2

0

So now I did the change ("Get number of frames") and I can define/ modify the sample rate. It's also running for a part of the wav file but at ~the half I get this Error message: PraatError: Argument "Time" has the value "undefined". For the line where I want to define f1

numPoints = praat.call(formants, "Get number of frames")
print(numPoints)
f1_list = []
f2_list = []
f3_list = []
t_list  = [] # timing
i= 0
for point in range(0, numPoints):
    point += 1
    t = praat.call(pointProcess, "Get time from index", point)
    f1 = praat.call(formants, "Get value at time", 1, t, 'Hertz', 'Linear')
    f2 = praat.call(formants, "Get value at time", 2, t, 'Hertz', 'Linear')
    f3 = praat.call(formants, "Get value at time", 3, t, 'Hertz', 'Linear')
    t_list.append(t)
    f1_list.append(f1)
    f2_list.append(f2)
    f3_list.append(f3)
0

For the record: the original question was asked on Gitter as well (or at least this question was linked to); see https://gitter.im/PraatParselmouth/Lobby?at=610be18129b165332e5e61f2

It seems that both issues have the same underlying cause: you are using parselmouth.praat.call to query the length of or the PointProcess object, or using that object convert the index to time, but afterwards use the results for the Formant object.

In the first case, that's why you always get the same number of points (time points in pointProcess), while you want the number of "frames" in formants. It also explains why you get the same points, but a rougher (interpolated) curve in your plots.

In the second case, you're asking for the time of the points in the PointProcess, rather than the time samples at which the formants were estimated.

I see that the same is happening in the blog post you link to. Potentially, it is correctly there, if you want to sample the formants at the points where Praat estimates the glottal pulses to be, but that seems to be slightly different from your aim?

Yannick Jadoul
  • 391
  • 1
  • 11
  • Ok, yes thats true. I have another aim. But how can I go on now, so that the code gives me the formants for the timepoints? – Kaja Rosa Aug 06 '21 at 13:31
  • You can get the time of the Formant frames, instead of of the PointProcess: `t = praat.call(formants, "Get time from frame number", point)`. I would also suggest to write`t = praat.call(formants, "Get time from frame number", point + 1)` and get rid of the `point += 1` line before. – Yannick Jadoul Aug 09 '21 at 10:30