BeeBMIDI (Part 6)
Jay Chapman and a Juno 106 voice dump program for use with E&MM's own MIDI interface unit for the BBC Micro. It can be adapted to suit other synth and computer combinations, too.
A program that allows you to dump Juno 106 voices onto disk or tape. And it can be adapted for other micros and MIDI synths.
This article is NOT just for Juno 106 and BBC Micro owners. With a bit of luck the rest of you have now been dragged back from turning the page. Admittedly, if you don't have a BBC Micro you'll have to do a fair amount of work 'translating' this program for your micro, but the algorithms used should still be of interest. And if you have a MIDI synth other than the Roland Juno 106, the extra work is not so daunting: I'll mention the sort of changes you'll have to make as I go along. However, you will need to have a reasonable understanding of the MIDI protocol and its 'System Exclusive' details for your synth: if in doubt have a look at the user manual or, failing that, back issues of E&MM.
On the other hand, if your synth won't transmit voice data via MIDI System Exclusive messages, then both this article and the program are not going to be of any practical use to you - sorry! Of course, you might be saving up for a better synth... Anyway, even if you do possess such an instrument, you may have to set some control to allow it to send the necessary messages. On the Juno 106, the required procedure is setting the MIDI Function Selector Switch on the back panel to III. Best to do this straight away, as if it's forgotten, the entire program will be about as useful as a fork for drinking soup.
The program listed on the following pages allows you to capture, name and save several hundred voice patches from the Juno 106 and, of course, send them back to the synth and write them into its memory. You can save and load the complete library to and from your current filestore, it's possible to display the names of all the voices in the library (in case you forget what you called some stored marvel), and you can search for a particular name to confirm that it exists in the currently-loaded library. If you need to tidy the library up, you can delete voices, too.
My own system, which has PAGE set at &1B00, can store about 250 sets of voice data. If you have PAGE set lower, you'll be able to increase the size of the arrays holding the data to store at least 300 sets (disk users with PAGE=&1900) and in some cases even more (tape and other users with PAGE=&E00). Try running the program with different values for 'max_number_of_voices' set in line 2490. The procedure 'PROCclear_arrays' (line 3750) fills the arrays to their maximum size so that you run out of room immediately (if you're going to do at all) rather than have the program crash after saving a whole album's worth of voices. It might be sensible to save the growing library after every two or three additions anyway - no point in tempting fate.
'PROCinitialise' (line 2440) is called at the start of the program to set up various global values and 'DIMension' does the same for the data arrays. Notice that one of the values, 'voice_data_size', needs altering if you have a synth other than the Juno 106: it represents the number of data bytes that must be transmitted within the MIDI System Exclusive message that conveys voice data. There are other bytes to be transmitted, starting with the System Exclusive byte (&F0) and the Roland Identification byte (&41), and ending with the End of Exclusive byte (&F7). Obviously some of these also need altering in addition to the data bytes. A quick look at the assembly code routine 'TXvoice' will show all the bytes for the Juno 106.
In other words, this is where you'll need some precise knowledge of the exact MIDI protocol for your synth...
Lines 2570 to 2630 relate to the use of E&MM's BeeBMIDI board, which has already been covered several times in this series of articles. Line 2660 marks the buffer (which the transfers are effected from/to) as empty by setting an illegal value (ie. one that cannot occur if real data were in the buffer) into the first byte of the buffer so that we can tell it's empty when necessary.
Lines 2680 to 3340 assemble the routines which can't be in BASIC (either as a result of speed considerations or because, in the case of enabling and disabling interrupts, there is simply no other way of doing things) into the 'user defined character definitions' page at &C00, which is not in use. The interrupt enable and disable were discussed in last month's BeeBMIDI article. (You did get E&MM last month, didn't you?)
After initialisation, the program loops around lines 1070 to 1290 until exited, displaying the menu, taking the user's selection and calling these procedures selected. Before describing these procedures it's worth looking at the data structures the program uses.
The names given to stored voices are kept, in alphabetical order, in the array 'name$()'. Whenever a new name is inserted into the array, all the names above that new name are moved up one position to create a gap at the correct point in the array. Thus, the array remains in alphabetical order.
This is not a terribly efficient way of inserting items, though it is simple. It does take some time when the array is nearly full, since on average about 150 names need moving - even this amount of work should hardly be noticeable, however.
So that we don't have to move the voice data about as well - which would slow the process down to an unreasonable degree - a second array, 'index%()' holds a pointer to the start of the data for each 'name$'. Look at 'PROCinsert-voice' (line 3490). If some of this sounds a bit heavy you'll just have to brush up on your programming, I'm afraid!
The reason for keeping the names in alphabetical order is so that we can look for a name in a more or less straightforward and logical manner. Rather than searching through the list linearly (ie. is the first name the one we want, is the second, is the third...?), which would be very slow and in the worst case (nearly full table and a search for a name that isn't there anyway) would end up with our doing several hundred comparisons just to find out that it wasn't worth bothering in the first place, we use the 'binary chop' algorithm encoded in 'FNfind_voice' (line 3380). Actually, this is the same algorithm we use when we search for a name in a telephone directory. What we do is compare the name in the middle of the list with the one we are searching for, and if they match up, we've finished. If they don't match, we decide whether the name we want is before or after (alphabetically) the name we just compared and look in the appropriate half of the list. We then apply the procedure to the new, shorter list. So, on each comparison that fails we are left with half of what we started with to search: if we had 256 names to search, in the worst case we would only have to make nine comparisons instead of 256. You compare successively one name in (approximately) 256, 128, 64, 32, 16, 8, 4, 2 and finally 1.
Another benefit of storing the names in alphabetical order is that 'PROCdisplay' (line 1320) becomes a relatively trivial exercise, as does 'PROCsearch' (line 1420) which uses the binary chop search routine 'FNfind_voice' to do its dirty work.
'PROCreceive' (line 1520) calls the machine code routine 'RXvoice' to get the voice data into the byte array 'buffer', and then calls 'PROCinsert_voice' (line 3490) which puts the user-given name and the voice data into the 'name$()', 'index%()' and voice data structures. Note that 'RXvoice' checks to see that the MIDI protocol is being followed correctly.
The reason you have to indicate that you're about to press the last of the selection keypads (lines 1580 to 1600) is that the Juno 106 sends voice data on each Group, Bank and Patch Number keypress. If you were on B24 (Group B, Bank 2, Patch Number 4) and wanted to store A15, you'd send A24, A14 and finally A15, as you pressed the Group A, then the '1' and then the '5' keypads respectively. So, hit the space bar just before you press the '5' keypad on the Juno.
'PROCtransmit' (line 1760) gets the voice data that the user specifies into 'buffer' so that 'TXvoice' can transmit it. You should see the 'voice parameters altered' full-stops in the Roland's LED display come on when the transmission is complete. If you want to save the voice, simply follow the instructions in the Juno manual.
The rest of the program ('PROCs delete', 'load' and 'save') is fairly straightforward, but it's worth pointing out that when you save the library, a back-up copy is maintained. This assumes that you are using a disk-based filestore: cassette users will want to make changes around lines 2250 to 2410.
Don't be afraid to experiment with the program code: the procedures have all been kept quite independent so that you can put them into your own programs. Some of you might want to have several different libraries at your disposal, in which case you'll need to add some code to ask for the library name and create a suitable filename out of the answer in 'PROCload' and 'PROCsave'.
If you can't face typing the program in, then EmmSoft will be delighted to supply you with a cassette at the suitably modest price of £3.95 including VAT. Incidentally, Jay Chapman's earlier voice dump program for the Yamaha DX7 is now also available at £3.95 - a price reduction of £4.00. If you're interested in either of these, send your order with payment in sterling cheque, postal order or bankers' draft payable to Music Maker Publications, to EmmSoft, E&MM, (Contact Details). Please allow 28 days for delivery.
Gear in this article:
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!