def test_enharmonic_fixed_tone(self):
        logging.debug('Start test_enharmonic_fixed_tone')
        note = Note(DiatonicPitch.parse("C:5"), Duration(1, 4))

        policy = FixedToneConstraint(note, DiatonicToneCache.get_tone("Bbb"))

        lower_policy_context = TestFixedToneConstraint.policy_creator(ModalityType.Major, DiatonicTone('G'), 'tV',
                                                                      'C:2', 'C:8')
        lower_contextual_note = ContextualNote(lower_policy_context)
        m = dict([(note, lower_contextual_note)])

        v_result = policy.values(m, note)

        assert len(v_result) == 6
        for note in v_result:
            print('test_simple_fixed_tone pitch = {0}'.format(note.diatonic_pitch))

            assert note.diatonic_pitch.diatonic_tone == DiatonicToneCache.get_tone('A')
            assert note.base_duration == Duration(1, 4)

            lower_contextual_note.note = note

            result = policy.verify(m)
            assert result is True

            lower_contextual_note.note = None

        logging.debug('End test_enharmonic_fixed_tone')
    def test_non_scale_note(self):
        logging.debug('Start test_non_scale_note')

        note = Note(DiatonicPitch.parse("Bb:4"), Duration(1, 4))
        policy = FixedPitchConstraint(note, DiatonicPitch.parse("Ab:5"))

        policy_context = TestFixedPitchConstraint.policy_creator(
            ModalityType.Major, DiatonicTone('C'), 'tIV', 'C:2', 'C:8')
        contextual_note = ContextualNote(policy_context)
        p_map = PMap()
        p_map[note] = contextual_note

        v_result = policy.values(p_map, note)

        result = next(iter(v_result))
        print('test_non_scale_note note= {0}'.format(result))

        assert result.diatonic_pitch == DiatonicPitch.parse("Ab:5")
        assert result.base_duration == Duration(1, 4)

        contextual_note.note = result

        result = policy.verify(p_map)
        assert result is True

        logging.debug('end test_non_scale_note')
    def test_is_equal(self):
        logging.debug('Start test_is_equal')

        note1 = Note(DiatonicPitch.parse('C:5'), Duration(1, 8))
        note2 = Note(DiatonicPitch.parse('C:5'), Duration(1, 8))

        lower_policy_context = TestEqualPitchConstraint.policy_creator(
            ModalityType.Major, DiatonicTone('G'), 'tV', 'C:2', 'C:8')
        lower_context_note_a = ContextualNote(
            lower_policy_context,
            Note(DiatonicPitch.parse('F#:6'), Duration(1, 8)))
        lower_context_note_b = ContextualNote(lower_policy_context)
        parameter_map = dict([(note1, lower_context_note_a),
                              (note2, lower_context_note_b)])
        parameter_map = PMap(parameter_map)

        policy = EqualPitchConstraint([note1, note2])

        result = policy.values(parameter_map, note2)

        actual_note = next(iter(result))
        print('test_is_equal; note = {0}'.format(actual_note))

        assert actual_note.diatonic_pitch == DiatonicPitch.parse("F#:6")
        assert actual_note.base_duration == Duration(1, 8)

        parameter_map[note2].note = actual_note

        assert policy.verify(parameter_map) is True

        logging.debug('End test_is_equal')
Exemple #4
0
    def test_basic_policy(self):
        logging.debug('Start test_basic_policy')
        lower_policy_context = TestRelativeScalarStepConstraint.policy_creator(
            ModalityType.Major, DiatonicTone('G'), 'tV', 'C:2', 'C:8')
        note1 = Note(DiatonicPitch.parse('C:5'), Duration(1, 8))
        note2 = Note(DiatonicPitch.parse('D:5'), Duration(1, 8))
        lower_note_1 = ContextualNote(
            lower_policy_context,
            Note(DiatonicPitch.parse('F#:5'), Duration(1, 8)))
        lower_note_2 = ContextualNote(lower_policy_context)

        p_map = dict([(note1, lower_note_1), (note2, lower_note_2)])

        # F#:5 --> G Major two below and 3 above
        policy = RelativeScalarStepConstraint(note1, note2, -2, 3)

        v_result = policy.values(p_map, note2)
        pitches = [n.diatonic_pitch for n in v_result]
        assert len(pitches) == 6
        for s in ['D:5', 'E:5', 'F#:5', 'G:5', 'A:5', 'B:5']:
            assert DiatonicPitch.parse(s) in pitches

        for note in v_result:
            logging.debug(note)

        # Check verify for each answer
        for n in v_result:
            lower_note_2.note = n
            assert policy.verify(p_map)

        logging.debug('End test_basic_policy')
Exemple #5
0
    def test_simple_fixed_pitch(self):
        logging.debug('Start test_simple_fixed_pitch')

        note = Note(DiatonicPitch.parse("C:5"), Duration(1, 4))

        select_notes = {'A:5', 'C:4', 'Eb:2', 'F#:6'}

        constraint = FixedPitchSelectSetConstraint(
            note, {DiatonicPitch.parse(p)
                   for p in select_notes})

        policy_context = TestFixedPitchSelectSetConstraint.policy_creator(
            ModalityType.Major, DiatonicTone('C'), 'tIV', 'C:2', 'C:8')
        lower_contextual = ContextualNote(policy_context)
        p_map = PMap()
        p_map[note] = lower_contextual

        v_results = constraint.values(p_map, note)
        assert v_results is not None
        assert len(v_results) == len(select_notes)
        for result in v_results:
            print(str(result))

        assert select_notes == {str(n.diatonic_pitch) for n in v_results}

        assert not constraint.verify(p_map)

        lower_contextual.note = Note(DiatonicPitch.parse('Eb:2'),
                                     Duration(1, 4))
        assert constraint.verify(p_map)
Exemple #6
0
    def test_is_not_equal(self):
        logging.debug('Start test_is_not_equal')
        note1 = Note(DiatonicPitch.parse('C:5'), Duration(1, 8))
        lower_policy_context = TestNotEqualPitchConstraint.policy_creator(
            ModalityType.Major, DiatonicTone('G'), 'tV', 'C:2', 'C:8')
        lower_context_note_a = ContextualNote(
            lower_policy_context,
            Note(DiatonicPitch.parse('F#:6'), Duration(1, 8)))
        p_map = PMap()
        p_map[note1] = lower_context_note_a

        other_source = []
        for tone in ['B:5', 'D:5', 'E:5']:
            n = Note(DiatonicPitch.parse(tone), Duration(1, 8))
            lower_context_note = ContextualNote(lower_policy_context)
            p_map[n] = lower_context_note
            other_source.append(n)

        params = list([note1])
        params.extend(other_source)
        policy = NotEqualPitchConstraint(params)

        for c_note in p_map.unassigned_actors(policy):
            print(c_note)
            v_result = policy.values(p_map, c_note)
            assert v_result is not None

            assert DiatonicPitch.parse('F#:6') not in {
                n.diatonic_pitch
                for n in v_result
            }

        p_map[other_source[1]].note = Note(DiatonicPitch.parse('E:6'),
                                           Duration(1, 8))
        for c_note in p_map.unassigned_actors(policy):
            print(c_note)
            v_result = policy.values(p_map, c_note)
            assert v_result is not None
            ret_pitches = {n.diatonic_pitch for n in v_result}
            assert len(
                ret_pitches.intersection(
                    {DiatonicPitch.parse('F#:6'),
                     DiatonicPitch.parse('E:6')})) == 0

        assert policy.verify(p_map) is False

        p_map[other_source[2]].note = Note(DiatonicPitch.parse('F#:6'),
                                           Duration(1, 8))
        assert policy.verify(p_map) is False

        p_map[other_source[0]].note = Note(DiatonicPitch.parse('D:6'),
                                           Duration(1, 8))
        assert policy.verify(p_map) is False

        p_map[other_source[2]].note = Note(DiatonicPitch.parse('A:6'),
                                           Duration(1, 8))
        assert policy.verify(p_map) is True

        logging.debug('End test_is_not_equal')
        return
    def test_across_tonalities(self):
        logging.debug('Start test_across_tonalities.')
        lower_policy_context_1 = TestRelativeDiatonicConstraint.policy_creator(
            ModalityType.Major, DiatonicTone('G'), 'tV', 'C:2', 'C:8')
        lower_policy_context_2 = TestRelativeDiatonicConstraint.policy_creator(
            ModalityType.Major, DiatonicTone('Ab'), 'tI', 'C:2', 'C:8')

        upper_note_1 = Note(DiatonicPitch.parse('C:5'), Duration(1, 8))
        upper_note_2 = Note(DiatonicPitch.parse('D:5'), Duration(1, 8))
        lower_note_1 = ContextualNote(
            lower_policy_context_1,
            Note(DiatonicPitch.parse('F#:5'), Duration(1, 8)))
        lower_note_2 = ContextualNote(lower_policy_context_2)

        p_map = dict([(upper_note_1, lower_note_1),
                      (upper_note_2, lower_note_2)])

        policy = RelativeDiatonicConstraint(upper_note_1, upper_note_2,
                                            Interval(3, IntervalType.Minor),
                                            Interval(3, IntervalType.Major))

        v_result = policy.values(p_map, upper_note_2)

        for note in v_result:
            logging.debug(note)

        pitches = [note.diatonic_pitch for note in v_result]
        assert {str(p) for p in pitches} == {'Eb:5', 'F:5', 'G:5', 'Ab:5'}

        logging.debug('End test_across_tonalities.')
Exemple #8
0
    def test_reversal_on_policy(self):
        logging.debug('Start test_reversal_on_policy')
        lower_policy_context = TestRelativeScalarStepConstraint.policy_creator(
            ModalityType.Major, DiatonicTone('G'), 'tV', 'C:2', 'C:8')
        note1 = Note(DiatonicPitch.parse('C:5'), Duration(1, 8))
        note2 = Note(DiatonicPitch.parse('D:5'), Duration(1, 8))
        lower_note_1 = ContextualNote(lower_policy_context)
        lower_note_2 = ContextualNote(
            lower_policy_context,
            Note(DiatonicPitch.parse('C:5'), Duration(1, 8)))

        p_map = dict([(note1, lower_note_1), (note2, lower_note_2)])

        # F#:5 --> G Major two below and 3 above
        policy = RelativeScalarStepConstraint(note1, note2, -2, 3)

        result = policy.values(p_map, note1)
        pitches = [n.diatonic_pitch for n in result]

        for pitch in pitches:
            logging.debug(pitch)

        # Check that each returned verifies
        for n in result:
            lower_note_1.note = n
            assert policy.verify(p_map)

        logging.debug('End test_reversal_on_policy')
    def test_simple_cross_tonality(self):
        logging.debug('Start test_simple_cross_tonality')

        # upper_policy_context = TestStepSequenceConstraint.policy_creator(ModalityType.Major, DiatonicTone('C'), 'tIV',
        #                                                             'C:2', 'C:8')
        lower_policy_context_1 = TestStepSequenceConstraint.policy_creator(ModalityType.Major, DiatonicTone('G'), 'tV',
                                                                           'C:2', 'C:8')
        lower_policy_context_2 = TestStepSequenceConstraint.policy_creator(ModalityType.Major, DiatonicTone('B'), 'tV',
                                                                           'C:2', 'C:8')
        upper_pitch_txts = ['C:5', 'D:5', 'E:5', 'F:5']
        tonalities = [lower_policy_context_1, lower_policy_context_1, lower_policy_context_2, lower_policy_context_2]
        differentials = [1, 1, 1]
        actors = list()
        p_map = dict()
        for i in range(0, len(upper_pitch_txts)):
            upper_note = Note(DiatonicPitch.parse(upper_pitch_txts[i]), Duration(1, 8))
            lower_note = ContextualNote(tonalities[i])
            actors.append(upper_note)
            p_map[upper_note] = lower_note

        policy = StepSequenceConstraint(actors, differentials)

        p_map[actors[0]].note = Note(DiatonicPitch.parse('B:5'), Duration(1, 8))
        answers = ['B:6', 'C:6', 'C#:6', 'D#:6']
        for i in range(1, len(actors)):
            notes = policy.values(p_map, actors[i])
            for note in notes:
                print(note.diatonic_pitch)
            assert str(next(iter(notes)).diatonic_pitch) == answers[i]
        print("------")

        upper_pitch_txts = ['F#:5', 'E:5', 'D:5', 'C:5']
        tonalities = [lower_policy_context_1, lower_policy_context_1, lower_policy_context_2, lower_policy_context_2]
        differentials = [-1, -1, -1]
        actors = list()
        p_map = dict()
        for i in range(0, len(upper_pitch_txts)):
            upper_note = Note(DiatonicPitch.parse(upper_pitch_txts[i]), Duration(1, 8))
            lower_note = ContextualNote(tonalities[i])
            actors.append(upper_note)
            p_map[upper_note] = lower_note

        policy = StepSequenceConstraint(actors, differentials)

        p_map[actors[0]].note = Note(DiatonicPitch.parse('F#:6'), Duration(1, 8))
        answers = ['F#:6', 'E:6', 'D#:6', 'C#:6']
        for i in range(1, len(actors)):
            notes = policy.values(p_map, actors[i])
            for note in notes:
                print(note.diatonic_pitch)
            assert str(next(iter(notes)).diatonic_pitch) == answers[i]
        print("------")

        logging.debug('End test_simple_cross_tonality')
    def test_compute_with_minor_key(self):
        print('-- test_compute_with_minor_key ---')
        line = Line()

        f = GenericUnivariatePitchFunction(
            TestFitPitchToFunctionConstraint.sinasoidal, Position(0),
            Position(2))
        v_notes = [
            Note(DiatonicPitch.parse('A:4'), Duration(1, 16))
            for _ in range(0, 33)
        ]
        for i in range(0, 33):
            line.pin(v_notes[i], Offset(i, 16))

        constraint, lower_policy_context = \
            TestFitPitchToFunctionConstraint.build_simple_constraint(v_notes[0], f, ModalityType.NaturalMinor,
                                                                     'C', 'tV')
        constraints = list()
        constraints.append(constraint)
        for i in range(1, 33):
            c, _ = \
                TestFitPitchToFunctionConstraint.build_simple_constraint(v_notes[i], f, ModalityType.NaturalMinor,
                                                                         'C', 'tV')
            constraints.append(c)

        p_map = PMap()
        p_map[v_notes[0]] = ContextualNote(lower_policy_context)

        results = constraint.values(p_map, v_notes[0])
        assert results is not None
        assert len(results) == 1
        print(next(iter(results)).diatonic_pitch)
        assert 'C:4' == str(next(iter(results)).diatonic_pitch)

        result_pitches = []
        for i in range(0, 33):
            p_map = PMap()
            p_map[v_notes[i]] = ContextualNote(lower_policy_context)
            results = constraints[i].values(p_map, v_notes[i])
            result_pitches.append(next(iter(results)).diatonic_pitch)

        assert len(result_pitches) == 33
        for i in range(0, 33):
            print('[{0}] {1}'.format(i, str(result_pitches[i])))

        checks = [
            'C:4', 'G:4', 'D:5', 'F:5', 'G:5', 'F:5', 'D:5', 'G:4', 'C:4'
        ]
        for i in range(0, len(checks)):
            assert checks[i] == str(result_pitches[i])
    def test_is_chordal(self):
        logging.debug('Start test_is_chordal')

        upper_context_note = Note(DiatonicPitch.parse('F:5'), Duration(1, 4))

        lower_policy_context = TestChordalToneConstraint.policy_creator(ModalityType.Major, DiatonicTone('G'), 'tV',
                                                                        'C:2', 'C:8')
        lower_context_note = ContextualNote(lower_policy_context)
        parameter_map = dict([(upper_context_note, lower_context_note)])
        policy = ChordalPitchConstraint(upper_context_note)

        v_result = policy.values(parameter_map, upper_context_note)

        results = {DiatonicTone('D'), DiatonicTone('F#'), DiatonicTone('A')}
        for note in v_result:
            print('test_is_chordal; note = {0}'.format(note))
            tone = note.diatonic_pitch.diatonic_tone
            octave = note.diatonic_pitch.octave
            assert tone in results
            assert octave in range(2, 9)

        assert len(v_result) == 6 * 3

        for note in v_result:
            parameter_map[upper_context_note].note = note
            assert policy.verify(parameter_map) is True
        logging.debug('End test_is_chordal')
Exemple #12
0
    def create(line_str, pitch_range, target_hct_list=None):
        """
        Create a PMap from
        :param line_str: a melodic string
        :param pitch_range: PitchRange
        :param target_hct_list: list of pairs ('tonality:chord', duration)
        :return: pmap
        Note if target_hct_list is not specified, we use the hct from the line_str.
        """
        lge = LineGrammarExecutor()
        line, hct = lge.parse(line_str)
        if target_hct_list is not None:
            hct = PMap.build_hct(target_hct_list)
        actors = line.get_all_notes()

        d = OrderedDict()
        for note in actors:
            hc = hct[note.get_absolute_position().position]
            if hc is None:
                raise Exception(
                    'Cannot locate harmonic context for note \'{0}\''.format(
                        note))
            contextual_note = ContextualNote(PolicyContext(hc, pitch_range))
            d[note] = contextual_note

        return PMap(d)
