Exemplo n.º 1
0
def bass_note_tendency_score(candidate, beat):
    this_chord = chords.get(beat.start())
    score = 0.0

    candidate_is_this_chord_bass_note = pitches.same_species(candidate, this_chord.bass_note)

    # first bass note should definitely be the root
    if beat.start() == 0 and candidate_is_this_chord_bass_note:
        return vars.FIRST_BEAT_BASS_ROOT

    # If beat one, we want to hear the bass note
    if beat.first_beat() and candidate_is_this_chord_bass_note:
        score += vars.FIRST_BEAT_BASS_NOTE

    last_chord = chords.get(0 if beat.start() == 0 else beat.previous().start())
    this_and_next_chord_are_same = chords.same(last_chord, this_chord)
    this_chord_root_in_bass = this_chord.root_in_bass()

    # Chord is the same as the last chord, and this is root note. Less important as root was likely
    # already established
    if this_and_next_chord_are_same and candidate_is_this_chord_bass_note and this_chord_root_in_bass:
        score += vars.BASS_ROOT_SAME_CHORD

    # Bass note does not equal root note, therefore it is especially important
    if pitches.same_species(candidate, this_chord.bass_note) and not this_chord_root_in_bass:
        score += vars.NON_ROOT_BASS_NOTE

    # new chord, we definitely want to hear the bass_note
    if not this_and_next_chord_are_same and candidate_is_this_chord_bass_note:
        score += vars.BASS_NOTE_NEW_CHORD

    return score
Exemplo n.º 2
0
    def __eq__(self, other):
        if not isinstance(other, self.__class__):
            return False

        return pitches.same_species(other.bass_note,
                                    self.bass_note) and pitches.same_species(
                                        other._root, self._root)
Exemplo n.º 3
0
    def functional_relevance(self, c1, c2):
        score = _KeySignature.functional_relevance(self, c1, c2)

        if self.is_functional(c1) and self.is_functional(c2) and \
                pitches.same_species(c1.root(), self.five()) and pitches.same_species(c2.root(), self.flat_six()):
            score += vars.FIVE_SIX_FUNCTIONALITY

        return score
Exemplo n.º 4
0
def third_preference_score(candidate, beat):
    chord = chords.get(beat.start())
    if isinstance(chord, chords.SevenChord):
        if [pitch for pitch in candidate if pitches.same_species(pitch, chord.three())]:
            return vars.THIRD_PREFERENCE

    return 0.0
Exemplo n.º 5
0
def __contains_one_or_five_seven(key_signature, chord_progression_stub):
    for key in chord_progression_stub.keys():
        chord = chord_progression_stub[key]
        if key_signature.is_functional(chord) and pitches.same_species(
                key_signature.one(), chord.root()):
            return True
    return False
Exemplo n.º 6
0
    def harmonic_relevance(self, chord):
        if pitches.same_species(chord.root(), self.one()) and \
                isinstance(chord, chords.MinorChord):
            return vars.ONE_CHORD_HARMONY
        elif pitches.same_species(chord.root(), self.two()) and \
                isinstance(chord, chords.DiminishedChord):
            return vars.TWO_CHORD_HARMONY
        elif pitches.same_species(chord.root(), self.three()) and \
                isinstance(chord, chords.MajorChord):
            return vars.THREE_CHORD_HARMONY
        elif pitches.same_species(chord.root(), self.four()) and \
                isinstance(chord, chords.MinorChord):
            return vars.FOUR_CHORD_HARMONY
        elif pitches.same_species(chord.root(), self.flat_six()) and \
                isinstance(chord, chords.MajorChord):
            return vars.SIX_CHORD_HARMONY

        return _KeySignature.harmonic_relevance(self, chord)
Exemplo n.º 7
0
    def harmonic_relevance(self, chord):
        """
        Some chords are more indicative of a certain key than other. E.g. in C, the chords C and G7 strongly
        indicate that we're in the key of C. Returns a score based on harmonic relevance to the key

        :param chord: chords.Chords object
        :return: Harmony relevance score
        """
        if pitches.same_species(chord.root(), self.five()) and \
                isinstance(chord, chords.SevenChord):
            return vars.FIVE_DOMINANT_HARMONY
        elif pitches.same_species(chord.root(), self.five()) and \
                isinstance(chord, chords.MajorChord):
            return vars.FIVE_MAJOR_HARMONY
        elif pitches.same_species(chord.root(), self.seven()) and \
                isinstance(chord, chords.DiminishedChord):
            return vars.MAJOR_SEVEN_DIMINISHED_HARMONY

        return 0.0
