Skip to content

Instantly share code, notes, and snippets.

@Nesh108
Created December 16, 2022 13:37
Show Gist options
  • Save Nesh108/75a4760e60c1456ba669c2e88b9d6935 to your computer and use it in GitHub Desktop.
Save Nesh108/75a4760e60c1456ba669c2e88b9d6935 to your computer and use it in GitHub Desktop.
[Speed Processing] Processing Praat TextGrids to calculate F1, F2 and F0 of angry and sad emotion files.
import glob
import tgt
import sys
import parselmouth
import statistics
DEBUG = False
def get_f0_mean_stdev(filesSounds):
sum = 0
f0s = []
for i, filename in enumerate(filesSounds):
pitch = parselmouth.Sound(filename).to_pitch()
f0_val = pitch.get_mean_absolute_slope()
sum += f0_val
f0s.append(f0_val)
return [sum/len(filesSounds), statistics.stdev(f0s)]
def process_formants(filesTextgrid, filesSound):
vowels_formants = {
"a": [[],[]],
"i": [[],[]],
"u": [[],[]],
}
for i, filename in enumerate(filesTextgrid):
try:
tg = tgt.io.read_textgrid(filename)
formant = parselmouth.Sound(filesSound[i]).to_formant_burg()
if DEBUG:
print(filename + " + " + filesSound[i])
for tiername in tg.get_tier_names():
if tiername in ["a", "i", "u"]:
annotation = tg.get_tier_by_name(tiername).get_annotations_with_text(tiername)[0]
f1_start_value = formant.get_value_at_time(1, annotation.start_time)
f1_end_value = formant.get_value_at_time(1, annotation.end_time)
f1_mean = (f1_start_value + f1_end_value) / 2
f2_start_value = formant.get_value_at_time(2, annotation.start_time)
f2_end_value = formant.get_value_at_time(2, annotation.end_time)
f2_mean = (f2_start_value + f2_end_value) / 2
vowels_formants[tiername][0].append(f1_mean)
vowels_formants[tiername][1].append(f2_mean)
if DEBUG:
print(filename + " " + format_formant(tiername, f1_mean, f2_mean))
elif DEBUG:
print('\t Skipping: ' + tiername)
except err:
print(filename + ' caused a problem.')
sys.stderr.write('ERROR: %s\n' % str(err))
return vowels_formants
def calculateFormantAverages(v_formants):
vowels = {
"a": [0,0],
"i": [0,0],
"u": [0,0],
}
for vowel_name, formants in v_formants.items():
sum = 0
for f0 in formants[0]:
sum += f0
vowels[vowel_name][0] = sum / len(formants[0])
sum = 0
for f1 in formants[1]:
sum += f1
vowels[vowel_name][1] = sum / len(formants[1])
return vowels
def print_formants(formants):
for vowel_name, formants in formants.items():
print(format_formant(vowel_name, formants[0], formants[1]))
def format_formant(vowel, f1, f2):
return "\t" + vowel + ") F1: " + str(f1) + " | F2: " + str(f2)
def main(argv=None):
print("=== Angry Emotions Analysis ===")
print("===============================\n")
filesTextgrid = glob.glob(r'../A_*.TextGrid')
filesSound = glob.glob(r'../wav/A_*.wav')
angry_formants = process_formants(filesTextgrid, filesSound)
print_formants(calculateFormantAverages(angry_formants))
mean, stdev = get_f0_mean_stdev(filesSound)
print("\tF0) Mean: " + str(mean) + " | Stdev: " + str(stdev))
print("\n=== Sad Emotions Analysis ===")
print("=============================\n")
filesTextgrid = glob.glob(r'../S_*.TextGrid')
filesSound = glob.glob(r'../wav/S_*.wav')
sad_formants = process_formants(filesTextgrid, filesSound)
print_formants(calculateFormantAverages(sad_formants))
mean, stdev = get_f0_mean_stdev(filesSound)
print("\tF0) Mean: " + str(mean) + " | Stdev: " + str(stdev))
if __name__ == '__main__':
sys.exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment