Exemple #1
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_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_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 #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_for_book_example_2(self):
        print('----- test for book example 2 -----')

        source_instance_expression = '{<A-Major:i> [sA:4 A A A] qA:4 [iA:4 A] <:iv> qA:4 [sA:4 A A A] qA:4}'
        target_instance_expression = '{<G-Major:i> wA:4 <:iv> wA:4}'
        lge = LineGrammarExecutor()

        source_instance_line, source_instance_hct = lge.parse(
            source_instance_expression)

        actors = source_instance_line.get_all_notes()
        for a in actors:
            print("{0}".format(a))

        target_instance_line, target_instance_hct = lge.parse(
            target_instance_expression)
        target_hcs = target_instance_hct.hc_list()
        for hc in target_hcs:
            print("{0}".format(hc))

        pitch_range = PitchRange(
            DiatonicPitch.parse('C:4').chromatic_distance,
            DiatonicPitch.parse('C:6').chromatic_distance)

        p_map = PMap.create(source_instance_expression, pitch_range,
                            [('G-Major:I', Duration(3, 4)),
                             ('G-Major:IV', Duration(3, 4))])

        actors = p_map.actors

        policies = OrderedSet()
        policies.add(
            StepSequenceConstraint(
                [actors[0], actors[1], actors[2], actors[3]], [1, 1, 1]))
        policies.add(ChordalPitchConstraint(actors[0]))
        policies.add(ChordalPitchConstraint(actors[4]))
        policies.add(ChordalPitchConstraint(actors[8]))
        policies.add(
            StepSequenceConstraint(
                [actors[8], actors[9], actors[10], actors[11]], [1, -1, -1]))
        policies.add(EqualPitchConstraint([actors[0], actors[12]]))
        policies.add(EqualPitchConstraint([actors[4], actors[7]]))
        policies.add(
            RelativeDiatonicConstraint(actors[4], actors[5],
                                       Interval(3, IntervalType.Major),
                                       Interval(1, IntervalType.Perfect)))
        policies.add(StepSequenceConstraint([actors[5], actors[6]], [-1]))

        # policies.add(ChordalPitchConstraint(actors[7]))

        solver = PitchConstraintSolver(policies)

        full_results, partial_results = solver.solve(p_map)
        print('Results has {0} results.'.format(len(full_results)))

        for pm in full_results:
            if str(pm[actors[7]].note.diatonic_pitch) == 'D:4' and str(
                    pm[actors[0]].note.diatonic_pitch) == 'G:4':
                print("{0}".format(pm))
Exemple #7
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])}
Exemple #8
0
    def test_create(self):
        music_line = '{<Ab-Major:I> qC:4 D E F <Db-Major:IV> iDb:4 Eb F Gb <C-Major:IV> qE:4 F G A }'
        pr = PitchRange.create('Ab:3', 'C:5')
        pm = PMap.create(music_line, pr)
        assert pm is not None
        assert len(pm.keys()) == 12
        assert pm.actors[11].diatonic_pitch is not None
        assert str(pm.actors[11].diatonic_pitch) == 'A:4'
        assert pm[pm.actors[11]] is not None
        assert pm[pm.actors[11]].policy_context is not None
        assert pm[pm.actors[11]].policy_context.harmonic_context is not None
        assert pm[
            pm.actors[11]].policy_context.harmonic_context.tonality is not None
        assert str(pm[pm.actors[11]].policy_context.harmonic_context.tonality
                   ) == 'C-Major'

        target_harmonic_list = [('A-Melodic:iv', 1),
                                ('A-Natural:i', Duration(1, 4)),
                                ('A-Melodic:V', 1)]
        pm = PMap.create(music_line, pr, target_harmonic_list)
        assert pm is not None
        assert len(pm.keys()) == 12
    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)
    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")
Exemple #11
0
    def solve(self, p_map_param, instance_limit=-1, accept_partials=False):
        """
        Solve the constraints constraint system using p_map_param as the start.
        :param p_map_param:  Initial PMap to fill out.
        :param instance_limit: Number of full results to limit search; -1 no limit
        :param accept_partials: Boolean, True means return some partial results
        :return:
        """
        p_map = p_map_param if isinstance(p_map_param, PMap) else PMap(p_map_param)
        self._check_p_map(p_map)

        self.__instance_limit = instance_limit
        self.__num_instances = 0  # reset
        self.__full_results = list()

        partial_results = [p_map]
        # list of tuples (v_note, {solution to v_note's policies}) sorted by low number of solutions.
        unsolved_nodes = [t[0] for t in self._build_potential_values(p_map, p_map.keys())]
        if len(unsolved_nodes) == 0:
            raise Exception('Policies insufficient for solution or parameter map is full.')

        while len(unsolved_nodes) != 0:
            v_node = unsolved_nodes[0]
            results_prime = list()
            for p_map in partial_results:
                if p_map[v_node] is None or p_map[v_node].note is None:
                    visit_results = self._visit(p_map, v_node)
                    if len(visit_results) == 0:
                        if accept_partials:  # if accept partials, keep in partial results.
                            results_prime.append(p_map)
                    else:
                        results_prime.extend(visit_results)  # note: contains possible extensions of pmap
                else:  # v_note already filled, keep it in partial_results.
                    results_prime.append(p_map)
            partial_results = results_prime
            if self.instance_limit != -1 and len(partial_results) >= self.instance_limit:
                break
            unsolved_nodes.remove(v_node)

        return self.full_results, partial_results if accept_partials else list()
    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')
    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 #14
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
Exemple #15
0
    def _build_pitch_solutions(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:
            # 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 are notes that were satisfied by constraints.
            ignore_notes = {
                q[n]
                for n in pitch_result_pmap.keys()
                if pitch_result_pmap[n].note is not None
            }

            # note_to_pitch_map maps each ignore-note in line to a curve fit pitch.
            note_to_pitch_map = self._generate_reshape_map(
                pitch_result_score.line, ignore_notes)

            # Map pitch result score notes to their resolved pitches
            master_map = dict()

            # mm: beat_result_score.line --> pitch_reslt_score.line (self.score or beat_result_score)
            # For pitch constraint notes, map them to their pitch constraint results.
            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())
            }
            # Put the constraint based notes into master
            for note in pitch_result_pmap.keys():
                # map notes in pitch_result_score to what beat_score_result would
                if pitch_result_pmap[note].note is None:
                    raise Exception(
                        'Note {0} not solved for value in constraint.'.format(
                            note))
                master_map[
                    mm[note]] = pitch_result_pmap[note].note.diatonic_pitch

            # Map reshaped notes in pitch_result_score to their resolved notes into master
            for note in note_to_pitch_map.keys():
                if note not in master_map.keys():
                    master_map[note] = note_to_pitch_map[note]

            # Clone pitch_result_score, and build a map from pitch_result_score.line to the clone's notes (mmm)
            line_answer = pitch_result_score.line.clone()
            mmm = {
                key: value
                for key, value in zip(pitch_result_score.line.get_all_notes(),
                                      line_answer.get_all_notes())
            }
            # A shallow form of apply (use mmm and master_map to reset the diatonic pitches on line_answer.
            for note in master_map.keys():
                if master_map[note] is not None:
                    mmm[note].diatonic_pitch = master_map[note]

            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
Exemple #16
0
    def test_for_book_example_1(self):
        print('----- test for book example 1 -----')

        source_instance_expression = '{<C-Major:IV> [sC:5 B:4 A G] qF:4 [sA:4 B C:5 D] qD:5}'
        target_instance_expression = '{<G-Major:V> wA:4}'

        lge = LineGrammarExecutor()

        target_instance_line, target_instance_hct = lge.parse(
            target_instance_expression)
        target_hcs = target_instance_hct.hc_list()
        for hc in target_hcs:
            print("{0}".format(hc))

        pitch_range = PitchRange.create('C:2', 'C:8')

        p_map = PMap.create(source_instance_expression, pitch_range,
                            [('G-Major:V', 1)])

        actors = p_map.actors
        for a in actors:
            print("{0}".format(a))

        policies = set()
        policies.add(
            PitchStepConstraint(actors[0], actors[1], 1,
                                PitchStepConstraint.Down))
        policies.add(
            PitchStepConstraint(actors[1], actors[2], 1,
                                PitchStepConstraint.Down))
        policies.add(
            PitchStepConstraint(actors[2], actors[3], 1,
                                PitchStepConstraint.Down))
        policies.add(
            PitchStepConstraint(actors[5], actors[6], 1,
                                PitchStepConstraint.UP))
        policies.add(
            PitchStepConstraint(actors[6], actors[7], 1,
                                PitchStepConstraint.UP))
        policies.add(
            PitchStepConstraint(actors[7], actors[8], 1,
                                PitchStepConstraint.UP))
        policies.add(EqualPitchConstraint([actors[3], actors[4]]))
        policies.add(EqualPitchConstraint([actors[8], actors[9]]))
        policies.add(
            RelativeDiatonicConstraint(actors[4], actors[5],
                                       Interval(3, IntervalType.Major),
                                       Interval(1, IntervalType.Perfect)))
        policies.add(
            RelativeDiatonicConstraint(actors[3], actors[8],
                                       Interval(5, IntervalType.Perfect),
                                       Interval(1, IntervalType.Perfect)))
        policies.add(ChordalPitchConstraint(actors[4]))
        policies.add(ChordalPitchConstraint(actors[9]))

        solver = PitchConstraintSolver(policies)

        full_results, _ = solver.solve(p_map)
        print('Results has {0} results.'.format(len(full_results)))

        for pm in full_results:
            print("{0}".format(pm))