Ejemplo n.º 1
0
    def test_create(self):
        with self.assertRaises(Exception):
            PitchRange(8, 96)

        with self.assertRaises(Exception):
            PitchRange(9, 97)

        with self.assertRaises(Exception):
            PitchRange('Ab:0', 'C:8')

        with self.assertRaises(Exception):
            PitchRange.create('A:0', 'C#:8')
Ejemplo n.º 2
0
def simple_reshape_no_pf():
    print('----- test_simple_reshape_no_pf -----')

    line_str = '{<C-Major: I> iE:4 E E E E E E E <:IV> qE ie e <:V> qe ie e <:VI>  qE E iE E E E}'

    score = create_score(line_str, 'violin', (3, 4, 'sww'))

    all_notes = score.line.get_all_notes()

    pitch_function = GenericUnivariatePitchFunction(sinasoidal, Position(0),
                                                    Position(3))
    time_range = Range(0, 3)

    # The first note should have one of 3 values, C:4, E:4, G:4
    constraints = {
        ChordalPitchConstraint(all_notes[0]),
        ChordalPitchConstraint(all_notes[9]),
        PitchRangeConstraint([all_notes[0]], PitchRange.create('C:4', 'G:4')),
    }

    motif = Motif(score.line, constraints, 'A')
    melodic_form = MelodicForm([motif])
    treshape = TReshape(score, pitch_function, time_range, melodic_form, False)

    results = treshape.apply()

    mc_filter = MinCurveFitFilter(pitch_function, results)
    print('{0} filtered results'.format(len(mc_filter.scored_results)))

    for index in range(0, min(5, len(mc_filter.scored_results))):
        result = mc_filter.scored_results[index]
        print('[{0}] {1} ({2})'.format(index, str_line(result[0].line),
                                       result[1]))
Ejemplo n.º 3
0
    def compute_closest_scale_tones(tonality, pitch):
        """
        Returns either the pitch if in tonality, or lower/upper pitches in scale to pitch.
        :param tonality:
        :param pitch:
        :return: an array with 1 element if exact match, otherwise closest lower and upper bound pitches
                 in given tonality.
        """
        from tonalmodel.pitch_range import PitchRange
        chromatic_index = pitch.chromatic_distance
        pitch_range = PitchRange(
            max(chromatic_index - 12, ChromaticScale.chromatic_start_index()),
            min(chromatic_index + 12, ChromaticScale.chromatic_end_index()))
        pitch_scale = PitchScale(tonality, pitch_range)

        for i in range(0, len(pitch_scale.pitch_scale)):
            p = pitch_scale.pitch_scale[i]
            if p.chromatic_distance < chromatic_index:
                continue
            if p.chromatic_distance == chromatic_index:
                return [p]
            if i == 0:
                raise Exception(
                    'unexpected logic issue in compute_closest_pitch_range {0}, {1]'
                    .format(tonality, pitch))
            return [pitch_scale.pitch_scale[i - 1], p]
        raise Exception(
            'unexpected logic fail in compute_closest_pitch_range {0}, {1]'.
            format(tonality, pitch))
    def test_non_centered_even_function(self):
        t_domain = Tonality.create(ModalityType.WholeTone, DiatonicTone('C'))
        r = PitchRange.create('E:3', 'E:7')

        f = DiatonicPitchReflectionFunction(
            t_domain, DiatonicPitch(4, DiatonicToneCache.get_tone('G#')), r,
            FlipType.UpperNeighborOfPair)

        TestFlipOnTonality.print_map('test_non_centered_even_function', f)

        t = f.tonal_function

        assert 'C' == t['D'].diatonic_symbol
        assert 'D' == t['C'].diatonic_symbol
        assert 'E' == t['A#'].diatonic_symbol
        assert 'F#' == t['G#'].diatonic_symbol
        assert 'G#' == t['F#'].diatonic_symbol
        assert 'A#' == t['E'].diatonic_symbol

        assert 'C:4' == str(f['D:5'])
        assert 'D:4' == str(f['C:5'])
        assert 'E:4' == str(f['A#:4'])
        assert 'F#:4' == str(f['G#:4'])
        assert 'G#:4' == str(f['F#:4'])
        assert 'A#:4' == str(f['E:4'])
        assert 'C:5' == str(f['D:4'])