Exemple #13
0
    def test_is_scalar_with_roles(self):
        logging.debug('Start test_is_scalar_with_roles')

        v_note = Note(DiatonicPitch.parse('F:5'), Duration(1, 4))

        lower_policy_context = TestScalarPitchConstraint.policy_creator(
            ModalityType.Major, DiatonicToneCache.get_tone('G'), 'tV', 'G:5',
            'G:7')

        lower_context_note = ContextualNote(lower_policy_context)

        parameter_map = dict([(v_note, lower_context_note)])

        policy = ScalarPitchConstraint(v_note, [3, 5])

        v_result = policy.values(parameter_map, v_note)

        tones = list(lower_policy_context.harmonic_context.tonality.annotation)
        tones = tones[:-1]
        for note in v_result:
            print('test_is_scalar; note = {0}'.format(note))
            tone = note.diatonic_pitch.diatonic_tone
            octave = note.diatonic_pitch.octave
            assert tone in tones
            assert tones.index(tone) in [3, 5]
            assert octave in range(5, 8)

        assert len(v_result) == 2 * 2

        for note in v_result:
            parameter_map[v_note].note = note
            assert policy.verify(parameter_map) is True
        logging.debug('End test_is_scalar_with_roles')
    def _build_p_map_dict(self, partial_pitch_results=None):
        actors = OrderedSet()
        for p in self.pitch_constraints:
            actors = actors.union(p.actors)

        d = OrderedDict()
        for note in actors:
            hc = self.hct[note.get_absolute_position().position]
            if hc is None:
                raise Exception(
                    'Cannot locate harmonic context for note \'{0}\''.format(
                        note))
            contextual = ContextualNote(PolicyContext(hc, self.pitch_range))
            d[note] = contextual

        if partial_pitch_results is not None:
            for k, v in partial_pitch_results.items():
                if not isinstance(k, Note):
                    raise Exception(
                        'key of partial_pitch_results must be a Note.')
                if not isinstance(v, DiatonicPitch):
                    raise Exception(
                        'value of partial_pitch_results must be a DiatonicPitch.'
                    )
                if k not in d:
                    raise Exception(
                        'Note \'{0}\' of partial result is not a constraint actor.'
                        .format(k))
                d[k].note = Note(v, k.base_duration, k.num_dots)

        return d
    def test_simple_major_scale_descent_two_steps(self):
        logging.debug('Start test_simple_major_scale_descent_two_steps')
        upper_context_notes = list()
        for s in ['C:6', 'A:5', 'F:5', 'D:5', 'B:4']:
            upper_context_notes.append(Note(DiatonicPitch.parse(s), Duration(1, 8)))

        lower_policy_context = TestPitchStepConstraint.policy_creator(ModalityType.Major, DiatonicTone('G'), 'tV',
                                                                      'C:2', 'C:8')

        lower_context_notes = list()
        for s in range(0, len(upper_context_notes)):
            lower_context_notes.append(ContextualNote(lower_policy_context))
        lower_context_notes[0].note = Note(DiatonicPitch.parse("E:5"), Duration(1, 8))

        parameter_map = dict()
        policies = []
        for s, sp in zip(upper_context_notes, lower_context_notes):
            parameter_map[s] = sp
        for i in range(0, len(upper_context_notes) - 1):
            policies.append(PitchStepConstraint(upper_context_notes[i], upper_context_notes[i + 1], 2,
                                                PitchStepConstraint.Down))

        answers = ['C:5', 'A:4', 'F#:4', 'D:4']
        for policy, answer in zip(policies, answers):
            result = policy.values(parameter_map, policy.note_two)
            note = next(iter(result))
            print(note)

            assert str(note.diatonic_pitch) == answer

            parameter_map[policy.note_two].note = note
            assert policy.verify(parameter_map)

        logging.debug('End test_simple_major_scale_descent_two_steps')
Exemple #16
0
    def _optimize_note_domain(self, note, constraints, score):
        """
        For note, get all values it can take satisfying all its constraints.
        Then if there is only one, build a fixed pitch constraint for it.
        If there are more than two, use the curve fits values to make a fixed pitch to set.
        :param note:
        :param constraints:
        :param score:
        :return:
        """
        domain = set()
        first = True
        for constraint in constraints:
            # build a pmap for all actor in the constraint
            pmap = PMap()
            for n in constraint.actors:
                hc = score.hct.get_hc_by_position(n.get_absolute_position())
                pmap[n] = ContextualNote(
                    PolicyContext(
                        hc,
                        score.instrument.sounding_pitch_range()
                        if score.instrument is not None else PitchRange.create(
                            'A:0', 'C:8')))
            # Get all possible pitch values for note in this constraint.
            # domain will hold all the values that match across all constraints
            values = {n.diatonic_pitch for n in constraint.values(pmap, note)}
            if first:
                domain = values
                first = False
            else:
                domain = domain.intersection(values)

        if len(domain) == 0:
            return set()

        pitch_list = list(domain)
        if len(domain) > 2:
            # Find 2 pitches in domain that are closest to the curve fit
            valuation = self.pitch_function.eval_as_nearest_pitch(
                note.get_absolute_position().position)
            candidates = [
                (p, abs(p.chromatic_distance - valuation.chromatic_distance))
                for p in domain
            ]
            candidates = sorted(candidates, key=lambda candidate: candidate[1]
                                )  # sort on chromatic distance.
            pitch_list = [candidates[0][0],
                          candidates[1][0]]  # Take the top to

        if len(pitch_list) == 1:
            return {FixedPitchConstraint(note, pitch_list[0])}

        #  set first as best, second as next best.
        (first, second) = (pitch_list[0], pitch_list[1]) if pitch_list[0].chromatic_distance <= \
            pitch_list[1].chromatic_distance else \
            (pitch_list[1], pitch_list[0])

        return {FixedPitchSelectSetConstraint(note, [first, second])}
    def test_more_than_two(self):
        logging.debug('Start test_more_than_two')

        lower_policy_context = TestEqualPitchConstraint.policy_creator(
            ModalityType.Major, DiatonicTone('G'), 'tV', 'C:2', 'C:8')

        upper_notes = list()
        for i in range(0, 5):
            upper_notes.append(Note(DiatonicPitch.parse('C:5'), Duration(1,
                                                                         8)))
        lower_notes = list()
        for i in range(0, 5):
            n = ContextualNote(lower_policy_context, Note(DiatonicPitch.parse('F#:6'),
                                                          Duration(1, 8))) if i == 0 else \
                ContextualNote(lower_policy_context)
            lower_notes.append(n)

        policy = EqualPitchConstraint(upper_notes)

        p_map = PMap()
        for i in range(0, 5):
            p_map[upper_notes[i]] = lower_notes[i]

        for i in range(1, len(upper_notes)):
            v_results = policy.values(p_map, upper_notes[i])
            assert len(v_results) == 1
            note = next(iter(v_results))
            print(note)

            assert str(note.diatonic_pitch) == 'F#:6'

        # Again but assign the received note each time - then call verify.
        for i in range(1, len(upper_notes)):
            v_results = policy.values(p_map, upper_notes[i])
            note = next(iter(v_results))
            p_map[upper_notes[i]].note = note

            assert str(note.diatonic_pitch) == 'F#:6'

        assert policy.verify(p_map)

        logging.debug("End test_more_than_two")
    def test_in_range(self):
        logging.debug('Start test_in_range')
        lower_policy_context = TestPitchRangeConstraint.policy_creator(ModalityType.Major, DiatonicTone('G'), 'tV',
                                                                       'C:2', 'C:8')

        v_notes = []
        p_map = PMap()
        for s in ['C:5', 'B:4', 'D:5', 'G:4']:
            v_note = Note(DiatonicPitch.parse(s), Duration(1, 8))
            v_notes.append(v_note)
            p_map[v_note] = ContextualNote(lower_policy_context)

        policy = PitchRangeConstraint(v_notes, PitchRange.create('G:3', 'A:4'))

        values = policy.values(p_map, v_notes[0])

        assert values is not None
        assert len(values) is not 0
        pitches = set()
        for v in values:
            print(v.diatonic_pitch)
            pitches.add(v.diatonic_pitch)

        answers_str = {'G:3', 'A:3', 'B:3', 'C:4', 'D:4', 'E:4', 'F#:4', 'G:4', 'A:4'}
        answers = {DiatonicPitch.parse(s) for s in answers_str}
        assert pitches == answers

        index = 0
        it = iter(values)
        for v_note in v_notes:
            p_map[v_note].note = next(it)
            index = index + 1
        assert policy.verify(p_map) is True

        # Change one and get false
        p_map[v_notes[0]].note = Note(DiatonicPitch.parse('B:4'), Duration(1, 8))
        assert policy.verify(p_map) is False

        logging.debug('End test_in_range')
