Example #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
Example #2
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
Example #3
0
def get_all_transforms(start_position, end_position, max_subdivisions):
    satb = sequences.soprano(), sequences.alto(), sequences.tenor(), sequences.bass()
    pitches = [(sequence.pitch(start_position), sequence.pitch(end_position)) for sequence in satb]

    chord = chords.get(start_position)

    rhythm_set_groups = get_rhythm_sets(config.minimum_time_unit(), max_subdivisions, end_position - start_position)
    direction_set_groups = [direction_permutations(i) for i in range(1, max_subdivisions)]

    all_transforms = []
    for i, (sequence, (start_pitch, end_pitch)) in enumerate(zip(satb[1:], pitches[1:])):
        # We can't (read: don't want to) transform to or from a rest; skip if the start or end pitch is a rest.
        if start_pitch == -1 or end_pitch == -1:
            all_transforms.append([[]])
            continue

        high_thresh = min([p for p in pitches[i] if p != -1] + [sequence.part().max_high])
        low_thresh = sequence.part().max_low if i == len(satb) - 1 else min(sequence.part().max_low, pitches[i - 1])

        bounded_pitches = [pitch for pitch in chord.scale() if low_thresh <= pitch <= high_thresh]

        sequence_transforms = []
        for i, direction_set_group in enumerate(direction_set_groups):
            pitch_sets = [group for direction_set in direction_set_group
                          for group in
                          pitch_sets_for_directions(bounded_pitches, start_pitch, end_pitch, direction_set)]
            trans = [StrongBeatPhrase(r, p) for p in pitch_sets for r in rhythm_set_groups[i]]

            sequence_transforms.extend(trans)

        all_transforms.append(sequence_transforms)

    product = list(itertools.product(*all_transforms))
    return product
Example #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
Example #5
0
def get_candidate_matrix(beat, soprano_value):
    current_chord = chords.get(beat.start())

    alto_candidates = sequences.alto().part().available_notes(current_chord) + [-1]
    tenor_candidates = sequences.tenor().part().available_notes(current_chord) + [-1]
    bass_candidates = sequences.bass().part().available_notes(current_chord) + [-1]

    return [g + [soprano_value] for g
            in combine_pitch_candidates(alto_candidates, tenor_candidates, bass_candidates)
            if parts_dont_cross(g, soprano_value)]
Example #6
0
def unique_pitch_score(candidate, beat):
    chord = chords.get(beat.start())
    unique_pitches = len(set([pitch % 12 for pitch in candidate if pitch in chord.all_octaves()]))
    return vars.unique_pitch_score(unique_pitches)