Beispiel #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')
    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'])
Beispiel #3
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]))
    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
    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'])
    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'])
Beispiel #7
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'])
Beispiel #8
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_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'])
Beispiel #10
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'])
Beispiel #11
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
Beispiel #12
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)
Beispiel #13
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'))
Beispiel #14
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'])
Beispiel #15
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])}
Beispiel #16
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)
Beispiel #17
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
Beispiel #18
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
Beispiel #19
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)
Beispiel #20
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'])
Beispiel #21
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)
Beispiel #22
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'])
Beispiel #23
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
Beispiel #24
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'])
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()])))
Beispiel #27
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 reshape_to_scale():
    print('----- test_reshape_to_scale (Fgure 17.24) -----')

    line_str = '{<C-Major: I> iE:4 E E E E E E E E E E E E E E E E E E E E E E E wE}'

    score = create_score(line_str, 'violin', (4, 4, 'swww'))

    tonality = score.hct.get_hc_by_position(0).tonality
    all_notes = score.line.get_all_notes()

    plf = PiecewiseLinearFunction([(0, 0), (1, 8), (Fraction(3, 2), 4), (2, 8),
                                   (3, 0)])
    for i in range(0, 17):
        x = Fraction(1, 8) * i
        y = plf(x)
        print('({0}, {1})'.format(x, y))
    time_range = Range(0, 3)

    interpreter = ScalarRangeInterpreter(tonality, DiatonicPitch.parse('C:4'),
                                         0, 1)

    pitch_function = GenericUnivariatePitchFunction(plf, Position(0),
                                                    Position(3), False,
                                                    interpreter)

    constraints = {
        ChordalPitchConstraint(all_notes[0]),
        PitchRangeConstraint([all_notes[0]], PitchRange.create('C:4', 'G:4')),
    }

    motif = Motif([all_notes[0]], constraints, 'A')
    melodic_form = MelodicForm([motif])
    t_reshape = TReshape(score, pitch_function, time_range, melodic_form,
                         False)

    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]))
    def __init__(self,
                 tonality,
                 anchor_pitch=None,
                 anchor_value=None,
                 pitch_unit=1):
        """
        Constructor.
        :param tonality: The tonality being mapped to.
        :param anchor_pitch: A DiatonicPitch, in combo with anchor_value is a sample of the mapping.
        :param anchor_value: A numeric value that maps to anchor_pitch.
        :param pitch_unit: In the linear map of value to pitches, pitch_unit is the distance between mapping values.
        """
        self.__tonality = tonality
        self.__pitch_scale = PitchScale(self.tonality,
                                        PitchRange.create('A:0',
                                                          'C:8')).pitch_scale

        self.anchor_pitch = self.pitch_scale[0] if anchor_pitch is None else \
            DiatonicPitch.parse(anchor_pitch) if isinstance(anchor_pitch, str) else anchor_pitch

        anchor_index = self.pitch_scale.index(self.anchor_pitch)
        if anchor_index == -1:
            raise Exception(
                'Anchor pitch \'{0}\' not found in pitch scale for tonality \'{1}\''
                .format(self.anchor_pitch, self.tonality))

        self.__pitch_unit = pitch_unit

        self.anchor_value = anchor_value if anchor_value is not None else anchor_index * self.pitch_unit

        # base value should map to beginning of pitch scale!
        # recall that pitch unit maps to each pitch, making the scalar scale linear in value!
        base_value = anchor_value - anchor_index * pitch_unit

        self.value_to_pitch = OrderedMap()
        self.pitch_to_value = dict()
        for i in range(0, len(self.pitch_scale)):
            pitch = self.pitch_scale[i]
            value = base_value + i * pitch_unit
            self.value_to_pitch.insert(value, pitch)
            self.pitch_to_value[pitch] = value

        PitchRangeInterpreter.__init__(self)
    def test_find_pitch(self):

        t_domain = Tonality.create(ModalityType.WholeTone, DiatonicTone('C'))
        r = PitchRange.create('E:1', 'E:7')

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

        TestFlipOnTonality.print_map('test_find_pitch', f)

        for t in t_domain.annotation:
            p = DiatonicPitch(1, t)
            closest_pitch, closest_distance = f._find_closest_pitch(p)
            print('pitch {0}  closest = ({1}, {2})'.format(
                p, closest_pitch, closest_distance))

        p = DiatonicPitch.parse("A:3")
        closest_pitch, closest_distance = f._find_closest_pitch(p)
        print('pitch {0}  closest = ({1}, {2})'.format(p, closest_pitch,
                                                       closest_distance))

        p = DiatonicPitch.parse("Ab:3")
        closest_pitch, closest_distance = f._find_closest_pitch(p)
        print('pitch {0}  closest = ({1}, {2})'.format(p, closest_pitch,
                                                       closest_distance))

        p = DiatonicPitch.parse("B:3")
        closest_pitch, closest_distance = f._find_closest_pitch(p)
        print('pitch {0}  closest = ({1}, {2})'.format(p, closest_pitch,
                                                       closest_distance))

        p = DiatonicPitch.parse("Cb:3")
        closest_distance = f._find_closest_pitch(p)
        print('pitch {0}  closest = ({1}, {2})'.format(p, closest_pitch,
                                                       closest_distance))

        p = DiatonicPitch.parse("C#:3")
        closest_pitch, closest_distance = f._find_closest_pitch(p)
        print('pitch {0}  closest = ({1}, {2})'.format(p, closest_pitch,
                                                       closest_distance))