[gmpi] Re: MIDI: Common event coding

  • From: "Ron Kuper" <ronkuper@xxxxxxxxxxx>
  • To: <gmpi@xxxxxxxxxxxxx>
  • Date: Tue, 22 Jun 2004 21:41:44 -0400

Tasty.  Hmm.  Yummy.  Good.  (Bowing down.)

----- Original Message ----- 
From: "Chris Grigg" <gmpi-public@xxxxxxxxxxxxxx>
To: <gmpi@xxxxxxxxxxxxx>
Sent: Tuesday, June 22, 2004 8:27 PM
Subject: [gmpi] MIDI: Common event coding


> PROPOSAL:
> GMPI as Addresses, Opcodes, and Operands
> 
> This proposal is intended to find a common coding for GMPI events 
> that neither privileges nor disadvantage either an OSC-style 
> paths/events approach or a MIDI message approach, permits the host to 
> fully manage plug message history, and also permits arbitrary routing 
> and processing of MIDI messages per se.
> 
> Contents
> 1. General Concepts
> 2. MIDI as Addresses, Opcodes, and Operands
> 3. Strawman Opcode Assignments
> 4. GMPI Messages Beyond MIDI
> 
> 
> 1. General Concepts
> 
> Messages - In the general case, all GMPI event types (set parameter, 
> launch note, etc.) can be considered as messages.  Even if fields are 
> actually communicated to plug via separate function parameters. 
> Exact format unimportant now.  Each message to contain one opcode, 
> one address, and any number of operands.
> 
> Opcodes as Integers - The set of event types will be small initially, 
> but able to expand hugely in future.  So events types can be coded as 
> integers.  Call these event type codes opcodes.  These numbers are 
> assigned in the spec, and universal across all of GMPI.  We put 
> opcodes in the actual messages, not text like 'set'
> 
> Addresses as Indexes - All GMPI plugs expose all commands & 
> parameters as list of OSC-style paths/addresses.  (MIDI plugs not a 
> special case.)  In this map, plug publishes a number for each exposed 
> path.  Call these paths addresses (within the plug).  These numbers 
> only have relevance for that plug instance.  This Params list is 
> rebuilt whenever plug reconfigures parameter set.
> 
> Operands - Depending on event type, zero or more operands are also in 
> the message.  Operand count and data type of each depends on the 
> event type.
> 
> So a general case message looks like this:
> 
> { <address> <opcode> [<operand> ... ] }
> 
> Example:
> If a plug exports this parameters map:
> 
> 1 /mode
> 2 /program
> 3 /inputGain
> 4 /outputGain
> 5 /sidechain/gain
> 6 /sidechain/filterCutoffFreq
> 
> Then the OSC-style-notated event "/sidechain/filterCutoffFreq 
> set 3500.9" is losslessly expressed in the form (assuming opcode for 
> 'set' is 2):
> 
> { <address: index 6> <opcode: 2> <operand: float( 3500.9 )> }
> 
> So GMPI hosts route these binary messages to plugs, can parse them in 
> a unified way, and therefore hosts have full access to each plug's 
> received message history.  All OSC-style semantics are still present, 
> especially at connection establishment time when they're most needed, 
> but there is no longer any need for literal OSC-style path text in 
> the actual event messages (good, since plugs now operate on ints, not 
> strings).
> 
> 
> 2. MIDI as Addresses, Opcodes, and Operands
> 
> All MIDI messages can also be losslessly encoded in the same form, as 
> <address> <opcode> [<operand> ...].  This requires un-binding 
> address, opcode, and operand parts from MIDI message, per the 
> unpacking required by each MIDI message type, and then re-assembling 
> the parts in the common GMPI message format.  Fortunately, the rules 
> for doing this are simple.  A detailed proposal appears below, 
> accounting for all defined MIDI message types.
> 
> This re-packaging allows the host to track all MIDI messages equally 
> well as any other GMPI messages -- because at the message level, 
> there is no difference between MIDI-originated messages and any other 
> GMPI message.  If the operand fields are, e.g. floats, then values 
> and ranges can express all MIDI msgs, but also transcend the MIDI 
> limits (integer, 7-bit, 14-bit, etc.).  And non-MIDI plugs are not 
> bound in any way by the native MIDI limitations on addressing, 
> parameter set, parameter datatype, etc.
> 
> 
> 2. 1. MIDI as Addressing
> 
> There are five forms of address used in MIDI: Whole-Unit Addressing, 
> Recipient ID Addressing, Channel Number Addressing, Channel Plus Key 
> Number Addressing, and Channel Plus Control Number Addressing.  Each 
> is first explained, then mapped to the proposed GMPI message model.
> 
> 2.1.1. Whole-Unit Addressing - Many messages implicitly address the 
> receiver as a whole unit:
> - System Real Time group (Timing Clock, Start, Continue, Stop, Active 
> Sensing, System Reset)
> - System Common group (MTC QuarterFrame, Song Position Pointer, Song 
> Select, Tune Request, End of SysEx
> - Manufacturer SysEx (may be internally addressed further, but in the 
> general case contents are opaque)
> 
> In GMPI, the 'whole unit' is probably the plug itself. These can be 
> represented by the path "/", which could be required in all parameter 
> maps, or could be inferred as a general GMPI rule.
> 
> 2.1.2. Recipient ID Addressing - Universal Real Time SysEx and 
> Universal Non-Real Time Sysex usually but not always have an explicit 
> recipient ID (can be 'broadcast' but will be used only by a specific 
> receiver, per user-assigned instance ID)
> 
> If plug Recipient ID can be set at graph config time, the Recipient 
> ID in the message may be redundant to routing and ignorable in the 
> address field, however the whole message including Recipient ID is 
> still delivered, as an operand.
> 
> 2.1.3. Channel Number Addressing - Some messages use only channel 
> number (0-15): Note On, Note Off, Channel Aftertouch, Program Change, 
> Pitch Bend Change
> 
> The channel number can be directly used as the message address when 
> MIDI is initially received; when making connections, the host merely 
> replaces the incoming MIDI channel number with the target parameter 
> index (per target plug's map).
> 
> 2.1.4. Channel Plus Key Number Addressing - Poly Aftertouch has both 
> channel & key number
> 
> Channel number plus 'pressure' can be used as the address, key number 
> should be translated to a note-id operand.
> 
> 2.1.5. Channel Plus Control Number Addressing - Control Change has 
> both channel & control number
> 
> Channel number and control number can be combined into a slashed address.
> 
> 
> 2.2. MIDI as Opcodes
> 
> This section details how every MIDI message type would be losslessly 
> converted to and from the proposed GMPI message model.  The MIDI 
> status bytes are shown for reference only, they would not be used 
> literally as the GMPI message opcodes; see section 3. Strawman Opcode 
> Assigments.  Gesture ID's are shown as optional operands where 
> appropriate.
> 
> 0x8n, 0x9n - Note On & Note Off - These are 'command' opcodes of some 
> kind -- that needs to be reconciled with 'pure GMPI' note concepts, 
> however those don't exist yet.  May be combined into one opcode, 
> maybe separated, but address would be channel n, with pitch-oriented 
> operand(s) , and probably some note-id operand.  For an event that 
> originated as a MIDI message, the literal MIDI message could be 
> included as the last operand.
> 
> strawman:
> <address: /channel> <opcode: note> <operand1: note-id> 
> [<operand2: pitchSomething>] [<operand3: gateOnOrOff>] [<operand3: 
> gesture-id>] [<operand4: MIDI>]
> 
> 0xAn, 0xDn - Polyphonic Aftertouch & Channel Aftertouch - These can 
> both use the 'set' opcode addressed to parameter 'pressure' in 
> channel n, but the operand set is different.  Poly aftertouch has an 
> extra operand for the target note-id. One pressure operand, either 
> way.  For an event that originated as a MIDI message, the literal 
> MIDI message could be included as the last operand.
> 
> channel:
> <address: index of /channel/pressure> <opcode: set> 
> <operand1: pressure-value> [<operand2: gesture-id>] [<operand3: MIDI>]
> poly:
> <address: index of /channel/pressure> <opcode: set> 
> <operand1: note-id> <operand2: pressure-value> [<operand3: 
> gesture-id>] [<operand4: MIDI>]
> 
> 
> 0xBn- Control Change & Channel Mode - This can use the 'set' opcode 
> addressed to the indicated parameter within channel n.  One value 
> operand.  For an event that originated as a MIDI message, the literal 
> MIDI message could be included as the last operand.  Note: .
> 
> <address: index of channel/selected-parameter> <opcode: set> 
> <operand1: control-value> [<operand2: gesture-id>] [<operand3: MIDI>]
> 
> 0xCn - Program Change - This can use the 'set' opcode addressed to 
> parameter 'program' channel n.  One value operand.  For an event that 
> originated as a MIDI message, the literal MIDI message could be 
> included as the last operand.
> 
> <address: index of channel/program parameter> <opcode: set> 
> <operand1: control-value> [<operand2: gesture-id>] [<operand3: MIDI>]
> 
> 0xEn - Pitch Bend Change - This can use the 'set' opcode addressed to 
> parameter 'pitchBend' in channel n (subject to final design of GMPI 
> note & pitch model).  One value operand, either way.  For an event 
> that originated as a MIDI message, the literal MIDI message could be 
> included as the last operand.  Note: pitchBendDepth should be a 
> 'well-known control'.
> 
> <address: index of channel/pitchBend parameter> <opcode: set> 
> <operand1: control-value> [<operand2: gesture-id>] [<operand3: MIDI>]
> 
> Note, we could also go beyond MIDI and introduce a 
> per-note-id pitch bend, by adding a note-id operand:
> <address: index of channel/pitchBend parameter> <opcode: set> 
> <operand1: note-id> <operand2: control-value> [<operand3: 
> gesture-id>] [<operand4: MIDI>]
> 
> 
> The remaining MIDI message types do not currently have an obvious 
> natural parallel in GMPI, yet .may. be meaningful to MIDI devices or 
> plugs, so no attempt is made to transcode the contents.  Fortunately 
> the addressing is clear.
> 
> 0xF0 - System Exclusive - This is a 'command' operation addressed to 
> the whole plug. One operand, the literal MIDI message.  Likely 
> deserves a separate 'SysEx command' opcode.
> 
> <address: index of '/'> <opcode: sysEx> <operand1: MIDI> 
> [<operand2: gesture-id>]
> 
> 
> 0xF1 - MTC Quarter Frame - This is a 'command' opcode addressed to 
> the whole plug. One operand, the literal MIDI message.
> 
> <address: index of '/'> <opcode: mtcQuarterFrame> <operand1: MIDI>
> 
> 
> 0xF2 - Song Position Pointer - This is a 'set' opcode addressed to 
> the whole plug.  One operand, the literal MIDI message.
> 
> <address: index of '/'> <opcode: songPositionPointer> <operand1: MIDI>
> 
> 
> 0xF3 - Song Select - This is a 'command' opcode  addressed to the 
> whole plug.  One operand, the literal MIDI message.
> 
> <address: index of '/'> <opcode: songSelect> <operand1: MIDI>
> 
> 
> 0xF6 - Tune Request - This is a 'command' opcode  addressed to the 
> whole plug.  One operand, the literal MIDI message.
> 
> <address: index of '/'> <opcode: tuneRequest> <operand1: MIDI>
> 
> 
> 0xF7 - End of System Exclusive - This should not normally result in a 
> message, as it merely signals end of a sys ex, but could be supported 
> for ultra-pure MIDI bytestream transparancy, e.g. 0xF7 when no sysex 
> has been started.
> 
> <address: index of '/'> <opcode: endSystemExclusive> 
> <operand1: MIDI> [<operand2: gesture-id>]
> 
> 
> 0xF8 - Timing Clock - This is a 'command' opcode  addressed to the 
> whole plug.  One operand, the 1-byte MIDI message.
> 
> <address: index of '/'> <opcode: timingClock> <operand1: MIDI>
> 
> 
> 0xFA - Start - This is a 'command' opcode  addressed to the whole 
> plug.  One operand, the 1-byte MIDI message.
> 
> <address: index of '/'> <opcode: start> <operand1: MIDI>
> 
> 
> 0xFB - Continue - This is a 'command' opcode  addressed to the whole 
> plug.  One operand, the 1-byte MIDI message.
> 
> <address: index of '/'> <opcode: continue> <operand1: MIDI>
> 
> 
> 0xFC - Stop - This is a 'command' opcode  addressed to the whole 
> plug.  One operand, the 1-byte MIDI message.
> 
> <address: index of '/'> <opcode: stop> <operand1: MIDI>
> 
> 
> 0xFE - Active Sensing - This is a 'command' opcode  addressed to the 
> whole plug.  One operand, the 1-byte MIDI message.
> 
> <address: index of '/'> <opcode: activeSensing> <operand1: MIDI>
> 
> 
> 0xFF - System Reset - This is a 'command' opcode  addressed to the 
> whole plug.  One operand, the 1-byte MIDI message.
> 
> <address: index of '/'> <opcode: systemReset> <operand1: MIDI>
> 
> 
> 3. Strawman Opcode Assignments
> 
> 0 No operation
> 1 Note
> 2 Set
> 3 System Exclusive
> 4 MTC Quarter Frame
> 5 Song Position Pointer
> 6 Song Select
> 7 Tune Request
> 8 End of System Exclusive
> 9 Timing Clock
> 10 Start
> 11 Continue
> 12 Stop
> 13 Active Sensing
> 14 System Reset
> 15-infinity: Reserved for GMPI expansion
> 
> 
> 4. GMPI Messages Beyond MIDI
> 
> There is no limit to adding addresses, further opcodes, or further 
> operand datatypes as needed for either the initial, or any future, 
> version of GMPI.
> 
> ..end..
> 
> ----------------------------------------------------------------------
> Generalized Music Plugin Interface (GMPI) public discussion list
> Participation in this list is contingent upon your abiding by the
> following rules:  Please stay on topic.  You are responsible for your own
> words.  Please respect your fellow subscribers.  Please do not
> redistribute anyone else's words without their permission.
> 
> Archive: //www.freelists.org/archives/gmpi
> Email gmpi-request@xxxxxxxxxxxxx w/ subject "unsubscribe" to unsubscribe
> 

----------------------------------------------------------------------
Generalized Music Plugin Interface (GMPI) public discussion list
Participation in this list is contingent upon your abiding by the
following rules:  Please stay on topic.  You are responsible for your own
words.  Please respect your fellow subscribers.  Please do not
redistribute anyone else's words without their permission.

Archive: //www.freelists.org/archives/gmpi
Email gmpi-request@xxxxxxxxxxxxx w/ subject "unsubscribe" to unsubscribe

Other related posts: