def compute_result(self, arg_contextual_note, target_contextual_note,
                       down_steps, up_steps):
        arg_pitch = arg_contextual_note.note.diatonic_pitch

        pitches = PitchScale.compute_tonal_pitch_range(
            target_contextual_note.policy_context.harmonic_context.tonality,
            arg_pitch, down_steps, up_steps)

        result = OrderedSet()
        for pitch in pitches:
            result.add(
                Note(pitch, self.note_two.base_duration,
                     self.note_two.num_dots))

        return result
    def verify(self, parameter_map):
        """
        Verify that p_map has values satisfying the constraint.
        :param parameter_map: 
        :return: 
        """
        first_contextual_note = parameter_map[self.note_one]
        second_contextual_note = parameter_map[self.note_two]
        if first_contextual_note.note is None or second_contextual_note.note is None:
            return False

        pitches = PitchScale.compute_tonal_pitch_range(
            second_contextual_note.policy_context.harmonic_context.tonality,
            first_contextual_note.note.diatonic_pitch, self.lower_steps,
            self.upper_steps)

        return second_contextual_note.note.diatonic_pitch in pitches
Пример #3
0
    def test_compute_tonal_pitch_range(self):
        logging.debug('Start test_compute_tonal_pitch_range')

        tonality = Tonality.create(ModalityType.Major, DiatonicTone('Ab'))

        pitch = DiatonicPitch(4, 'B#')
        pitches = PitchScale.compute_tonal_pitch_range(tonality, pitch, 5, 7)
        for p in reversed(pitches):
            print(p)

        test_pitches = [
            'A:4', 'B:4', 'C:4', 'D:4', 'E:4', 'F:4', 'G:4', 'Ab:4', 'Bb:4',
            'Db:4', 'Eb:4', 'C#:4', 'D#:4', 'G#:4', 'A#:4', 'B#:4', 'Cb:4',
            'B##:4', 'Cbb:4'
        ]

        ranges = [[0, 5], [-5, 0], [-4, 2], [-5, -3], [5, 7]]

        answers = [
            '[Ab:4,Bb:4,C:5,Db:5,Eb:5,F:5,G:5]',
            '[C:4,Db:4,Eb:4,F:4,G:4,Ab:4,Bb:4]',
            '[Db:4,Eb:4,F:4,G:4,Ab:4,Bb:4,C:5,Db:5]',
            '[C:4,Db:4,Eb:4]',
            '[G:5,Ab:5,Bb:5]',
            '[Bb:4,C:5,Db:5,Eb:5,F:5,G:5,Ab:5]',
            '[Db:4,Eb:4,F:4,G:4,Ab:4,Bb:4,C:5]',
            '[Eb:4,F:4,G:4,Ab:4,Bb:4,C:5,Db:5,Eb:5]',
            '[Db:4,Eb:4,F:4]',
            '[Ab:5,Bb:5,C:6]',
            '[C:4,Db:4,Eb:4,F:4,G:4,Ab:4]',
            '[Eb:3,F:3,G:3,Ab:3,Bb:3,C:4]',
            '[F:3,G:3,Ab:3,Bb:3,C:4,Db:4,Eb:4]',
            '[Eb:3,F:3,G:3]',
            '[Ab:4,Bb:4,C:5]',
            '[Db:4,Eb:4,F:4,G:4,Ab:4,Bb:4,C:5]',
            '[F:3,G:3,Ab:3,Bb:3,C:4,Db:4,Eb:4]',
            '[G:3,Ab:3,Bb:3,C:4,Db:4,Eb:4,F:4,G:4]',
            '[F:3,G:3,Ab:3]',
            '[C:5,Db:5,Eb:5]',
            '[Eb:4,F:4,G:4,Ab:4,Bb:4,C:5,Db:5]',
            '[G:3,Ab:3,Bb:3,C:4,Db:4,Eb:4,F:4]',
            '[Ab:3,Bb:3,C:4,Db:4,Eb:4,F:4,G:4,Ab:4]',
            '[G:3,Ab:3,Bb:3]',
            '[Db:5,Eb:5,F:5]',
            '[F:4,G:4,Ab:4,Bb:4,C:5,Db:5]',
            '[Ab:3,Bb:3,C:4,Db:4,Eb:4,F:4]',
            '[Bb:3,C:4,Db:4,Eb:4,F:4,G:4,Ab:4]',
            '[Ab:3,Bb:3,C:4]',
            '[Db:5,Eb:5,F:5]',
            '[G:4,Ab:4,Bb:4,C:5,Db:5,Eb:5]',
            '[Bb:3,C:4,Db:4,Eb:4,F:4,G:4]',
            '[C:4,Db:4,Eb:4,F:4,G:4,Ab:4,Bb:4]',
            '[Bb:3,C:4,Db:4]',
            '[Eb:5,F:5,G:5]',
            '[Ab:4,Bb:4,C:5,Db:5,Eb:5,F:5]',
            '[C:4,Db:4,Eb:4,F:4,G:4,Ab:4]',
            '[Db:4,Eb:4,F:4,G:4,Ab:4,Bb:4,C:5]',
            '[C:4,Db:4,Eb:4]',
            '[F:5,G:5,Ab:5]',
            '[Bb:4,C:5,Db:5,Eb:5,F:5,G:5]',
            '[Db:4,Eb:4,F:4,G:4,Ab:4,Bb:4]',
            '[Eb:4,F:4,G:4,Ab:4,Bb:4,C:5,Db:5]',
            '[Db:4,Eb:4,F:4]',
            '[G:5,Ab:5,Bb:5]',
            '[Db:4,Eb:4,F:4,G:4,Ab:4,Bb:4]',
            '[F:3,G:3,Ab:3,Bb:3,C:4,Db:4]',
            '[G:3,Ab:3,Bb:3,C:4,Db:4,Eb:4,F:4]',
            '[F:3,G:3,Ab:3]',
            '[Bb:4,C:5,Db:5]',
            '[Eb:4,F:4,G:4,Ab:4,Bb:4,C:5]',
            '[G:3,Ab:3,Bb:3,C:4,Db:4,Eb:4]',
            '[Ab:3,Bb:3,C:4,Db:4,Eb:4,F:4,G:4]',
            '[G:3,Ab:3,Bb:3]',
            '[C:5,Db:5,Eb:5]',
            '[Db:4,Eb:4,F:4,G:4,Ab:4,Bb:4]',
            '[F:3,G:3,Ab:3,Bb:3,C:4,Db:4]',
            '[G:3,Ab:3,Bb:3,C:4,Db:4,Eb:4,F:4]',
            '[F:3,G:3,Ab:3]',
            '[Bb:4,C:5,Db:5]',
            '[Eb:4,F:4,G:4,Ab:4,Bb:4,C:5]',
            '[G:3,Ab:3,Bb:3,C:4,Db:4,Eb:4]',
            '[Ab:3,Bb:3,C:4,Db:4,Eb:4,F:4,G:4]',
            '[G:3,Ab:3,Bb:3]',
            '[C:5,Db:5,Eb:5]',
            '[Ab:4,Bb:4,C:5,Db:5,Eb:5,F:5]',
            '[C:4,Db:4,Eb:4,F:4,G:4,Ab:4]',
            '[Db:4,Eb:4,F:4,G:4,Ab:4,Bb:4,C:5]',
            '[C:4,Db:4,Eb:4]',
            '[F:5,G:5,Ab:5]',
            '[Bb:4,C:5,Db:5,Eb:5,F:5,G:5]',
            '[Db:4,Eb:4,F:4,G:4,Ab:4,Bb:4]',
            '[Eb:4,F:4,G:4,Ab:4,Bb:4,C:5,Db:5]',
            '[Db:4,Eb:4,F:4]',
            '[G:5,Ab:5,Bb:5]',
            '[C:5,Db:5,Eb:5,F:5,G:5,Ab:5]',
            '[Eb:4,F:4,G:4,Ab:4,Bb:4,C:5]',
            '[F:4,G:4,Ab:4,Bb:4,C:5,Db:5,Eb:5]',
            '[Eb:4,F:4,G:4]',
            '[Ab:5,Bb:5,C:6]',
            '[Bb:3,C:4,Db:4,Eb:4,F:4,G:4,Ab:4]',
            '[Db:3,Eb:3,F:3,G:3,Ab:3,Bb:3,C:4]',
            '[Eb:3,F:3,G:3,Ab:3,Bb:3,C:4,Db:4,Eb:4]',
            '[Db:3,Eb:3,F:3]',
            '[Ab:4,Bb:4,C:5]',
            '[Db:5,Eb:5,F:5,G:5,Ab:5,Bb:5]',
            '[F:4,G:4,Ab:4,Bb:4,C:5,Db:5]',
            '[G:4,Ab:4,Bb:4,C:5,Db:5,Eb:5,F:5]',
            '[F:4,G:4,Ab:4]',
            '[Bb:5,C:6,Db:6]',
            '[Bb:3,C:4,Db:4,Eb:4,F:4,G:4]',
            '[Db:3,Eb:3,F:3,G:3,Ab:3,Bb:3]',
            '[Eb:3,F:3,G:3,Ab:3,Bb:3,C:4,Db:4]',
            '[Db:3,Eb:3,F:3]',
            '[G:4,Ab:4,Bb:4]',
        ]

        answer_idx = 0
        for pitch_str in test_pitches:
            for r in ranges:
                pitch = DiatonicPitch.parse(pitch_str)
                pitches = PitchScale.compute_tonal_pitch_range(
                    tonality, pitch, r[0], r[1])
                answer_str = '[' + (','.join(str(p) for p in pitches)) + ']'
                # print '\'[' + (','.join(str(p) for p in pitches)) + ']\','
                answer = answers[answer_idx]
                answer_idx = answer_idx + 1
                print('{0} [{1}, {2}]: {3}'.format(pitch, r[0], r[1],
                                                   answer_str))

                assert answer == answer_str

        logging.debug('End test_compute_tonal_pitch_range')
