def inversion_exhauster( triad, shorthand, tries, result, ): """Recursive helper function that runs tries every inversion and saves 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 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 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 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) # Determine 'normal' chords 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 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 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 inversion_exhauster(triad, shorthand, tries, result): """Recursive helper function that runs tries every inversion and saves 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 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(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 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
def determine(chord, key, shorthand=False): """Determines the harmonic function of chord in key. This function can also deal with lists of chords. {{{ >>> 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] # Sevenths elif chord_type == x[2]: if shorthand: func += "7" else: func = func_dict[func] + " seventh" # Other else: 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 determine(scale): """Determines the kind of scale. Can recognize all the diatonic modes and the \ minor scales. Example: {{{ >>> determine([\"C\", \"D\", \"E\", \"F\", \"G\", \"A\", \"B\"]) 'C ionian' }}}""" possible_result = [ [ 'ionian', [ 'major second', 'major third', 'perfect fourth', 'perfect fifth', 'major sixth', 'major seventh', ] ], [ 'dorian', [ 'major second', 'minor third', 'perfect fourth', 'perfect fifth', 'major sixth', 'minor seventh', ] ], [ 'phrygian', [ 'minor second', 'minor third', 'perfect fourth', 'perfect fifth', 'minor sixth', 'minor seventh', ] ], [ 'lydian', [ 'major second', 'major third', 'major fourth', 'perfect fifth', 'major sixth', 'major seventh', ] ], [ 'mixolydian', [ 'major second', 'major third', 'perfect fourth', 'perfect fifth', 'major sixth', 'minor seventh', ] ], [ 'aeolian', [ 'major second', 'minor third', 'perfect fourth', 'perfect fifth', 'minor sixth', 'minor seventh', ] ], [ 'locrian', [ 'minor second', 'minor third', 'perfect fourth', 'minor fifth', 'minor sixth', 'minor seventh', ] ], [ 'natural minor', [ 'major second', 'minor third', 'perfect fourth', 'perfect fifth', 'minor sixth', 'minor seventh', ] ], [ 'harmonic minor', [ 'major second', 'minor third', 'perfect fourth', 'perfect fifth', 'minor sixth', 'major seventh', ] ], [ 'melodic minor', [ 'major second', 'minor third', 'perfect fourth', 'perfect fifth', 'major sixth', 'major seventh', ] ], ] tonic = scale[0] n = 0 # -- Describing the algorithm: Filter out all the wrong answers in # possible_result for note in scale[1:]: # 1. Determine the interval intval = intervals.determine(tonic, note) a = 0 temp = [] # 2. Go through possible_result and add it to temp if it's a hit, do # nothing otherwise for x in possible_result: if x[1][n] == intval: temp.append(x) n += 1 # 3. Set possible_result to temp possible_result = temp # Get the results from possible_result and return res = [] for x in possible_result: res.append(scale[0] + ' ' + x[0]) return res
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") # Other elif triad == 'm7': if intval3 == 'perfect fourth': add_result("11") elif triad == '7b5': if intval3 == 'minor seventh': add_result("7b5") # Loop until we have exhausted all the inversions 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 determine(scale): """Determines the kind of scale. Can recognize all the diatonic modes and the \ minor scales. Example: {{{ >>> determine([\"C\", \"D\", \"E\", \"F\", \"G\", \"A\", \"B\"]) 'C ionian' }}}""" possible_result = [ ['ionian', [ 'major second', 'major third', 'perfect fourth', 'perfect fifth', 'major sixth', 'major seventh', ]], ['dorian', [ 'major second', 'minor third', 'perfect fourth', 'perfect fifth', 'major sixth', 'minor seventh', ]], ['phrygian', [ 'minor second', 'minor third', 'perfect fourth', 'perfect fifth', 'minor sixth', 'minor seventh', ]], ['lydian', [ 'major second', 'major third', 'major fourth', 'perfect fifth', 'major sixth', 'major seventh', ]], ['mixolydian', [ 'major second', 'major third', 'perfect fourth', 'perfect fifth', 'major sixth', 'minor seventh', ]], ['aeolian', [ 'major second', 'minor third', 'perfect fourth', 'perfect fifth', 'minor sixth', 'minor seventh', ]], ['locrian', [ 'minor second', 'minor third', 'perfect fourth', 'minor fifth', 'minor sixth', 'minor seventh', ]], ['natural minor', [ 'major second', 'minor third', 'perfect fourth', 'perfect fifth', 'minor sixth', 'minor seventh', ]], ['harmonic minor', [ 'major second', 'minor third', 'perfect fourth', 'perfect fifth', 'minor sixth', 'major seventh', ]], ['melodic minor', [ 'major second', 'minor third', 'perfect fourth', 'perfect fifth', 'major sixth', 'major seventh', ]], ] tonic = scale[0] n = 0 # -- Describing the algorithm: Filter out all the wrong answers in # possible_result for note in scale[1:]: # 1. Determine the interval intval = intervals.determine(tonic, note) a = 0 temp = [] # 2. Go through possible_result and add it to temp if it's a hit, do # nothing otherwise for x in possible_result: if x[1][n] == intval: temp.append(x) n += 1 # 3. Set possible_result to temp possible_result = temp # Get the results from possible_result and return res = [] for x in possible_result: res.append(scale[0] + ' ' + x[0]) return res
def determine(scale): """Determines the kind of scale. Can recognize all the diatonic modes and \ the minor scales. Example: {{{ >>> determine(["C", "D", "E", "F", "G", "A", "B"]) 'C ionian' }}}""" possible_result = [ ["ionian", ["major second", "major third", "perfect fourth", "perfect fifth", "major sixth", "major seventh"]], ["dorian", ["major second", "minor third", "perfect fourth", "perfect fifth", "major sixth", "minor seventh"]], ["phrygian", ["minor second", "minor third", "perfect fourth", "perfect fifth", "minor sixth", "minor seventh"]], ["lydian", ["major second", "major third", "major fourth", "perfect fifth", "major sixth", "major seventh"]], ["mixolydian", ["major second", "major third", "perfect fourth", "perfect fifth", "major sixth", "minor seventh"]], ["aeolian", ["major second", "minor third", "perfect fourth", "perfect fifth", "minor sixth", "minor seventh"]], ["locrian", ["minor second", "minor third", "perfect fourth", "minor fifth", "minor sixth", "minor seventh"]], ["natural minor", ["major second", "minor third", "perfect fourth", "perfect fifth", "minor sixth", "minor seventh"]], ["harmonic minor", ["major second", "minor third", "perfect fourth", "perfect fifth", "minor sixth", "major seventh"]], ["melodic minor", ["major second", "minor third", "perfect fourth", "perfect fifth", "major sixth", "major seventh"]], ] tonic = scale[0] n = 0 # -- Describing the algorithm: # Filter out all the wrong answers in possible_result for note in scale[1:]: # 1. Determine the interval intval = intervals.determine(tonic, note) a=0 temp = [] # 2. Go through possible_result and add it to temp if # it's a hit, do nothing otherwise for x in possible_result: if x[1][n] == intval: temp.append(x) n += 1 # 3. Set possible_result to temp possible_result = temp # Get the results from possible_result and return res = [] for x in possible_result: res.append(scale[0] + " " + x[0]) return res