Table of Contents

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.

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