====== MIDI to OSC mapping - Draft v0.1 (pre-alpha) - 2012-03 ====== Initial author: Emanuel Rumpf ===== Purpose ===== OSC (open sound control) is a protocol for exchange of arbitrary (media) data over TCP/IP or UDP/IP between a server and client application. \\ Currently there is no consensus how to represent and address MIDI data over OSC. \\ This document is a draft / brainstrom for transmission of MIDI data in a standardized way using the OSC protocol. \\ \\ The point: You could implement a transmitter, being sure that each receiver following this spec would be able to play back the received midi data without further configuration. \\ \\ Everyone is welcome to improve / implement this. \\ ==== Related Links ==== * [[http://opensoundcontrol.org/introduction-osc| OSC]] * [[http://liblo.sourceforge.net/| liblo OSC library]] * [[http://das.nasophon.de/pyliblo/| liblo Python Binding]] * [[http://das.nasophon.de/pyliblo/API.html| liblo Python API]] * [[http://www.blitter.com/~russtopia/MIDI/~jglatt/tech/midispec.htm| MIDI Spec. ]] ===== Draft v0.1 ===== ==== Address Scheeme ==== / ApplicationName / ApplicationSection / midi (keyword) / channel (keyword) / ch-nr. / midi-msg-type / midi-msg-name (see midi-actions) \\ Strings not-required default to "none" \\ \\ **example (using python, liblo):** target = liblo.Address( 1234 ) # play a C note (60) at channel 0 with velocity (loudness) of 112 liblo.send( target, "/osc_receiver01/none/midi/channel/#0/note_on/none", 60, 112 ) # change expression-controller on channel 0 to 117 (dec) liblo.send( target, "/osc_receiver01/none/midi/channel/#0/controller_change/expression", 117 ) === Access by Number === If access by number is possible (e.g. controller names, channels), the related number can be used \\ by prefixing with # for decimal values or by #0x for hex values. \\ \\ example: \\ # send a controller_change event for expression (value 11) liblo.send( target, "/osc_receiver01/none/midi/channel/#0/controller_change/expression", 117 ) # value # alternatives with numbers: liblo.send( target, "/osc_receiver01/none/midi/channel/#0/controller_change/#11", 117 ) liblo.send( target, "/osc_receiver01/none/midi/channel/#0/controller_change/#0x0B", 117 ) === Fine / Coarse values === \\ MIDI distinguishes fine and coarse control. \\ If not specified, coarse is default. \\ Coarse and fine can be combined. (2 bytes coarse, followed by 2 bytes fine). \\ \\ # fine / coarse liblo.send( target, "/osc_receiver01/none/midi/channel/#0/controller_change/expression_coarse", 117 ) liblo.send( target, "/osc_receiver01/none/midi/channel/#0/controller_change/expression_fine", 18 ) # combined: liblo.send( target, "/osc_receiver01/none/midi/channel/#0/controller_change/expression_combi", (117 << 16) & (18) ) ==== Values ==== All values are transmitted as **integer 32 bit** unsigned values (allowing a higher precision than MIDI for the future) ==== MIDI message types ==== (midi messages usually consist of 1 to 3 values (bytes) ) (hex) 8 = note_off 9 = note_on A = aftertouch (ie, key pressure) B = controller_change C = program_change D = channel_pressure E = pitch_wheel ** additions ** sysex start stop continue mode file ==== MIDI message-names (controller-names) for the message-type "control_change" ==== \\ **control_change messages** \\ (dec) 0 bank_select (coarse) 1 modulation_wheel (coarse) 2 breath_controller (coarse) 4 foot_pedal (coarse) 5 portamento Time (coarse) 6 data_entry (coarse) 7 volume (coarse) 8 balance (coarse) 10 pan position (coarse) 11 expression (coarse) 12 effect_control_1 (coarse) 13 effect_control_2 (coarse) 16 general_purpose_slider_1 17 general_purpose_slider_2 18 general_purpose_slider_3 19 general_purpose_slider_4 32 bank_select (fine) 33 modulation_wheel (fine) 34 breath_controller (fine) 36 foot_pedal (fine) 37 Portamento Time (fine) 38 Data Entry (fine) 39 Volume (fine) 40 Balance (fine) 42 Pan position (fine) 43 Expression (fine) 44 Effect Control 1 (fine) 45 Effect Control 2 (fine) 64 Hold Pedal (on/off) 65 Portamento (on/off) 66 Sustenuto Pedal (on/off) 67 Soft Pedal (on/off) 68 Legato Pedal (on/off) 69 Hold 2 Pedal (on/off) 70 Sound Variation 71 Sound Timbre 72 Sound Release Time 73 Sound Attack Time 74 Sound Brightness 75 Sound Control 6 76 Sound Control 7 77 Sound Control 8 78 Sound Control 9 79 Sound Control 10 80 General Purpose Button 1 (on/off) 81 General Purpose Button 2 (on/off) 82 General Purpose Button 3 (on/off) 83 General Purpose Button 4 (on/off) 91 Effects Level 92 Tremulo Level 93 Chorus Level 94 Celeste Level 95 Phaser Level 96 Data Button increment 97 Data Button decrement 98 Non-registered Parameter (fine) 99 Non-registered Parameter (coarse) 100 Registered Parameter (fine) 101 Registered Parameter (coarse) 120 All Sound Off 121 All Controllers Off 122 Local Keyboard (on/off) 123 All Notes Off 124 Omni Mode Off 125 Omni Mode On 126 Mono Operation 127 Poly Operation ==== System Exclusive "SysEx" Messages ==== # integer values, first is count of elements (incl. length value) ! blob = [0, 8, 15, 16, 23, 42] # set length blob[0] = len( blob ) # send liblo.send( target, "/osc_receiver01/none/midi/channel/#0/sysex/none", blob ) ==== Standard MIDI file transmission (SMF) ==== TODO