Exemple #19
0
    def create_contextual_notes(pitch_list, duration_list, policy_context):
        assert len(pitch_list) == len(duration_list)
        assert len(pitch_list) > 0

        result = []
        for pitch_str, duration_str in zip(pitch_list, duration_list):
            pitch = DiatonicPitch.parse(pitch_str)
            duration = TestPitchConstraintSolver.parse_duration(duration_str)
            note = Note(pitch, duration)
            cn = ContextualNote(policy_context, note)
            result.append(cn)

        return result
    def test_is_not_equal(self):
        logging.debug('Start test_is_not_equal')

        note1 = Note(DiatonicPitch.parse('C:5'), Duration(1, 8))

        note2 = Note(DiatonicPitch.parse('C:5'), Duration(1, 8))

        lower_policy_context = TestEqualPitchConstraint.policy_creator(
            ModalityType.Major, DiatonicTone('G'), 'tV', 'C:2', 'C:8')
        lower_context_note_a = ContextualNote(
            lower_policy_context,
            Note(DiatonicPitch.parse('F#:6'), Duration(1, 8)))
        lower_context_note_b = ContextualNote(
            lower_policy_context,
            Note(DiatonicPitch.parse('G:6'), Duration(1, 8)))
        parameter_map = dict([(note1, lower_context_note_a),
                              (note2, lower_context_note_b)])

        policy = EqualPitchConstraint([note1, note2])

        assert policy.verify(parameter_map) is False

        logging.debug('End test_is_not_equal')
    def test_reverse_arguments(self):
        logging.debug('Start test_reverse_arguments')
        lower_policy_context = TestPitchStepConstraint.policy_creator(ModalityType.Major, DiatonicTone('G'), 'tV',
                                                                      'C:2', 'C:8')

        upper_context_notes = list()
        for s in ['C:6', 'B5']:
            upper_context_notes.append(Note(DiatonicPitch.parse(s), Duration(1, 8)))

        policy = PitchStepConstraint(upper_context_notes[0], upper_context_notes[1], 1, PitchStepConstraint.Down)

        lower_contextual_note_0 = ContextualNote(lower_policy_context)
        lower_contextual_note_1 = ContextualNote(lower_policy_context, Note(DiatonicPitch.parse("E:5"), Duration(1, 4)))

        parameter_map = dict([(upper_context_notes[0], lower_contextual_note_0),
                              (upper_context_notes[1], lower_contextual_note_1)])

        result = policy.values(parameter_map, policy.note_one)
        note = next(iter(result))
        print(note)
        assert str(note.diatonic_pitch) == 'F#:5'

        logging.debug('End test_reverse_arguments')
    def test_compute_simple_function_tone(self):
        print('--- test_compute_simple_function_tone ---')
        line = Line()

        f = GenericUnivariatePitchFunction(
            TestFitPitchToFunctionConstraint.sinasoidal, Position(0),
            Position(2))
        v_note = Note(DiatonicPitch.parse('A:4'), Duration(1, 32))
        line.pin(v_note, Offset(0))

        constraint, lower_policy_context = TestFitPitchToFunctionConstraint.build_simple_constraint(
            v_note, f, ModalityType.Major, 'G', 'tV')
        p_map = PMap()
        p_map[v_note] = ContextualNote(lower_policy_context)

        results = constraint.values(p_map, v_note)
        assert results is not None
        assert len(results) == 1
        print(next(iter(results)).diatonic_pitch)
        assert 'C:4' == str(next(iter(results)).diatonic_pitch)

        v_note = Note(DiatonicPitch.parse('A:4'), Duration(1, 32))
        line.pin(v_note, Offset(1, 32))

        constraint, lower_policy_context = TestFitPitchToFunctionConstraint.build_simple_constraint(
            v_note, f, ModalityType.Major, 'G', 'tV')
        p_map = PMap()
        p_map[v_note] = ContextualNote(lower_policy_context)

        results = constraint.values(p_map, v_note)
        assert results is not None
        assert len(results) == 1
        print(next(iter(results)).diatonic_pitch)
        assert 'E:4' == str(next(iter(results)).diatonic_pitch)

        p_map[v_note].note = next(iter(results))
        assert constraint.verify(p_map)