Ejemplo n.º 5
0
    def test_additional_octaves(self):
        t_domain = Tonality.create(ModalityType.MinorPentatonic,
                                   DiatonicTone('C'))
        i = Interval(12, IntervalType.Perfect)
        r = PitchRange.create('E:3', 'E:7')

        f = CrossTonalityShiftPitchFunction(t_domain, r, i)

        print('f={0}'.format(f))

        assert 'P:12' == str(f.root_shift_interval)

        assert 'G:5' == str(f['C:4'])
        assert 'A:5' == str(f['D:4'])
        assert 'B:5' == str(f['E:4'])
        assert 'C:6' == str(f['F:4'])

        i = Interval(11, IntervalType.Perfect).negation()
        f = CrossTonalityShiftPitchFunction(t_domain, r, i)
        print('f={0}'.format(f))

        assert '-P:11' == str(f.root_shift_interval)

        assert 'G:2' == str(f['C:4'])
        assert 'A:2' == str(f['D:4'])
        assert 'B:2' == str(f['E:4'])
        assert 'C:3' == str(f['F:4'])
Ejemplo n.º 6
0
    def test_simple_reverse_pitch_function(self):
        t_domain = Tonality.create(ModalityType.Major, DiatonicTone('E'))
        cycles = [['E', 'G#', 'A', 'C#'], ('F#', 'D#')]
        permutation_function = TonalityPermutationFunction.create(
            t_domain, cycles)

        r = PitchRange.create('E:3', 'E:7')
        f = TonalityPitchFunction(permutation_function, ('E:4', 'E:5'), r,
                                  True)

        TestTonalityPitchFunction.print_map(
            'test_simple_reverse_pitch_fnction', f)

        assert 'G#:5' == str(f['E:4'])
        assert 'D#:6' == str(f['F#:4'])
        assert 'A:5' == str(f['G#:4'])
        assert 'C#:6' == str(f['A:4'])
        assert 'B:5' == str(f['B:4'])
        assert 'E:5' == str(f['C#:5'])
        assert 'F#:5' == str(f['D#:5'])

        assert 'G#:4' == str(f['E:5'])
        assert 'D#:5' == str(f['F#:5'])
        assert 'A:4' == str(f['G#:5'])
        assert 'C#:5' == str(f['A:5'])
        assert 'B:4' == str(f['B:5'])
        assert 'E:4' == str(f['C#:6'])
        assert 'F#:4' == str(f['D#:6'])
Ejemplo n.º 7
0
    def test_diatonic_modal_indexed_function(self):
        t_domain = Tonality.create(ModalityType.Major, DiatonicTone('C'))
        i = Interval(2, IntervalType.Major)
        r = PitchRange.create('E:3', 'E:7')

        f = CrossTonalityShiftPitchFunction(t_domain, r, i, modal_index=4)

        print('f={0}'.format(f))

        TestCrossTonalityShiftPitchFunction.print_map('test_diatonic_function',
                                                      f)

        t = f.tonal_function
        print(t)

        # test diatonic maps
        assert 'D:4' == str(f['C:4'])
        assert 'E:4' == str(f['D:4'])
        assert 'F#:4' == str(f['E:4'])
        assert 'G:4' == str(f['F:4'])
        assert 'A:4' == str(f['G:4'])
        assert 'B:4' == str(f['A:4'])
        assert 'C:5' == str(f['B:4'])
        assert 'D:5' == str(f['C:5'])

        assert 'M:2' == str(f.root_shift_interval)
    def test_non_centered_odd_function(self):
        t_domain = Tonality.create(ModalityType.Major, DiatonicTone('E'))
        r = PitchRange.create('E:3', 'E:7')

        f = DiatonicPitchReflectionFunction(
            t_domain, DiatonicPitch(4, DiatonicToneCache.get_tone('F#')), r,
            FlipType.LowerNeighborOfPair)

        TestFlipOnTonality.print_map('test_non_centered_odd_function', f)

        t = f.tonal_function

        assert 'E' == t['A'].diatonic_symbol
        assert 'F#' == t['G#'].diatonic_symbol
        assert 'G#' == t['F#'].diatonic_symbol
        assert 'A' == t['E'].diatonic_symbol
        assert 'B' == t['D#'].diatonic_symbol
        assert 'C#' == t['C#'].diatonic_symbol
        assert 'D#' == t['B'].diatonic_symbol

        assert 'C#:4' == str(f['C#:5'])
        assert 'D#:4' == str(f['B:4'])
        assert 'E:4' == str(f['A:4'])
        assert 'F#:4' == str(f['G#:4'])
        assert 'G#:4' == str(f['F#:4'])
        assert 'A:4' == str(f['E:4'])
        assert 'B:4' == str(f['D#:4'])
        assert 'C#:5' == str(f['C#:4'])
        assert 'D#:5' == str(f['B:3'])
