Skip to content

Instantly share code, notes, and snippets.

@coxevan
Last active May 31, 2021 01:44
Show Gist options
  • Save coxevan/1a4b9ce8540abd8238bde0df962f6489 to your computer and use it in GitHub Desktop.
Save coxevan/1a4b9ce8540abd8238bde0df962f6489 to your computer and use it in GitHub Desktop.
Python script that'll convert MIDI message strings to channel number (G#1 -> 44)
'''
Convert midi message into number
C-2 -> 0
G8 - 127
Supports Korg/Roland/synths with alternative starting octaves
* Example: In korg/roland synths, the low C is C-1(#0) and high G is G9(#127)
'''
_NOTES = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
def midi_to_note_number(midi:str, octave_min=-2):
"""
Given a midi note string, return that notes channel number
* Note - kwarg 'octave_min' should be used when the minimum octave count for your keyboard/controller/synth etc.
is known and not equal to the default value: -2
Examples here are KORG and Roland synths
:param str midi: A string that holds note, accidental and octave ex. C#1
:param int octave_min: Optional, minimum octave of the note range.
:return: int
"""
note_index, octave = _get_note_parts(midi)
normalized_octave = octave_min - octave
return abs(normalized_octave * 12) + note_index
def _get_note_parts(midi:str):
"""
Given a midi note, get its note and octave
Note conversion example
C-2 -> 0, -2
C#-2 -> 1, -2
...
E0-> 4, 0
...
B4 -> 11, 4
etc..
:param str midi: A string that holds note, accidental and octave
:return: [note: int, octave: int]
"""
if '#' in midi:
note = midi[:2]
octave = int(midi[2:])
else:
note = midi[0]
octave = int(midi[1:])
try:
note_index = _NOTES.index(note)
except ValueError:
raise RuntimeError('Invalid midi note passed. {0}. '
'Must match convention <note><accidental><octave> (ex. C#-1)'.format(midi))
return note_index, octave
if __name__ == '__main__':
# tests
print("Midi Note Conversion Tests: ")
print(midi_to_note_number("G#1"))
print(midi_to_note_number("C-2") == 0, midi_to_note_number("G8") == 127)
print("Midi Note Conversion Tests: octave min = -1")
print(midi_to_note_number("G#1", octave_min=-1))
print(midi_to_note_number("G9", octave_min=-1))
print(midi_to_note_number("C-1", octave_min=-1) == 0, midi_to_note_number("G9", octave_min=-1) == 127)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment