Various Music-related Files --------------------------- Note: Any file which is a program will be stored in xzx tape format, which is as follows: bytes 0- 3: the string "XZF1". bytes 4-20: a spectrum tape header, including: byte 4: zero bytes 5-14: a name bytes 15-16: the file length bytes 17-18: the LINE number, if any bytes 19-20: the length of the program, excluding variables. bytes 21- : the program itself. This format can be changed into a +3 disk image using "xzx2plus3" by Thomas Kjaer (available from ftp.nvg.unit.no). Any file which is CODE will be stored as raw data. The start address and length will be given with the file's description below. If the start address is given as "start", then the code is relocatable and any start address may be chosen. Each of these files except "FL" and part of 2TUNE2C is written by Ian Collier. Permission to use and distribute as-is for non-commercial purposes is granted provided due acknowledgement is given. ADVERTISEMENT Many of these programs work best on the +3 in "48K Disk BASIC", which is available for v4.0 +3 machines from ftp.nvg.unit.no. FL (CODE 49152,1152) - the tune from FAIRLIGHT. This piece of code was hacked (without permission, sorry) out of the said game. Call 49152 and listen. Note: the program exits when a key is pressed. After the tune has finished the program will still continue to pause waiting for a keystroke. FL2 (CODE 60000,1350) / 2TUNEC (CODE 62200,145) - a copy of the tune from FAIRLIGHT. Before I examined the game to find the tune, I attempted to reproduce the effect myself. The result wasn't perfect, but see how well I did... Load both pieces of code and then call 62200. This program always runs until the tune has finished. 2TUNE2 (program) / 2TUNE2C (CODE 60000,155) - a 2-channel tune generator If I remember correctly, the code uses a slightly modified version of the algorithm used in FAIRLIGHT to generate 2-channel music (as opposed to 2TUNEC, which was written independently). The program is a simple-minded entry system for the music. When you run the program, it will ask for a unit note length. Type in a number between, say, 0.05 and 0.5, which is a time value measured in seconds. Each note will have a duration which is a multiple of this number. After answering this question, type in for each note two note values and a duration. Note: the maximum note length is just below 1.8 seconds. If you ask for more than this then the program will fail horribly. The two note values can be either zero (for a rest) or a semitone number which is much like the spectrum's BEEP instruction except that middle C is about 24 instead of zero. Typing a space instead of the first note value will play the music so far. Entering nothing (the null string) instead of the first note value will stop the program. To save the music, save from 60000 to X inclusive. that is, type SAVE "somename" CODE 60000, x-59999 . To play the music, call 60000. JJ2 (CODE 60000,1419) - a 2-channel tune This is a tune entered using the system described above. Call 60000 and see whether you recognise this well-known piece by J. S. Bach... MINUETZ (program) / MIN (CODE 59000,5903) - a Mozartian music generator The idea for this program was based on program by Hopkins/Laverty which was supplied with their Protek sound board for the Spectrum (and also published in Your Computer), which was in turn based upon an idea by Mozart. This is a 128K spectrum version which has been written from scratch, except that the same bars and table have been kept. Mozart wrote about 160 bars of 3-part music and a table showing which bar of music was to be used for each throw of two dice, depending upon the position of the bar within a 16-bar minuet. Each set of 16 throws of a pair of dice therefore generates a different minuet. This process is clearly very suited to implementation on a computer, and that is where this program comes in. The computer will throw the dice (or, for the impatient, just draw up a table of 16 numbers), and will then play the minuet which has been generated. The music will sound through the 128K spectrum's sound chip, and will also appear on MIDI channels 1, 2 and 3 via the MIDI port. Unfortunately, this program suffers from a misinterpretation which was made by the original authors. If the dice throw for the last bar in the first half of the minuet is an odd number, then the notes which are generated will apparently clash. After this program was written I saw an article which included a facsimile of this bar written by Mozart, and it turns out that the discordant notes are not to be played together. Instead, the lower sequence of four notes in the bass clef should be played on the first time and the upper four notes should be played on the repeat. TUNE (program) / TUNE.BIN (CODE 64000,1216) / FILL.BIN (CODE start,3294) - a tune player This is an interrupt-driven tune program which was designed for the 48K Spectrum with Protek sound generator board or for 48K {Disk} BASIC on 128K machines, but it works in 128K mode as long as the program isn't unexpectedly paged out. The tune is played in 3 channels on the sound chip, and also (on a 128K Spectrum) output on MIDI channels 1, 2 and 3. All the tunes I have typed in are by the band SKY - hence the large SKY banner which is displayed by the program... CANNON.TUN (CODE 29994,2080) / DANZA.TUN (CODE 29994,1440) / GRACE.TUN (CODE 29994,171) - tunes to play with the program TUNE (The tunes are "Cannonball" and "Danza" from SKY and "Grace" from SKY3). MAKETUNE (program) - a 3-channel tune generator This program outputs tunes in the format which is used by TUNE above. A tune file contains three "programs" (one for each channel of music) which are interpreted simultaneously by the TUNE program, and three start addresses. In order to play a tune, you should load TUNE.BIN, poke in the three start addresses into the variables st1, st2 and st3 (which are, in this version, at 65166, 65168 and 65170, respectively), and then call 64000. The tune will play in the background until it has finished, or until a STOP error occurs (which is detected by testing the contents of 23610). The program then puts the interrupt mode back to normal. Each program may contain the following commands: (zero): this is a rest, and takes a one-byte parameter which is the length of the rest in 1/50 second units. (any non-zero number): this is a note, and takes a one-byte parameter which is the length of the note in 1/50 second units. The note value is a semitone number, with middle C being note 48. end: this must be placed at the end of each program. vol: this sets the volume of the current channel to the one-byte parameter. In addition, if bit 7 of the parameter is set then the channel becomes a white-noise channel instead of a tone channel. wave: this tells the channel to use the AY-3-8910 envelope waveform given by the one-byte parameter until the next "wave" or "vol" instruction. x: this sets the waveform period to a value given by the one-byte parameter. call: this calls a program at the address given by a two-byte parameter. Calls can be nested to a level of 10. ret: this returns from a called program. It must be placed at the end of any program which is called, but must not be placed in any program which is not called. djnz: this takes two one-byte parameters: a repetition count and a relative jump (the program inputs an address and then calculates the relative jump). Repeated sections may be nested to an arbitrary level. Note: the "number of repetitions so far" is stored in memory, so may be corrupted if a tune is stopped before it has finished. The program has a command "reset" which puts all the "djnz" instructions back to normal. Running a tune to completion will reset all the "djnz" instructions back to normal. The MAKETUNE program inputs any of the above commands and pokes them in at the address shown in the prompt. It also accepts any of the following commands: m: moves the current address pointer to x. st: prints the current values of st1, st2, st3 (initially these all point to a program containing the single instruction "end"). st: sets the value of stn (where n is 1, 2 or 3) to the current address. play: plays the current tune (starting from the most recent values assigned to st1, st2 and st3). play c: plays only the channel numbers listed in the string c. stop: stops the tune if it is in progress (this command resets any "djnz" instructions back to normal). reset: resets any "djnz" instructions in the most recently played tune. do: plays a "call x" instruction. The program starting at x must end with either "ret" or "end". do: plays a "call" at the current address. v: views one screen's worth of memory starting at location x. v: views one screen's worth of memory continuing from the point where the last "v" command left off, or from the current address (if there was no previous "v" command or the "m" command has been executed since the last "v" command). save: saves the tune in a format suitable for use by the TUNE program. The code which is saved starts at 29994 with the values of st1, st2 and st3, and then includes any programs which have been typed in between 30000 and the current address. The current address must be at the end of the tune in order for this to work. load: loads a tune which has been saved with the "save" instruction. PLAY (program) / PLAY.BIN (CODE 62500,2520) - a "piano" program This program turns the spectrum keyboard into a piano keyboard with 3-note polyphony. The program stores the tune as three sequences of note and rest commands as described above, so a tune can be saved and used with the TUNE.BIN program. The PLAY program does not contain an option to save the tune, but the pointers are always displayed so that sections of the tune can be saved. SOUND2 (CODE 63000,2120) - BBC Micro sounds emulator This program was also originally designed for the 48K spectrum with a Protek sound board, and works on that or in 48K modes of 128K machines. Call 63000 to initialise (this has to be done after each RUN or CLEAR, so put it at the start of any program which uses SOUND2). The new commands "=s" and "=e" will be available. These emulate the BBC Micro's SOUND and ENVELOPE commands, respectively, with a couple of minor differences. Descriptions of the commands follow. =s &HSFN, vol|env, pitch, duration &HSFN is a collection of flags written as hex digits. Unfortunately, the spectrum does not have hex conversion (except with my modified Interface 1 ROM or some other utility) so the number should be expressed as N+16*F+256*S+4096*H (which, of course, simplifies when one or more of H, S and F is zero). N is a channel number. Unlike the BBC Micro's sound chip, the AY-3-891x does not have a channel 0. Instead, white noise is produced by adding 4 to the channel number, which should be between 1 and 3 (inclusive). F is a flush flag. If F=1 then all pending notes on channel N are flushed and the note takes place immediately. If F is zero then notes will queue up. S is a synchronisation flag. In a chord of two notes or more, each note should have S set to the number of other notes in the chord (that is, 1 or 2). Notes with a non-zero S flag will wait until the correct number of other notes, each with a non-zero S flag, are ready to be played. H is a delay flag. If it is set to 1 then the note will wait until the previous note has finished its "release" cycle (that is, it has reached zero volume) before playing. In the usual case where H is zero, the note will be played as soon as the previous note has reached the end of its duration. The vol|env parameter is either a number between -15 and 0 whose absolute value indicates the volume at which the note should be played, or the number of a defined envelope. The pitch parameter is a number between 0 and 255, which indicates pitch in steps of a quarter-semitone. A value of 80 indicates middle C (thus a value of 0 indicates a bass E and a value of 255 indicates a slightly flat very high G#). The duration parameter gives the length of the note in tenths of a second. The =s command queues notes for each channel in a separate queue. Each queue can hold four notes. If the queue is full then the =s command will pause until there is enough space in the queue. =e N, T, PS1, PS2, PS3, NS1, NS2, NS3, AR, DR, SR, RR, AT, DT where each parameter is an integer and 1 <= N <= 10 1 <= T <= 255 -255 <= PS1, PS2, PS3 <= 255 0 <= NS1, NS2, NS3 <= 255 0 <= AR, AT, DT <= 126 -126 <= DR, SR <= 126 -126 <= RR <= 0 N is an envelope number. T is a time value in 1/50-second units (not 1/100 as on the BBC Micro) between 1 and 127, plus a repeat flag. Usually the pitch part of the envelope is repeated forever, but if bit 7 (the high bit) of T is set then the pitch part of the envelope is only executed once, after which the pitch remains constant. The pitch part of the envelope is defined by the three pairs of values PS1/NS1, PS2/NS2 and PS3/NS3. Each pair gives a pitch step (PS) and a number of steps (NS). At every time interval of length T, the current pitch of any note played using this envelope is altered by adding the PS value, modulo 256 (for example, 255+1 is zero and 0-1 is 255). This is carried out NS times, and then the next pair of values is considered in sequence. The volume part of the envelope consists of an attack cycle, a decay cycle, a sustain cycle and a release cycle. Each cycle increases or decreases the volume by a certain amount at every time interval of length T. The volume at any time is a 7-bit number in the range 0-126 (which is, of course, divided by 8 before passing it to the sound chip). The attack rate is given by AR, and the attack cycle continues until the volume reaches or passes the attack target given by AT. The decay cycle then takes place, at a rate given by DR (note that although this is called the "decay" cycle, the volume of the note can increase during this cycle). This cycle continues until the volume reaches or passes the decay target given by DT. The sustain cycle then takes place at a rate given by SR, and continues until the duration of the note (given on the =s instruction) has ended. At this point, if there is a note queuing (which does not have the H flag set) then the current note finishes. Otherwise, the release cycle takes place, at a rate given by RR, and finishes whenever the volume reaches zero. Note that since RR may be zero, the note may continue forever. PLAYCOM (CODE 60000,3205) - a PLAY command giving 5 channels in 48K BASIC This program was also originally designed for the 48K spectrum with a Protek sound board, and works on that or in 48K modes of 128K machines. Its advantage over the 128K mode PLAY command is that it gives up to five channels on audio by using the "beeper" as well as the sound chip, but the disadvantage is that it does not do MIDI. A short information file that I typed years ago is contained in PLAYCOM.FSE (this is a Unix ASCII text file). In case you do not have access to a 128K Spectrum manual, here is a brief summary of commands: a..g A..G notes (capitals are an octave higher) & rest # sharpen following note $ flatten following note 1..12 note lengths _ add note lengths together (as in "5_3") !text! comment (...) repeat the enclosed text H halt M set mask to n (complement of sound chip register 7) N null O change octaves ("O5c" is middle C) T tempo n crotchets per minute U use a sound-chip envelope V change volume W change waveform number and note lengths: 1 semiquaver 2 dotted semiquaver 3 quaver 4 dotted quaver 5 crotchet 6 dotted crotchet 7 minim 8 dotted minim 9 semibreve 10 triplet semiquavers 11 triplet quavers 12 triplet crotchets. CHRISTUS / GABRIELI / HOSANNA / MICHAEL / PURCELL / SATWS / SUSSEX (all programs) - music written in PLAY statements Each of these except SATWS ("See amid the winter snow") and SUSSEX (the Sussex carol) are described in REM statements at the start of the program. The latter two are carols from "100 Carols for Choirs". HOSANNA and PURCELL will work as-is using either 128K PLAY or PLAYCOM (above). SATWS and SUSSEX will only work on PLAYCOM. GABRIELI will only work on 128K PLAY because it is in 8 parts. The other two files are designed for 128K PLAY but can easily be converted to PLAYCOM. Converting from 128K PLAY to PLAYCOM involves the following. * Select the 4 or 5 most important channels from tunes that have more than 4 or 5 channels (4 is better because with 5 channels PLAYCOM can get a bit out of tune. However, the above programs are OK to play with 5 channels) (in MICHAEL, f$ is clearly the least important). * If 5 channels remain, then select the two channels which are least important and/or contain the lowest notes to be played on the beeper. Lower notes have a higher probability of being played in tune (in MICHAEL, choose d$ and e$ as the two lowest; in CHRISTUS choose c$ and e$ since c$ has only a few notes and e$ is the lowest). * If 4 channels remain, consider putting the bass or the melody channel on the beeper, because it is likely to be louder than the other channels. * When selecting the beeper channels also note that notes played on the beeper will be (temporarily) stopped whenever another note ends or starts. * Remove all Y instructions from all strings and remove V instructions from the string(s) which will be played on the beeper. * Write the PLAY instructions with the beeper channel(s) last.