Esempio n. 1
0
    def get_undirected_interval_grade(self, chorale):
        key = chorale.analyze('key')
        chorale_distribution = histogram_to_distribution(
            get_interval_histogram(chorale, directed=False))
        dataset_distribution = self.distributions[
            f'{key.mode}_undirected_interval_distribution']
        u, v, u_weights, v_weights = distributions_to_wasserstein_inputs(
            chorale_distribution, dataset_distribution)

        return wasserstein_distance(u, v, u_weights, v_weights)
Esempio n. 2
0
    def get_harmonic_quality_grade(self, chorale):
        key = chorale.analyze('key')
        chorale_distribution = histogram_to_distribution(
            get_harmonic_quality_histogram(chorale))
        dataset_distribution = self.distributions[
            f'{key.mode}_harmonic_quality_distribution']
        u, v, u_weights, v_weights = distributions_to_wasserstein_inputs(
            chorale_distribution, dataset_distribution)

        return wasserstein_distance(u, v, u_weights, v_weights)
Esempio n. 3
0
    def get_B_directed_interval_grade(self, chorale):
        key = chorale.analyze('key')
        voice_ih = get_SATB_interval_histogram(chorale, voice=3, directed=True)

        chorale_distribution = histogram_to_distribution(voice_ih)
        dataset_distribution = self.distributions[
            f'{key.mode}_B_directed_interval_distribution']
        u, v, u_weights, v_weights = distributions_to_wasserstein_inputs(
            chorale_distribution, dataset_distribution)

        return wasserstein_distance(u, v, u_weights, v_weights)
Esempio n. 4
0
    def get_rhythm_grade(self, chorale):
        """
        Arguments
            chorale: music21.stream.Stream

        Returns Wasserstein distance between normalized chorale rhythm distribution and normalized dataset rhythm distribution
        """
        chorale_distribution = histogram_to_distribution(
            get_rhythm_histogram(chorale))
        dataset_distribution = self.distributions['rhythm_distribution']
        u, v, u_weights, v_weights = distributions_to_wasserstein_inputs(
            chorale_distribution, dataset_distribution)

        return wasserstein_distance(u, v, u_weights, v_weights)
Esempio n. 5
0
    def get_note_grade(self, chorale):
        """
        Arguments
            chorale: music21.stream.Stream

        Returns Wasserstein distance between normalized chorale note distribution and normalized dataset note distribution
        """
        key = chorale.analyze('key')
        chorale_distribution = histogram_to_distribution(
            get_note_histogram(chorale, key))
        dataset_distribution = self.distributions[
            f'{key.mode}_note_distribution']
        u, v, u_weights, v_weights = distributions_to_wasserstein_inputs(
            chorale_distribution, dataset_distribution)

        return wasserstein_distance(u, v, u_weights, v_weights)
Esempio n. 6
0
    def get_error_grade(self, chorale):
        num_notes = len(chorale.flat.notes)
        chorale_histogram = get_error_histogram(chorale, self.voice_ranges)

        num_errors = sum(chorale_histogram.values())
        # if num_errors == 0, the coefficient will be 0, so we can sidestep the calculation of wasserstein
        if num_errors == 0:
            return 0
        chorale_distribution = histogram_to_distribution(chorale_histogram)
        dataset_distribution = self.distributions['error_distribution']
        error_note_ratio = num_errors / num_notes

        u, v, u_weights, v_weights = distributions_to_wasserstein_inputs(
            chorale_distribution, dataset_distribution)
        return wasserstein_distance(u, v, u_weights, v_weights) * (
            error_note_ratio / self.error_note_ratio)