Ejemplo n.º 9
0
    def test_forward_with_extension(self):
        t_domain = Tonality.create(ModalityType.Major, DiatonicTone('E'))
        cycles = [['E', 'G#', 'A', 'C#'], ('F#', 'D#')]

        extension = dict()
        extension['D'] = 'F'
        extension['F'] = 'G'
        permutation_function = TonalityPermutationFunction.create(
            t_domain, cycles, extension)

        r = PitchRange.create('E:3', 'E:7')
        f = TonalityPitchFunction(permutation_function, ('E:4', 'E:5'), r,
                                  False)

        TestTonalityPitchFunction.print_map('test_forward_with_extension', f)

        assert 'G#:5' == str(f['E:4'])
        assert 'G:5' == str(f['F:4'])
        assert 'D#:6' == str(f['F#:4'])
        assert 'A:5' == str(f['G#:4'])
        assert 'C#:6' == str(f['A:4'])
        assert 'B:5' == str(f['B:4'])
        assert 'E:5' == str(f['C#:5'])
        assert 'E:5' == str(f['B##:4'])
        assert 'F:5' == str(f['D:5'])
        assert 'F:5' == str(f['C##:5'])
        assert 'F#:5' == str(f['D#:5'])
    def test_centered_even_function(self):
        t_domain = Tonality.create(ModalityType.HWOctatonic, DiatonicTone('C'))
        r = PitchRange.create('E:3', 'E:7')

        f = DiatonicPitchReflectionFunction(
            t_domain, DiatonicPitch(4, DiatonicToneCache.get_tone('A')), r,
            FlipType.CenterTone)

        TestFlipOnTonality.print_map('test_centered_even_function', f)

        t = f.tonal_function

        assert 'C' == t['Gb'].diatonic_symbol
        assert 'Db' == t['Fb'].diatonic_symbol
        assert 'Eb' == t['Eb'].diatonic_symbol
        assert 'Fb' == t['Db'].diatonic_symbol
        assert 'Gb' == t['C'].diatonic_symbol
        assert 'G' == t['Bb'].diatonic_symbol
        assert 'A' == t['A'].diatonic_symbol
        assert 'Bb' == t['G'].diatonic_symbol

        assert 'C:4' == str(f['Gb:5'])
        assert 'Db:4' == str(f['Fb:5'])

        assert 'Eb:4' == str(
            f['Eb:5'])  # The other stable tone outside of the centered!

        assert 'Fb:4' == str(f['Db:5'])
        assert 'Gb:4' == str(f['C:5'])
        assert 'G:4' == str(f['Bb:4'])
        assert 'A:4' == str(f['A:4'])
        assert 'Bb:4' == str(f['G:4'])
        assert 'C:5' == str(f['Gb:4'])
        assert 'Db:5' == str(f['Fb:4'])
    def test_centered_odd_function(self):
        t_domain = Tonality.create(ModalityType.Major, DiatonicTone('E'))
        r = PitchRange.create('E:3', 'E:7')

        f = DiatonicPitchReflectionFunction(
            t_domain, DiatonicPitch(4, DiatonicToneCache.get_tone('A')), r,
            FlipType.CenterTone)

        print('f={0}'.format(f))

        TestFlipOnTonality.print_map('test_simple_pitch_function', f)

        t = f.tonal_function

        assert 'E' == t['D#'].diatonic_symbol
        assert 'F#' == t['C#'].diatonic_symbol
        assert 'G#' == t['B'].diatonic_symbol
        assert 'A' == t['A'].diatonic_symbol
        assert 'B' == t['G#'].diatonic_symbol
        assert 'C#' == t['F#'].diatonic_symbol
        assert 'D#' == t['E'].diatonic_symbol

        assert 'D#:5' == str(f['E:4'])
        assert 'C#:5' == str(f['F#:4'])
        assert 'A:4' == str(f['A:4'])
        assert 'G#:4' == str(f['B:4'])
        assert 'F#:4' == str(f['C#:5'])
        assert 'E:4' == str(f['D#:5'])
Ejemplo n.º 12
0
 def test_pitch_inbounds(self):
     pr = PitchRange.create('C:4', 'B:4')
     scale = list('CDEFGAB')
     for s in scale:
         self.assertTrue(pr.is_pitch_inbounds(s + ':4'))
     self.assertFalse(pr.is_pitch_inbounds('Cb:4'))
     self.assertFalse(pr.is_pitch_inbounds('B#:4'))
Ejemplo n.º 13
0
    def _build_tunnel_constraints(self, source_to_target, tag_map):
        if tag_map is None or len(tag_map) == 0:
            return []

        one_id = next(iter(tag_map.keys()))
        source_note = self.source_line.get_all_notes()[one_id]
        target_pitch = tag_map[one_id]

        mvmt_interval = Interval.create_interval(source_note.diatonic_pitch,
                                                 target_pitch)

        constraints = list()
        note_annotations = self.source_analysis.note_annotation
        for annotation in note_annotations:
            if annotation.note.diatonic_pitch is None:
                continue
            target_note = source_to_target[annotation.note]

            dest_ctr_pitch = mvmt_interval.get_end_pitch(
                annotation.note.diatonic_pitch)
            low_pitch = self.tunnel_half_interval.get_start_pitch(
                dest_ctr_pitch)
            high_pitch = self.tunnel_half_interval.get_end_pitch(
                dest_ctr_pitch)
            p_range = PitchRange.create(low_pitch, high_pitch)

            constraint = PitchRangeConstraint([target_note], p_range)
            constraints.append(constraint)

        return constraints
Ejemplo n.º 14
0
    def test_major_modality(self):
        print('Testing Major Modality: D-Major, cue=G:4')
        domain_tonality = Tonality.create(ModalityType.Major, DiatonicFoundation.get_tone('D'))
        cue_pitch = DiatonicPitch.parse('G:4')

        domain_pitch_range = PitchRange.create('D:3', 'C#:6')
        f = ChromaticPitchReflectionFunction(domain_tonality, cue_pitch, domain_pitch_range, FlipType.CenterTone)

        TestChromaticPitchReflectionFunction.print_function(f)

        # Ensure all domain keys are in the domain_pitch_range
        for pitch in f.domain:
            assert domain_pitch_range.is_pitch_inbounds(pitch), \
                'Pitch {0} is not in range {1}.'.format(pitch, domain_pitch_range)

        assert DiatonicPitch.parse('D:3') in f.domain
        assert DiatonicPitch.parse('C#:6') in f.domain

        # Test for octave coverage
        assert 6 == f['D:3'].octave
        assert 5 == f['C#:4'].octave
        assert 5 == f['D:4'].octave
        assert 4 == f['C#:5'].octave
        assert 4 == f['D:5'].octave
        assert 3 == f['C#:6'].octave
