Difference between revisions of "Meas formants"
From Phonlab
Jump to navigationJump to searchm |
|||
Line 26: | Line 26: | ||
"(?P<vowel>AA|AE|AH|AO|AW|AX|AXR|AY|EH|ER|EY|IH|IX|IY|OW|OY|UH|UW|UX)(?P<stress>\d)?" |
"(?P<vowel>AA|AE|AH|AO|AW|AX|AXR|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. |
# The output header line. |
||
− | head = '\t'.join(( |
+ | head = '\t'.join(fldmap[0:len(fldmap):2]) + '\n' |
− | rms f1 f2 f3 f4 f0 word context' |
||
⚫ | |||
# Format string used for output. |
# Format string used for output. |
||
− | fmt = '\t'.join( |
+ | fmt = '\t'.join( \ |
+ | [ \ |
||
− | "{idx:d}", "{vowel}", "{stress}", "{rms}", "{f1}", "{f2}", |
||
− | + | '{' + '{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. |
# Name to use for ifcformant output file. |
Revision as of 12:22, 15 October 2013
#!/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|AX|AXR|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)