Пример #1
0
    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))
Пример #2
0
    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))
Пример #3
0
    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
Пример #4
0
    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))
Пример #5
0
    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))
Пример #6
0
    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))
Пример #7
0
    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))
Пример #8
0
    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))
Пример #9
0
    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))
Пример #10
0
    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))
Пример #11
0
    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))
Пример #12
0
    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))
Пример #13
0
    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))
Пример #14
0
    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))
Пример #15
0
    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))
Пример #16
0
    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))
Пример #17
0
    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))
Пример #18
0
    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))
Пример #19
0
    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))