Classic Computer Magazine Archive ST-Log ISSUE 33 / JUNE 1989 / PAGE 64

(or: Yep, It's Got MIDI. So What?)


This article will show you one way to use the MIDI Out port on your ST. I'm assuming that you have a Roland Juno 106 synthesizer and at least one MIDI cable. Even if you don't, the information here will help you better understand the arcane world of MIDI system exclusive codes.

One of the most unfortunate things about the J-106 is that, once you've programmed a voice, it's gone. Sure, it's still in memory, but can you remember which parameter is affecting what? That makes tweaking parameters a matter of guesswork, because it's not always clear what modulator is creating which effect. And fine-tuning parameters is nearly impossible with analog sliders.

The answer, of course, is to spend a hundred bucks on a patch editor/librarian that will let you program the synth from your ST and store hundreds of extra patches on disk. But a hundred bucks could probably be used for more useful things. And wouldn't it be fun to get your hands dirty?

The fact is that you can easily (and I mean easily) put together a simple program that will let you specify exactly what values to assign to which parameters.

In addition, if you have a sequencer that allows you to transmit system-exclusive information, you can embed not just program changes, but complete programs in your sequences. That means that if your J-106's memory gets wiped, you'll still be able to play your sequences with the original voices.

The brass tacks

Because the Juno 106 has such a rudimentary voice structure, it doesn't take a lot of numbers to set up a sound. So the real work is figuring out the MIDI patch-dump command sequence. The inside back cover of the J-106 owner's manual gives the whole MIDI implementation. For the purposes of this article, we're interested only in "Part 3: Exclusive Messages."

When we want to send system-exclusive data to the J-106, we have to transmit a certain series of commands before we send the data, and then we have to know what the order of the parameters is. But before we mess around with control codes, we have to make sure that the J-106 is set up to receive them. The first step is to set the function switch on the back of the machine (off to one side of the MIDI terminals) to III; that is, all the way away from the terminals. Now the J-106 will accept controllers, notes and system-exclusive data.

Next check to see what channel the J-106 is set to transmit and receive on. Remember this number. Write it down.

In Section 3.1 of the "Exclusive Messages" section on the MIDI Implementation page of the J-106 owner's manual, you'll see a column of letters, binary numbers, hexadecimal equivalents and a short description of what all of the above mean. Because the numbers are in hexadecimal, and the MIDI Outs like to have data sent through in decimal, we'll have to translate from hex into decimal notation. It's a good idea to learn how to do this. If you're not sure, I've included decimal equivalents for the hex codes, and there's a sidebar for converting binary to decimal numbers.

  1. $F0 (240)—This is the value that tells the J-106 to expect system-exclusive data.
  2. $41 (65)—Tells the J-106 that the data is coming from a Roland machine—which is not exactly the case. The data is coming from an Atari ST speaking "Rolandese."
  3. $30 (48)—Tells the J-106 to expect all parameters for a single voice.
  4. $00-$0F (0-15)—This number is equal to whatever channel on which the J-106 is set to respond minus 1. Even though the display reads 1-16, the machine will expect a number between 0 and 15. So when you press the MIDI Channel button, subtract 1 and enter that number here. For example, if the display reads 3, then enter 2.
  5. $nn—The source of the data. Not terribly important for our purposes. Set it to 0 and forget about it.
  6. The next 18 numbers are the actual program data. More on this below.
  7. $F7 (247)—This tells the J-106 that the data transmission has concluded. In effect, it hangs up the system-exclusive telephone line.

Program Data: Section 3.4 of the MIDI Implementation gives a complete rundown of the order of parameters. In typical lab-coat fashion, they list them from 0 to 17. If it helps to think of them in terms of 1-18, go ahead. All it means is that the first number you send will set the LFO Rate, the second will set the LFO Delay Time, etc. I recommend that you make a chart such as the one below.

LFO Rate =
LFO Delay =
Noise Level =
VCF Cutoff =
Resonance =
VCA Level =
Attack Rate =
Decay Rate =
Sus Level =
Release Rte =
Sub 0sc Lvl =

Easy, huh? Just send the first bunch of information numbers, then plop in some parameter values, and you've almost got a complete voice. But now comes the tricky part.

Listed above are only 16 parameters. Chorus, wave, range and a few other settings are missing. The reason is bit-mapping of parameters. (For more on bit-mapping, see the sidebar.) It's a lovely concept, but considering that there are so few parameters in the J-106 voice, I wonder why they were so desperate to save such a small amount of memory. The fact is that the machine uses just over 2K of memory, and bit-mapping only saves about 1K.

The layout for the 17th parameter is shown in Figure 1. So if we want Chorus 1 on, we have to set the left-most two bits like this: 10. The left bit set to 1 means that Chorus 1 is selected, and the other bit turns it on. Obviously, if you set the second bit to 1 (OFF), then it won't matter which chorus you've selected with the first bit.

We turn the SAW wave on by putting a 1 to the right of the first two bits. Combined with the chorus data, this is how our byte looks so far: 101.

We want the pulse wave OFF, so we put a 0 into the fourth position: 1010.

The last three bits set the range. If we want an eight-foot range, we set the last three bits to 010. The whole seven-bit parameter now looks like this: 1010010. When we run this number though the brain-mill we get a value of 82.

The procedure for the last byte of data is much the same, only easier. The left-most bits set the high-pass filter. The next bit toggles the VCA from gate to ENV follow mode; the next sets the envelope polarity; and finally, the right-most bit sets the PWM source to either manual or LFO, as shown in Figure 2.

In this case, a setting of 01110 would indicate that Filter 2 was being used, the VCA was set to gate, the envelope polarity is negative, and the LFO is the pulse-width modulation source. We throw this into the magic binary blender and come out with a decimal value of 14. Now that the work is over, it's a simple matter to dream up a patch, load your sequencer and throw that data in. The procedure is virtually the same for both GFA and ST (gag) BASIC.

Listing 1 is a simple program written in GFA BASIC that you can use to send patch data. As I mention in the sidebar, I hate programming. So if you want a flowery user-interface with bells and whistles, go ahead. This little program simply gets the job done.

Using this sort of a procedure to program your synth, you can exercise bit-resolution control over the parameters. You can fine-tune a sound until it's just right.

But don't forget: Once you've got a winner, print it out on paper or write the values into a voice chart. And whatever you do, don't forget to save the sound in the synth's memory. (And you do keep a memory map regularly updated, don't you?)

If you have a sequencer that will allow you to send system-exclusive data, you've got it made. Simply go into event edit, and insert the access codes, the parameters and, finally, the F7 EOX command. For the MIDI Recording Studio from Dr. T., Figure 3 is how the whole sequence would look.

When you're just jamming, the front panel is fine. And when you're under the red light, you don't want to waste time doing decimal conversions. However, there is no better way to make sure that your sounds are repeatable than to send them to the synth each time you play the song.

Leaving the patch inside the synth is fine until your battery dies. Or until someone accidentally spills beer onto it. Or until you write over it while doodling one day.

Besides, I've found that analog sliders simply do not have 127-value resolution. Working digitally, you know exactly what parameter has exactly what value. Short of buying a full-fledged librarian (simply a splurge for the struggling student), this is the best way to control your patches.

I've included some of my favorite programs in Figure 4 for use in this format. Try them out, tweak them parameters and have fun! Just remember, each time you send the data, you must first send the five identification bytes, the 18 parameters and the EOX Byte.

Decoding Binary

Time for a revelation: I hate programs. Debugging bugs me. So instead of writing a program to convert numbers from one base to another, I've learned how to do it in my head. For those of you who still need to figure out how to get from a binary string like 01011101 to the decimal number 93, here's a quick lesson.

We've become so accustomed to the decimal system of numbers that it's difficult to really understand how numbers work and what they mean. The number 285, for example, is automatically understood to mean. . .well. . .285. But what it really means is this:

2 × 102 + 8 × l01 + 5 × 10°

We understand that the 2 represents the value of 2 multiplied by 10 to the second power.

If this is all clear so far, you won't have any problem with binary. If it makes your head feel like arythmic tapioca, don't worry. It took me most of tenth grade to figure this out.

Now when we get a binary, the rules are the same—only the numbers have changed. Instead of going from 0 to 9 before we skip to the next place to the left, we only have 1s and 0s. And instead of 10, the base number is 2. But the exponents are always the same. The right-most position is 2 to the zero power. The next is 2 to the first power, and so on.

So now let's go back to our friend 01011101. This does not stand for the decimal value of 1,011,101. Until you get fluent in binary (or write a program to save you from thinking), you should work it out on paper. Because the lowest exponent value is always 0 and there are eight digits or places in this number, we write down the exponents from 7 to 0, left to right, and then place the value of each bit in the appropriate column:


Chorus Type	Off/On	Saw Wave	Pulse Wave	DCO Range
1: Chorus 1      1: Off  1: On          1: On           100: 4'
0: Chorus 2      0: On   0: Off         0: Off          010: 8'
                                                        001: 16'


HP Filter       VCA Mode        ENV Polarity    PWM Source
1 1 : Off       1: Gate         1: -  1:		Man
1 0 : 1         0: ENV          0: +  0:               LFO
0 1 : 2
0 0 : 3


1       1       1       0       *       240  (Sys Ex Begins)
1       2       2       1       *       65  (Roland ID)
1       3       3       1       *       48  (Function Type)
1       4       4       1       *       0  (MIDI Channel 1)
1       5       5       1       *       0  (Program #)
1       6       6       1       *       57   -(LFO Rate
1       7       7       1       *       45   -(LFO Delay
1       8       8       1       *       0   - DCO LFO
1       9       9       1       *       55   - DCO PWM
1       10      10      1       *       0   - Noise Level
1       11      11      1       *       85   - VCF Cutoff
1       12      12      1       *       0   - Resonance
1       13      13      1       *       0   - VCF ENU
1       14      14      1       *       0   - VCF LFO
1       15      15      1       *       25   - VCF KYBD
1       16      16      1       *       52   - VCA Level
1       17      17      1       *       59   - Attack
1       18      18      1       *       32   - Decay
1       19      19      1       *       86   - Sustain
1       20      20      1       *       40   - Release
1       21      21      1       *       0   - Sub 0sc Level
1       22      22      1       *       26   - Compound Byte # 1
1       23      23      1       *       24   - Compound Byte # 2
1       24      24      1       *       247  (End of Sys-Ex)


Patch:     Whootdwhind     Metalcussion     Head Trip     Brasspad     Warble
LFO Rate        82               94              127             0      108
LFO DELAY       40               0                 0             0       0
DCO LFO         11              127                0             0       0
DCO PWM         0               102              102            62       0
Noise Lvl       0               116                0             0       0
VCF Cut         87               46               20            65       94
Resonance       27               0               125            39      127
VCF ENU         17               63               33             3       80
VCF LFO         0                9                 0            11       23
VCF KYBD        56               84              127           127	127
VCA Level       127              0                31            59       0
Attack          7                0                0             50       0
Decay           127              95              127           100      127
Sustain         127              15               0             94       51
Release         6                45              127            44       71
Sub Level       0                0                0              0       0
Switches 1      74               2                68            82       2
Switches 2      11              17                1             25       26
2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0
 0   1   0   1   1   1   0   1
 0 + 64 + 0 + 16 + 8 + 4 + 8 + 1 = 93
or: 1*26 + 1*24 1*23 + 1*22 + 1*20 = 93

If you're still experiencing the tapioca effect, any introductory text on computer programming should be able to give you more information.

Incidentally, you can check your work by adding the remaining numbers (27+25+21 = 162). The "values" of the 0s added to the values of the 1s should work out to 255 for an 8-bit number, 127 for a 7-bit number and 31 for a 5-bit number.

The Strange World of Bit-Mapping

If you ever tried to program the sound chip of the C-64, you'll already be familiar with the process of bit-mapping. The whole idea is used to save memory and speed up data transmission. Consider the J-106. There are 11 noncontinuous parameters in the voice. When I say "noncontinuous," I mean that a given parameter has only a few possible values.

The LFO Rate is a continuous parameter: It can have integer value between 0 and 127. The high-pass filter, by comparison, has only four possible settings, and the pulse waveform has only two: on and off.

You could assign each of these switchable parameters to a full byte of data. A value of 0 would indicate the off position, and a value of 127 would indicate on. But why use a full byte of data when you can store the same information in a fraction of a byte? A value of 1 could indicate that the pulse wave is on, while 0 would indicate the off state.

The high-pass filter has four possible values. That range can be expressed using two binary digits where 11 is off, and 00 indicates the maximum setting of 3.(A high value on the synth doesn't always correspond to a greater binary value. Don't ask me why, I didn't build the thing.)

So now we've put two values into three binary bits. That leaves us with up to five more bits in which to store other switched data. Roland doesn't always use up the full eight: The first of the switch-bytes uses only seven bits, while the second uses only five.

Michael Friesen has worked as a bookbinder, a chicken-shed cleaner, a cow milker, a ditch digger, a jingle composer and a synthesist for a touring theatre company. He's now a full-time journalism student at the University of Western Ontario.