def test_rms_extraction(self): """ Does the RMS calculation using Praat work properly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I"), (11.63, 11.72, "e:"), (11.79, 11.85, "I"), (11.96, 12.03, "U"), (12.16, 12.24, "o:"), ], columns=["start_est", "end", "phone"], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df) rms = np.around(tester.get_rms(), decimals=4) expected_vals = np.around( np.array([ 0.17689167172400735, 0.2278562589839203, 0.16188228973962826, 0.1256124165026432, 0.1446231088144042, ]), decimals=4, ) self.assertTrue(np.array_equal(rms, expected_vals, equal_nan=True))
def test_intensity_extraction_ip_mean(self): """ Does the intensity extraction (dB) for intonation phrases work properly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I", 11.41, 13.91), (13.8, 14.1, "e:", 13.911, 16.2), (16.4, 16.7, "I", 16.201, 18.91), ], columns=["start_est", "end", "phone", "ip_start", "ip_end"], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df) tester.calc_intensity() intensities = np.around(tester.get_intensity_ip(), decimals=4) expected_vals = np.around( np.array([75.39665468978198, 71.55360893937386, 70.32496318148395]), decimals=4, ) self.assertTrue( np.array_equal(intensities, expected_vals, equal_nan=True))
def run_config(self): self.accents = self.collect_annotations("accents") self.phones = self.collect_annotations("phones") self.tones = self.collect_annotations("tones") self.words = self.collect_annotations("words") if self.config["find_nuclei"]: points = find_syllable_nuclei.get_nucleus_points(self.wav_file) self.nuclei_raw = find_syllable_nuclei.assign_points_labels( points, self.phones, self.words, self.tones, self.accents ) self.nuclei = self.nuclei_raw.loc[ self.nuclei_raw["phone"].notna() ].reset_index() to_extract = [ func for func, to_run in self.config["features"].items() if to_run ] # compile list of functions that should be run according to the config if to_extract: extractor = extract_features.Extractor( self.wav_file, self.nuclei, self.speaker[1] ) features = self.nuclei.copy() # Will add extracted feature values to main feature DataFrame for func_to_run in to_extract: self.call_function(extractor, features, func_to_run) return features else: pass
def test_normalized_duration_ip(self): """ Are normalized durations relative to remainder of the intonation phrase extracted correctly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I", 11.41, 13.91), (11.63, 11.72, "e:", 11.41, 13.91), (11.79, 11.85, "I", 11.41, 13.91), (11.96, 12.03, "U", 11.41, 13.91), (12.16, 12.24, "o:", 11.41, 13.91), ], columns=["start_est", "end", "phone", "ip_start", "ip_end"], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df) durations = np.around(tester.get_duration_normed(), decimals=4) expected_vals = np.around( np.array([1.3414634, 1.097561, 0.73170732, 0.85365854, 0.97560976]), decimals=4, ) self.assertTrue( np.array_equal(durations, expected_vals, equal_nan=True))
def test_pitch_excursion_word(self): """ Does the extraction of pitch excursion across the word work correctly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I", 11.41, 11.6, 117.87253295571392), (11.63, 11.72, "e:", 11.6, 11.75, 123.1675694877848), (11.79, 11.85, "I", 11.75, 12.3, 134.76548248292062), (11.96, 12.03, "U", 11.75, 12.3, 136.5251634214678), (12.16, 12.24, "o:", 11.75, 12.3, 151.56666619140884), ], columns=[ "start_est", "end", "phone", "word_start", "word_end", "f0_max" ], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df, gender="m") tester.calc_pitch() excursions = np.around(tester.get_excursion("word"), decimals=4) expected_vals = np.around( np.array([ 0.9820240572061552, 1.756133256029977, 3.216669606719651, 3.44125989959283, 5.2506872809056775, ]), decimals=4, ) self.assertTrue( np.array_equal(excursions, expected_vals, equal_nan=True))
def test_pitch_excursion_ip(self): """ Does the extraction of pitch excursion across the intonation phrase work correctly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I", 11.41, 13.91, 117.87253295571392), (11.63, 11.72, "e:", 11.41, 13.91, 123.1675694877848), (11.79, 11.85, "I", 11.41, 13.91, 134.76548248292062), (11.96, 12.03, "U", 11.41, 13.91, 136.5251634214678), (12.16, 12.24, "o:", 11.41, 13.91, 151.56666619140884), ], columns=[ "start_est", "end", "phone", "ip_start", "ip_end", "f0_max" ], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df, gender="m") tester.calc_pitch() excursions = np.around(tester.get_excursion("ip"), decimals=4) expected_vals = np.around( np.array([ 4.729683832131741, 5.4904221848570725, 7.04836523259897, 7.272955525472149, 9.082382906784996, ]), decimals=4, ) self.assertTrue( np.array_equal(excursions, expected_vals, equal_nan=True))
def test_spectral_tilt_mean(self): """ Does the extraction of spectral tilt work properly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I"), (11.63, 11.72, "e:"), (11.79, 11.85, "I"), (11.96, 12.03, "U"), (12.16, 12.24, "o:"), ], columns=["start_est", "end", "phone"], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df, gender="m") tilt = np.around( tester.get_spectral_tilt_mean(), decimals=0 ) # crude rounding factor due to problem with disparity between Praat GUI and API commands, not fatal expected_vals = np.around( np.array([ 142.71001735123184, 238.82379641896938, 209.10863223758525, 247.9976699000063, 299.64676965508664, ]), decimals= 0, # crude rounding factor due to problem with disparity between Praat GUI and API commands, not fatal ) self.assertTrue(np.array_equal(tilt, expected_vals, equal_nan=True))
def test_f0_extraction_nuclei_range(self): """ Does the F0 range extraction for syllable nuclei work properly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I"), (11.63, 11.72, "e:"), (11.79, 11.85, "I"), (11.96, 12.03, "U"), (12.16, 12.24, "o:"), ], columns=["start_est", "end", "phone"], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df, gender="m") tester.calc_pitch() tester.get_f0_min_nuclei() tester.get_f0_max_nuclei() f0s = np.around(tester.get_f0_range_nuclei(), decimals=4) expected_vals = np.around( np.array([ 7.0453877222195445, 9.912871858567698, 6.595729085405338, 11.790601978020263, 13.21372287577313, ]), decimals=4, ) self.assertTrue(np.array_equal(f0s, expected_vals, equal_nan=True))
def test_spectral_tilt_range(self): """ Does the extraction of spectral tilt range work properly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I"), (11.63, 11.72, "e:"), (11.79, 11.85, "I"), (11.96, 12.03, "U"), (12.16, 12.24, "o:"), ], columns=["start_est", "end", "phone"], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df, gender="m") tilt = np.around( tester.get_spectral_tilt_range(), decimals=0 ) # crude rounding factor due to problem with disparity between Praat GUI and API commands, not fatal expected_vals = np.around( np.array([ 149.61228824324905, 103.69618917064011, 76.79120165132159, 195.89299491267772, 125.97013425133713, ]), decimals= 0, # crude rounding factor due to problem with disparity between Praat GUI and API commands, not fatal ) self.assertTrue(np.array_equal(tilt, expected_vals, equal_nan=True))
def test_intensity_min_extraction(self): """ Is the mininum intensity extracted correctly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I"), (11.63, 11.72, "e:"), (11.79, 11.85, "I"), (11.96, 12.03, "U"), (12.16, 12.24, "o:"), ], columns=["start_est", "end", "phone"], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df, gender="m") tester.calc_intensity() intensities = np.around(tester.get_min_intensity_nuclei(), decimals=4) expected_vals = np.around( np.array([ 72.52231907753077, 78.54116284340166, 75.2261318921721, 70.07862900229256, 76.88232010504962, ]), decimals=4, ) self.assertTrue( np.array_equal(intensities, expected_vals, equal_nan=True))
def test_max_pitch_pos_nuclei(self): """ Does the extraction of the relative position of the pitch minimum within syllable nuclei work properly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I"), (11.63, 11.72, "e:"), (11.79, 11.85, "I"), (11.96, 12.03, "U"), (12.16, 12.24, "o:"), ], columns=["start_est", "end", "phone"], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df, gender="m") tester.calc_pitch() pos = np.around(tester.get_f0_max_pos(), decimals=4) expected_vals = np.around( np.array([ 0.3352272727272441, 0.35416666666662144, 0.7812499999999343, 0.45535714285709367, 0.9609374999999467, ]), decimals=4, ) self.assertTrue(np.array_equal(pos, expected_vals, equal_nan=True))
def test_f0_extraction_nuclei_std(self): """ Does the F0 standard deviation extraction for syllable nuclei work properly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I"), (11.63, 11.72, "e:"), (11.79, 11.85, "I"), (11.96, 12.03, "U"), (12.16, 12.24, "o:"), ], columns=["start_est", "end", "phone"], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df, gender="m") tester.calc_pitch() f0s = np.around(tester.get_f0_std_nuclei(), decimals=4) expected_vals = np.around( np.array([ 2.280839592346914, 2.202496205316962, 2.411086034540446, 4.471311329355762, 5.209220274575025, ]), decimals=4, ) self.assertTrue(np.array_equal(f0s, expected_vals, equal_nan=True))
def test_f0_extraction_nuclei_min(self): """ Does the F0 minimum extraction for syllable nuclei work properly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I"), (11.63, 11.72, "e:"), (11.79, 11.85, "I"), (11.96, 12.03, "U"), (12.16, 12.24, "o:"), ], columns=["start_est", "end", "phone"], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df, gender="m") tester.calc_pitch() f0s = np.around(tester.get_f0_min_nuclei(), decimals=4) expected_vals = np.around( np.array([ 110.82714523349438, 113.2546976292171, 128.16975339751528, 124.73456144344753, 138.3529433156357, ]), decimals=4, ) self.assertTrue(np.array_equal(f0s, expected_vals, equal_nan=True))
def test_f0_extraction_nuclei_max(self): """ Does the F0 peak extraction for syllable nuclei work properly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I"), (11.63, 11.72, "e:"), (11.79, 11.85, "I"), (11.96, 12.03, "U"), (12.16, 12.24, "o:"), ], columns=["start_est", "end", "phone"], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df, gender="m") tester.calc_pitch() f0s = np.around(tester.get_f0_max_nuclei(), decimals=4) expected_vals = np.around( np.array([ 117.87253295571392, 123.1675694877848, 134.76548248292062, 136.5251634214678, 151.56666619140884, ]), decimals=4, ) self.assertTrue(np.array_equal(f0s, expected_vals, equal_nan=True))
def test_local_pitch_slope(self): """ Is the absolute slope (without octave jumps) calculated correctly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I"), (11.63, 11.72, "e:"), (11.79, 11.85, "I"), (11.96, 12.03, "U"), (12.16, 12.24, "o:"), ], columns=["start_est", "end", "phone"], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df, gender="m") pitch_slope = np.around(tester.get_pitch_slope(), decimals=4) expected_vals = np.around( np.array([ 26.819895462113966, 10.194947721704583, 15.767233863040769, 21.886583599912406, 32.763328999228335, ]), decimals=4, ) self.assertTrue( np.array_equal(pitch_slope, expected_vals, equal_nan=True))
def test_intensity_std_extraction(self): """ Is the standard deviation for intensity extracted correctly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I"), (11.63, 11.72, "e:"), (11.79, 11.85, "I"), (11.96, 12.03, "U"), (12.16, 12.24, "o:"), ], columns=["start_est", "end", "phone"], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df, gender="m") tester.calc_intensity() stds = np.around(tester.get_intensity_std_nuclei(), decimals=4) expected_vals = np.around( np.array([ 3.369907965314268, 1.1402104298852436, 1.5638238156409505, 3.419440119923512, 0.5701671691859589, ]), decimals=4, ) self.assertTrue(np.array_equal(stds, expected_vals, equal_nan=True))
def test_intensity_max_pos_extraction(self): """ Is the relative position of the intensity maximum in the syllable nucleus extracted correctly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I"), (11.63, 11.72, "e:"), (11.79, 11.85, "I"), (11.96, 12.03, "U"), (12.16, 12.24, "o:"), ], columns=["start_est", "end", "phone"], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df, gender="m") tester.calc_intensity() pos = np.around(tester.get_max_intensity_pos(), decimals=4) expected_vals = np.around( np.array([ 0.8715909090908767, 0.39861111111106107, 0.5979166666666152, 0.5982142857142112, 0.023437499999934254, ]), decimals=4, ) self.assertTrue(np.array_equal(pos, expected_vals, equal_nan=True))
def test_intensity_min_pos_extraction(self): """ Is the relative position of the intensity minimum in the syllable nucleus extracted correctly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I"), (11.63, 11.72, "e:"), (11.79, 11.85, "I"), (11.96, 12.03, "U"), (12.16, 12.24, "o:"), ], columns=["start_est", "end", "phone"], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df, gender="m") tester.calc_intensity() pos = np.around(tester.get_min_intensity_pos(), decimals=4) expected_vals = np.around( np.array([ 0.14431818181812883, 0.043055555555504624, 0.0645833333332859, 0.1410714285713439, 0.42343749999993424, ]), decimals=4, ) self.assertTrue(np.array_equal(pos, expected_vals, equal_nan=True))
def test_intensity_extraction_nuclei_max(self): """ Does the intensity extraction (dB) using Praat work properly? """ wav_file = "tests/test_material/feature_extraction/test.wav" nuclei_df = DataFrame( [ (11.41, 11.52, "I"), (11.63, 11.72, "e:"), (11.79, 11.85, "I"), (11.96, 12.03, "U"), (12.16, 12.24, "o:"), ], columns=["start_est", "end", "phone"], ) tester = extract_features.Extractor(wav_file, nuclei=nuclei_df) tester.calc_intensity() intensities = np.around(tester.get_max_intensity_nuclei(), decimals=4) expected_vals = np.around( np.array([ 81.1521732084371, 81.72280626772428, 79.37680512029912, 77.91419036596378, 78.403839787533, ]), decimals=4, ) self.assertTrue( np.array_equal(intensities, expected_vals, equal_nan=True))