Exemplo n.º 1
0
def shift_change_modal_index_modality_and_shift():
    print('----- Shift Change Modal Index, modality, shift Example -----')
    source_expression = '{<C-Major: I> iC:4 C qD E <:IV> iF G hA <:V> ig b qf g <:VI> ie e qd ic d <:i> h@c}'

    t_shift = TShift.create(source_expression)
    print('Shift examples based on:')
    print_line(t_shift.source_line)
    print()

    print('Shift to modal index 1 (dorian)')
    target_line, target_hct = t_shift.apply(root_shift_interval=TonalInterval.parse('M:2'), modal_index=1)

    print_line(target_line)
    print_hct(target_hct)
    print()

    t_shift = TShift(target_line, target_hct)

    print('Shift P:4 to modal index 2 (phrygian) of MelodicMinor')
    target_line, target_hct = t_shift.apply(root_shift_interval=TonalInterval.parse('P:4'),
                                            range_modality_type=ModalityType.MelodicMinor, modal_index=2)

    print_line(target_line)
    print_hct(target_hct)
    print()
Exemplo n.º 2
0
    def test_book_examples(self):
        # Interval Creation
        interval = Interval(5, IntervalType.Perfect)
        print(interval)
        interval = Interval.parse("m:10")
        print(interval)
        interval = Interval.create_interval(DiatonicPitch.parse("a:3"), DiatonicPitch.parse("f#:4"))
        print(interval)

        # Interval Addition/Subtraction
        i1 = Interval(5, IntervalType.Perfect)
        i2 = Interval.parse("M:3")
        interval = i1 + i2
        print(interval)
        interval = i1 - i2
        print(interval)
        interval += i2
        print(interval)
        interval -= i2
        print(interval)

        # compute end and start
        interval = Interval(5, IntervalType.Perfect)
        pitch = interval.get_end_pitch(DiatonicPitch.parse("F#:5"))
        print(pitch)
        pitch = interval.get_start_pitch(DiatonicPitch.parse("C:5"))
        print(pitch)
Exemplo n.º 3
0
    def test_inversion(self):
        interval_strs = ['d:1', 'P:1', 'A:1', 'd:2', 'm:2', 'M:2', 'A:2', 'd:3', 'm:3', 'M:3', 'A:3',
                         'd:4', 'P:4', 'A:4', 'd:5', 'P:5', 'A:5',
                         'd:6', 'm:6', 'M:6', 'A:6', 'd:7', 'm:7', 'M:7', 'A:7', 'd:8', 'P:8', 'A:8']
        answers = ['A:8', 'P:8', 'd:8', 'A:7', 'M:7', 'm:7', 'd:7', 'A:6', 'M:6', 'm:6', 'd:6',
                   'A:5', 'P:5', 'd:5', 'A:4', 'P:4', 'd:4',
                   'A:3', 'M:3', 'm:3', 'd:3', 'A:2', 'M:2', 'm:2', 'd:2', 'A:1', 'P:1', 'd:1']
        intervals = [Interval.parse(s) for s in interval_strs]
        print('+++++')
        for interval, answer in zip(intervals, answers):
            print('{0} --> {1}'.format(interval, interval.inversion()))
            assert str(interval.inversion()) == answer
        print('-----')

        interval = Interval.parse('A:12')
        inversion = interval.inversion()
        print('int={0} inv={1}'.format(interval, inversion))
        
        # Test augmented and negative intervals
        interval_strs = ['A:15', 'P:15', 'd:15', 'A:14', 'M:14', 'm:14', 'd:14', 'A:13', 'M:13', 'm:13', 'd:13',
                         'A:12', 'P:12', 'd:12',
                         'A:11', 'P:11', 'd:11', 'A:10', 'M:10', 'm:10', 'd:10', 'A:9', 'M:9', 'm:9', 'd:9',
                         ]
        answers = ['d:1', 'P:1', 'A:1', 'd:2', 'm:2', 'M:2', 'A:2', 'd:3', 'm:3', 'M:3', 'A:3', 'd:4', 'P:4', 'A:4',
                   'd:5', 'P:5', 'A:5', 'd:6', 'm:6', 'M:6', 'A:6', 'd:7', 'm:7', 'M:7', 'A:7']
        intervals = [Interval.parse(s) for s in interval_strs]
        print('+++++')
        for interval, answer in zip(intervals, answers):
            print('{0} --> {1}  {2}'.format(interval, interval.inversion(), answer))
            assert str(interval.inversion()) == answer
        print('-----')
        
        interval_strs = ['-d:1', '-P:1', '-A:1', '-d:2', '-m:2', '-M:2', '-A:2', '-d:3', '-m:3', '-M:3', '-A:3',
                         '-d:4', '-P:4', '-A:4', '-d:5', '-P:5', '-A:5',
                         '-d:6', '-m:6', '-M:6', '-A:6', '-d:7', '-m:7', '-M:7', '-A:7', '-d:8', '-P:8', '-A:8']
        answers = ['d:8', 'P:8', 'A:8', '-A:7', '-M:7', '-m:7', '-d:7', '-A:6', '-M:6', '-m:6', '-d:6', '-A:5',
                   '-P:5', '-d:5', '-A:4', '-P:4', '-d:4',
                   '-A:3', '-M:3', '-m:3', '-d:3', '-A:2', '-M:2', '-m:2', '-d:2', 'd:1', 'P:1', 'A:1']
        intervals = [Interval.parse(s) for s in interval_strs]
        print('+++++')
        for interval, answer in zip(intervals, answers):
            print('{0} --> {1}'.format(interval, interval.inversion()))
            assert str(interval.inversion()) == answer
        print('-----')
        
        interval_strs = ['-A:15', '-P:15', '-d:15', '-A:14', '-M:14', '-m:14', '-d:14',
                         '-A:13', '-M:13', '-m:13', '-d:13', '-A:12', '-P:12', '-d:12',
                         '-A:11', '-P:11', '-d:11', '-A:10', '-M:10', '-m:10', '-d:10', '-A:9', '-M:9', '-m:9', '-d:9',
                         ]
        answers = ['A:1', 'P:1', 'd:1', 'd:2', 'm:2', 'M:2', 'A:2', 'd:3', 'm:3', 'M:3', 'A:3', 'd:4', 'P:4', 'A:4',
                   'd:5', 'P:5', 'A:5', 'd:6', 'm:6', 'M:6', 'A:6', 'd:7', 'm:7', 'M:7', 'A:7']
        intervals = [Interval.parse(s) for s in interval_strs]
        print('+++++')
        for interval, answer in zip(intervals, answers):
            print('{0} --> {1}  {2}'.format(interval, interval.inversion(), answer))
        print('-----')
Exemplo n.º 4
0
 def test_interval_exception(self):
     i1 = Interval.parse('d:4')
     i2 = Interval.parse('d:3')
     try:
         i = i1 + i2
     except IntervalException as e:
         print('caught exception ' + str(e))
         assert e
     else:
         assert i is not None
Exemplo n.º 5
0
 def test_parse(self):
     interval = Interval.parse('P:5')
     assert str(interval) == 'P:5'
     
     assert str(Interval.parse('A:8')) == 'A:8'
     assert str(Interval.parse('d:8')) == 'd:8'
     assert str(Interval.parse('M:3')) == 'M:3'
     assert str(Interval.parse('m:6')) == 'm:6'
     
     assert Interval.parse('-d:1') == Interval.parse('A:1')
     assert Interval.parse('-A:1') == Interval.parse('d:1')
Exemplo n.º 6
0
    def create_instrument(inst_node, parent):
        low = high = ''
        up_down = None
        transpose_interval = None
        articulations = []
        for c in inst_node:
            if c.tag == 'Range':
                for lh in c:
                    if lh.tag == 'Low':
                        low = lh.text
                    elif lh.tag == 'High':
                        high = lh.text
            elif c.tag == 'Transpose':
                updown_txt = c.get('direction')
                if updown_txt != 'up' and updown_txt != 'down':
                    raise Exception(
                        'Illegal transpose up/down must be \'up\' or \'down\'  now \'{0}\''
                        .format(updown_txt))
                up_down = updown_txt == 'up'
                transpose_interval = Interval.parse(c.get('interval'))
            elif c.tag == 'Articulations':
                articulations = InstrumentCatalog._parse_articulations(c)

        instrument = Instrument(inst_node.get('name'), inst_node.get('key'),
                                low, high, up_down, transpose_interval, parent)
        instrument.extend_articulations(articulations)
        return instrument
Exemplo n.º 7
0
def cue_examples():
    print('--------------  Cue examples  --------------------------')
    source_expression = '{<Bb-Major: I> sBb:4 A G F qEb D sF g iA i@Bb sF <:IVMaj7> ' \
                        'ir Eb sEb F G A iBb sEb:5 F i@Eb C ' \
                        '<:IIIMin7> sR F:5 Eb D C Bb:4 C:5 D i@Eb sC sr G:4 A G <:I> sG:5 F Eb D D C Bb:4 A ir q@G}'

    t_flip = TDiatonicReflection.create(source_expression,
                                        DiatonicPitch.parse('Eb:4'))
    print('Flip examples based on:')
    print_line(t_flip.source_line)
    print_hct(t_flip.source_hct)
    print()

    print('Flip on Eb:4 (Figure 16.12)')
    target_line, target_hct = t_flip.apply()

    print_line(target_line)
    print_hct(target_hct)
    print()

    print('Shift up an octave (Figure 16.13)')
    t_shift = TShift(target_line, target_hct, TonalInterval.parse('P:8'))
    final_line, final_hct = t_shift.apply()
    print_line(final_line)
    print_hct(final_hct)
Exemplo n.º 8
0
def example2():
    print('----- Debug meaning of modal index change and hct -----')

    # example tonality with modal index
    # Create a harmonic minor tonality of some basis root which as Mixolydian has F as the root.
    #       The answer is Bb-HarmonicMinor F(4)

    source_expression = '{<C-Major: I> iC:4}'

    t_shift = TShift.create(source_expression)
    print('Shift examples based on:')
    print_line(t_shift.source_line)
    print()

    print('Shift to modal index 4 (Mixolydian)')
    # This makes C the Mixolydian of F-Major
    target_line, target_hct = t_shift.apply(modal_index=4)
    print_line(target_line)
    print_hct(target_hct)
    print()

    # if you wanted G Mixolydian based on C
    print('Shift as if moving to modal index 4 (Mixolydian) in C')
    target_line, target_hct = t_shift.apply(
           root_shift_interval=TonalInterval.parse('P:5'), modal_index=4)

    print_line(target_line)
    print_hct(target_hct)
    print()
Exemplo n.º 9
0
def shift_modulating_sequence_example():
    print('----- Shift sequence standard example (Figure 15.14) -----')

    source_expression = '{<C-Major: IV> sf:4 a b C:5 <:V/ii> sa:4 e:5 tc# b:4 sC#:5 <:ii> sd tc a:4 sb:4 a}'

    lge = LineGrammarExecutor()
    source_instance_line, source_instance_hct = lge.parse(source_expression)
    print_score('\n[0]: ', source_instance_line, source_instance_hct)

    t_shift = TShift.create(source_expression)
    target_line, target_hct = t_shift.apply(root_shift_interval=TonalInterval.parse('M:2'),
                                            range_modality_type=ModalityType.Major)
    print_score('\n[1]: ', target_line, target_hct)

    t_shift = TShift(target_line, target_hct)
    target_line, target_hct = t_shift.apply(root_shift_interval=TonalInterval.parse('M:2'),
                                            range_modality_type=ModalityType.Major)
    print_score('\n[2]: ', target_line, target_hct)
Exemplo n.º 10
0
def shift_details_on_secondary_chord():
    print('----- Book example of shifted secondary tonality (Figure 15.6) -----')
    source_expression = '{<C-Major: V/iii> iD#:4 F# G A qD#:5 B:4}'

    t_shift = TShift.create(source_expression, TonalInterval.parse('M:3'))
    target_line, target_hct = t_shift.apply(range_modality_type=ModalityType.MelodicMinor)
    print(t_shift.source_hct)
    print(target_line)
    print(target_hct)
Exemplo n.º 11
0
def tonality_mode_change():
    print('----- Book example of shifted tonality on modal not 0 (Figure 15.5) -----')
    source_expression = '{<D-Major(1): I> iE:4 F# G A qE B}'

    t_shift = TShift.create(source_expression,
                            TonalInterval.parse('P:4'))
    target_line, target_hct = t_shift.apply(range_modality_type=ModalityType.MelodicMinor, modal_index=2)
    print(t_shift.source_hct)
    print(target_line)
    print(target_hct)
Exemplo n.º 12
0
 def test_whole_note_scale_inrements(self):
     for i in range(0, 6):
         intervals = ['P:1']
         for count in range(0, 6):
             if i == count:
                 intervals.append('d:3')
             else:
                 intervals.append('M:2')
                 
         # test result
         answer = Interval.parse('P:1')
         answers = [answer]
         iterintervals = iter(intervals)
         next(iterintervals)
         for x in iterintervals:
             xi = Interval.parse(x)
             answer += xi
             answers.append(answer)
         incrementals = ', '.join(t for t in intervals)
         results = ', '.join(str(t) for t in answers)
         print('{0}   -->   {1}'.format(incrementals, results))
     print('end of test')
Exemplo n.º 13
0
def shift_sequence_tonal_example():
    print('----- Shift sequence tonal example -----')

    source_expression = '{<C-Major: IV> qf:4 a b C:5 <:V/ii> a:4 e:5 id C# <:ii> qd c b:4 a}'

    lge = LineGrammarExecutor()
    source_instance_line, source_instance_hct = lge.parse(source_expression)
    print_score('\n[0]: ', source_instance_line, source_instance_hct)

    t_shift = TShift.create(source_expression)
    target_line, target_hct = t_shift.apply(root_shift_interval=TonalInterval.parse('M:2'),
                                            range_modality_type=ModalityType.MelodicMinor)
    print(target_line)
    print(target_hct)
    print()

    t_shift = TShift(target_line, target_hct)
    target_line, target_hct = t_shift.apply(root_shift_interval=TonalInterval.parse('M:2'),
                                            range_modality_type=ModalityType.MelodicMinor)
    print(target_line)
    print(target_hct)
    print()
Exemplo n.º 14
0
 def test_HW_Oct_scale_inrements(self):
     prime = ['P:1', 'm:2', 'M:2', 'm:2', 'M:2', 'm:2', 'M:2', 'm:2', 'M:2']
     for i in range(0, 4):
         intervals = ['P:1']
         for count in range(1, 9):
             if 2 * i + 1 == count:
                 intervals.append('A:1')
             else:
                 intervals.append(prime[count])
                 
         # test result
         answer = Interval.parse('P:1')
         answers = [answer]
         iterintervals = iter(intervals)
         next(iterintervals)
         for x in iterintervals:
             xi = Interval.parse(x)
             answer += xi
             answers.append(answer)
         incrementals = ', '.join(t for t in intervals)
         results = ', '.join(str(t) for t in answers)
         print('{0}   -->   {1}'.format(incrementals, results))
     print('end of test')
Exemplo n.º 15
0
 def test_reduction(self):
     
     interval_strs = ['d:1', 'P:1', 'A:1', 'M:2', 'M:3', 'P:4', 'P:5', 'M:6', 'M:7', 'd:8', 'P:8', 'A:8', 'M:9',
                      'M:10', 'P:11', 'P:12', 'M:13', 'M:14', 'd:15', 'P:15', 'A:15',
                      '-d:1', '-P:1', '-A:1', '-M:2', '-M:3', '-P:4', '-P:5', '-M:6', '-M:7', '-d:8', '-P:8',
                      '-A:8', '-M:9', '-M:10', '-P:11', '-P:12', '-M:13', '-M:14', '-d:15', '-P:15', '-A:15']
     intervals = [Interval.parse(i) for i in interval_strs]  
     answers = ['d:1', 'P:1', 'A:1', 'M:2', 'M:3', 'P:4', 'P:5', 'M:6', 'M:7', 'd:8', 'P:8', 'A:8', 'M:2',
                'M:3', 'P:4', 'P:5', 'M:6', 'M:7', 'd:8', 'P:8', 'A:8',
                'A:1', 'P:1', 'd:1', '-M:2', '-M:3', '-P:4', '-P:5', '-M:6', '-M:7', '-d:8', '-P:8', '-A:8',
                '-M:2', '-M:3', '-P:4', '-P:5', '-M:6', '-M:7', '-d:8', '-P:8', '-A:8']
     for interval, answer in zip(intervals, answers):
         reduction = interval.reduction()
         print('reduce({0}) --> {1}, answer = {2}'.format(interval, reduction, answer))
         assert str(reduction) == answer, 'reduce({0}) --> {1}, answer = {2}'.format(interval, reduction, answer)
Exemplo n.º 16
0
 def add_intervals(interval_strs):
     intervals = [Interval.parse(x) for x in interval_strs]
     
     result = []
     for a in intervals:
         for b in intervals:
             # noinspection PyBroadException
             try:                
                 c = a + b
                 print('{0} + {1} = {2}'.format(a, b, c))
                 result.append(c)
             except Exception:
                 print('{0} + {1} = X'.format(a, b))
                 result.append(None)
     return result
Exemplo n.º 17
0
def simple_shift_example():
    print('----- Simple Shift Example -----')
    source_expression = '{<C-Major: I> iC:4 C qD E <:IV> iF G hA <:V> ig b qf g <:VI> ie e qd ic d <:I> h@c}'

    t_shift = TShift.create(source_expression, TonalInterval.parse('M:3'))
    print('Shift examples based on:')
    print_line(t_shift.source_line)
    print()

    print('Shift up M:3 (Figure 15.8)')
    target_line, target_hct = t_shift.apply()

    print_line(target_line)
    print_hct(target_hct)
    print()

    t_shift = TShift.create(source_expression, TonalInterval.parse('-m:2'))

    target_line, target_hct = t_shift.apply()

    print('Shift down m:2 (Figure 15.9)')
    print_line(target_line)
    print_hct(target_hct)
    print()
Exemplo n.º 18
0
    def __init__(self, modality_type, incremental_interval_strs):
        """
        Constructor.

        :param modality_type:
        :param incremental_interval_strs:
        """
        if isinstance(modality_type, int):
            self.__modality_type = ModalityType(modality_type)    
        elif not isinstance(modality_type, ModalityType):
            raise Exception('Illegal modality type argument {0}.'.format(type(modality_type))) 
        else:
            self.__modality_type = modality_type
            
        if not isinstance(incremental_interval_strs, list):
            raise Exception('Illegal incremental intervals argument type {0}', type(incremental_interval_strs))
        
        self.__incremental_intervals = [Interval.parse(interval) for interval in incremental_interval_strs]
Exemplo n.º 19
0
    def find_modality(tones):
        answers = list()
        if len(tones) == 5:
            for t in [ModalityType.MajorPentatonic]:
                modality_spec = PentatonicModality.MODALITY_DEFINITION_MAP[t]

                p1 = Interval.parse('P:1')
                for scale_start in range(0, 5):
                    intervals = [p1] + [
                        Interval.calculate_tone_interval(
                            tones[(scale_start + i) % 5],
                            tones[(scale_start + i + 1) % 5])
                        for i in range(0, len(tones))
                    ]
                    if intervals == modality_spec.incremental_intervals:
                        answers.append(
                            PentatonicModality.create(t, (-scale_start) %
                                                      len(tones)))
        return answers
Exemplo n.º 20
0
def build_incremental_intervals(scale):
    from tonalmodel.diatonic_pitch import DiatonicPitch
    from tonalmodel.interval import Interval
    partition = 4
    iter_scale = iter(scale)
    first = next(iter_scale)
    prior_pitch = DiatonicPitch(partition, first)
    prior = TONES.index(first.diatonic_letter)
    intervals = [Interval.parse('P:1')]
    for dt in iter_scale:    
        if TONES.index(dt.diatonic_letter) - prior < 0:
            partition += 1
        prior = TONES.index(dt.diatonic_letter)
        current_pitch = DiatonicPitch(partition, dt)
        intervals.append(Interval.create_interval(prior_pitch, current_pitch))
        
        prior_pitch = current_pitch
        
    return intervals    
Exemplo n.º 21
0
def shift_change_modality():
    print('----- Shift Change Modality Example -----')
    source_expression = '{<C-Major: I> iC:4 C qD E <:IV> iF G hA <:V> ig b qf g <:VI> ie e qd ic d <:i> h@c}'

    t_shift = TShift.create(source_expression, TonalInterval.parse('P:4'))
    print('Shift examples based on:')
    print_line(t_shift.source_line)
    print()

    print('Shift up P:4, modality MelodicMinor (Figure 5.10)')
    target_line, target_hct = t_shift.apply(range_modality_type=ModalityType.MelodicMinor)

    print_line(target_line)
    print_hct(target_hct)
    print()

    print('Shift up P:4, modality NaturalMinor (Figure 15.11)')
    target_line, target_hct = t_shift.apply(range_modality_type=ModalityType.NaturalMinor)

    print_line(target_line)
    print_hct(target_hct)
    print()
    def __init__(self,
                 domain_tonality,
                 domain_pitch_range,
                 root_shift_interval=None,
                 inherent_modality_type=None,
                 modal_index=0):
        """
        Constructor.
        :param domain_tonality:
        :param domain_pitch_range:
        :param root_shift_interval: interval mapping first domain tone to first range tone.
        :param inherent_modality_type: alternative modality type (not modal index)
        :param modal_index: alternative index
        """

        self.__root_shift_interval = Interval.parse(
            'P:1') if root_shift_interval is None else root_shift_interval
        range_modality_type = domain_tonality.modality.modality_type if inherent_modality_type is None \
            else inherent_modality_type

        self.__domain_tonality = domain_tonality

        self.__domain_pitch_range = domain_pitch_range
        self.__modal_index = modal_index

        # Take the root tone from the domain tonality, shift it by the interval, to produce new_root.
        # That new root has to be the modal_index-th tone in some new tonality.
        new_root = self.__root_shift_interval.get_end_tone(
            domain_tonality.root_tone)
        self.__tonal_function = CrossTonalityShiftTonalFunction(
            domain_tonality, new_root, self.__modal_index, range_modality_type)
        self.__range_tonality = self.tonal_function.range_tonality
        if domain_tonality.cardinality != self.__range_tonality.cardinality:
            raise Exception(
                'domain and range tonalities must have same cardinality')

        self.__range_pitch_range = None

        GeneralPitchFunction.__init__(self, self._build_pitch_map())
Exemplo n.º 23
0
    def __init__(self,
                 source_line,
                 source_hct,
                 default_root_shift_interval=None,
                 default_modal_index=None,
                 default_range_modality_type=None):
        """
        Constructor
        :param source_line: Melodic Line being shifted
        :param source_hct: Harmonic Context Track being shifted
        :param default_root_shift_interval: Interval of shift from old to new key
        :param default_modal_index: modal index for key note to serve as root of key
        :param default_range_modality_type: specifies modality type of new key. If none, use original.
        Note: default_range_modality_type applies to any key in source_hct hc's.
        """

        if default_root_shift_interval is None:
            default_root_shift_interval = TonalInterval.parse('P:1')

        self.__source_line = source_line
        self.__source_hct = source_hct
        self.__domain_pitch_range = TShift.compute_pitch_range(source_line)
        self.__default_root_shift_interval_interval = default_root_shift_interval
        self.__default_modal_index = default_modal_index
        self.__default_range_modality_type = default_range_modality_type

        self.temporal_extent = None
        self.keep_hct = None
        self.pre_extent = None
        self.post_extent = None

        self.hc_pitch_function_map = dict()

        self.root_shift_interval = None
        self.modal_index = None
        self.range_modality_type = None

        Transformation.__init__(self)
Exemplo n.º 24
0
    def find_modality(tones):
        answers = list()
        if len(tones) == 7:
            for t in [
                    ModalityType.Major, ModalityType.NaturalMinor,
                    ModalityType.MelodicMinor, ModalityType.HarmonicMinor,
                    ModalityType.HarmonicMajor
            ]:
                modality_spec = DiatonicModality.MODALITY_DEFINITION_MAP[t]

                p1 = Interval.parse('P:1')
                for scale_start in range(0, 7):
                    intervals = [p1] + [
                        Interval.calculate_tone_interval(
                            tones[(scale_start + i) % 7],
                            tones[(scale_start + i + 1) % 7])
                        for i in range(0, len(tones))
                    ]
                    if intervals == modality_spec.incremental_intervals:
                        answers.append(
                            DiatonicModality.create(t, (-scale_start) %
                                                    len(tones)))
        return answers
Exemplo n.º 25
0
 def test_negation(self):
     assert Interval.parse('-d:1').negation() == Interval.parse('d:1')
     assert Interval.parse('-A:1').negation() == Interval.parse('A:1')
Exemplo n.º 26
0
    def test_negative_intervals(self):
        interval = Interval(-3, IntervalType.Major)
        assert interval.diatonic_distance == -2
        assert interval.chromatic_distance == -4
        assert str(interval) == '-M:3'
        print(interval)
        
        interval = Interval.parse('-P:5')
        assert interval.diatonic_distance == -4
        assert interval.chromatic_distance == -7
        assert str(interval) == '-P:5'
        print(interval)
        
        pitch_a = DiatonicPitch(5, 'C')
        pitch_b = DiatonicPitch(4, 'C')
        interval = Interval.create_interval(pitch_a, pitch_b)
        print(interval)
        assert interval.interval_type == IntervalType(IntervalType.Perfect)
        assert interval.diatonic_distance == -7
        
        pitch_a = DiatonicPitch(5, 'C')
        pitch_b = DiatonicPitch(4, 'Cb')
        interval = Interval.create_interval(pitch_a, pitch_b)
        print(interval)
        assert interval.interval_type == IntervalType(IntervalType.Augmented)
        assert interval.diatonic_distance == -7
        assert str(interval) == '-A:8'
        
        pitch_a = DiatonicPitch(5, 'C')
        pitch_b = DiatonicPitch(4, 'C#')
        interval = Interval.create_interval(pitch_a, pitch_b)
        print(interval)
        assert interval.interval_type == IntervalType(IntervalType.Diminished)
        assert interval.diatonic_distance == -7
        assert str(interval) == '-d:8'

        pitch_a = DiatonicPitch(5, 'C')
        lower_pitches = [DiatonicPitch(4, i) for i in list('CDEFGAB')]
        answers = ['-P:8', '-m:7', '-m:6', '-P:5', '-P:4', '-m:3', '-m:2']
        for (p, a) in zip(lower_pitches, answers):
            interval = Interval.create_interval(pitch_a, p)
            assert str(interval) == a
          
        lower_pitches = [DiatonicPitch(4, i) for i in 'Cb,Db,Eb,Fb,Gb,Ab,Bb'.split(',')]
        answers = ['-A:8', '-M:7', '-M:6', '-A:5', '-A:4', '-M:3', '-M:2']
        for (p, a) in zip(lower_pitches, answers):
            interval = Interval.create_interval(pitch_a, p)
            assert str(interval) == a

        lower_pitches = [DiatonicPitch(4, i) for i in 'C#,D#,E#,F#,G#,A#,B#'.split(',')]
        answers = ['-d:8', '-d:7', '-d:6', '-d:5', '-d:4', '-d:3', '-d:2']
        for (p, a) in zip(lower_pitches, answers):
            interval = Interval.create_interval(pitch_a, p)
            assert str(interval) == a

        interval = Interval.parse('-M:3')
        p = DiatonicPitch(4, 'Ab')
        end_p = interval.get_end_pitch(p)
        print(end_p)
        assert str(end_p) == 'Fb:4'
        
        interval = Interval.parse('-P:5')
        p = DiatonicPitch(4, 'D')
        end_p = interval.get_end_pitch(p)
        print(end_p)
        assert str(end_p) == 'G:3'

        interval_strs = ['-P:1', '-M:2', '-M:3', '-P:4', '-P:5', '-M:6', '-M:7', '-P:8', '-M:9', '-M:10',
                         '-P:11', '-P:12', '-M:13', '-M:14', '-P:15']
        intervals = [Interval.parse(i) for i in interval_strs]
        p = DiatonicPitch(4, 'G')
        answers = ['G:4', 'F:4', 'Eb:4', 'D:4', 'C:4', 'Bb:3', 'Ab:3', 
                   'G:3', 'F:3', 'Eb:3', 'D:3', 'C:3', 'Bb:2', 'Ab:2',
                   'G:2'
                   ]
        end_ps = []
        for interval in intervals:
            end_p = interval.get_end_pitch(p)
            print(end_p)
            end_ps.append(end_p)
        for end_p, answer in zip(end_ps, answers):
            assert str(end_p) == answer
            
        # Negation tests
        interval_strs = ['P:1', 'M:2', 'M:3', 'P:4', 'P:5', 'M:6', 'M:7', 'P:8', 'M:9', 'M:10', 'P:11',
                         'P:12', 'M:13', 'M:14', 'P:15',
                         '-P:1', '-M:2', '-M:3', '-P:4', '-P:5', '-M:6', '-M:7', '-P:8', '-M:9', '-M:10', '-P:11',
                         '-P:12', '-M:13', '-M:14', '-P:15']
        intervals = [Interval.parse(i) for i in interval_strs]
        count = 1
        for interval, i_str in zip(intervals, interval_strs):
            neg_interval = interval.negation()
            if count <= 15:
                assert str(neg_interval) == ('-' if count > 1 else '') + i_str
            else:
                assert str(neg_interval) == i_str[1:]
            count += 1
            
        interval_strs = ['-P:1', '-M:2', '-M:3', '-P:4', '-P:5', '-M:6', '-M:7', '-P:8', '-M:9', '-M:10', '-P:11',
                         '-P:12', '-M:13', '-M:14', '-P:15']
        intervals = [Interval.parse(i) for i in interval_strs]
        p = DiatonicPitch(4, 'G')
        answers = ['G:4', 'A:4', 'B:4', 'C:5', 'D:5', 'E:5', 'F#:5', 
                   'G:5', 'A:5', 'B:5', 'C:6', 'D:6', 'E:6', 'F#:6',
                   'G:6'
                   ]
        end_ps = []
        print('+++++')
        for interval in intervals:
            end_p = interval.get_start_pitch(p)
            print(end_p)
            end_ps.append(end_p)
        print('-----')
        for end_p, answer in zip(end_ps, answers):
            assert str(end_p) == answer