Exemple #23
0
    def _build_p_map_dict(self, hct, pitch_constraints):
        actors = set()
        for p in pitch_constraints:
            actors = actors.union(p.actors)

        d = OrderedDict()
        for note in actors:
            hc = hct[note.get_absolute_position().position]
            if hc is None:
                raise Exception(
                    'Cannot locate harmonic context for note \'{0}\''.format(
                        note))
            pitch_range = self.score.instrument.sounding_pitch_range() if self.score.instrument is not None \
                else PitchRange.create('A:0', 'C:8')
            contextual = ContextualNote(PolicyContext(hc, pitch_range))
            d[note] = contextual

        return d
    def test_simple_diatonic_test(self):
        logging.debug('Start test_simple_diatonic_test')
        lower_policy_context = TestRelativeDiatonicConstraint.policy_creator(
            ModalityType.Major, DiatonicTone('G'), 'tV', 'C:2', 'C:8')
        upper_note_1 = Note(DiatonicPitch.parse('C:5'), Duration(1, 8))
        upper_note_2 = Note(DiatonicPitch.parse('D:5'), Duration(1, 8))
        lower_note_1 = ContextualNote(
            lower_policy_context,
            Note(DiatonicPitch.parse('F#:5'), Duration(1, 8)))
        lower_note_2 = ContextualNote(lower_policy_context)

        p_map = dict([(upper_note_1, lower_note_1),
                      (upper_note_2, lower_note_2)])

        policy = RelativeDiatonicConstraint(upper_note_1, upper_note_2,
                                            Interval(3, IntervalType.Minor),
                                            Interval(3, IntervalType.Major))

        v_result = policy.values(p_map, upper_note_2)

        for note in v_result:
            logging.debug(note)

        pitches = [note.diatonic_pitch for note in v_result]
        assert {str(p)
                for p in pitches} == {'D:5', 'E:5', 'F#:5', 'G:5', 'A:5'}

        # test for determining note 1
        logging.debug('Determining note 1')
        lower_note_2.note = lower_note_1.note
        lower_note_1.note = None

        v_result = policy.values(p_map, upper_note_1)

        for note in v_result:
            logging.debug(note)

        pitches = [note.diatonic_pitch for note in v_result]
        assert {str(p) for p in pitches} == {'A:5', 'G:5', 'F#:5', 'E:5'}

        logging.debug('End test_simple_diatonic_test')
Exemple #25
0
 def create_pmap(upper_notes, lower_policy_context):
     p_map = OrderedDict()
     for s in upper_notes:
         lower_cn = ContextualNote(lower_policy_context)
         p_map[s] = lower_cn
     return p_map
    def test_compute_simple_scale_tones(self):
        print('Start test_compute_simple_scale_tones')

        # upper_policy_context = TestStepSequenceConstraint.policy_creator(ModalityType.Major, DiatonicTone('Ab'),
        # 'tIV',
        #                                                            'C:2', 'C:8')
        lower_policy_context = TestStepSequenceConstraint.policy_creator(ModalityType.Major, DiatonicTone('G'), 'tV',
                                                                         'C:2', 'C:8')
        upper_pitch_txts = ['C:5', 'D:5', 'E:5', 'G:5', 'B:5', 'C:6', 'B:5', 'G:5', 'E:5', 'D:5', 'C:5', 'C:5']
        actors = list()
        differentials = [1, 1, 2, 2, 1, -1, -2, -2, -1, -1, 0]
        p_map = PMap()
        for pitch_txt in upper_pitch_txts:
            upper_note = Note(DiatonicPitch.parse(pitch_txt), Duration(1, 8))
            lower_note = ContextualNote(lower_policy_context)
            p_map[upper_note] = lower_note
            actors.append(upper_note)

        policy = StepSequenceConstraint(actors, differentials)

        notes = policy.values(p_map, actors[2])

        print('uninitialized: {0} notes'.format(len(notes)))
        for note in notes:
            print(note.diatonic_pitch)
        print('-----')

        assert len(notes) == 7 * 6 + 1
        assert str(next(iter(notes)).diatonic_pitch) == 'C:2'
        note = None
        for n in notes:
            note = n
        assert note is not None
        assert str(note.diatonic_pitch) == 'C:8'

        p_map[actors[0]].note = Note(DiatonicPitch.parse('F#:4'), Duration(1, 8))
        answers = ['F#:4', 'G:4', 'A:4', 'C:5', 'E:5', 'F#:5', 'E:5', 'C:5', 'A:4', 'G:4', 'F#:4', 'F#:4']
        for i in range(1, len(actors)):
            notes = policy.values(p_map, actors[i])
            for note in notes:
                print(note.diatonic_pitch)
            assert str(next(iter(notes)).diatonic_pitch) == answers[i]
        print('-----')

        p_map[actors[-1]].note = Note(DiatonicPitch.parse('F#:4'), Duration(1, 8))
        p_map[actors[0]].note = None
        answers = ['F#:4', 'G:4', 'A:4', 'C:5', 'E:5', 'F#:5', 'E:5', 'C:5', 'A:4', 'G:4', 'F#:4', 'F#:4']
        for i in range(1, len(actors)):
            notes = policy.values(p_map, actors[i])
            for note in notes:
                print(note.diatonic_pitch)
            assert str(next(iter(notes)).diatonic_pitch) == answers[i]
        print('-----')

        p_map[actors[6]].note = Note(DiatonicPitch.parse('E:5'), Duration(1, 8))
        p_map[actors[-1]].note = None
        answers = ['E:5', 'G:4', 'A:4', 'C:5', 'E:5', 'F#:5', 'E:5', 'C:5', 'A:4', 'G:4', 'F#:4', 'F#:4']
        for i in range(1, len(actors)):
            notes = policy.values(p_map, actors[i])
            for note in notes:
                print(note.diatonic_pitch)
            assert str(next(iter(notes)).diatonic_pitch) == answers[i]
        print('-----')

        logging.debug('End test_compute_simple_scale_tones')
