def create_track(chords, tonality): hc_track = HarmonicContextTrack() for c in chords: chord_t = ChordTemplate.generic_chord_template_parse(c[0]) chord = chord_t.create_chord(tonality) duration = Duration(c[1]) if isinstance(c[1], int) else Duration(c[1][0], c[1][1]) hc_track.append(HarmonicContext(tonality, chord, duration)) return hc_track
def __init__(self): """ Constructor. """ self.tie_list = list() self.__line = Line() self.current_level = Level(self.__line, LineConstructor.DEFAULT_LINE_DURATION) self.level_stack = list() self.current_tonality = LineConstructor.DEFAULT_TONALITY self.harmonic_tag_list = list() self.current_harmonic_tag = None # Set up a default harmonic tag. In cases where a tag is immediately specified, this is discarded self.construct_harmonic_tag(LineConstructor.DEFAULT_TONALITY, ChordTemplate.generic_chord_template_parse('ti'))
def parse(chord_string): """ Parse an input string into a TertialChordTemplate. Args: chord_string: string input representing chord Returns: TertianChordTemplate """ if not chord_string: raise Exception( 'Unable to parse chord string to completion: {0}'.format( chord_string)) m = SecondaryChordTemplate.SECONDARY_CHORD_PATTERN.match(chord_string) if not m: raise SecondaryChordException( 'Unable to parse chord string to completion: {0}'.format( chord_string)) principal_chord_text = m.group( SecondaryChordTemplate.INITIAL_CHORD_TEXT_NAME) secondary_scale_degree_text = m.group( SecondaryChordTemplate.SCALE_DEGREE_NAME) secondary_scale_degree = ChordTemplate.SCALE_DEGREE_MAP[ secondary_scale_degree_text] secondary_modality_text = m.group( SecondaryChordTemplate.DIATONIC_MODALITIES_NAME) secondary_modality = ModalityType( secondary_modality_text) if secondary_modality_text else None principal_chord_template = ChordTemplate.generic_chord_template_parse( principal_chord_text) if not principal_chord_template: raise SecondaryChordException( 'Unable to parse principle chord in secondary template: {0}'. format(principal_chord_text)) logging.info('{0}, {1}, {2}, {3}'.format( principal_chord_text, str(principal_chord_template), secondary_scale_degree, str(secondary_modality) if secondary_modality else '')) return SecondaryChordTemplate(principal_chord_template, secondary_scale_degree, secondary_modality)
def construct_chord_template(self, tone, chord_type_str, chord_modality): if tone: chord_template_str = 't' + tone.diatonic_symbol + (chord_modality if chord_modality else '') else: chord_template_str = 't' + chord_type_str + (chord_modality if chord_modality else '') return ChordTemplate.generic_chord_template_parse(chord_template_str)
def interpret(self, hc_list, duration=Duration(1, 4)): """ Give a list of HarmonicContext's, interpret the HCExpression into a HarmonicContext. :param hc_list: :param duration: :return: HarmonicContext """ if isinstance(self.key, str): key_tone = DiatonicToneCache.get_tone(self.key) else: if self.key not in range(0, len(hc_list)): raise Exception('@{0} not in range.'.format(self.key)) key_tone = hc_list[self.key].tonality.diatonic_tone if self.key_modifier is not None: key_tone = self.key_modifier.get_end_tone(key_tone) if self.modality_index: if isinstance(self.modality_index, str): modal_index = int(self.modality_index) else: if self.modality_index not in range(0, len(hc_list)): raise Exception('@{0} not in range.'.format( self.modality_index)) modal_index = hc_list[self.modality_index].tonality.modal_index else: modal_index = 0 if isinstance(self.key_modality, str): modality_type = ModalityType(self.key_modality) else: if self.key_modality not in range(0, len(hc_list)): raise Exception('@{0} not in range.'.format(self.key_modality)) modality_type = hc_list[self.key_modality].tonality.modality_type # Note: chord_numeral is origin 1 if isinstance(self.chord_numeral, str): chord_numeral = ChordTemplate.SCALE_DEGREE_MAP[self.chord_numeral] else: if self.chord_numeral not in range(0, len(hc_list)): raise Exception('@{0} not in range.'.format( self.chord_numeral)) chord_numeral = hc_list[ self.chord_numeral].chord.chord_template.scale_degree if self.chord_type: if isinstance(self.chord_type, str): chord_type = TertianChordType.to_type(self.chord_type) else: if self.chord_type not in range(0, len(hc_list)): raise Exception('@{0} not in range.'.format( self.chord_type)) chord_type = hc_list[self.chord_type].chord.chord_type else: chord_type = None tonality = Tonality.create(modality_type, key_tone, modal_index) chord_template = ChordTemplate.generic_chord_template_parse( ChordTemplate.SCALE_DEGREE_REVERSE_MAP[chord_numeral] + (str(chord_type) if chord_type else '')) chord = chord_template.create_chord(tonality) hc = HarmonicContext(tonality, chord, duration) return hc