Talking MIDI (Part 6)
Part 6. Resident software specialist Jay Chapman clears up some misleading terminology first, then moves on to relate how the MIDI protocol organises such matters as Program Changes in those humble synthesizers we all take for granted.
How are synthesizer program numbers defined internally by MIDI? Why the confusion today between 'patch' and 'program'? These points and more are answered in this sixth part of Jay Chapman's revealing series on the bits and bytes of MIDI.
This month it's time to look at the three Channel Voice messages we've not yet considered in the series ie. those with the most significant nybbles of their status bytes set to &C, &D, and &E (& signifies hexadecimal code by the way). We'll then move on to discuss the System messages whose status bytes start with &F.
The first thing I'd like to do - if only for my own benefit - is to get the terminology straight. These days I often hear the following three words used interchangeably: voice, program, patch. My understanding of these words may be different to yours so I will define them so that you know what I mean in the context of this article.
A synthesizer voice is (generally) a combination of analogue circuitry and computer hardware/software that produces a sound. A monophonic synthesizer has exactly one voice; a polyphonic synthesizer has several voices whether they must all sound the same (mono-timbral) or not (multi-timbral). The voice is directed by such controllers as the ubiquitous keyboard and pitch wheel which define various dynamic performance parameters such as pitch, trigger and/or gate. The actual timbre (tonal characteristic) of the sound produced by a voice and the degree of response to the performance controllers just mentioned is defined by the voice's program.
A program is one set of stored parameters which can be selected via front panel switches, or via MIDI; these parameters, in the simplest case, correspond to a given sound eg. 'Funky Warthog' or 'Twanged Pretzel'. Many synthesizers will offer a combination of preset and programmable parameter stores. In the latter case you will be able to edit the individual parameters making up a program. The parameters correspond to the settings of the multitude of knobs, switches and sliders that usually don't appear on the front panel of the synthesizer these days! On a multi-timbral synth, the program may also be responsible for selecting which sub-programs are selected simultaneously to define each of the different voices although this may be selected on a per-channel basis if the synth is used in Omni Off/Mono On mode.
A patch refers to the tangle of patch cords that used to look like a miniature telephone exchange on the front of Moog and Roland modular synthesizer systems. On most modern synths all of the components of the voice circuitry are permanently connected though some of the program parameters may be responsible for saying whether or not one component is allowed to influence another. The Matrix Modulation system of the Oberheim Xpander and Matrix 6 synthesizers takes this 'conceptual patching' closest to the old understanding of a 'patch' by allowing you to connect up components in a fairly arbitrary manner with the flexibility afforded by patch cords but without actually needing the cords!
So, in some senses, the word patch does not usually apply to non-modular systems. Most people manage to use this term as a synonym for program, however, which is quite understandable. The term voice is quite different from the other two, however, and this is where confusion often arises. MIDI can send the parameters forming a program from one synthesizer to another as we shall see later. If the receiving synthesizer 'understands' the details of the program's parameters (for example, a DX7 program sent to a TX7 will be 'understood'), then the actual sound produced by the voices in both synthesizers using these same program parameters will be identical at both ends. In most cases, one synthesizer can't understand the internal program details of another and there would be no point in transmitting such information between synthesizers (although computers can be used to absorb, edit and regurgitate it!).
There is often a situation where the musician wishes to use complementary voices in two or three synthesizers during a performance. For example, a particular song in the set requires Synth 1 to sound like a 'slap bass' and Synth 2 'organ'. The next song then needs 'string pad' plus 'brass stabs'. If Synth 1 is set up with 'slap bass' and 'string pad' in program memories 1 and 2 respectively, and Synth 2 with 'organ' and 'brass stabs' in its program memories 1 and 2, then life is getting a little organised for our musician. If we now connect MIDI Out on Synth 1 to MIDI In on Synth 2 and set up the synthesizers properly, we can use the Program Change message to do the dirty work of changing the programs in synchronisation for us.
In other words we should be able to select a program memory number on Synth 1 and this fact would be transmitted over MIDI via a Program Change (&Cn) message. Table 2 in last month's article suffered a slight alignment problem so I'll point out that this message is made up of two bytes of the form %1100nnnn %0ppppppp where %nnnn is the MIDI channel number (internally 0 to 15, externally 1 to 16 as usual) and %ppppppp is the program number that has just been selected on the transmitting synthesizer. So, if we select program memory number 1 the message sent out might look like %11000000 %00000001 (ie. &C0 &01) if we were transmitting on MIDI channel 1 (internal channel %0000).
When another synthesizer receives this message it will (if so enabled) select the same program. In our Synth 1/Synth 2 example above, we made sure that the contents of the program memories corresponded to the sound we required for the songs. In this way, if we select program memory 1 on Synth 1 then Synth 2 will follow suit and select its program memory 1; if we select program memory 2 on Synth 1 we obtain program memory 2 on Synth 2 and so on. With a bit of foresight and planning at least part of the live control of a bank of synthesizers during a performance is simplified. A sequencer should be able to organise program changes using the same messages of course.
There is one slight complication in the world of the MIDI Program Change message that we need to worry about for a moment or two. The new program number is held in the %ppppppp data byte which means that it can take on the values %0000000 to %1111111 (or 0 to 127 decimal). Now, I very much doubt that your synthesizer has program memories numbered 0 to 127 (or even 1 to 128...) so we need to discover the correspondence between whatever it does have and our range of data values. Briefly, a combination of reading the synthesizer's manual and a bit of experimentation is needed!
Looking at the Yamaha TX7 Expander manual as an example, we are told that we should ignore the first two bits (giving us %ppppp rather than %ppppppp) and that the remaining five bits select program numbers 1 to 32. Since we know that %00000 to %11111 represent decimal 0 to 31, we I can guess that internal program number 0 (%00000) corresponds to the external (displayed) program number 1, continuing with 1 to 2,2 to 3, ... and 31 to 32 in exactly the same manner as the coding of the MIDI channel numbers. Experimentation in this case might consist of sending &C0 &03 to the TX7 which has been set to receive on MIDI channel 1 and observing that the TX7 display shows that program 4 (think about it!) has been selected. If you are using a DX7 to drive a TX7 then selecting program number 4 on the DX7 will result in a data byte value of 3 being transmitted since there is the same conversion from external to internal numbering. As I have said before, we computer scientists count from zero and not from one like everybody else!
On quite a few synthesizers the program memories are split into banks. You might have 16 preset programs stored in each of two banks named A and B, say, and two lots of 16 programmable memories referred to as banks C and D. Typically all 64 programs will be referred to internally as program numbers 0 to 63 whereas the display will show A1, B2, or D16. With a little concentration we can guess that selecting A1 on this synthesizer would select program number 1 on a TX7 that was suitably connected over MIDI. B2 would select 18 and D16 would select 64 - if the TX7 had that many programs! In fact, the TX7 would probably select 32 when the other synth selected D16 - see if you can work out why before I give an answer at the end of the article...
The important point here is that it doesn't matter which way the correspondence works as long as you can work out what it is by experimentation. If A1 selects 16 and B16 selects 17 (unlikely, but it could happen!) then you use A1/16 and B16/17 as 'paired' memories. If in doubt connect the synthesizers via MIDI, press the program select buttons on the master instrument and note down what gets selected on the slave.
Channel Pressure is generally referred to as After-Touch. This is not wrong - but needs some qualification since Polyphonic Key Pressure (&An) is also referred to as After-Touch. In both cases there is measurement of pressure applied to the keyboard after a key/chord has been played. After-Touch permits quite a sensitive method of control and might be used to add varying amounts of vibrato or to fade in a string voice over a held piano chord, for example. Such measurement is totally unrelated to key velocity in theory, but in practice if you play a very 'heavy' (fast velocity) chord your keyboard pressure 'on arrival' maybe quite sufficient to register as After-Touch as well!
The difference between Channel and Polyphonic Pressure is well defined by their names. In the Polyphonic case it is the pressure that is exerted on individual keys that is communicated over MIDI; the relevant message (discussed last month) therefore needs a data byte to say which key is being pressed and a second byte to give the pressure measurement value. In the Channel case, only one pressure measurement over the whole keyboard is taken, so only one data byte for the one pressure value is required. For example, %11010000 %00000010 (&D0 &02) would indicate a fairly weak pressure on MIDI channel 1. There are no prizes for guessing why you will find Channel Pressure on lots of synthesizers and Polyphonic Pressure on hardly any...
A word of warning here. If you are using a sequencer to record the activity on a MIDI keyboard, watch out for hundreds of extra bytes being stored if Channel (or Polyphonic) Pressure is being transmitted. Some synthesizers, such as the DX7, transmit Channel Pressure messages even when they themselves are not at that moment programmed to respond to them. This is not a fault, by the way, because it increases the DX7's usefulness as a master keyboard; it would still have been useful to be able to disable this feature though! Having said that, most decent sequencers (eg. UMI-2B), MIDI processors (eg. Yamaha MEP4) and even some interfaces (eg. Hinton Instruments' MIDIC) will filter out extraneous messages upon request.
There is an obvious problem in terms of using up space but it is also worth considering the fact that 300 extra bytes take up a tenth of a second slot in your MIDI transmission. Other messages, such as key on/offs from the same keyboard will be interleaved with the After-Touch messages and will not themselves be badly delayed but if you have ten synthesizers under a sequencer's control and you had to send out a combination of After-Touch, Pitch-Bend, and a few Continuous Controller movements, then MIDI may get a bit overloaded. The moral of this story is: if you don't need them, don't send them; if you can't prevent sending them, filter them out along the way!
Out of all the possible controllers, the pitch wheel was considered sufficiently ubiquitous to merit a MIDI message of its own. The three byte message takes the form %1110nnnn %01111111 %0mmmmmmm where %nnnn is the MIDI channel and %1111111 and %mmmmmmm are the least and most significant bytes respectively of the latest pitch wheel position. The actual position is calculated as %mmmmmmm x 128 + %1111111 as discussed for the controllers last month. As with any Continuous Controller, the position of the wheel is sent when it changes and this means that a single pitch-bend can send hundreds of bytes flying over MIDI - see SPACE/TIME WARNING above.
Unlike other Continuous Controllers it is assumed that the pitch wheel's default position is in the centre of its possible range of movement. This is for the obvious reason that you will be able to bend up or down from the rest position. You will find that some synthesizers actually send out a Pitch Wheel Change message of &En &00 &40 when they power up to ensure that any slave synthesizers start with their pitch-bend capability set to 'centred'.
As with all Continuous Controllers the sensitivity of the slave synthesizer to controller changes is actually set in the slave synthesizer. It would be possible for the slave to allow a full pitch-bend up (final message &En &7F &7F) to cause a whole tone bend or an octave bend depending on their 'response' setting. Many synthesizers ignore the least significant byte of a Pitch Wheel Change completely.
All the messages that we have considered so far have contained a channel number as part of the status byte so that the messages could be 'routed' to devices listening on the specified channel. As we already know, all messages transmitted on one MIDI daisy chain will be heard by all devices connected to that daisy chain (unless some device filters messages out). Any device (or part-device) that hears a message whose channel number does not correspond to its own simply ignores the message. Similarly, if a message is on the correct channel but the synthesizer cannot respond (because it doesn't 'understand' Polyphonic Pressure messages for example), then it also ignores the message.
System messages are those that all devices on the MIDI network need to listen for and respond to if they can. Their transmission and reception is quite independent of the 'routing' mechanism provided by MIDI channels so they do not have the least significant nybble (LSN) encoded as a channel number - this field acts as the message type instead. All the System messages start with a most significant nybble of &F and are divided into two groups according to the state of the left-most bit of the LSN. Table 1 shows those with this bit turned off (System Common messages).
As can be seen from Table 1, three of the possible eight combinations of bit patterns (from %11110xxx) are undefined. It is probably not a good idea to use these patterns for your own nefarious purposes, however, because they may be used in a later MIDI specification. If you need some messages of your own then use the spare Controller messages (see last month's article) intended for such use.
Tune Request is intended to be used where there are analogue synthesizers on the MIDI network which may need to be told to retune their oscillators every now and again. Perhaps a sequencer could send out Tune Request commands at sensible intervals when such synthesizers were going to be unused in the song for the necessary amount of time.
The Song Select message is used when some devices on the MIDI network may be capable of storing information about several different 'songs'. Typical devices would be sequencers and drum machines. A drum machine may have songs which define different groups and sequences of internally recorded drum patterns for example. Before starting a song, a master sequencer (or even a human performer!) can cause all such devices to select the same song information by sending a Song Select message with the song number encoded in the single data byte eg. %11110011 %00000010 would select the third song (0,1,2,...).
Having selected the song, it may not be the case that we want to commence playing from the start. Time is measured in MIDI terms at 24 clocks per crotchet and the current position within a song is measured in terms of intervals called MIDI beats, each made up of 6 MIDI clocks (more on MIDI timing next month). MIDI beats therefore correspond musically to sixteenth notes. Any device that understands song positions will have an internal register that counts MIDI beats during recording or playback so that any point in a song can be identified to a resolution of one sixteenth note. The Song Position Pointer message simply allows the contents of the internal song pointer register to be set to some value which is encoded in the pair of data bytes. The maximum size of a song can be easily calculated: the smallest Song Position Pointer is 0 and the largest is 127 x 128 + 127 (two seven bit data bytes) = 16383, which is more than 4000 bars of rock 'n' roll!
The System Exclusive Start and End messages are proving to be a very powerful feature of the MIDI protocol and deserve more space than there is available this month, so you'll have to fork out for next month's Sound On Sound to find out what they're all about! We'll also look at the last set of MIDI messages that we haven't yet dealt with: System Real-Time.
P.S. The following explains why the Yamaha TX7 selects program 32. Selecting D16 on the master synthesizer would cause a Program Change message of the form %11000000 %00111111 to be sent to the TX7. The second byte holds the value 63 which is the internal coding of the 64th program number on the master synthesizer. That is, assuming the programs are stored in the order: A1 to A16, B1 to B16, C1 to C16, D1 to D16, then D16 is the 64th program. The TX7 ignores all but the least significant five bits so that the bit patterns %00000000 to %00011111, %00100000 to %00111111 and %01000000 to %01111111 all appear to the TX7 as %00000 to %11111. In other words, any program number greater than 31 will effectively have 32 subtracted from it until it is in the range 0 to 31. Thus program D16 becomes internal 63 which is sent out as a 'change program to 63' message. The TX7 interprets this as 'change to internal 31 ' (ie. 63-32 = 31) and displays it as program number 32. So now you know!
Feature by Jay Chapman
Previous article in this issue:
Next article in this issue:
mu:zines is the result of thousands of hours of effort, and will require many thousands more going forward to reach our goals of getting all this content online.
If you value this resource, you can support this project - it really helps!