Exemple #27
0
    def test_compute_simple_scale_tones(self):
        logging.debug('Start test_compute_simple_scale_tones')

        lower_policy_context = TestPMap.policy_creator(ModalityType.Major,
                                                       DiatonicTone('G'), 'tV',
                                                       'C:2', 'C:8')
        upper_pitch_txts = [
            'C:5', 'D:5', 'E:5', 'G:5', 'B:5', 'C:6', 'B:5', 'G:5', 'E:5',
            'D:5', 'C:5', 'C:5'
        ]
        actors = list()
        differentials = [1, 1, 2, 2, 1, -1, -2, -2, -1, -1, 0]
        p_map = OrderedDict()
        for pitch_txt in upper_pitch_txts:
            upper_note = Note(DiatonicPitch.parse(pitch_txt), Duration(1, 8))
            lower_note = ContextualNote(lower_policy_context)
            p_map[upper_note] = lower_note
            actors.append(upper_note)

        policy = StepSequenceConstraint(actors, differentials)
        p_map[actors[2]].note = Note(DiatonicPitch.parse('G:5'),
                                     Duration(1, 8))

        solver = PitchConstraintSolver([policy])
        results = None
        try:
            results, _ = solver.solve(p_map)
            if results is None:
                print("Results is None")
            else:
                print("Results is not None")
                if len(results) == 0:
                    print("Results is empty")
                else:
                    print('Results has {0} results.'.format(len(results)))

                    # verify
                    for pm in results:
                        if not policy.verify(pm.p_map):
                            print('Policy failure: {0}'.format(
                                type(policy).__name__))
                            print(pm)
                            continue

                    for pm in results:
                        print(pm)

        except Exception as e:
            print(e)
            # print >> sys.stderr, traceback.format_exc()
            traceback.print_exc()

        assert results is not None
        assert len(results) == 1
        pm = next(iter(results))

        answers = [
            'E:5', 'F#:5', 'G:5', 'B:5', 'D:6', 'E:6', 'D:6', 'B:5', 'G:5',
            'F#:5', 'E:5', 'E:5'
        ]
        for i in range(0, len(actors)):
            assert str(pm[actors[i]].note.diatonic_pitch) == answers[i]
        print('-----')

        #  Build a line and test apply on pm
        line = Line()
        begin_note = Note(DiatonicPitch.parse('A:2'), Duration(1, 2))
        end_note = Note(DiatonicPitch.parse('B:2'), Duration(1, 2))
        offset = Offset(0)
        line.pin(begin_note, offset)
        offset = offset + begin_note.duration.duration
        for note in actors:
            line.pin(note, offset)
            offset += note.duration.duration
        line.pin(end_note, offset)

        new_line = pm.apply(line)
        assert new_line is not None
        assert new_line != line

        all_notes = new_line.get_all_notes()
        assert len(all_notes) == 2 + len(actors)

        assert str(all_notes[0].diatonic_pitch) == 'A:2'
        assert str(all_notes[-1].diatonic_pitch) == 'B:2'

        for i in range(1, len(all_notes) - 1):
            assert str(all_notes[i].diatonic_pitch) == answers[i - 1]
    def test_basic_policy(self):
        logging.debug('Start test_basic_policy')

        lower_policy_context = TestComparativePitchConstraint.policy_creator(
            ModalityType.Major, DiatonicTone('G'), 'tV', 'C:4', 'C:6')
        upper_note_1 = Note(DiatonicPitch.parse('C:5'), Duration(1, 8))
        upper_note_2 = Note(DiatonicPitch.parse('D:5'), Duration(1, 8))
        lower_note_1 = ContextualNote(
            lower_policy_context,
            Note(DiatonicPitch.parse('F#:5'), Duration(1, 8)))
        lower_note_2 = ContextualNote(lower_policy_context)

        p_map = dict([(upper_note_1, lower_note_1),
                      (upper_note_2, lower_note_2)])

        policy = ComparativePitchConstraint(
            upper_note_1, upper_note_2, ComparativePitchConstraint.LESS_THAN)
        result = policy.values(p_map, upper_note_2)

        pitches = sorted([note.diatonic_pitch for note in result])

        for pitch in pitches:
            logging.debug(pitch)

        # validate
        assert DiatonicPitch.parse('F#:5') not in pitches
        assert len(pitches) == 4
        for pitch in pitches:
            assert pitch.chromatic_distance > DiatonicPitch.parse('F#:5').chromatic_distance, \
                "{0} <= {1}".format(pitch,  DiatonicPitch.parse('F#:5'))

        for note in result:
            lower_note_2.note = note
            assert policy.verify(p_map) is True
        lower_note_2.note = None

        # Do less than
        logging.debug('------')
        policy = ComparativePitchConstraint(
            upper_note_1, upper_note_2,
            ComparativePitchConstraint.GREATER_THAN)
        result = policy.values(p_map, upper_note_2)

        pitches = sorted([note.diatonic_pitch for note in result])
        for pitch in pitches:
            logging.debug(pitch)

        assert DiatonicPitch.parse('F#:5') not in pitches
        assert len(pitches) == 10

        for pitch in pitches:
            assert pitch.chromatic_distance < DiatonicPitch.parse('F#:5').chromatic_distance, \
                "{0} >= {1}".format(pitch,  DiatonicPitch.parse('F#:5'))

        for note in result:
            lower_note_2.note = note
            assert policy.verify(p_map) is True
        lower_note_2.note = None

        # Do greater than or equal
        logging.debug('------')
        policy = ComparativePitchConstraint(
            upper_note_1, upper_note_2, ComparativePitchConstraint.LESS_EQUAL)
        result = policy.values(p_map, upper_note_2)

        pitches = sorted([note.diatonic_pitch for note in result])
        for pitch in pitches:
            logging.debug(pitch)

        assert DiatonicPitch.parse('F#:5') in pitches
        assert len(pitches) == 5

        for pitch in pitches:
            assert pitch.chromatic_distance >= DiatonicPitch.parse('F#:5').chromatic_distance, \
                "{0} < {1}".format(pitch,  DiatonicPitch.parse('F#:5'))

        for note in result:
            lower_note_2.note = note
            assert policy.verify(p_map) is True
        lower_note_2.note = None

        # Do less than or equal
        logging.debug('------')
        policy = ComparativePitchConstraint(
            upper_note_1, upper_note_2,
            ComparativePitchConstraint.GREATER_EQUAL)
        result = policy.values(p_map, upper_note_2)

        pitches = sorted([note.diatonic_pitch for note in result])
        for pitch in pitches:
            logging.debug(pitch)

        assert DiatonicPitch.parse('F#:5') in pitches
        assert len(pitches) == 11

        for pitch in pitches:
            assert pitch.chromatic_distance <= DiatonicPitch.parse('F#:5').chromatic_distance, \
                "{0} > {1}".format(pitch,  DiatonicPitch.parse('F#:5'))

        for note in result:
            lower_note_2.note = note
            assert policy.verify(p_map) is True
        lower_note_2.note = None

        # Do equal
        logging.debug('------')
        policy = ComparativePitchConstraint(upper_note_1, upper_note_2,
                                            ComparativePitchConstraint.EQUAL)
        result = policy.values(p_map, upper_note_2)

        pitches = sorted([note.diatonic_pitch for note in result])
        for pitch in pitches:
            logging.debug(pitch)

        assert DiatonicPitch.parse('F#:5') in pitches
        assert len(pitches) == 1

        for pitch in pitches:
            assert pitch.chromatic_distance == DiatonicPitch.parse('F#:5').chromatic_distance, \
                "{0} != {1}".format(pitch,  DiatonicPitch.parse('F#:5'))

        for note in result:
            lower_note_2.note = note
            assert policy.verify(p_map) is True
        lower_note_2.note = None

        logging.debug('End test_basic_policy')
