Sunday, 18 November 2012

Spectrum 128 and MIDI




Information on MIDI and the ZX Spectrum is available on the net but it is a bit more scarce than one might think. So I'll try to collect some of the useful things here and also fool around with Spectrum and MIDI.

The RS232/MIDI port on the back of the Spectrum is not a standard MIDI port, obviously. But making it work is not a matter of simply rewiring the port, as it needs a few resistors and a transistor. Also, a somewhat obscure plug is needed if one does not wish to build the cable directly into the Spectrum.

Pictured, a BT-like plug and a DIN-8 connector, which passes for a MIDI port.
The plug at least looks like a BT cable, 631A, with all the six pins. The plastic parts may need some changes before it fits the Spectrum port. For the MIDI connector, I used an 8-pin DIN, which has more pins than a MIDI port requires, but as long as there are holes in the correct place it does not matter. My MIDI connector is built according to a document by Ben Versteeg at benophetinternet.nl/hobby. Direct link to the document is here.

The white cable is connected to the RS232/MIDI port. Yes, it looks a bit messy now.

Programming MIDI via BASIC

Try as I did, I could not really find a proper MIDI sequencer for the Spectrum. I suppose around 1986 onward nobody in UK did little else than games for the Spectrum. Possibly the russians have made something for their Pentagons and Scorpions, but they might not work on a vanilla machine.

Fortunately, BASIC offers a simple way to test the port in action. The Sinclair Spectrum 128k introductory manual describes all the commands. Perfectly timed sequences can be built out of text strings. As the Spectrum BASIC allows fairly flexible string manipulation, tunes can be structured programmatically. The single PLAY command then initiates the whole multi-channel sequence.

The pseudo-full screen BASIC editor in 128 Spectrum.
Something like this was used to create the loop in the video above.
 
The example below should be valid in 128 BASIC:

10 LET a$="T120Y1M1O3N((1e1e1e1e1e1e1e1e))"
20 LET b$="T120Y1M1O3N((1c1&1&1&1&2&1&1&))"
30 PLAY a$,b$

The example plays notes simultaneusly on two channels. T sets the tempo at 120BPM. Y is the important command here, as Y1 selects the MIDI output channel #1.

The actual tune is controlled by the codes within the character strings. Lower case letters cdefgab play the notes on the octave, whereas upper case letters CDEFGAB play notes on a higher octave. The & denotes a rest. The notes are preceded by a number (1-9) that defines their length. Using a # indicates a sharp note. The brackets are used to repeat a section, and this can be done to up to four levels. Here I'm looping the contents four times.

M selects the channel (not needed for MIDI I think). O1 sets the octave at the second lowest octave. N is used to separate numbers from each other. It seems to be a good practice to insert it at least between the setup and the notes. Z apparently would send out raw MIDI data, but I'll see about that one later.

A 32-step sequencer with two channels.
It's fairly easy to sketch out graphical ways for creating sequences. as the data can always be "compiled" into the strings and played. However, in BASIC these things are notoriously slow. One thing to avoid is trying to build loops or song structures with GOTO commands. It just won't work. It's better to append the whole song into the character strings and use a single PLAY statement.

To be continued...

The Spectrum connected to a KORG Electribe sampler.

3 comments:

  1. Especially nice to see the shortened +2 put into use :)

    ReplyDelete
  2. There were MIDI sequencers for the original ZX Spectrum, but all that I know ("10"Systems, XRI) used specialized hardware for the actual interface. By the time the +2 came out, I think the sequencing market had moved to other machines.

    I don't know how hard it would be to port any of the old software to the +2. At least the "10"Systems sequencer needed a clock signal from the MIDI interface driving an interrupt pin on the Z80 as a time base.

    ReplyDelete