Ejemplo n.º 15
0
    def test_pentatonic_tonal_function(self):
        t_domain = Tonality.create(ModalityType.MinorPentatonic,
                                   DiatonicTone('C'))
        i = Interval(5, IntervalType.Perfect)
        r = PitchRange.create('E:3', 'E:7')

        f = CrossTonalityShiftPitchFunction(t_domain, r, i)

        print('f={0}'.format(f))

        TestCrossTonalityShiftPitchFunction.print_map(
            'test_pentatonic_tonal_function', f)

        t = f.tonal_function
        print(t)

        assert 'G' == t['C'].diatonic_symbol
        assert 'Bb' == t['Eb'].diatonic_symbol
        assert 'C' == t['F'].diatonic_symbol
        assert 'D' == t['G'].diatonic_symbol
        assert 'F' == t['Bb'].diatonic_symbol

        assert 'G:5' == str(f['C:5'])
        assert 'F:5' == str(f['Bb:4'])
        assert 'D:5' == str(f['G:4'])
        assert 'C:5' == str(f['F:4'])
        assert 'Bb:4' == str(f['Eb:4'])
        assert 'G:4' == str(f['C:4'])

        # test range
        d = f.domain_pitch_range
        print(d)
        assert d.start_index == DiatonicPitch.parse('E:3').chromatic_distance
        assert d.end_index == DiatonicPitch.parse('E:7').chromatic_distance
        r = f.range_pitch_range
        print(r)
        assert r.start_index == DiatonicPitch.parse('B:3').chromatic_distance
        assert r.end_index == DiatonicPitch.parse('B:7').chromatic_distance

        # test chromatics
        assert 'G#:5' == str(f['C#:5'])
        assert 'F#:5' == str(f['B:4'])
        assert 'E#:5' == str(f['A#:4'])
        assert 'E:5' == str(f['A:4'])
        assert 'D#:5' == str(f['G#:4'])
        assert 'C#:5' == str(f['F#:4'])
        assert 'B:4' == str(f['E:4'])
        assert 'A:4' == str(f['D:4'])
        assert 'A#:4' == str(f['D#:4'])
        assert 'G#:4' == str(f['C#:4'])

        assert 'Gb:5' == str(f['Cb:5'])
        assert 'Fb:5' == str(f['Bbb:4'])
        assert 'Eb:5' == str(f['Ab:4'])
        assert 'Db:5' == str(f['Gb:4'])
        assert 'Cb:5' == str(f['Fb:4'])
        assert 'Bbb:4' == str(f['Ebb:4'])
        assert 'Ab:4' == str(f['Db:4'])
        assert 'Gb:4' == str(f['Cb:4'])
Ejemplo n.º 16
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))
    def policy_creator(modality_type, modality_tone, tertian_chord_txt, low_pitch_txt, hi_pitch_txt):
        diatonic_tonality = Tonality.create(modality_type, modality_tone)
        chord = TertianChordTemplate.parse(tertian_chord_txt).create_chord(diatonic_tonality)
        hc = HarmonicContext(diatonic_tonality, chord, Duration(1, 2))

        pitch_range = PitchRange(DiatonicPitch.parse(low_pitch_txt).chromatic_distance,
                                 DiatonicPitch.parse(hi_pitch_txt).chromatic_distance)
        return PolicyContext(hc, pitch_range)
Ejemplo n.º 18
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])}
Ejemplo n.º 19
0
    def test_low_range(self):
        ranges = PitchRange.create("A:0", "C:5")
        for modality_type in SYSTEM_MODALITIES:
            for validTone in ModalityFactory.create_modality(modality_type).get_valid_root_tones():
                tonality = Tonality.create(modality_type, DiatonicFoundation.get_tone(validTone))
        
                pitch_scale = PitchScale(tonality, ranges)
                print('Scale {0} {1} on {2}: {3}'.format(validTone, modality_type.name, ranges,
                                                         ','.join(map(get_symbol, pitch_scale.pitch_scale))))

                scale_check(pitch_scale, tonality)
Ejemplo n.º 20
0
    def apply(self,
              target_hct,
              window_anchor_pitch,
              tag_map=None,
              window_height=None,
              num_solutions=-1,
              tunnel_half_interval=Interval(5, IntervalType.Perfect)):
        """
        Apply method for transformation.
        :param target_hct: Target hct for new target line.
        :param window_anchor_pitch: Pitch specifying the lowest pitch for the target line window.
        :param tag_map: map index of source/target note to specified pitch.
        :param window_height: Height of target pitch window (in semi-tones) - use source line height if None specified.
        :param num_solutions: Maximum number of solutions to return, -1 == unbounded.
        :param tunnel_half_interval: half-interval for pitch range on each target tone.
        :return: MCSResults
        """
        if self.source_hct.duration != target_hct.duration:
            raise Exception(
                'Target hct duration {0} does not match source hct duration {1}.'
                .format(target_hct.duration, self.source_hct.duration))

        window_anchor_pitch = DiatonicPitch.parse(window_anchor_pitch) if isinstance(window_anchor_pitch, str) \
            else window_anchor_pitch

        target_line = self._build_target_line()

        self.__tunnel_half_interval = tunnel_half_interval

        source_notes = self.source_line.get_all_notes()
        target_notes = target_line.get_all_notes()
        source_to_target = {
            source_note: target_note
            for source_note, target_note in zip(source_notes, target_notes)
        }

        constraints = self._build_constraints(source_to_target, tag_map)
        ts_seq, tempo_seq = THarmonicTranscription._build_default_time_sig_tempo(
        )

        height = window_height if window_height else self.height
        pitch_range = PitchRange(
            window_anchor_pitch.chromatic_distance,
            window_anchor_pitch.chromatic_distance + height)

        solver = MelodicConstraintSolver(target_line, tempo_seq, ts_seq,
                                         target_hct, pitch_range, constraints)

        initial_map = {target_notes[k]: v
                       for k, v in tag_map.items()} if tag_map else None
        results = solver.solve(initial_map, num_solutions)
        return results
Ejemplo n.º 21
0
    def _build_pitch_segment_dict(tonality, scale_origin_str):
        origin_pitch = DiatonicPitch.parse(scale_origin_str)
        pitch_range = PitchRange.create(
            '{0}:{1}'.format(origin_pitch.diatonic_tone.diatonic_symbol, origin_pitch.octave),
            '{0}:{1}'.format(origin_pitch.diatonic_tone.diatonic_symbol, origin_pitch.octave + 1))

        scale = PitchScale(tonality, pitch_range).pitch_scale[0: -1]

        d = OrderedDict()
        for p in scale:
            d[p.diatonic_tone] = p.octave

        return d
Ejemplo n.º 22
0
    def test_simple_reshape(self):
        print('----- test_hct_simple_shift -----')

        s_notes = [
            ('E:4', 'e'),
            ('E:4', 'e'),
            ('E:4', 'e'),
            ('E:4', 'e'),
            ('E:4', 'e'),
            ('E:4', 'e'),
            ('E:4', 'e'),
            ('E:4', 'e'),

            ('E:4', 'h'),
            ('E:4', 'h'),

            ('E:4', 'q'),
            ('E:4', 'q'),
            ('E:4', 'q'),
            ('E:4', 'q'),
        ]
        chords = [('tI', 1), ('tIV', (1, 2)), ('tV', (1, 2)), ('tVI', 1)]

        score = TestTReshape.create_score(s_notes, ModalityType.Major, 'C', chords, 'violin', (3, 4, 'sww'))

        all_notes = score.line.get_all_notes()

        pitch_function = GenericUnivariatePitchFunction(TestTReshape.sinasoidal, Position(0), Position(3))
        time_range = Range(0, 3)

        # The first note should have one of 3 values, C:4, E:4, G:4
        constraints = {
            ChordalPitchConstraint(all_notes[0]),
            PitchRangeConstraint([all_notes[0]], PitchRange.create('C:4', 'G:4')),
        }

        motif = Motif(score.line, constraints, 'A')
        melodic_form = MelodicForm([motif])
        treshape = TReshape(score, pitch_function, time_range, melodic_form, False)

        results = treshape.apply()
        assert results is not None
        assert len(results) == 3
        for result in results:
            print('-----')
            print(result.line)

        first_pitch_set = {str(result.line.get_all_notes()[0].diatonic_pitch) for result in results}
        assert {'E:4', 'C:4', 'G:4'} == first_pitch_set

        assert abs(TestTReshape.sinasoidal(Fraction(1, 8)) - DiatonicPitch.parse('D:5').chromatic_distance) < 1
Ejemplo n.º 23
0
    def test_lowest_placement(self):
        pr = PitchRange.create('G:3', 'G:5')
        answers = [4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3]
        for i in range(0, 12):
            lowest = pr.find_lowest_placement_in_range(i)
            partition = ChromaticScale.index_to_location(lowest)[0]
            self.assertTrue(partition == answers[i], 'Assert failure {0} != {1}'.format(partition, answers[i]))
            print(i, partition)
            
        with self.assertRaises(Exception):
            pr.find_lowest_placement_in_range(-1)

        with self.assertRaises(Exception):
            pr.find_lowest_placement_in_range(12)
Ejemplo n.º 24
0
    def test_reversal_tonal_function(self):
        t_domain = Tonality.create(ModalityType.Major, DiatonicTone('G'))
        cycles = [['C'], ['B', 'D'], ['E', 'A'], ['G', 'F#']]

        permutation_function = TonalityPermutationFunction.create(
            t_domain, cycles)

        r = PitchRange.create('E:3', 'E:7')
        f = TonalityPitchFunction(permutation_function, ('E:4', 'E:4'), r,
                                  True)

        TestTonalityPitchFunction.print_map('test_reversal_tonal_function', f)

        assert 'C:5' == str(f['C:5'])
Ejemplo n.º 25
0
    def compute_pitch_range(line):
        notes = line.get_all_notes()
        max_pitch = min_pitch = notes[0].diatonic_pitch

        for i in range(1, len(notes)):
            pitch = notes[i].diatonic_pitch
            if pitch is None:
                continue
            if pitch < min_pitch:
                min_pitch = pitch
            elif pitch > max_pitch:
                max_pitch = pitch

        return PitchRange.create(min_pitch, max_pitch)
Ejemplo n.º 26
0
    def test_shift_create(self):
        t_domain = Tonality.create(ModalityType.MelodicMinor,
                                   DiatonicTone('C'))
        i = Interval(5, IntervalType.Perfect)
        r = PitchRange.create('E:3', 'E:7')

        f = CrossTonalityShiftPitchFunction(t_domain, r, i)

        assert 'P:5' == str(f.root_shift_interval)

        assert 'G:4' == str(f['C:4'])
        assert 'A:4' == str(f['D:4'])
        assert 'B:4' == str(f['E:4'])
        assert 'C:5' == str(f['F:4'])
Ejemplo n.º 27
0
    def test_melodic_minor_modality(self):
        print('Testing Melodic Minor Modality: C-MelodicMinor, cue=Eb:3')
        domain_tonality = Tonality.create(ModalityType.MelodicMinor, DiatonicFoundation.get_tone('C'))
        cue_pitch = DiatonicPitch.parse('Eb:3')

        domain_pitch_range = PitchRange.create('D:4', 'F:5')
        f = ChromaticPitchReflectionFunction(domain_tonality, cue_pitch, domain_pitch_range, FlipType.CenterTone)

        TestChromaticPitchReflectionFunction.print_function(f)

        assert 2 == f['D:4'].octave
        assert 2 == f['G:4'].octave
        assert 1 == f['A:4'].octave
        assert 1 == f['C:5'].octave
        assert 1 == f['f:5'].octave
