def from_shorthand(note, interval, up=True): """Return the note on interval up or down. Examples: >>> from_shorthand('A', 'b3') 'C' >>> from_shorthand('D', '2') 'E' >>> from_shorthand('E', '2', False) 'D' """ # warning should be a valid note. if not notes.is_valid_note(note): return False # [shorthand, interval function up, interval function down] shorthand_lookup = [ ['1', major_unison, major_unison], ['2', major_second, minor_seventh], ['3', major_third, minor_sixth], ['4', major_fourth, major_fifth], ['5', major_fifth, major_fourth], ['6', major_sixth, minor_third], ['7', major_seventh, minor_second], ] # Looking up last character in interval in shorthand_lookup and calling that # function. val = False for shorthand in shorthand_lookup: if shorthand[0] == interval[-1]: if up: val = shorthand[1](note) else: val = shorthand[2](note) # warning Last character in interval should be 1-7 if val == False: return False # Collect accidentals for x in interval: if x == '#': if up: val = notes.augment(val) else: val = notes.diminish(val) elif x == 'b': if up: val = notes.diminish(val) else: val = notes.augment(val) else: return val
def diminished_seventh(note): """Build a diminished seventh chord on note. Example: >>> diminished_seventh('C') ['C', 'Eb', 'Gb', 'Bbb'] """ return (diminished_triad(note) + [notes.diminish(intervals.minor_seventh(note))])
def dominant_flat_five(note): """Build a dominant flat five chord on note. Example: >>> dominant_flat_five('C') ['C', 'E', 'Gb', 'Bb'] """ res = dominant_seventh(note) res[2] = notes.diminish(res[2]) return res
def augment_or_diminish_until_the_interval_is_right(note1, note2, interval): """A helper function for the minor and major functions. You should probably not use this directly. """ cur = measure(note1, note2) while cur != interval: if cur > interval: note2 = notes.diminish(note2) elif cur < interval: note2 = notes.augment(note2) cur = measure(note1, note2) # We are practically done right now, but we need to be able to create the # minor seventh of Cb and get Bbb instead of B######### as the result val = 0 for token in note2[1:]: if token == '#': val += 1 elif token == 'b': val -= 1 # These are some checks to see if we have generated too much #'s or too much # b's. In these cases we need to convert #'s to b's and vice versa. if val > 6: val = val % 12 val = -12 + val elif val < -6: val = val % -12 val = 12 + val # Rebuild the note result = note2[0] while val > 0: result = notes.augment(result) val -= 1 while val < 0: result = notes.diminish(result) val += 1 return result
def get_interval(note, interval, key='C'): """Return the note an interval (in half notes) away from the given note. This will produce mostly theoretical sound results, but you should use the minor and major functions to work around the corner cases. """ intervals = map(lambda x: (notes.note_to_int(key) + x) % 12, [ 0, 2, 4, 5, 7, 9, 11, ]) key_notes = keys.get_notes(key) for x in key_notes: if x[0] == note[0]: result = (intervals[key_notes.index(x)] + interval) % 12 if result in intervals: return key_notes[intervals.index(result)] + note[1:] else: return notes.diminish(key_notes[intervals.index((result + 1) % 12)] + note[1:])
def minor_unison(note): return notes.diminish(note)