How to automate voice reports for Praat

2019-08-20 09:39发布

问题:

Is there a way to automate the generation of a voice report (under 'Pulses' in the View & Edit window) for Praat as I have to do this for over 100 files. I need the voice report for the whole file and would ideally do this in Python as I am familiar with that.

回答1:

The voice report is an editor command, and will therefore not be available in batch instances of Praat. You will need an instance of Praat that is connected to a GUI (otherwise you'll get a Cannot view or edit a Sound from batch error).

I am unfamiliar with current Python-specific libraries, so I am unaware if there is one that can sidestep this issue (I doubt it). That said, you might be able to avoid this by using sendpraat to procedurally control a remote Praat instance, that can in turn be connected to a GUI. See this answer for some more info on how that would work.

Below you can find an answer using the scripting language in Praat itself. This can be put into a script and executed as a system command (or sent using sendpraat) from whatever language you prefer.

form Voice report...
  positive F0_min 50
  positive F0_max 500
endform

sound = selected("Sound")
end = Get total duration

View & Edit
editor: sound
  # Optimise settings for voice research 
  # and make sure things are turned on
  Pitch settings: f0_min, f0_max, 
    ... "Hertz", "cross-correlation", "automatic"
  info$ = Editor info
  if !extractNumber(info$, "Pulses show:")
    Show pulses
  endif

  Select: 0, end
  report$ = Voice report
endeditor

# Remove header from report
# This leaves text that is parsable as YAML
report$ = replace_regex$(report$, "-- Voice report .*\n", "", 1)
report$ = replace_regex$(report$, "\nTime range .*\n", "", 1)
report$ = replace_regex$(report$, "\s*From 0 to .*\n", "", 1)

writeInfoLine: report$

The voice report (as with most output from Praat) is primarily planned to be consumed by humans, and so is not trivial to parse by machine. I've added some additional commands to pre-process the voice report in my answer to make the output at least parseable by YAML, which might make things easier in your case.



回答2:

[Disclaimer: I am the author of the mentioned Parselmouth library]

Depending on your actual goal, it seems you can get the same 'Voice report' output outside of the Sound editor menu (opened with View & Edit): select a Sound object, analyze its pitch (select Sound, click Analyse periodicity > To Pitch...), and pulses (select Sound and Pitch objects, click To PointProcess (cc)). Afterwards, selecting all 3 objects (Sound, Pitch, PointProcess) and the action Voice report... will allow you to get the output.

This works even in a batch version of Praat (i.e., without graphical user interface). I am no expert in writing Praat scripts, but converting this workflow seems reasonably straightforward.

As for the other part of your question: doing this is Python is actually possible with the Parselmouth library. This is an open-source library I have been creating that allows accessing Praat from Python in a Python-intuitive way:

import parselmouth
sound = parselmouth.Sound("the_north_wind_and_the_sun.wav")
pitch = sound.to_pitch()
pulses = parselmouth.praat.call([sound, pitch], "To PointProcess (cc)")
voice_report_str = parselmouth.praat.call([sound, pitch, pulses], "Voice report", 0.0, 0.0, 75, 600, 1.3, 1.6, 0.03, 0.45)

For some things a Python methods exist on the objects, for some other functionality you'll need to use parselmouth.praat.call until more work gets done on the library. But it works from Python.

However, if you are interested in only a part of the voice report and want to get these as actual numeric variables (for example because you want to run some stats on all 100 files?), all of these things can be accessed independently from the Voice report functionality. E.g., to only get the mean pitch of a certain sound file as Python float:

mean_pitch = parselmouth.praat.call(pitch, "Get mean", 0.0, 0.0, "Hertz")