How to Use DH_MIDIMungerMIDI Message Conversion
Module
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
MIDI Message StructureTo use DH_MIDIMunger effectively, you need to have a basic understanding of the various types of MIDI messages, their functions, and their structure. Each MIDI message consists of a Status byte, which may be followed by one or more Data bytes. The Status byte identifies the message type, and the MIDI Channel. Most of the message types the DH_MIDIMunger works on have 2 Data bytes, which we will refer to as Data1 and Data2. The meaning of the data in the Data1 and Data2 bytes varies, depending upon the message type.
The table below shows how the Data1 and Data2 bytes are used for the
message types supported by DH_MIDIMunger. Note that the values range only
from 0 to 127. This is because the first bit is always 0 to identify the
Data1 and Data2 bytes as Data bytes. (A Status byte's first bit is always
1.) |
Top Index |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
In addition to these message types, DH_MIDIMunger also supports conversion to and from the multiple-message sequences used for Registered and Non-Registered Parameter Numbers (RPN and NRPN). This is discussed in more detail later in this document. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
Rules RuleYou use rules to tell DH_MIDIMunger which messages you want to change, and what changes you want to make. A rule is just a line of text containing 13 fields, separated by commas.
The 7th field has a special purpose that will be explained shortly. For
now, you can think of it as a convenient divider between the 6 Selection
fields and the 6 Action fields.
You can put a specific value in to require an exact match on a field, or you can use an asterisk (*) as a wildcard to match all values for a field that's not a selection factor. You can match on a range of values for the Data1 and Data2 fields, or put the same value in both the Min and Max fields to require an exact match. The 6 Action fields, 8 - 13 correspond to the outgoing MIDI message in
exactly the same way. An asterisk (*) in these fields means that the value
in the field is to be passed through from the incoming message unchanged.
If you enter specific values for a field, DH_MIDIMunger will change the
value of that field in the outgoing message, based on what you enter, for
all messages that match the rule. |
Top Index |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Top Index |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Here's a simple rule that selects Mod Wheel messages (Controller 1) coming in on channel 2 and changes them into Controller 10 messages on channel 1:
On the selection side of the rule, we've specified that we only want to match channel 2 Control Change messages. We're only interested in Controller 1 messages. The Controller number is in the Data1 byte of a Control Change message, so we've put a 1 in both the Min and Max of the Data1 In range. Data2 is the value to be sent to the controller. We want all CC1 messages, regardless of value, so we've used asterisks for the Data2 In range. On the action side, we've specified that the channel is to be changed to channel 1. It's still to be a Control Change message, but we put a 10 in both the Min and Max of the Data1 Out range to change it to CC10. We want the values coming in from the Mod Wheel to be passed through to CC10 unchanged, so asterisks go in the Data2 Out range.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
Input RangesYou can limit the selection of messages to those that have a Data1 or Data2 value that falls within a specific range by entering the range's minimum and maximum values in the Data1 or Data2 Min In and Max In fields. The rules below use this feature to split the keyboard between MIDI channels 1 and 2.
In a Note On message, the MIDI note
number is in the Data1 byte, and the velocity is in the Data2 byte.
The rules select Note On and Note Off messages for channel 1 where the
note number is in the range 0 - 59, and change the channel to channel 2.
Wildcards are used in the Data2 range fields, because velocity is not a
factor in the selection, and we want the velocity information to be passed
through unchanged. Messages with note numbers 60 - 127 are not
affected, so they remain on channel 1. |
Top Index |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
Output Ranges & Data InterpolationIf you specify a numeric range for the outgoing Data1 or Data2, DH_MIDIMunger will interpolate the new value within your specified range, based on the incoming value's relative position in the incoming range. For example, the following rule compresses the dynamic range of velocities:
The Rule uses wildcards for both the incoming and outgoing
Data1 ranges so that all notes will be selected, and the note numbers will
pass through unchanged. The Data2 fields map the range 1 - 127 to the
range 64 - 100, so that if the velocity in the incoming message were, say,
1/3 of the way from 1 to 127, the velocity in the outbound message would
be 1/3 of the way from 64 to 100. |
Top Index |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
DH_MIDIMunger's interpolation capabilities can also be used in some not-so-obvious ways. These 2 rules reverse the keyboard by mapping the note number range 0 - 127 to the range 127 to 0:
Not that you'd want to do this to anyone ;-) ...but you may find other applications for inversely interpolating MIDI parameters.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
The Pass Message On FlagNormally, when a message matches a rule, we want the modified message to replace the incoming message. An N in the 7th field of a rule prevents further processing of the original incoming message. No attempt will be made to match it with other rules, and it will not be output. In some situations, however, we may want an incoming message to generate more than one outgoing message. Or, we may want to keep the original incoming message in addition to any messages it generates by matching rules. In such cases, a Y in the 7th field of a rule tells DH_MIDIMunger to continue processing the original message. Here's a simple Octaver that uses the Pass Message On flag:
The rules transpose by translating the note range 0 - 115 to the range 12 - 127. Since 12 has been added to both the Data1 Min In and Data1 Max In fields to get the corresponding output values, the rules add 12 to the note number in the Data1 byte of each message matched. The "Y"s in field 7 cause both the original (unmodified) and the modified messages to be output. |
Top Index |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
Swapping Data1 and Data2Sometimes, when converting from one message type to another, you need to set the value in Data1 of the outgoing message based on the Data2 value of the incoming message, or vice versa. For example, suppose you want to use Control Change messages to generate Note Ons, with the Control Change values (in the Data2 byte of the incoming messages) determining the note numbers (in the Data 1 byte of the outgoing Note On messages). DH_MIDIMunger rules use Swap Flags of ">" and "<" for this purpose. They are added at the end of the 13 standard rule fields, separated from field 13 by the usual comma. A Swap Flag of "<" will cause DH_MIDIMunger to set the value of the
outgoing Data1 byte based on the incoming Data2 value. Similarly, a Swap
Flag of ">" will cause the value of the outgoing Data2 byte to be set
based on the incoming Data1 value. To swap both fields, use both Swap
Flags, separated by a comma. |
Top Index |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
| The following rules translate
CC20 messages to Note Ons and Note Offs. This can be used with a knob or
slider on an external controller to create a nice
glissando effect. (Depending on the patch's dynamic envelope, the Note Off
rule may be left out.)
|
Top Index |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
RPNs and NRPNs: BackgroundAs synth designers and others apply MIDI control to more and more parameters, having to work within the bounds of the original 128 Controller numbers, many of which have standard pre-assigned uses, has become very limiting. Registered Parameter Numbers (RPNs) and Non-Registered Parameter Numbers (NRPNs) open up 32,768 additional numbers (16,384 RPNs and 16,384 NRPNs) for possible use in MIDI control. The additional flexibility of RPNs and NRPNs comes at the price of
added complexity. Unlike standard Control Change messages, NRPNs use
multiple-message sequences. The topic DH_MIDIMunger Support for RPNs and NRPNs describes how
DH_MIDIMunger has been
designed to manage most of this complexity for you. It still helps to have
a basic understanding of how RPNs and NRPNs work, however.
Data values for NRPNs are sent in separate messages that follow immediately after the CC99 and CC98 messages. There are several alternatives:
So, a typical NRPN sequence would be CC99 3 This sequence sends the value 9,996 ( 78 * 128 + 12 ) The MIDI standard provides that CC99 and CC98 messages need not be repeated unless they change. Therefore, once 3 is established as the current NRPN MSB with the above sequence, the following would be a valid sequence for NRPN 501: CC98 117
|
Top Index
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
RPNs and NRPNs in SynthEditYou can assign RPNs and NRPNs to SynthEdit controls for MIDI Automation. In the screen shots below, NRPN 500 has been assigned to the Slider. Note that 98/99 - NRPN (or 100/101 - RPN) must be selected as the controller.
The MIDI Monitor displays the NRPN sequences that were generated by moving the slider. The NRPN MSB of 3 and the NRPN LSB of 116 add up to our NRPN of 500 (3 * 128 + 116) The slider will also respond to sequences like this, targeted to NRPN 500.
|
Top Index |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
DH_MIDIMunger Support for RPNs and NRPNsDH_MIDIMunger allows you to work with RPNs and NRPNs as if they were just 2 additional message types. You can change parameter numbers, convert RPNs or NRPNs to or from other message types, and interpolate data ranges without having to get involved with the underlying message sequences, MSBs and LSBs, and so on. All of this is taken care of automatically. In a rule, you use a RPN or NRPN "message type" much like the Control Change message type. The Data1 range is used for the parameter number, and the Data2 range is used for the data value. The parameter numbers and data values can range from 0 - 16383, instead of just 0 - 127. With a Message Type In of RPN or NRPN, the rule will match a RPN or
NRPN sequence. When such a sequence is detected in the input, the
parameter number and data value are calculated from the MSB and LSB fields
in its messages and matched against the rule's Data1 In and Data2 In
ranges.
CC99 26 CC99 0 The next rule converts CC1 (Mod Wheel) messages to RPN 150 messages:
There is a problem, however. This rule translates the message CC1 67 to the sequence CC101 1 Note that the wildcard character
is used in the
Data2 ranges, so there is no change in the data value. Since the RPN data
range is 0 - 16,383, this puts the value 67 in the Data Entry LSB
(CC38). The result will be that although the mod wheel is positioned just
past the half-way mark (67/127), the RPN value is only 67/16383, or 0.4%
of the total.
With this rule, CC1 67 translates to CC101 1
|
Top Index |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
Known Limitations:
|
Top Index |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
FAQ
|
Top Index |
|||||||||||||||||||||||||||||||||||||||||||||||||||||