Exemple #29
0
    def _build_pitch_solutions_old(self, beat_score_results,
                                   pitch_constraints):
        """
        Build the final results using the beat results, then the pitch results, then the reshape constraints.
        :param beat_score_results: Set of (PositionDeltaInfo, LiteScore)'s
        :param pitch_constraints: Set of Constraints
        :return:
        """
        final_results = list()
        pitch_results = list()

        # Solve the pitch constraints using the beat constraint results.
        if beat_score_results is not None:
            for beat_result_pdi, beat_result_score in beat_score_results:
                revised_constraints = TReshape._regenerate_constraints(
                    pitch_constraints, self.score.line, beat_result_score.line)
                pitch_solver = PitchConstraintSolver(revised_constraints)
                p_map_dict = PMap(
                    self._build_p_map_dict(beat_result_pdi.hct,
                                           revised_constraints))
                pitch_solver_results = pitch_solver.solve(p_map_dict)
                for pitch_pmap in pitch_solver_results:
                    line = pitch_pmap.apply(beat_result_score.line)
                    pitch_results.append(
                        (pitch_pmap, beat_result_score,
                         LiteScore(line, beat_result_pdi.hct,
                                   self.score.instrument,
                                   beat_result_pdi.tempo_event_sequence,
                                   beat_result_pdi.ts_event_sequence)))

        else:
            pitch_solver = PitchConstraintSolver(pitch_constraints)
            p_map_dict = PMap(
                self._build_p_map_dict(self.score.hct, pitch_constraints))
            pitch_solver_results = pitch_solver.solve(p_map_dict)
            for pitch_pmap in pitch_solver_results:
                line = pitch_pmap.apply(self.score.line)
                pitch_results.append(
                    (pitch_pmap, self.score,
                     LiteScore(line, self.score.hct, self.score.instrument,
                               self.score.tempo_sequence,
                               self.score.time_signature_sequence)))

        # Solve the reshape constraints using the pitch constraint solutions.
        for pitch_result_pmap, beat_result_score, pitch_result_score in pitch_results:
            # Issue 1. we generate constraints for ALL NOTES on pitch_result_score's line, note that this means
            #          we cannot reliably use pitch_result_pmap further on since pitch_result_score is buily with
            #          an apply - meaning the notes are in the pmap's range, not domain.
            # tersely:  pitch_result_pmap: self.score.line --> pitch_result_score.line
            q = {
                key: value
                for key, value in zip(beat_result_score.line.get_all_notes(),
                                      pitch_result_score.line.get_all_notes())
            }
            ignore_notes = {
                q[n]
                for n in pitch_result_pmap.keys()
                if pitch_result_pmap[n].note is not None
            }
            reshape_constraints = self._generate_reshape_constraints(
                pitch_result_score.line, pitch_result_score.tempo_sequence,
                pitch_result_score.time_signature_sequence, ignore_notes)

            p_map = PMap()
            for c in reshape_constraints:
                note = c.actor_note
                hc = pitch_result_score.hct[
                    note.get_absolute_position().position]
                if hc is None:
                    raise Exception(
                        'Cannot locate harmonic context for note \'{0}\''.
                        format(note))
                contextual = ContextualNote(
                    PolicyContext(
                        hc,
                        pitch_result_score.instrument.sounding_pitch_range()
                        if pitch_result_score.instrument is not None else
                        PitchRange.create('A:0', 'C:8')))
                # Note: p_map maps from pitch_result_score's line notes to something else (does not matter)
                p_map[note] = contextual

            pitch_solver = PitchConstraintSolver(reshape_constraints)
            reshape_results = pitch_solver.solve(p_map)
            # reshape_pmap_result maps pitch_result_score's line notes to something else with a pitch designation.
            # Issue 2): we are getting failures on some notes due to being too close to chord on beat. In these cases,
            #           the solve is not failing, but giving back a partial result.
            for reshape_pmap_result in reshape_results:
                master_pmap = PMap()
                # Not sure  pitch_result_pmap maps from beat_score_result.line notes to a note with pitch desig.
                # reshape_pmap_result pitch_result_score's line notes to something else with a pitch designation.
                # mm: beat_result_score --> self.score or beat_result_score
                mm = {
                    key: value
                    for key, value in zip(
                        beat_result_score.line.get_all_notes() if
                        beat_result_score else self.score.line.get_all_notes(),
                        pitch_result_score.line.get_all_notes())
                }
                for note in pitch_result_pmap.keys():
                    # map notes in pitch_result_score to what beat_score_result would
                    master_pmap[mm[note]] = pitch_result_pmap[note]
                for note in reshape_pmap_result.keys():
                    if note not in master_pmap.keys():
                        master_pmap[note] = reshape_pmap_result[note]
                line_answer = master_pmap.apply(pitch_result_score.line)
                final_results.append(
                    LiteScore(line_answer, pitch_result_score.hct,
                              pitch_result_score.instrument,
                              pitch_result_score.tempo_sequence,
                              pitch_result_score.time_signature_sequence))

        return final_results