def set_note(self, name='C', octave=4, dynamics={}): """Set the note to name in octave with dynamics. Return the objects if it succeeded, raise an NoteFormatError otherwise. """ dash_index = name.split('-') if len(dash_index) == 1: if notes.is_valid_note(name): self.name = name self.octave = octave self.dynamics = dynamics return self else: raise NoteFormatError("The string '%s' is not a valid " "representation of a note in mingus" % name) elif len(dash_index) == 2: if notes.is_valid_note(dash_index[0]): self.name = dash_index[0] self.octave = int(dash_index[1]) self.dynamics = dynamics return self else: raise NoteFormatError("The string '%s' is not a valid " "representation of a note in mingus" % name) return False
def get_notes(key='C'): """Return an ordered list of the notes in this natural key. Examples: >>> get_notes('F') ['F', 'G', 'A', 'Bb', 'C', 'D', 'E'] >>> get_notes('c') ['C', 'D', 'Eb', 'F', 'G', 'Ab', 'Bb'] """ if key in _key_cache: return _key_cache[key] if not is_valid_key(key): raise NoteFormatError("unrecognized format for key '%s'" % key) result = [] # Calculate notes altered_notes = list(map(operator.itemgetter(0), get_key_signature_accidentals(key))) if get_key_signature(key) < 0: symbol = 'b' elif get_key_signature(key) > 0: symbol = '#' raw_tonic_index = base_scale.index(key.upper()[0]) for note in islice(cycle(base_scale), raw_tonic_index, raw_tonic_index+7): if note in altered_notes: result.append('%s%s' % (note, symbol)) else: result.append(note) # Save result to cache _key_cache[key] = result return result
def major_unison(note: str) -> str: """Returns the major unison of the note. Raises: NoteFormatError: If the note is an invalid note.""" if not notes.is_valid_note(note): raise NoteFormatError("Invalid note: {}".format(note)) return note
def relative_minor(key): """Return the relative minor of a major key. Example: >>> relative_minor('C') 'a' """ for couple in keys: if key == couple[0]: return couple[1] raise NoteFormatError("'%s' is not a major key" % key)
def get_key_signature(key='C'): """Return the key signature. 0 for C or a, negative numbers for flat key signatures, positive numbers for sharp key signatures. """ if not is_valid_key(key): raise NoteFormatError("unrecognized format for key '%s'" % key) for couple in keys: if key in couple: accidentals = keys.index(couple) - 7 return accidentals
def __init__(self, name='C', octave=4, dynamics={}): if type(name) == str: self.set_note(name, octave, dynamics) elif hasattr(name, 'name'): # Hardcopy Note object self.set_note(name.name, name.octave, name.dynamics) if hasattr(name, 'channel'): self.channel = name.channel if hasattr(name, 'velocity'): self.velocity = name.velocity elif type(name) == int: self.from_int(name) else: raise NoteFormatError("Don't know what to do with name object: " "'%s'" % name)
def note_to_int(note): """Convert notes in the form of C, C#, Cb, C##, etc. to an integer in the range of 0-11. Throw a NoteFormatError exception if the note format is not recognised. """ if is_valid_note(note): val = _note_dict[note[0]] else: raise NoteFormatError("Unknown note format '%s'" % note) # Check for '#' and 'b' postfixes for post in note[1:]: if post == 'b': val -= 1 elif post == '#': val += 1 return val % 12
def reduce_accidentals(note): """Reduce any extra accidentals to proper notes. Example: >>> reduce_accidentals('C####') 'E' """ val = note_to_int(note[0]) for token in note[1:]: if token == 'b': val -= 1 elif token == '#': val += 1 else: raise NoteFormatError("Unknown note format '%s'" % note) if val >= note_to_int(note[0]): return int_to_note(val % 12) else: return int_to_note(val % 12, 'b')
def __init__(self, note, octaves): if note.islower(): raise NoteFormatError("Unrecognised note '%s'" % note) self.tonic = note self.octaves = octaves
def from_shorthand(shorthand_string, slash=None): """Take a chord written in shorthand and return the notes in the chord. The function can recognize triads, sevenths, sixths, ninths, elevenths, thirteenths, slashed chords and a number of altered chords. The second argument should not be given and is only used for a recursive call when a slashed chord or polychord is found. See http://tinyurl.com/3hn6v8u for a nice overview of chord patterns. Examples: >>> from_shorthand('Amin') ['A', 'C', 'E'] >>> from_shorthand('Am/M7') ['A', 'C', 'E', 'G#'] >>> from_shorthand('A') ['A', 'C#', 'E'] >>> from_shorthand('A/G') ['G', 'A', 'C#', 'E'] >>> from_shorthand('Dm|G') ['G', 'B', 'D', 'F', 'A'] Recognised abbreviations: the letters "m" and "M" in the following abbreviations can always be substituted by respectively "min", "mi" or "-" and "maj" or "ma". Example: >>> from_shorthand('Amin7') == from_shorthand('Am7') True Triads: 'm', 'M' or '', 'dim' Sevenths: 'm7', 'M7', '7', 'm7b5', 'dim7', 'm/M7' or 'mM7' Augmented chords: 'aug' or '+', '7#5' or 'M7+5', 'M7+', 'm7+', '7+' Suspended chords: 'sus4', 'sus2', 'sus47' or '7sus4', 'sus', '11', 'sus4b9' or 'susb9' Sixths: '6', 'm6', 'M6', '6/7' or '67', '6/9' or '69' Ninths: '9' or 'add9', 'M9', 'm9', '7b9', '7#9' Elevenths: '11' or 'add11', '7#11', 'm11' Thirteenths: '13' or 'add13', 'M13', 'm13' Altered chords: '7b5', '7b9', '7#9', '67' or '6/7' Special: '5', 'NC', 'hendrix' """ # warning reduce?? if isinstance(shorthand_string, list): res = [] for x in shorthand_string: res.append(from_shorthand(x)) return res if shorthand_string in ["NC", "N.C."]: return [] # Shrink shorthand_string to a format recognised by chord_shorthand shorthand_string = shorthand_string.replace("min", "m") shorthand_string = shorthand_string.replace("mi", "m") shorthand_string = shorthand_string.replace("-", "m") shorthand_string = shorthand_string.replace("maj", "M") shorthand_string = shorthand_string.replace("ma", "M") # Get the note name if not notes.is_valid_note(shorthand_string[0]): raise NoteFormatError("Unrecognised note '%s' in chord '%s'" % (shorthand_string[0], shorthand_string)) name = shorthand_string[0] # Look for accidentals for n in shorthand_string[1:]: if n == "#": name += n elif n == "b": name += n else: break # Look for slashes and polychords '|' slash_index = -1 s = 0 rest_of_string = shorthand_string[len(name):] for n in rest_of_string: if n == "/": slash_index = s elif n == "|": # Generate polychord return from_shorthand( shorthand_string[:len(name) + s], from_shorthand(shorthand_string[len(name) + s + 1:]), ) s += 1 # Generate slash chord if slash_index != -1 and rest_of_string not in ["m/M7", "6/9", "6/7"]: res = shorthand_string[:len(name) + slash_index] return from_shorthand( shorthand_string[:len(name) + slash_index], shorthand_string[len(name) + slash_index + 1:], ) shorthand_start = len(name) short_chord = shorthand_string[shorthand_start:] if short_chord in chord_shorthand: res = chord_shorthand[short_chord](name) if slash != None: # Add slashed chords if isinstance(slash, six.string_types): if notes.is_valid_note(slash): res = [slash] + res else: raise NoteFormatError( "Unrecognised note '%s' in slash chord'%s'" % (slash, slash + shorthand_string)) elif isinstance(slash, list): # Add polychords r = slash for n in res: if n != r[-1]: r.append(n) return r return res else: raise FormatError("Unknown shorthand: %s" % shorthand_string)