示例#1
0
    def compute(self, beat):
        if sequences.soprano().is_rest(beat.start()):
            soprano_pitch = -1
        else:
            soprano_pitch = sequences.soprano().pitch(beat.start()).midi()

        candidates = get_candidate_matrix(beat, soprano_pitch)
        scored = {tuple(candidate): self.score(beat, candidate) for candidate in candidates}

        return util.key_for_highest_value(scored)
示例#2
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
示例#3
0
    def score(self, beat, candidate):
        bass_score = get_bass_score(candidate[BASS_POSITION], beat)
        tenor_score = get_tenor_score(candidate[TENOR_POSITION], beat)
        alto_score = get_alto_score(candidate[ALTO_POSITION], beat)
        harmony_score = get_harmony_score(candidate, beat)
        duplicate_penalty = get_duplicate_penalty(candidate)
        rest_penalty = get_rest_penalty(candidate)
        motion_score = parallel_motion_score(candidate, beat, sequences.soprano(), sequences.alto(),
                                             sequences.tenor(), sequences.bass())

        return sum([bass_score, tenor_score, alto_score, harmony_score, motion_score, rest_penalty, duplicate_penalty])
示例#4
0
    def test__Sequence_note_duration_count(self):
        fileloader.load(constants.TEST_MIDI + 'linear_motion.mid', False)
        sequence = sequences.soprano()

        number_of_sixteenths = 2
        number_of_eighths = 5

        duration_count = sequence.note_duration_count()

        self.assertEqual(duration_count.get(constants.SIXTEENTH_NOTE, 0),
                         number_of_sixteenths)
        self.assertEqual(duration_count.get(constants.EIGHTH_NOTE, 0),
                         number_of_eighths)
示例#5
0
    def test__Sequence_add_entities_splits(self):
        fileloader.load(constants.TEST_MIDI + 'entities.mid', False)
        sequence = sequences.soprano()

        new_entity_start = 480
        new_entity_end = 576

        note = sequences.Rest(sequence, new_entity_start, new_entity_end)
        sequence.add_entities(note)

        self.assertEqual(new_entity_start,
                         sequence.entities().values()[3].end())
        self.assertEqual(new_entity_end,
                         sequence.entities().values()[5].start())
示例#6
0
    def test__Sequence_add_entities_consumes(self):
        fileloader.load(constants.TEST_MIDI + 'entities.mid', False)
        sequence = sequences.soprano()

        new_entity_start = 144
        new_entity_end = 528

        note = sequences.Note(sequence, new_entity_start, new_entity_end,
                              pitches.Pitch(61))
        sequence.add_entities(note)

        self.assertEqual(new_entity_start,
                         sequence.entities().values()[1].end())
        self.assertEqual(new_entity_end,
                         sequence.entities().values()[3].start())
示例#7
0
    def test__flicker_avoidance_score(self):
        fileloader.load(constants.TEST_MIDI + 'flicker.mid', False)
        sequence = sequences.soprano()

        c = pitches.MIDI_VALUES['C5']
        e = pitches.MIDI_VALUES['E5']

        beat2 = time.beat_at_index(2)
        beat3 = time.beat_at_index(3)

        self.assertEqual(
            1 * vars.FLICKER_COEF,
            note_picker.flicker_avoidance_score(c, beat2, sequence))
        self.assertEqual(
            2 * vars.FLICKER_COEF,
            note_picker.flicker_avoidance_score(e, beat3, sequence))
示例#8
0
    def test__get_motion_score(self):
        fileloader.load(constants.TEST_MIDI + 'parallel1.mid', False)
        soprano = sequences.soprano()
        tenor = sequences.RootSequence(
            read_pattern(constants.TEST_MIDI + 'parallel2.mid')[0])

        irrelevant_pitch = 11

        # [0] = alto, [1] = tenor, [2] = bass
        candidate = pitches.MIDI_VALUES['D5'], pitches.MIDI_VALUES[
            'A5'], irrelevant_pitch,

        self.assertEqual(
            0.0,
            note_picker.parallel_motion_score(candidate, time.beat_at_index(0),
                                              soprano, sequences.alto(), tenor,
                                              sequences.bass()))
        self.assertEqual(
            vars.PARALLEL_MOVEMENT,
            note_picker.parallel_motion_score(candidate, time.beat_at_index(1),
                                              soprano, sequences.alto(), tenor,
                                              sequences.bass()))
示例#9
0
def rhythm_based_strong_beat_score(measure, pattern):
    """
    Returns the likelihood that a measure's strong beat pattern is the given pattern

    :param measure: time.Measure that we're testing
    :param pattern: tuple with the pattern, e.g. (0, 2, 4) or (3, 2, 2) in 7
    :return: likelihood score
    """
    likelihood_score = 0.0
    position = 0
    sequence = sequences.soprano()

    for i in range(len(pattern)):
        target_duration = ((pattern + (len(measure.beats()), ))[i + 1] - pattern[i]) * measure.beat_length()
        entity = sequence.entity(measure.start() + sum([j * measure.beat_length() for j in pattern[:i + 1]]))

        if entity.length() == target_duration and entity.start() == position:
            likelihood_score += vars.RHYTHM_PHRASING_COEF * ((pattern + (len(measure.beats()), ))[i + 1] - pattern[i])

        position += target_duration

    return likelihood_score
示例#10
0
    def test__linear_motion_score(self):
        fileloader.load(constants.TEST_MIDI + 'quarter_arpeg.mid', False)
        sequence = sequences.soprano()

        beat_0_pitch = 59
        motion_pitch = 61

        # start of midi clip, no motion, return 0
        self.assertEqual(
            0.0,
            note_picker.linear_motion_score(beat_0_pitch,
                                            time.beat_at_index(0), sequence))

        # same note as last beat
        self.assertEqual(
            0.0,
            note_picker.linear_motion_score(beat_0_pitch,
                                            time.beat_at_index(1), sequence))

        # linear motion exists
        self.assertEqual(
            vars.LINEAR_MOTION,
            note_picker.linear_motion_score(motion_pitch,
                                            time.beat_at_index(1), sequence))
示例#11
0
for last_beat, this_beat in zip(strong_beats, strong_beats[1:]):
    t = transforms.get_all_transforms(last_beat.start(), this_beat.start(), 3)
    print 'yo'


# motionizer = motion.Motionizer()
# for measure in sequences.bass().measures():
#     for beat in measure.beats():
#         position = measure.sample_position() + beat.beat_index * config.resolution
#
#         transforms = motionizer.compute_next(sequences.soprano, sequences.alto(), sequences.tenor(), sequences.bass())
#
#         sequences.alto().apply_transform(transforms['alto'])
#         sequences.tenor().apply_transform(transforms['tenor'])
#         sequences.bass().apply_transform(transforms['bass'])

# ~~~~~~~~ Write to file ~~~~~~~~

# print(pat_util.sample_length(sequences.soprano().to_pattern()))

folder = constants.OUT_DIR + config.name + '/'
if not os.path.exists(folder):
    os.makedirs(folder)

midi.write_midifile(folder + 'soprano.mid', sequences.soprano().to_pattern())
midi.write_midifile(folder + 'alto.mid', sequences.alto().to_pattern())
midi.write_midifile(folder + 'tenor.mid', sequences.tenor().to_pattern())
midi.write_midifile(folder + 'bass.mid', sequences.bass().to_pattern())

print 'Your arrangement has been written to ', folder, ' :)'