def note_to_midi(note: Note) -> int: """Returns the midi value corresponding to the given `Note`.""" c0_code = 12 name, octave = note name, shift = split_to_base_and_shift(name, name_before_accidental=True) for candidate, offset in zip(MAJOR_FROM_C, MAJOR_SCALE_OFFSETS.values()): if name == candidate: return c0_code + offset + shift + 12 * octave raise InvalidNote(name)
def _chord_options_triad_with_lower_note(lower_note, upper_triad, _rec): bass_degree = semitone_to_degree_options(12 - lower_note)[0] upper_triad_shifted = [semitone - lower_note for semitone in upper_triad] options = [ "{}/{}".format(option, bass_degree) for option in semitones_to_chord_name_options(set(upper_triad_shifted), _rec - 1) ] base_degree, _ = split_to_base_and_shift(bass_degree, name_before_accidental=False) return [ option for option in options if bass_degree not in option or "(no{})".format(base_degree) not in option ]
def _name_options_triad_with_lower_note( lower_note: int, upper_triad: Iterable[int], _rec: int ) -> List[str]: """ Returns possible names for a triad with a lower note (a bass note) """ bass_degree = semitone_to_degree_options(12 - lower_note)[0] upper_triad_shifted = [semitone - lower_note for semitone in upper_triad] options = [ f"{option}/{bass_degree}" for option in semitones_to_name_options(set(upper_triad_shifted), _rec - 1) ] base_degree, _ = split_to_base_and_shift(bass_degree, name_before_accidental=False) return [ option for option in options if not (bass_degree in option and f"(no{base_degree})" in option) ]
def test_split_to_base_and_shift_after(item, base, shift): assert split_to_base_and_shift(item, name_before_accidental=True) == (base, shift)
def test_split_to_base_and_shift_before(item, base, shift): assert split_to_base_and_shift(item, name_before_accidental=False) == (base, shift)