Exemplo n.º 27
0
    def parse(expression_text):
        """
        Parse an input string into a parts of HCExpression

        Args:
          expression_text: string input representing hc expression
        Returns:
          HC Expression parts.
        """
        if not expression_text:
            raise Exception(
                'Unable to parse hc expression string to completion: {0}'.
                format(expression_text))
        m = HCExpression.HC_EXPRESSION.match(expression_text)
        if not m:
            raise Exception(
                'Unable to parse hc expression string to completion: {0}'.
                format(expression_text))

        ref_0 = m.group(HCExpression.GROUP_REFERENCE_0)
        ref_0_p = m.group(HCExpression.GROUP_REFERENCE_0P)
        key_ltr = m.group(HCExpression.GROUP_KEY_LTR)
        # scale_distance = m.group(HCExpression.GROUP_SCALE_DISTANCE)
        interval_distance = m.group(HCExpression.GROUP_INTERVAL_DISTANCE)
        if interval_distance:
            try:
                interval_distance = Interval.parse(interval_distance)
            except Exception as e:
                print('Exception parsing interval {0} - {1}'.format(
                    interval_distance, e))
                return
        modality_name = m.group(HCExpression.GROUP_MODALITY_NAME)
        ref_1 = m.group(HCExpression.GROUP_REFERENCE_1)
        ref_1_p = m.group(HCExpression.GROUP_REFERENCE_1P)
        modal_index = m.group(HCExpression.GROUP_MODAL_INDEX)
        modal_index_ref = m.group(HCExpression.GROUP_MODAL_REFERENCE)
        explicit_chord_degree = m.group(
            HCExpression.GROUP_EXPLICIT_CHORD_DEGREE)
        chord_degree_reff = m.group(HCExpression.GROUP_CHORD_DEGREE_REFERENCE)
        chord_degree_reff_p = m.group(
            HCExpression.GROUP_CHORD_DEGREE_REFERENCE_PAREND)
        chord_explicit_name = m.group(HCExpression.GROUP_CHORD_NAME)

        key = int(ref_0) if ref_0 else int(ref_0_p) if ref_0_p else key_ltr
        key_modality = int(ref_1) if ref_1 else int(
            ref_1_p) if ref_1_p else modality_name if modality_name else None
        if key_modality == 'Minor':
            key_modality = 'MelodicMinor'
        if key_modality == 'Natural':
            key_modality = 'NaturalMinor'
        if key_modality == 'Melodic':
            key_modality = 'MelodicMinor'
        if key_modality == 'Harmonic':
            key_modality = 'HarmonicMinor'
        chord_numeral = int(chord_degree_reff) if chord_degree_reff else int(chord_degree_reff_p) \
            if chord_degree_reff_p else explicit_chord_degree if explicit_chord_degree else None

        key_modifier = interval_distance if interval_distance else None
        # key_modifier = interval_distance if interval_distance else int(scale_distance) if scale_distance else None
        modality_index = int(modal_index_ref) if modal_index_ref else str(
            modal_index) if modal_index else None
        chord_type = chord_explicit_name if chord_explicit_name else None

        # interited qualities
        if isinstance(key, int):
            key_modality = key if key_modality is None else key_modality
            # chord type inherits from chord_numeral if not none, else from key.
            if chord_type is None:
                if chord_numeral is not None:
                    chord_type = chord_numeral if isinstance(
                        chord_numeral, int) else None
                else:
                    chord_type = key
            chord_numeral = key if chord_numeral is None else chord_numeral

        if chord_numeral is None:
            chord_numeral = 'i'
        if key_modality is None:
            key_modality = 'Major'

        logging.info('{0}, {1}, {2}, {3}'.format(key, key_modality,
                                                 chord_numeral, key_modifier,
                                                 modality_index, chord_type))

        return key, key_modality, chord_numeral, key_modifier, modality_index, chord_type
Exemplo n.º 28
0
def chromatic_reflection():
    print('Chromatic_Reflection')
    source_expression = '{<Bb-Major: I> sBb:4 A G F iEb D sF g iA i@Bb sF <:IVMaj7> ' \
                        'ir Eb sEb F G A iBb sEb:5 F i@Eb C ' \
                        '<:IIIMin7> sR F:5 Eb D C Bb:4 C:5 D i@Eb sC sr G:4 A G <:I> sG:5 F Eb D D C Bb:4 A ir q@G}'

    t_flip = TChromaticReflection.create(source_expression,
                                         DiatonicPitch.parse('G:4'))
    print('Flip examples based on:')
    print_line(t_flip.source_line)
    print_hct(t_flip.source_hct)
    print()

    print('Flip on G:4  ')
    target_line, target_hct = t_flip.apply()

    print_line(target_line)
    print_hct(target_hct)
    print()

    print('Shift up an octave (Figure 16.16)')
    t_shift = TShift(target_line, target_hct, TonalInterval.parse('P:8'))
    final_line, final_hct = t_shift.apply()
    print_line(final_line)
    print_hct(final_hct)

    # Center-Tone to upper
    t_flip = TChromaticReflection.create(source_expression,
                                         DiatonicPitch.parse('G:4'),
                                         FlipType.UpperNeighborOfPair)
    print('Flip examples based on:')
    print_line(t_flip.source_line)
    print_hct(t_flip.source_hct)
    print()

    print('Upper Flip on G:4 ')
    target_line, target_hct = t_flip.apply()

    print_line(target_line)
    print_hct(target_hct)
    print()

    print('Shift up an octave (Figure 16.17)')
    t_shift = TShift(target_line, target_hct, TonalInterval.parse('P:8'))
    final_line, final_hct = t_shift.apply()
    print_line(final_line)
    print_hct(final_hct)

    # Center-Tone to lower
    t_flip = TChromaticReflection.create(source_expression,
                                         DiatonicPitch.parse('G:4'),
                                         FlipType.LowerNeighborOfPair)
    print('Flip examples based on:')
    print_line(t_flip.source_line)
    print_hct(t_flip.source_hct)
    print()

    print('Lower Flip on G:4 (Figure 16.18)')
    target_line, target_hct = t_flip.apply()

    print_line(target_line)
    print_hct(target_hct)
    print()

    print('Shift up an octave:')
    t_shift = TShift(target_line, target_hct, TonalInterval.parse('P:8'))
    final_line, final_hct = t_shift.apply()
    print_line(final_line)
    print_hct(final_hct)