def inversion_exhauster(triad, shorthand, tries, result): """Run tries every inversion and save the result.""" intval1 = intervals.determine(triad[0], triad[1], True) intval2 = intervals.determine(triad[0], triad[2], True) def add_result(short): result.append((short, tries, triad[0])) intval = intval1 + intval2 if intval == "25": add_result("sus2") elif intval == "3b7": add_result("dom7") # changed from just '7' elif intval == "3b5": add_result("7b5") # why not b5? elif intval == "35": add_result("M") elif intval == "3#5": add_result("aug") elif intval == "36": add_result("M6") elif intval == "37": add_result("M7") elif intval == "b3b5": add_result("dim") elif intval == "b35": add_result("m") elif intval == "b36": add_result("m6") elif intval == "b3b7": add_result("m7") elif intval == "b37": add_result("m/M7") elif intval == "45": add_result("sus4") elif intval == "5b7": add_result("m7") elif intval == "57": add_result("M7") if tries != 3 and not no_inversions: return inversion_exhauster([triad[-1]] + triad[:-1], shorthand, tries + 1, result) else: res = [] for r in result: if shorthand: res.append(r[2] + r[0]) else: res.append(r[2] + chord_shorthand_meaning[r[0]] + int_desc(r[1])) return res
def inversion_exhauster(triad, shorthand, tries, result): """Run tries every inversion and save the result.""" intval1 = intervals.determine(triad[0], triad[1], True) intval2 = intervals.determine(triad[0], triad[2], True) def add_result(short): result.append((short, tries, triad[0])) intval = intval1 + intval2 if intval == '25': add_result('sus2') elif intval == '3b7': add_result('dom7') # changed from just '7' elif intval == '3b5': add_result('7b5') # why not b5? elif intval == '35': add_result('M') elif intval == '3#5': add_result('aug') elif intval == '36': add_result('M6') elif intval == '37': add_result('M7') elif intval == 'b3b5': add_result('dim') elif intval == 'b35': add_result('m') elif intval == 'b36': add_result('m6') elif intval == 'b3b7': add_result('m7') elif intval == 'b37': add_result('m/M7') elif intval == '45': add_result('sus4') elif intval == '5b7': add_result('m7') elif intval == '57': add_result('M7') if tries != 3 and not no_inversions: return inversion_exhauster([triad[-1]] + triad[:-1], shorthand, tries + 1, result) else: res = [] for r in result: if shorthand: res.append(r[2] + r[0]) else: res.append(r[2] + chord_shorthand_meaning[r[0]] + int_desc(r[1])) return res
def __sub__(self, other): is_up = self.value <= other.value if is_up: lower, upper = self.value.name, other.value.name else: lower, upper = other.value.name, self.value.name return EdgeInterval(determine(lower, upper, shorthand=True), is_up=is_up)
def inversion_exhauster(chord, shorthand, tries, result, polychords): """Recursive helper function.""" # Determine polychords if tries == 1 and not no_polychords: polychords += determine_polychords(chord, shorthand) def add_result(short): result.append((short, tries, chord[0])) ch = determine_extended_chord6(chord[:6], True, True, True) intval6 = intervals.determine(chord[0], chord[6]) for c in ch: c = c[len(chord[0]):] if c == '11': if intval6 == 'major sixth': add_result('13') elif c == 'm11': if intval6 == 'major sixth': add_result('m13') elif c == 'M11': if intval6 == 'major sixth': add_result('M13') if tries != 6: return inversion_exhauster([chord[-1]] + chord[:-1], shorthand, tries + 1, result, polychords) else: res = [] for r in result: if shorthand: res.append(r[2] + r[0]) else: res.append(r[2] + chord_shorthand_meaning[r[0]] + int_desc(r[1])) return res + polychords
def determine(chord, shorthand=False, no_inversions=False, no_polychords=False): """Name a chord. This function can determine almost every chord, from a simple triad to a fourteen note polychord.""" if chord == []: return [] elif len(chord) == 1: return chord elif len(chord) == 2: return [intervals.determine(chord[0], chord[1])] elif len(chord) == 3: return determine_triad(chord, shorthand, no_inversions, no_polychords) elif len(chord) == 4: return determine_seventh(chord, shorthand, no_inversions, no_polychords) elif len(chord) == 5: return determine_extended_chord5(chord, shorthand, no_inversions, no_polychords) elif len(chord) == 6: return determine_extended_chord6(chord, shorthand, no_inversions, no_polychords) elif len(chord) == 7: return determine_extended_chord7(chord, shorthand, no_inversions, no_polychords) else: return determine_polychords(chord, shorthand)
def test_determine_shorthand(self): self.assertEqual('3', intervals.determine('C', 'E', True)) self.assertEqual('b3', intervals.determine('C', 'Eb', True)) self.assertEqual('##3', intervals.determine('C', 'E##', True)) self.assertEqual('bb3', intervals.determine('C', 'Ebb', True)) self.assertEqual('b1', intervals.determine('C', 'Cb', True)) self.assertEqual('#1', intervals.determine('Cb', 'C', True)) self.assertEqual('bb1', intervals.determine('C', 'Cbb', True))
def test_determine_shorthand(self): self.assertEqual("3", intervals.determine("C", "E", True)) self.assertEqual("b3", intervals.determine("C", "Eb", True)) self.assertEqual("##3", intervals.determine("C", "E##", True)) self.assertEqual("bb3", intervals.determine("C", "Ebb", True)) self.assertEqual("b1", intervals.determine("C", "Cb", True)) self.assertEqual("#1", intervals.determine("Cb", "C", True)) self.assertEqual("bb1", intervals.determine("C", "Cbb", True))
def create_interval_perfect(start_note): start = start_note options = [ intervals.perfect_fifth(start), intervals.perfect_fourth(start), intervals.major_unison(start) ] end = options[(randint(0, 2))] interval = intervals.determine(start, end) return interval
def descending(self): notes = [self.tonic] for note in reversed(get_notes(self.key)): if intervals.determine(note, notes[-1]) == ('major second'): notes.append(reduce_accidentals(diminish(notes[-1]))) notes.append(note) else: notes.append(note) notes.pop() return notes * self.octaves + [notes[0]]
def ascending(self): notes = [self.tonic] for note in get_notes(self.key)[1:] + [self.tonic]: if intervals.determine(notes[-1], note) == ('major second'): notes.append(augment(notes[-1])) notes.append(note) else: notes.append(note) notes.pop() return notes * self.octaves + [notes[0]]
def inversion_exhauster(chord, shorthand, tries, result, polychords): """Recursive helper function.""" def add_result(short): result.append((short, tries, chord[0])) triads = determine_triad(chord[:3], True, True) sevenths = determine_seventh(chord[:4], True, True, True) # Determine polychords if tries == 1 and not no_polychords: polychords += determine_polychords(chord, shorthand) intval4 = intervals.determine(chord[0], chord[4]) for seventh in sevenths: seventh = seventh[len(chord[0]):] if seventh == 'M7': if intval4 == 'major second': add_result('M9') elif seventh == 'm7': if intval4 == 'major second': add_result('m9') elif intval4 == 'perfect fourth': add_result('m11') elif seventh == '7': if intval4 == 'major second': add_result('9') elif intval4 == 'minor second': add_result('7b9') elif intval4 == 'augmented second': add_result('7#9') elif intval4 == 'minor third': add_result('7b12') elif intval4 == 'augmented fourth': add_result('7#11') elif intval4 == 'major sixth': add_result('13') elif seventh == 'M6': if intval4 == 'major second': add_result('6/9') elif intval4 == 'minor seventh': add_result('6/7') if tries != 5 and not no_inversions: return inversion_exhauster([chord[-1]] + chord[:-1], shorthand, tries + 1, result, polychords) else: res = [] for r in result: if shorthand: res.append(r[2] + r[0]) else: res.append(r[2] + chord_shorthand_meaning[r[0]] + int_desc(r[1])) return res + polychords
def inversion_exhauster(chord, shorthand, tries, result, polychords): """Recursive helper function.""" def add_result(short): result.append((short, tries, chord[0])) triads = determine_triad(chord[:3], True, True) sevenths = determine_seventh(chord[:4], True, True, True) # Determine polychords if tries == 1 and not no_polychords: polychords += determine_polychords(chord, shorthand) intval4 = intervals.determine(chord[0], chord[4]) for seventh in sevenths: seventh = seventh[len(chord[0]):] if seventh == "M7": if intval4 == "major second": add_result("M9") elif seventh == "m7": if intval4 == "major second": add_result("m9") elif intval4 == "perfect fourth": add_result("m11") elif seventh == "7": if intval4 == "major second": add_result("9") elif intval4 == "minor second": add_result("7b9") elif intval4 == "augmented second": add_result("7#9") elif intval4 == "minor third": add_result("7b12") elif intval4 == "augmented fourth": add_result("7#11") elif intval4 == "major sixth": add_result("13") elif seventh == "M6": if intval4 == "major second": add_result("6/9") elif intval4 == "minor seventh": add_result("6/7") if tries != 5 and not no_inversions: return inversion_exhauster([chord[-1]] + chord[:-1], shorthand, tries + 1, result, polychords) else: res = [] for r in result: if shorthand: res.append(r[2] + r[0]) else: res.append(r[2] + chord_shorthand_meaning[r[0]] + int_desc(r[1])) return res + polychords
def create_interval_dissonant(start_note): start = start_note options = [ intervals.minor_second(start), intervals.major_second(start), intervals.minor_fifth(start), intervals.minor_seventh(start), intervals.major_seventh(start) ] end = options[(randint(0, len(options) - 1))] interval = intervals.determine(start, end) return interval
def get_interval(note_a, note_b): """ Takes two NoteNode objects. Returns a tuple of the form: (str: interval name, int: octaves between) """ if note_a.is_rest or note_b.is_rest: name = ' ' octave = 0 else: name = mintervals.determine(note_a, note_b, True) octave = abs(int(note_a) - int(note_b))/12 return (name, octave)
def create_interval_consonant(start_note): start = start_note options = [ intervals.perfect_fifth(start), intervals.perfect_fourth(start), intervals.major_unison(start), intervals.major_third(start), intervals.minor_third(start), intervals.major_sixth(start), intervals.minor_sixth(start) ] end = options[(randint(0, len(options) - 1))] interval = intervals.determine(start, end) return interval
def inversion_exhauster( chord, shorthand, tries, result, polychords, ): """Recursive helper function""" # Determine polychords if tries == 1 and not no_polychords: polychords += determine_polychords(chord, shorthand) def add_result(short): result.append((short, tries, chord[0])) ch = determine_extended_chord5(chord[:5], True, True, True) intval5 = intervals.determine(chord[0], chord[5]) for c in ch: c = c[len(chord[0]):] if c == "9": if intval5 == "perfect fourth": add_result("11") elif intval5 == "augmented fourth": add_result("7#11") elif intval5 == "major sixth": add_result("13") elif c == "m9": if intval5 == "perfect fourth": add_result("m11") elif intval5 == "major sixth": add_result("m13") elif c == "M9": if intval5 == "perfect fourth": add_result("M11") elif intval5 == "major sixth": add_result("M13") if tries != 6 and not no_inversions: return inversion_exhauster([chord[-1]] + chord[:-1], shorthand, tries + 1, result, polychords) else: res = [] for r in result: if shorthand: res.append(r[2] + r[0]) else: res.append(r[2] + chord_shorthand_meaning[r[0]] + int_desc(r[1])) return res + polychords
def create_interval_aug_or_dim(start_note): start = start_note options = [ augmented_fifth(start), augmented_fourth(start), augmented_second(start), augmented_sixth(start), diminished_fifth(start), augmented_third(start), diminished_unison(start), diminished_fourth(start), ] end = options[(randint(0, len(options) - 1))] interval = intervals.determine(start, end) return interval
def find_last_note(self, parent, notes, degrees, returned_notes): """Find one of the last note Recursive function""" # TODO dans le cas d'une succession comme V-I, le saut de quarte est aussi bon que le saut de quinte. Sélectionner aléatoirement ? new_note = notes[0] parent_note = parent parent_degree = self.find_degree(parent_note) par_octave = parent_note.octave possible_notes = [ mcn.Note(new_note, octave) for octave in (par_octave - 1, par_octave, par_octave + 1) ] possible_notes_semitones = { abs(parent_note.measure(n)): n for n in possible_notes } find_interval = lambda x, y: int(mci.determine(x, y, True)[-1]) interval1 = find_interval(new_note, parent_note.name) interval2 = find_interval(parent_note.name, new_note) lower, greater = (interval1, interval2) if interval1 < interval2 else (interval2, interval1) selected_note = None if lower in self.config.degrees_numeric[parent_degree]: possible_min = min(possible_notes_semitones.keys()) selected_note = possible_notes_semitones[possible_min] if not (self.check_tessitura(selected_note)): selected_note = None del (possible_notes_semitones[possible_min]) if selected_note is None: if greater in self.config.degrees_numeric[parent_degree]: # we must take here the minimum, since the max possible would be too large selected_note = possible_notes_semitones[min( possible_notes_semitones.keys())] if not (self.check_tessitura(selected_note)): selected_note = None else: return returned_notes returned_notes.append(Node(selected_note)) if len(notes) > 1: return self.find_last_note(selected_note, notes[1:], degrees[1:], returned_notes) return returned_notes
def create_answer(track, key): # First look for any perfect fifth leaps from the root note in the melody # If found, diminsh the fifth to a fourth before transposing track_copy = copy.deepcopy(track) for i in range(len(track_copy[0]) - 1): if track_copy[0][i][2] is None: continue note1 = track_copy[0][i][2][ 0].name # This monstrosity is the note name if note1 == key: note2 = track_copy[0][i + 1][2][0].name interval = intervals.determine(note1, note2) if interval == 'perfect fifth': track_copy[0][i + 1][2][0].transpose('2', False) answer = transpose_from_halfnote(track_copy, 7, up=True) return answer
def determine_chords(chords): sh = [] for chord in chords: if chord[0].endswith('bbb'): sh.append('r1') else: res = {} if len(chord) == 4: if Intervals.determine(chord[0], chord[3]).split(' ')[0] == 'minor': res['seventh'] = '' elif Intervals.determine(chord[0], chord[3]).split(' ')[0] == 'major': res['seventh'] = 'maj' else: res['seventh'] = '-' if chord[0].find('#') != -1: res['acc'] = 'is' res['tonic'] = chord[0][0:(chord[0].find('#'))].lower() elif chord[0].find('b') != -1: res['acc'] = 'es' res['tonic'] = chord[0][0:(chord[0].find('b'))].lower() else: res['acc'] = '-' res['tonic'] = chord[0].lower() if Intervals.determine(chord[0], chord[2]).split(' ')[0] == 'minor': res['fifth'] = 'dim' elif Intervals.determine(chord[0], chord[2]).split(' ')[0] == 'augmented': res['fifth'] = 'aug' else: res['fifth'] = '-' if Intervals.determine(chord[0], chord[1]).split(' ')[0] == 'major': res['mode'] = '' elif Intervals.determine(chord[0], chord[1]).split(' ')[0] == 'minor': res['mode'] = 'min' str = res['tonic'] if res['acc'] != '-': str += res['acc'] str += '1:' if res['fifth'] != '-': str += res['fifth'] sh.append(str) continue str += res['mode'] if res['seventh'] != '-': str += ('7' + res['seventh']) sh.append(str) return sh
def shuffle(self, seq, previous): """Suffle seq and return a new sequence Balance between intervals is applied.""" weights = {} for elt in seq: pn, en = previous.note.name, elt.note.name n1, n2 = (pn, en) if previous.note < elt.note else (en, pn) #self.weights.append(self.intervals_balance[mci.determine(n1,n2,True)]) itvl = mci.determine(n1, n2, True)[-1] weights[elt] = self.intervals_balance[int(itvl)] shuffled_seq = [] while len(weights) > 0: selected = random.choices(list(weights.keys()), tuple(weights.values()))[0] shuffled_seq.append(selected) del (weights[selected]) return shuffled_seq
def get_interval(response, fb_id): """Determnine the interval between 2 notes.""" try: # Extract the 2 notes user sent notes = response['entities']["Note:Note"] note1 = notes[0]['value'] note2 = notes[1]['value'] except (KeyError, IndexError) as e: text = "Sorry, I don't think you provided enough notes :/" return text # Exit early try: # Determine interval between notes interval = intervals.determine(note1, note2) text = f"The interval between {note1} and {note2} is {interval}." except Exception as e: print("EXCEPTION", e) text = f"Sorry! I don't know the interval between {note1} and {note2} :/" return text
def inversion_exhauster(seventh, shorthand, tries, result, polychords): """Determine sevenths recursive functions.""" # Check whether the first three notes of seventh are part of some triad. triads = determine_triad(seventh[:3], True, True) # Get the interval between the first and last note intval3 = intervals.determine(seventh[0], seventh[3]) def add_result(short, poly=False): """Helper function.""" result.append((short, tries, seventh[0], poly)) # Recognizing polychords if tries == 1 and not no_polychords: polychords = polychords + determine_polychords(seventh, shorthand) # Recognizing sevenths for triad in triads: # Basic triads triad = triad[len(seventh[0]):] if triad == 'm': if intval3 == 'minor seventh': add_result('m7') elif intval3 == 'major seventh': add_result('m/M7') elif intval3 == 'major sixth': add_result('m6') elif triad == 'M': if intval3 == 'major seventh': add_result('M7') elif intval3 == 'minor seventh': add_result('7') elif intval3 == 'major sixth': add_result('M6') elif triad == 'dim': if intval3 == 'minor seventh': add_result('m7b5') elif intval3 == 'diminished seventh': add_result('dim7') elif triad == 'aug': if intval3 == 'minor seventh': add_result('m7+') if intval3 == 'major seventh': add_result('M7+') elif triad == 'sus4': if intval3 == 'minor seventh': add_result('sus47') elif intval3 == 'minor second': add_result('sus4b9') elif triad == 'm7': # Other if intval3 == 'perfect fourth': add_result('11') elif triad == '7b5': if intval3 == 'minor seventh': add_result('7b5') if tries != 4 and not no_inversion: return inversion_exhauster([seventh[-1]] + seventh[:-1], shorthand, tries + 1, result, polychords) else: # Return results res = [] # Reset seventh seventh = [seventh[3]] + seventh[0:3] for x in result: if shorthand: res.append(x[2] + x[0]) else: res.append(x[2] + chord_shorthand_meaning[x[0]] + int_desc(x[1])) return res + polychords
def test_determine(self): self.assertEqual("major third", intervals.determine("C", "E")) self.assertEqual("minor third", intervals.determine("C", "Eb")) self.assertEqual("diminished third", intervals.determine("C", "Ebb")) self.assertEqual("minor unison", intervals.determine("C", "Cb")) self.assertEqual("augmented unison", intervals.determine("Cb", "C")) self.assertEqual("diminished unison", intervals.determine("C", "Cbb")) self.assertEqual("augmented unison", intervals.determine("Cbb", "C")) self.assertEqual("minor unison", intervals.determine("A", "Ab")) self.assertEqual("diminished unison", intervals.determine("A", "Abb")) self.assertEqual("major unison", intervals.determine("A", "A")) self.assertEqual("augmented unison", intervals.determine("Abb", "A")) self.assertEqual("augmented unison", intervals.determine("A", "A##########")) self.assertEqual("major seventh", intervals.determine("Cb", "Bb")) self.assertEqual("major seventh", intervals.determine("Cbb", "Bbb")) self.assertEqual("major seventh", intervals.determine("Cbbb", "Bbbb")) self.assertEqual("major seventh", intervals.determine("Ab", "G"))
def determine(chord, key, shorthand=False): """Determine the harmonic function of chord in key. This function can also deal with lists of chords. Examples: >>> determine(['C', 'E', 'G'], 'C') ['tonic'] >>> determine(['G', 'B', 'D'], 'C') ['dominant'] >>> determine(['G', 'B', 'D', 'F'], 'C', True) ['V7'] >>> determine([['C', 'E', 'G'], ['G', 'B', 'D']], 'C', True) [['I'], ['V']] """ result = [] # Handle lists of chords if type(chord[0]) == list: for c in chord: result.append(determine(c, key, shorthand)) return result func_dict = { 'I': 'tonic', 'ii': 'supertonic', 'iii': 'mediant', 'IV': 'subdominant', 'V': 'dominant', 'vi': 'submediant', 'vii': 'subtonic', } expected_chord = [ ['I', 'M', 'M7'], ['ii', 'm', 'm7'], ['iii', 'm', 'm7'], ['IV', 'M', 'M7'], ['V', 'M', '7'], ['vi', 'm', 'm7'], ['vii', 'dim', 'm7b5'], ] type_of_chord = chords.determine(chord, True, False, True) for chord in type_of_chord: name = chord[0] # Get accidentals a = 1 for n in chord[1:]: if n == 'b': name += 'b' elif n == '#': name += '#' else: break a += 1 chord_type = chord[a:] # Determine chord function (interval_type, interval) = intervals.determine(key, name).split(' ') if interval == 'unison': func = 'I' elif interval == 'second': func = 'ii' elif interval == 'third': func = 'iii' elif interval == 'fourth': func = 'IV' elif interval == 'fifth': func = 'V' elif interval == 'sixth': func = 'vi' elif interval == 'seventh': func = 'vii' # Check whether the chord is altered or not for x in expected_chord: if x[0] == func: # Triads if chord_type == x[1]: if not shorthand: func = func_dict[func] elif chord_type == x[2]: # Sevenths if shorthand: func += '7' else: func = func_dict[func] + ' seventh' else: # Other if shorthand: func += chord_type else: func = func_dict[func]\ + chords.chord_shorthand_meaning[chord_type] # Handle b's and #'s (for instance Dbm in key C is bII) if shorthand: if interval_type == 'minor': func = 'b' + func elif interval_type == 'augmented': func = '#' + func elif interval_type == 'diminished': func = 'bb' + func else: if interval_type == 'minor': func = 'minor ' + func elif interval_type == 'augmented': func = 'augmented ' + func elif interval_type == 'diminished': func = 'diminished ' + func # Add to results result.append(func) return result
import mingus.core.notes as notes import mingus.core.keys as keys import mingus.core.intervals as intervals print(notes.is_valid_note('C#')) print(notes.int_to_note(0)) # [0,..,11] print(keys.get_notes("C")) print(intervals.second("E", "C")) print(intervals.determine("Gbb", "Ab")) print(intervals.determine("Gbb", "Ab", True)) print(intervals.measure("C", "D")) print(intervals.measure("D", "C"))
def test_determine(self): self.assertEqual('major third', intervals.determine('C', 'E')) self.assertEqual('minor third', intervals.determine('C', 'Eb')) self.assertEqual('diminished third', intervals.determine('C', 'Ebb')) self.assertEqual('minor unison', intervals.determine('C', 'Cb')) self.assertEqual('augmented unison', intervals.determine('Cb', 'C')) self.assertEqual('diminished unison', intervals.determine('C', 'Cbb')) self.assertEqual('augmented unison', intervals.determine('Cbb', 'C')) self.assertEqual('minor unison', intervals.determine('A', 'Ab')) self.assertEqual('diminished unison', intervals.determine('A', 'Abb')) self.assertEqual('major unison', intervals.determine('A', 'A')) self.assertEqual('augmented unison', intervals.determine('Abb', 'A')) self.assertEqual('augmented unison', intervals.determine('A', 'A##########')) self.assertEqual('major seventh', intervals.determine('Cb', 'Bb')) self.assertEqual('major seventh', intervals.determine('Cbb', 'Bbb')) self.assertEqual('major seventh', intervals.determine('Cbbb', 'Bbbb')) self.assertEqual('major seventh', intervals.determine('Ab', 'G'))
def create_interval_all(start_note): start = start_note end = notes.int_to_note(randint(0, 11)) interval = intervals.determine(start, end) return interval
def determine(chord, key, shorthand=False): """Determine the harmonic function of chord in key. This function can also deal with lists of chords. Examples: >>> determine(['C', 'E', 'G'], 'C') ['tonic'] >>> determine(['G', 'B', 'D'], 'C') ['dominant'] >>> determine(['G', 'B', 'D', 'F'], 'C', True) ['V7'] >>> determine([['C', 'E', 'G'], ['G', 'B', 'D']], 'C', True) [['I'], ['V']] """ result = [] # Handle lists of chords if isinstance(chord[0], list): for c in chord: result.append(determine(c, key, shorthand)) return result func_dict = { "I": "tonic", "ii": "supertonic", "iii": "mediant", "IV": "subdominant", "V": "dominant", "vi": "submediant", "vii": "subtonic", } expected_chord = [ ["I", "M", "M7"], ["ii", "m", "m7"], ["iii", "m", "m7"], ["IV", "M", "M7"], ["V", "M", "7"], ["vi", "m", "m7"], ["vii", "dim", "m7b5"], ] type_of_chord = chords.determine(chord, True, False, True) for chord in type_of_chord: name = chord[0] # Get accidentals a = 1 for n in chord[1:]: if n == "b": name += "b" elif n == "#": name += "#" else: break a += 1 chord_type = chord[a:] # Determine chord function (interval_type, interval) = intervals.determine(key, name).split(" ") if interval == "unison": func = "I" elif interval == "second": func = "ii" elif interval == "third": func = "iii" elif interval == "fourth": func = "IV" elif interval == "fifth": func = "V" elif interval == "sixth": func = "vi" elif interval == "seventh": func = "vii" # Check whether the chord is altered or not for x in expected_chord: if x[0] == func: # Triads if chord_type == x[1]: if not shorthand: func = func_dict[func] elif chord_type == x[2]: # Sevenths if shorthand: func += "7" else: func = func_dict[func] + " seventh" else: # Other if shorthand: func += chord_type else: func = func_dict[ func] + chords.chord_shorthand_meaning[chord_type] # Handle b's and #'s (for instance Dbm in key C is bII) if shorthand: if interval_type == "minor": func = "b" + func elif interval_type == "augmented": func = "#" + func elif interval_type == "diminished": func = "bb" + func else: if interval_type == "minor": func = "minor " + func elif interval_type == "augmented": func = "augmented " + func elif interval_type == "diminished": func = "diminished " + func # Add to results result.append(func) return result
def inversion_exhauster(seventh, shorthand, tries, result, polychords): """Determine sevenths recursive functions.""" # Check whether the first three notes of seventh are part of some triad. triads = determine_triad(seventh[:3], True, True) # Get the interval between the first and last note intval3 = intervals.determine(seventh[0], seventh[3]) def add_result(short, poly=False): """Helper function.""" result.append((short, tries, seventh[0], poly)) # Recognizing polychords if tries == 1 and not no_polychords: polychords = polychords + determine_polychords(seventh, shorthand) # Recognizing sevenths for triad in triads: # Basic triads triad = triad[len(seventh[0]):] if triad == "m": if intval3 == "minor seventh": add_result("m7") elif intval3 == "major seventh": add_result("m/M7") elif intval3 == "major sixth": add_result("m6") elif triad == "M": if intval3 == "major seventh": add_result("M7") elif intval3 == "minor seventh": add_result("7") elif intval3 == "major sixth": add_result("M6") elif triad == "dim": if intval3 == "minor seventh": add_result("m7b5") elif intval3 == "diminished seventh": add_result("dim7") elif triad == "aug": if intval3 == "minor seventh": add_result("m7+") if intval3 == "major seventh": add_result("M7+") elif triad == "sus4": if intval3 == "minor seventh": add_result("sus47") elif intval3 == "minor second": add_result("sus4b9") elif triad == "m7": # Other if intval3 == "perfect fourth": add_result("11") elif triad == "7b5": if intval3 == "minor seventh": add_result("7b5") if tries != 4 and not no_inversion: return inversion_exhauster([seventh[-1]] + seventh[:-1], shorthand, tries + 1, result, polychords) else: # Return results res = [] # Reset seventh seventh = [seventh[3]] + seventh[0:3] for x in result: if shorthand: res.append(x[2] + x[0]) else: res.append(x[2] + chord_shorthand_meaning[x[0]] + int_desc(x[1])) return res + polychords