Пример #4
0
    def values(self, p_map, v_note):
        """

        :param p_map:
        :param v_note:
        :return:
        """

        index = self.actors.index(v_note) if v_note in self.actors else None
        if index is None:
            raise Exception('Cannot find v_note in constraints actors')

        if p_map[v_note].note is not None:
            return OrderedSet([p_map[v_note].note])

        # find the first assigned note
        assigned_index = None
        for i in range(0, len(self.actors)):
            if p_map[self.actors[i]].note is not None:
                assigned_index = i
                break

        if assigned_index is None:
            pitches = p_map.all_tonal_pitches(v_note)
            return OrderedSet([Note(p, v_note.base_duration, v_note.num_dots) for p in pitches])

        known_note = p_map[self.actors[assigned_index]].note
        if assigned_index < index:
            for i in range(assigned_index + 1, index + 1):
                unknown_contextual_note = p_map[self.actors[i]]
                unknown_note = unknown_contextual_note.note
                if unknown_note is not None:
                    known_note = unknown_note
                    continue

                lower_index = self.variance_list[i - 1] if self.variance_list[i - 1] < 0 else 0
                upper_index = self.variance_list[i - 1] if self.variance_list[i - 1] > 0 else 0
                pitches = PitchScale.compute_tonal_pitch_range(
                    unknown_contextual_note.policy_context.harmonic_context.tonality,
                    known_note.diatonic_pitch, lower_index, upper_index)
                pitch_index = self.variance_list[i - 1] + (len(pitches) - 1 if self.variance_list[i - 1] < 0 else 0)
                if pitch_index < 0 or pitch_index >= len(pitches):
                    if pitches is None or len(pitches) == 0:
                       return OrderedSet()
                    pitch = pitches[0] if pitch_index < 0 else pitches[len(pitches) - 1]
                else:
                    pitch = pitches[pitch_index]
                known_note = Note(pitch, self.actors[i].base_duration, self.actors[i].num_dots)
            return OrderedSet([known_note])

        for i in range(assigned_index - 1, index - 1, -1):
            unknown_contextual_note = p_map[self.actors[i]]
            unknown_note = unknown_contextual_note.note
            if unknown_note is not None:
                known_note = unknown_note
                continue

            upper_index = -self.variance_list[i] if self.variance_list[i] < 0 else 0
            lower_index = -self.variance_list[i] if self.variance_list[i] > 0 else 0
            pitches = PitchScale.compute_tonal_pitch_range(
                unknown_contextual_note.policy_context.harmonic_context.tonality,
                known_note.diatonic_pitch, lower_index, upper_index)
            pitch_index = -self.variance_list[i] + (len(pitches) - 1 if self.variance_list[i] > 0 else 0)
            if pitch_index < 0:
                pitch_index = 0
            elif pitch_index >= len(pitches):
                pitch_index = len(pitches) - 1
            pitch = pitches[pitch_index]
            known_note = Note(pitch, self.actors[i].base_duration, self.actors[i].num_dots)
        return OrderedSet([known_note])