Exemplo n.º 8
0
def preemption_penalty(candidate, beat):
    if beat.end() == config.song_length:
        return 0.0

    this_chord = chords.get(beat.start())
    next_chord = chords.get(beat.next().start())

    if pitches.same_species(candidate, next_chord.root()) and this_chord != next_chord:
        return vars.PREEMPTION

    return 0.0
Exemplo n.º 9
0
    def __get_musicality(self):
        score = 0.0

        next_pitch = self.sequence[self.position + config.resolution].midi()
        next_chord = config.chord_progression[self.position +
                                              config.resolution]
        next_key = config.key_signatures[self.position + config.resolution]
        this_key = config.key_signatures[self.position]

        if pitches.same_species(next_pitch, next_chord.root()):
            y = this_key != next_key
            s = next_chord.root()
            e = next_key.one()
            t = pitches.same_species(next_chord.root(), next_key.one())
            score += vars.APPROACH_KEY_CHANGE \
                if pitches.same_species(next_chord.root(), next_key.one()) and this_key != next_key \
                else vars.APPROACH_NEW_CHORD_ROOT
        else:
            score += vars.APPROACH_DEFAULT_MUSICALITY

        score += vars.FLICKER_COEF if self.causes_flickering() else 0.0

        return score
Exemplo n.º 10
0
    def is_functional(self, chord):
        chord_root = chord.root()

        if (pitches.same_species(chord_root, self.three()) or
            pitches.same_species(chord_root, self.flat_six()) or
            pitches.same_species(chord_root, self.five())) and \
                isinstance(chord, chords.MajorChord):
            return True
        elif (pitches.same_species(chord_root, self.five())) \
                and isinstance(chord, chords.SevenChord):
            return True
        elif (pitches.same_species(chord_root, self.one()) or
              pitches.same_species(chord_root, self.four())) and \
                isinstance(chord, chords.MinorChord):
            return True
        elif (pitches.same_species(chord_root, self.seven() or
                                               pitches.same_species(chord_root, self.two())) and
              isinstance(chord_root, chords.DiminishedChord)):
            return True

        return False
Exemplo n.º 11
0
 def root_in_bass(self):
     return pitches.same_species(self._root, self.bass_note)
Exemplo n.º 12
0
    def functional_relevance(self, c1, c2):
        """
        Some functional relationships are more indicative of some key sigantures. E.g. A7 -> D is strongly
        indicative of the key of D. Returns a score based on how functionally relevant the two chords are in this key.

        * Not currently implemented: The dimension of time needs to be included within the scoring mechanism.
        The following example illustrates why. Assume we're in 4/4 and the actual key signature is A

        | A |   |   |   || D |   |   |   || F- |   |   |  ||

        Why humans can deduce that this relationship is indicative of A, the computer just see A -> D, which is
        more indicative of the key of D. The F- could be any chord that would force a key change to be registered.

        :param c1: first chord
        :param c2: second chord
        :return: functionality score based on the chords
        """
        score = 0.0

        if self.is_functional(c1) and self.is_functional(c2):
            # Dominant five chords in functional relationship are more valuable than just major fives
            if (pitches.same_species(c1.root(), self.five()) and isinstance(c1, chords.SevenChord)) or \
                    (pitches.same_species(c2.root(), self.five()) and isinstance(c2, chords.SevenChord)):
                score += vars.DOMINANT_FIVE_IN_FUNCTIONAL_RELEVANCE
            elif (pitches.same_species(c1.root(), self.five()) and isinstance(c1, chords.MajorChord)) or \
                    (pitches.same_species(c2.root(), self.five()) and isinstance(c2, chords.MajorChord)):
                score += vars.MAJOR_FIVE_IN_FUNCTIONAL_RELEVANCE

            if pitches.same_species(c1._root, self.five()) and pitches.same_species(c2._root, self.one()):
                score += vars.FIVE_ONE_FUNCTIONALITY
            elif pitches.same_species(c1._root, self.seven()) and pitches.same_species(c2._root, self.one()):
                score += vars.SEVEN_ONE_FUNCTIONALITY
            elif pitches.same_species(c1._root, self.two()) and pitches.same_species(c2._root, self.five()):
                score += vars.TWO_FIVE_FUNCTIONALITY
            elif pitches.same_species(c1._root, self.four()) and pitches.same_species(c2._root, self.five()):
                score += vars.FOUR_FIVE_FUNCTIONALITY

        return score