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