Difference between revisions of "Meas formants"
From Phonlab
Jump to navigationJump to searchm |
m |
||
Line 1: | Line 1: | ||
<code>meas_formants</code> is a sample script for doing formant analysis on an audio file, reading an associated Praat TextGrid, and extracting formant measurements from vowel tokens. You can copy the script and customize it to your own project. |
<code>meas_formants</code> is a sample script for doing formant analysis on an audio file, reading an associated Praat TextGrid, and extracting formant measurements from vowel tokens. You can copy the script and customize it to your own project. |
||
+ | |||
+ | See [[meas_formants_walkthrough]] for more detail on some of the concepts used in this script. |
||
<nowiki> |
<nowiki> |
Revision as of 10:21, 11 February 2014
meas_formants
is a sample script for doing formant analysis on an audio file, reading an associated Praat TextGrid, and extracting formant measurements from vowel tokens. You can copy the script and customize it to your own project.
See meas_formants_walkthrough for more detail on some of the concepts used in this script.
#!/usr/bin/env python # Measure formants. Read input textgrids, call ifcformant on associated audio file, # and output measurements to .meas files. Usage = 'meas_formants speaker file1.TextGrid [file2.TextGrid] ... [fileN.TextGrid]' import audiolabel import os, sys, subprocess import re import numpy as np # Do minimal checking to ensure the script was called with appropriate # arguments. try: if not (sys.argv[1] == 'male' or sys.argv[1] == 'female' or sys.argv[1] == 'child'): raise sys.argv[2] != None except: raise Exception('Usage: ' + Usage) # Regular expression used to identify vowels. vre = re.compile( "^(?P<vowel>AA|AE|AH|AO|AW|AXR|AX|AY|EH|ER|EY|IH|IX|IY|OW|OY|UH|UW|UX)(?P<stress>\d)?$" ) # Mapping of column headings to column formats fldmap = ( "t1", "0.4f", "t2", "0.4f", "lintime", "0.4f", "ifctime", "0.4f", "idx", "d", "vowel", "s", "stress", "s", "rms", "s", "f1", "s", "f2", "s", "f3", "s", "f4", "s", "f0", "s", "word", "s", "context", "s", ) # The output header line. head = '\t'.join(fldmap[0:len(fldmap):2]) + '\n' # Format string used for output. fmt = '\t'.join( \ [ \ '{' + '{0}:{1}'.format(col,fmt) + '}' \ for col, fmt in zip( \ fldmap[0:len(fldmap):2], \ fldmap[1:len(fldmap):2] \ ) \ ] \ ) + '\n' # Name to use for ifcformant output file. tempifc = '__temp.ifc' speaker = sys.argv[1] ifc_args = ['ifcformant', '--speaker=' + speaker, '-e', 'gain -n -3 sinc -t 10 60 contrast', '--print-header', '--output=' + tempifc] # Loop over all the input files specified on the command line. for tg in sys.argv[2:]: fname = os.path.splitext(tg)[0] # get filename without extension with open(fname + '.meas', 'w') as out: # Praat LabelManager. pm = audiolabel.LabelManager(fromFile=tg, fromType='praat') # Create ifcformant results and read into ifc LabelManager. proc = subprocess.Popen(ifc_args + [fname + '.wav'], stderr=subprocess.PIPE) proc.wait() if proc.returncode != 0: for line in proc.stderr: sys.stderr.write(line + '\n') raise Exception("ifcformant exited with status: {0}".format(proc.returncode)) ifc = audiolabel.LabelManager(fromFile=tempifc, fromType='table', t1Col='sec') out.write(head) # Loop over all the vowel labels in the tier named 'phone'. for v, m in pm.tier('phone').search(vre, returnMatch=True): if v.duration() > 1 and v.t1() != 0: continue # Safer to use center of a label as reference point than an edge. word = pm.tier('word').labelAt(v.center()) context = pm.tier('context').labelAt(v.center()) # Take measurements at start and end of vowel and at five # equally-spaced intervals in between them. for idx, t in enumerate(np.linspace(v.t1(), v.t2(), num=7)): meas = ifc.labelsAt(t) out.write(fmt.format(t1=v.t1(), t2=v.t2(), lintime=t, ifctime=meas.f1.t1(), idx=idx, vowel=m.group('vowel'), stress=m.group('stress'), rms=meas.rms.text, f1=meas.f1.text, f2=meas.f2.text, f3=meas.f3.text, f4=meas.f4.text, f0=meas.f0.text, word=word.text, context=context.text) ) os.unlink(tempifc)