Part 19 Sound Subjects covered... BEEP, PLAY As you will have already noticed, the +3 can make a variety of noises. To get the best quality of sound, it's important to make sure that your TV is tuned-in properly (see chapter 2). If, instead of a TV, you are using a VDU monitor (which won't reproduce the +3's sound), note that a separate sound signal (which may be connected to an audio amplifier powering speaker(s) or headphones) is available from the TAPE/SOUND socket at the back of the +3. Headphones may not be plugged into the TAPE/SOUND socket directly. Connections to the TAPE/SOUND socket are described in chapter 10. To get the most out of the +3's musical ability, it helps to have a little knowledge about musical terms. Note that in the examples that follow, it is important that you type in the string expressions exactly as shown in upper case and lower case letters, i.e. the example "ga" should not be typed in as "Ga" "gA" or "GA". [Note also that I'll be showing literal strings in the text without the normal quoting - i.e. "like this", not '"like this"'. Be sure to type in the quotes.] Type in this command (don't worry what it means just yet)... PLAY "ga" Two notes were played - the second slightly higher than the first. The difference between the notes is called a tone. Now try... PLAY "g$a" Again there were two notes played - the first one was the same as the previous example, but there was less of a jump to the second. If you didn't hear the difference, then try the first example followed by the second again. The second example has half the difference between notes, and this is called a semitone. When you're happy with semitones, try this... PLAY "gD" This sort of difference is called a fifth, and occurs quite often in music of all kinds. With that example ringing in your ears, type... PLAY "gG" Although (hopefully) you noticed that there was a much bigger difference that time than for the fifth, the two notes somehow sounded much more similar. This is called an octave, and is the point at which music starts to repeat itself. Don't worry about that unduly, just remember what an octave sounds like. There are two ways of making music and sounds with the +3. The most elementary is the somewhat spartan BEEP command. This takes the form... BEEP duration,pitch ...where the duration and pitch parameters represent numerical expressions. The duration is given in seconds, and the pitch is given in semitones above middle C (negative number for notes below middle C). Here is a diagram to show the pitch values of all the notes in one octave on the piano for BEEP... | | | | C#| D#| | | F#| G#| A#| | | | | | | | | Db| Eb| | | Gb| Ab| Bb| | | | | |-2 | | | 1 | 3 | | | 6 | 8 |10 | | |13 |15 | __|___| | |___|___| | |___|___|___| | |___|___| | | | | | | | | | | | -3 |-1 | 0 | 2 | 4 | 5 | 7 | 9 |11 |12 |14 |16 ____|___|___|___|___|___|___|___|___|___|___|____ C D E F G A B C Hence, to play the A above middle C for half a second, you would use... BEEP 0.5,9 ...and to play a scale (for example, C major) a complete (albeit short) program is needed... 10 FOR f=1 TO 8 20 READ note 30 BEEP 0.5,note 40 NEXT f 50 DATA 0,2,4,5,7,9,11,12 To get higher or lower notes, you have to add or subtract 12 for each octave that you go up or down. BEEP exists mostly to provide compatibility with the older designs of Spectrum, though it can be useful for very short or rapid sound effects. For any new program you develop, the second way of producing sound is much to be preferred, and this is achieved using the PLAY command (if you worked through the simple examples earlier in this section, you'll remember that that's what you used). PLAY is much more flexible than BEEP - it can play up to three voices in harmony with all manner of effects, and gives a much higher quality of sound. It's also much easier to use. For example, to play A above middle C for half a second, simply type in... PLAY "a" ...and to play the C major scale (which needed a program to itself before), use... PLAY "cdefgabC" Notice that the last 'C' in the example above is in upper case. This tells the PLAY command to play it an octave higher than the lower case 'c'. A scale, by the way, is the term used for a set of notes spanning an octave. The example above is called the C major scale because it's the set of notes between two C's. Why not? There are two main classes of scale, major and minor, and this is just musical shorthand for describing two different sets. Just for interest, the C minor scale sounds like this... PLAY "cd$efg$a$bC" Preceding a note by '$' drops it by a semitone (flattens it), and preceding a note by '#' raises it by a semitone (sharpens it). The PLAY command spans 9 octaves, and can be told which one to use by having the upper case letter 'O' followed by a number, in the list of notes it is given. Type in this little program... 10 LET o$="O5" 20 LET n$="DECcg" 30 LET a$=o$+n$ 40 PLAY a$ There are a few new things in this program. Firstly, PLAY is just as happy with a string variable as with a string constant. In other words, providing that 'a$' has been set up beforehand, 'PLAY a$' works just as well as 'PLAY "O5DECcg"'. In fact, using variables in PLAY statements has certain distinct advantages, and we shall be doing this from now on. Notice also that the string 'a$' has been 'built up' by combining the two smaller strings 'o$' and 'n$'. While this doesn't make much difference at this sort of level, PLAY can cope with strings many thousands of notes long, and the only sensible way of creating and editing those strings from BASIC is to combine lots of smaller strings in this way. Now run the above program. Edit line 10 so that "O5" becomes "O7", and run it again, or if you want to be a big spaceship make it "O2". If you don't specify an octave number for a particular string, then the +3 assumes that you want octave 5. Here follows a diagram of the notes and octave numbers which correspond to the standard even-tempered musical scale... [OK, time to use your imagination here...] _______________________________________________________ |C|D|E|F|G|A|B|C|D|E|F|G|A|B|C|D|E|F|G|A|B|C|D|E|F|G|A|B| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | _ | | | | | | | | | | | | | | | | | | | | | | | | | | |.|'| _____|/___|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|.|'|_|_|___ |_|___/____|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|.|'|_|_|_|_|___| |_|__/|____|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|.|'|_|_|_|_|_|_|___| |_|_(_(_)__|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|.|'|_|_|_|_|_|_|_|_|___| |_|__`-'___|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|.|'|_|_|_|_|_|_|_|_|_|_|___| ._/ | | | | | | | | | | | | | | |.|'| | | | | | | | | | | | | | __________|_|_|_|_|_|_|_|_|_|_|_|_|.|'|_|_|_|_|_|_|_|_|_|_|_|_|_|_|___| |_|_/^\__*_|_|_|_|_|_|_|_|_|_|_|.|'|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|___| |_|(*__)_*_|_|_|_|_|_|_|_|_|.|'|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|___| |_|___/____|_|_|_|_|_|_|.|'|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|___| |_|__/_____|_|_|_|_|.|'|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|___| ^ | | |.|'| | | | | | | | | | | | | | | | | | | | | | | | | |.|'| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |c|d|e|f|g|a|b|C|D|E|F|G|A|B| | | | | | | | | | | | | | | |__________OCTAVE_3_________| | | | | | | | | | | | | | | |c|d|e|f|g|a|b|C|D|E|F|G|A|B| | | | | | | | |__________OCTAVE_4_________| | | | | | | | |c|d|e|f|g|a|b|C|D|E|F|G|A|B| |__________OCTAVE_5_________| There is a lot of overlap, so for example, "O3b" is the same as "O4d". This makes it easier to write tunes without having the change octave all the time. Some of the notes in the lowest octaves (0 and 1) aren't very accurate for technical reasons, and so the computer just makes a brave attempt at getting as close as possible. PLAY can also handle many different lengths of note. Edit the program above so that line 10 is now... 10 LET o$="2" ...and run it. Then alter the setting of 'o$' between "1" and "9". The note length can be changed anywhere in a string by including a number between 1 and 9, and this is effective for all subsequent notes until a new number is encountered. Each of these nine note lengths has a specific musical name, and looks different when written down in musical notation. The following table shows which is which... .-----------------------------------------------------. | NUMBER | NOTE NAME | MUSICAL SYMBOL | |-----------|----------------------|------------------| | | | |= | | 1 | semi-quaver | @' | | | | |= | | 2 | dotted semi-quaver | @' . | | | | |` | | 3 | quaver | @' | | | | |` | | 4 | dotted quaver | @' . | | | | | | | 5 | crotchet | @' | | | | | | | 6 | dotted crotchet | @' . | | | | | | | 7 | minim | O' | | | | | | | 8 | dotted minim | O' . | | | | | | 9 | semi-breve | () | |___________|______________________|__________________| PLAY can also cope with triplets, which are three notes played in the time for two. Unlike simple note lengths, the triplet number only applies for the three notes immediately following, and then the previous note length number resumes. The triplet numbers are as follows... .-----------------------------------------------------. | NUMBER | NOTE NAME | MUSICAL SYMBOL | |-----------|----------------------|------------------| | | | 3 | | | | |==|==| | | 10 | triplet semi-quaver | @' @' @' | | | | | | | | __3__ | | | | | | | | | 11 | triplet quaver | @' @' @' | | | | | | | | [---3---] | | | | | | | | | 12 | triplet crochet | @' @' @' | |___________|______________________|__________________| PLAY is quite happy about being told to 'shut up'! A timed period during which no notes play is called a reset, and "&" is used to signify this. The length of reset it produces is the same as the current note length. To demonstrate, edit lines 10 and 20 to... 10 LET o$="O4" 20 LET n$="DEC&cg" Two notes played together without a break are called tied notes, which are signified in a PLAY command by an '_' underline, so a crotchet c and a minim c tied together would be "5_7c". (The second value is then used as the note length for all subsequent notes, as before.) There are occasions when ambiguity creeps in. Say that a piece of music needs octave 6 and a note length of 2, then... 10 LET o$="O62" ...seems a good bet - but no! The computer will find the 'O' and try to read the number following it. When it finds '62', it will stop with the report 'n Out of range'. In cases like this, there is a 'dummy note' called 'N' that just serves to split things up, so line 10 should be... 10 LET o$="O6N2" The volume can be set between 0 (minimum) and 15 (maximum) using "V" followed by a number. In practice, only 10 to 15 are likely to be useful, as 1 to 9 are too soft unless the +3 is being used with an amplifier. As previously mentioned, BEEP is louder than a single channel of PLAY, but if all three channels play a note at volume 15, then it should be at the same level as a note produced by BEEP. Playing more than one channel at a time is very simple; you just separate lists of notes by commas. Try this new program... 10 LET a$="O4cCcCgGgG" 20 LET b$="O6CaCe$bd$bD" 30 PLAY a$,b$ In general, there is no difference between the three channels, and any string of notes can be put onto any channel. The overall speed of the music (the tempo) must be in the string assigned to channel A (the first string after PLAY), otherwise it will be ignored. To set tempo in beats (crotchets) per minute, use "T" followed by a number between 60 and 240. The standard value is 120, or two crotchets per second. Modify the program above to... 5 LET t$="T120" 10 LET a$=t$+"O4cCcCgGgG" 20 LET b$="O6CaCe$bd$bD" 30 PLAY a$,b$ ...and run it several times, changing line 5 for different tempos. A common feature in music is the repetition of a group of notes. Any part of a string can be repeated by enclosing it in brackets, so if you change line 10 to... 10 LET a$="t$+"O4(cC)(gG)" ...PLAY treats it just the same as the old line 10. If you include a closing bracket (with no matching opening bracket), then the string up to that point is repeated indefinitely. This is useful for rhythm effects and bass lines. To demonstrate, try this (you'll have to press BREAK to stop the sound)... PLAY "O4N2cdefgfed)" ...and... PLAY "O4N2cd(efgf)ed)" IF you set up an infinitely repeating bass line, and then play a melody with it, then it would be nice if the bass line stops when the melody does. There is a device to do this - if PLAY comes across "H" (for halt) in any of the strings it is playing, then it stops all sounds immediately. Run the following program (again, you'll have to press BREAK to stop it)... 10 LET a$="cegbdfaC" 20 LET b$="O4cC)" 30 PLAY a$,b$ Now modify line 10 to... 10 LET a$="cegbdfaCH" ...and run it again. So far we've only used notes which start and stop at one level of volume. The +3 can alter the volume of a note while it is playing, so it can start loud and die away like a piano, or rise and fall like a dog growling. To turn these effects on, use "W" (for waveform) followed by a number between 0 and 7, together with "U" for each channel you want to use the effect on. Any channel with a volume setting ("V") will not respond to "U". This table shows graphically how the volume changes for each setting... \ 0 \_________________ 0 - single decay then off. /| 1 / |________________ 1 - single attack then off. ________________ \ | 2 \| 2 - single decay then hold. _________________ / 3 / 3 - single attack then hold. \ |\ |\ |\ |\ |\ |\ 4 \| \| \| \| \| \| 4 - repeated decay. /| /| /| /| /| /| 5 / |/ |/ |/ |/ |/ |/ 5 - repeated attack. /\ /\ /\ /\ /\ 6 / \/ \/ \/ \/ 6 - repeated attack-decay. \ /\ /\ /\ /\ 7 \/ \/ \/ \/ \/ 7 - repeated decay-attack. This program plays the same note with each effect in turn, so you can compare them again the diagram above. 10 LET a$="UX1000W0C&W1C&W2C&W3C&W4C&W5C&W6C&W7C" 20 PLAY a$ The 'U' turns on effects, and the 'W' selects which waveform to use. There's also an "X1000". 'X' sets how long the effect will last for (from 0 to 65535). If you don't include an 'X', then the +3 will choose the longest value. Waveforms that settle down (0 to 3 in the previous table) after the initial part, work best with 'X' settings of about 1000, whereas repetitive effects (4-7) are more effective with short values like 300. Try varying the 'X' setting in the previous program to get some idea of how each works. The PLAY command isn't limited to pure musical notes. There are also three 'white noise' generators (white noise is a sound which is like an un-tuned FM radio or TV), and any of the three channels can play notes, white noise, or a mixture of both. To select a mix of noise and note, you may use "M" followed by a number between 1 and 63. You can work out which number to use from this table... .--------+-----------------+-----------------. | | Tone channels | Noise channels | | |-----+-----+-----+-----+-----+-----| | | A | B | C | A | B | C | |--------+-----+-----+-----+-----+-----+-----| | Number | 1 | 2 | 4 | 8 | 16 | 32 | `--------+-----+-----+-----+-----+-----+-----' Write down the numbers corresponding to the effects you want, and then add them together. If you wanted A to be noise, B to be tone, and C to be both tone and noise, then add 8, 2, 4 and 32 to get 46 (the order of the channels is the order of the strings which follow the PLAY command). The best effects can be obtained with the A channel - don't be afraid to experiment. By now, you'll be writing symphonies! However, it can be difficult to work out just which part of the music a particular section of string is responsible for. To alleviate this problem, your music string may include 'comments' enclosed between '!' exclamation marks. For example... 1090 LET z$="CDcE3Ge4_6f! end of 75th bar !egeA" The PLAY command will simply 'hop over' any comments in the string. If you have an electronic musical instrument with MIDI, then the +3 can control it using PLAY. Up to 8 channels of music can be sent to synthesisers, drum machines or sequencers. The PLAY command is constructed exactly as described so far in this section, except that each string should include a "Y" followed by a number between 1 and 16. The number after the 'Y' controls which channel the music data is assigned to. Up to eight strings can be used; the first three strings will still be played through the TV as before so you'll probably want to turn the TV sound down. You can also send MIDI programming codes via the PLAY command, using "Z" followed by the code number. Key velocities (loudness) are calculated and sent at 8 times the 'V' setting (so "V6" will send 48 as a key velocity). So, to send a little tune (in four-part harmony) to a four-voice synthesiser (after consulting your synth's handbook to find out how to allocate MIDI channels to different voices), you would use the PLAY command with four strings, each starting with 'Y' followed by a number. This example program illustrates the PLAY command in some of its full glory... 10 LET a$="Y1T100O2(((1CCg$b))(($E$E$b$D))((FFC$E))((GGDF))))" 20 LET b$="Y2O5N&&&&C$bfG)" 30 LET c$= "Y3O4((3C&)C&1CCDD(3$E&)$E&1$E$EEE(3F&)F&1FF$G$G(3G&)G&1GG$EC))" 40 LET d$="Y4N9&&&&&&&&(9EGF7b5CD))" 50 PLAY a$,b$,c$,d$ Summary table Finally, here is a brief list of the parameters that can be used in the string of a PLAY command, together with the values they may have... STRING FUNCTION a...g ]_ Specifies the pitch of the note within the A...G ] current octave range. $ Specifies that the note which follows must be flattened. # Specifies that the note which follows must be sharpened. O Specifies the octave number to be used (followed by 0 to 8). 1...12 Specifies the length of notes to be used. & Specifies that a rest is to be played. _ Specifies that a tied note is to be played. N Separates two numbers. V Specifies the volume to be used (followed by 0 to 15). W Specifies the volume effect is to be used in a string. U Specifies that the volume effect is to be used in a string. X Specifies duration of volume effect (followed by 0 to 65535). T Specifies tempo of music (followed by 60 to 240). ( ) Specifies that enclosed phrase must be repeated. !...! Specifies that enclosed comment is to be skipped over. H Specifies that the PLAY command must stop. M Specifies the channel(s) to be used (followed by 1 to 63). Y Specifies that MIDI channel is to be used (followed by 1 to 16). Z Specifies MIDI programming code (followed by code number).