Ejemplo n.º 28
0
    def test_natural_minor_modality(self):
        print('Testing Natural Minor Modality: C-Major, cue=Eb:3')
        domain_tonality = Tonality.create(ModalityType.NaturalMinor, DiatonicFoundation.get_tone('C'))
        cue_pitch = DiatonicPitch.parse('Eb:3')

        domain_pitch_range = PitchRange.create('D:2', 'F:4')
        f = ChromaticPitchReflectionFunction(domain_tonality, cue_pitch, domain_pitch_range, FlipType.CenterTone)

        TestChromaticPitchReflectionFunction.print_function(f)

        # Test for octave coverage
        assert 4 == f['D:2'].octave
        assert 3 == f['Bb:2'].octave
        assert 3 == f['C:3'].octave
        assert 2 == f['Bb:3'].octave
        assert 2 == f['F:4'].octave
    def test_check_chromatics_on_pentatonic(self):
        t_domain = Tonality.create(ModalityType.MajorPentatonic,
                                   DiatonicTone('E'))
        # E F# G# B C# E
        r = PitchRange.create('E:1', 'E:7')

        f = DiatonicPitchReflectionFunction(
            t_domain, DiatonicPitch(4, DiatonicToneCache.get_tone('G#')), r,
            FlipType.CenterTone)
        TestFlipOnTonality.print_map('test_check_chromatics_on_pentatonic', f)

        t = f.tonal_function
        assert 'G#' == t['G#'].diatonic_symbol
        assert 'F#' == t['B'].diatonic_symbol
        assert 'E' == t['C#'].diatonic_symbol
        assert 'B' == t['F#'].diatonic_symbol
        assert 'C#' == t['E'].diatonic_symbol

        assert 'E:4' == str(f['C#:5'])
        assert 'F#:4' == str(f['B:4'])
        assert 'G#:4' == str(f['G#:4'])
        assert 'B:4' == str(f['F#:4'])
        assert 'C#:5' == str(f['E:4'])

        assert 'E#:5' == str(f['C:4'])
        assert 'D#:5' == str(f['D:4'])
        assert 'B#:4' == str(f['F:4'])
        assert 'G##:4' == str(
            f['G:4'])  # Note this and next are not symmetrical!
        assert 'G:4' == str(f['A#:4'])
        assert 'F##:4' == str(f['A:4'])

        assert 'E##:5' == str(f['Cb:4'])
        assert 'D##:5' == str(f['Db:4'])
        assert 'C##:5' == str(f['Eb:4'])
        assert 'B##:4' == str(f['Fb:4'])
        assert 'G###:4' == str(f['Gb:4'])
        assert 'F###:4' == str(
            f['Ab:4']
        )  # Very interesting case!!! closest is G#, but need F# to get to G#
        assert 'F##:4' == str(f['Bb:4'])

        assert 'F:4' == str(f['B#:4'])
        assert 'D:5' == str(f['D#:4'])
        assert 'C:5' == str(f['E#:4'])
        assert 'G:4' == str(f['A#:4'])
Ejemplo n.º 30
0
def simple_reshape_cpf():
    print('----- test_simple_reshape_cpf (Fgure 17.21) -----')

    line_str = '{<C-Major: I> iE:4 E E E E E E E <:IV> qE ie e <:V> qe ie e <:VI>  qE E iE E E E}'
    score = create_score(line_str, 'violin', (3, 4, 'sww'))

    all_notes = score.line.get_all_notes()

    # 11 scalar notes to C:4 (0) to G:5 (1) with pitch unit 1/19
    interpreter = ChromaticRangeInterpreter(DiatonicPitch.parse('C:4'), 0,
                                            Fraction(1, 19))

    pitch_function = GenericUnivariatePitchFunction(three_sin,
                                                    Position(0),
                                                    Position(3),
                                                    interp=interpreter)

    # The first note should have one of 3 values, C:4, E:4, G:4
    constraints = {
        ChordalPitchConstraint(all_notes[0]),
        ChordalPitchConstraint(all_notes[8]),
        ChordalPitchConstraint(all_notes[11]),
        ChordalPitchConstraint(all_notes[14]),
        PitchRangeConstraint([all_notes[0]], PitchRange.create('C:4', 'E:4')),
    }

    # motif = Motif(score.line, constraints, 'A')
    motif = Motif([all_notes[0], all_notes[8], all_notes[11], all_notes[14]],
                  constraints, 'A')
    melodic_form = MelodicForm([motif])
    t_reshape = TReshape(score, pitch_function, Range(0, 3), melodic_form,
                         True)

    results = t_reshape.apply()

    filters = MinCurveFitFilter(pitch_function, results)
    print('{0} filtered results'.format(len(filters.scored_results)))

    for index in range(0, min(5, len(filters.scored_results))):
        result = filters.scored_results[index]
        print('[{0}] {1} ({2})'.format(index, str_line(result[0].line),
                                       result[1]))

    print('Chords: {0}'.format(','.join([str(c)
                                         for c in score.hct.hc_list()])))