Bottom     Previous     Contents

CHAPTER 8
Playing the BBC Micro

The introduction of sound chips into personal computers brought about the birth of a totally new musical instrument - the computer itself. How easy and effective it is to play depends both upon the hardware and the software used to drive it. The BBC micro excels in both departments and we can use it to perform some quite complex musical feats.

Using the BBC micro as a musical keyboard

Most musical instruments are designed to be ergonomically easy to play - within the confines of the shape required by the instrument to produce whatever sound it is supposed to produce. A piano-type keyboard is probably one of the best examples, although designs exist for other keyboards which are intended to be easier to play.
Computers, unless they are specifically designed to operate as a musical instrument, are not normally supplied with a musical keyboard and if we want to play the computer we must make do with what we have, ie the QWERTY typewriter keyboard.
Depending upon your musical upbringing, you may find this easy or difficult to adapt to. The QWERTY keys are not laid out like a piano keyboard and are not labelled to correspond to musical notes. It may well be that here the non-musician has a distinct advantage over the keyboard player.
If you can play a piano keyboard your playing will tend to be partly automatic and, after a little practice, your fingers know how to move in order to play a certain sequence of notes. Much the same applies to the typist who is used to the QWERTY keyboard but in this case the fingers are responding to different patterns, ie word patterns, not musical ones.
Musicians and non-musicians alike will find that a little practice greatly improves their skill in using the QWERTY keyboard as a musical instrument but it will still be difficult to play anything of any technical difficulty. We can, however, still have a lot of fun using the computer in this way.

Monophonic and polyphonic instruments

A monophonic instrument is one which can only play one note at a time. Most instruments fall into this category, eg flute, trumpet, violin: although it is technically possible to play more than one note on some of them, they are generally classed as monophonic.
A polyphonic instrument is one which can sound many notes at once (and, usually, all of them should this be required) such as the piano, organ, harp, etc.
You will often see synthesisers described as monophonic or polyphonic. Sometimes the polyphonic category is qualified by a number such as 6-note or 8-note polyphonic. Some monophonic synthesisers have a duophonic mode which means they can sound two notes at once. With the ever-decreasing cost of electronics and silicon chips, the trend is towards producing instruments with ever-greater polyphonic capabilities.

The BBC as a monophonic keyboard

There is more than one way of writing a program which allows us to play music from the keyboard. The next program illustrates just one way in which it can be approached: it turns the computer into a monophonic keyboard.

10 REM PROGRAM 8.1

20 REM Monophonic Keyboard

30 REM From G (Pitch=33)

40 REM To E (Pitch=117)

50

60 ON ERROR GOTO150

70

80 Keyboard$="Q2W3ER5T6YU8I9O0P^[\_"

90 *FX11,1

100 REPEAT

110 Key$=INKEY$(0)

120 Pitch=29+4*INSTR(Keyboard$,Key$)

130 IF Key$<>"":IF Pitch>29 SOUND&11,-

15,Pitch,2

140 UNTIL FALSE

150 *FX12,0

The program is so simple it could probably be condensed into a couple of fines. Keyboard$ contains the keys we use and each key from left to right increases the pitch by a semitone. If you refer to Figure 2.4 they correspond to the notes from G (P=33) to E (P=117).

Program notes

Input is detected by INKEY$ and checked with the INSTR function to see if it corresponds to a key in Keyboard$. The basis for pitch calculation is 29 and the pitch is increased in multiples of four, according to the position of the pressed key in Keyboard$ as determined by the INSTR function. This is done in line 120. If no key is pressed the INSTR function returns a value of 0, and if Pitch is no more than 29 the sound will not occur.
The SOUND command contains a flush instruction so each new note sounds immediately upon being received. *FX11,1 removes the auto delay.
The program continually cycles through the REPEAT loop and sends a continuous series of instructions to the SOUND command. The duration value of 2 is necessary to prolong the note for the length of time the BASIC program takes to work through the loop. Reduce it to 1 and hear what happens„.
If you try to use envelope control, you will find that the cycling will sometimes cause the note to continually repeat. A case in point would be this envelope:

ENVELOPE1,1 ,0,0,0 ,0,0,0,126,-4,0,-4,126,80

You may find the idea useful for mandolin or banjo effects.

Keyboard display program

When playing a strange instrument it is often helpful to have a diagram of the keyboard with the relevant buttons or keys marked on. The next program draws such a display in mode 7 graphics and can be appended to any of these programs to provide a visual display and aid as you play the keyboard. You may also find it helpful to stick small pieces of paper over the keys you don't play to make the QWERTY layout look a little more like a piano keyboard.

1000 REM PROGRAM 8.2

1010 REM Keyboard Display

1020

1030 DEF PROCKeyBoard

1040 CLS

1050 FOR Title=1 TO 2

1060 PRINTTAB(9,1+Title)CHR$141;CHR$132

;"K E Y B O A R D"

1070 NEXT Title

1080

1090 PRINT''" f1 f2 f3 f4"

1100 PRINT"ENV1 ENV2 ENV3 ENV4"

1110 PRINT''" 2 3 5 6 8 9

0 ^ |"

1120

1130 K$=CHR$156+CHR$151+CHR$157

1140 J$=CHR$148+CHR$181+" "

1150

1160 FOR Key=1 TO 4

1170 PRINTCHR$151;CHR$255;

1180 PRINTK$;K$;J$;K$;K$;J$;

1190 PRINTK$;K$;K$;J$;K$;K$;CHR$156

1200 NEXT Key

1210

1220 FOR Key=1 TO 5

1230 PRINTCHR$151;CHR$157;CHR$148;

1240 PRINTSTRING$(12,CHR$181+" "+" ")

1250 NEXT Key

1260

1270 PRINT" Q W E R T Y U I O

P @ [ _"

1280 ENDPROC


The procedure assumes the computer is in mode 7 - do not change mode inside the procedure. Insert a line containing:

PROCKeyBoard

near the beginning of the program. See Appendix 2 and the User Guide page 402 for tips on merging programs.
The display is made up from teletext characters and is relatively straightforward although it may not be easy at first to see what the various strings produce. See Chapter 28, page 150, of the User Guide for more information on the use of teletext graphics.
Lines 1090 and 1100 are there for the benefit of the next program.

Alternative methods of note production

If we want to use envelope control or if we want to play more than one note at once, we need to employ a slightly more sophisticated method of key detection. One such method involves the use of the negative INKEY function which we used in Program 7 .3, the Rhythm Unit Program.The advantage of the negative INKEY function is that it only tests for one particular key and any number can be used together so we can test for three simultaneous key depressions. (See page 273 of the User Guide for further information.)
The next program allows us to play up to three notes at once to produce chords (see Chapter 2).

10 REM PROGRAM 8.3

20 REM 3-Note Polyphonic

30 REM Keyboard (Q - _)

40 REM From G (Pitch=81)

50 REM To E (Pitch=165)

60

70 DIM KBoard%(26)

80 DIM KFlag%(26)

90 DIM CH%(3)

100

110 FOR Channel=1 TO 3

120 CH%(Channel)=0

130 NEXT Channel

140

150 FOR Keys=1 TO 26

160 READ Data

170 KBoard%(Keys)=Data

180 KFlag%(Keys)=-1

190 NEXT Keys

200

210 DATA 17,50,34,18,35,52,20,36,53

220 DATA 69,54,22,38,39,55,40,56,72

230 DATA 25,57,121,41,114,115,116,21

240

250 REM f1=ENVELOPE1:f2=ENVELOPE2

260 REM f3=ENVELOPE3:f4=ENVELOPE4

270

280 ENVELOPE1,1,0,0,0,0,0,0,126,-4,-4,

-4,126,100

290 ENVELOPE2,129,12,0,-4,1,0,3,126,-1

,0,-4,126,100

300 ENVELOPE3,1,0,1,-1,0,1,1,126,-1,0,

-4,126,100

310 ENVELOPE4,8,0,0,0,0,0,0,63,10,0,-6

3,63,126

320

330 Pitch%=77

340 E%=2

350

360 KPressed%=0

370 REPEAT

380 FOR N%=1 TO 26

390 IF INKEY(-(KBoard%(N%)))=KFlag%(N%

) PROCP

400 NEXT N%

410 UNTIL FALSE

420 END

430

440 DEF PROCP

450 IF N%>22 PROCE:ENDPROC

460 IF KPressed%=3 AND KFlag%(N%) ENDP

ROC

470 Chan%=0

480 IF KFlag%(N%) REPEAT Chan%=Chan%+1

:UNTIL CH%(Chan%)=0:CH%(Chan%)=N%:SOUND&

10+Chan%,E%,Pitch%+N%*4,255:KPressed%=KP

ressed%+1

490 IF NOT KFlag%(N%) REPEAT Chan%=Cha

n%+1:UNTIL CH%(Chan%)=N%:CH%(Chan%)=0:SO

UND&1010+Chan%,0,0,0:KPressed%=KPressed%

-1

500 KFlag%(N%)=NOT KFlag%(N%)

510 ENDPROC

520

530 DEF PROCE

540 E%=N%-22

550 ENDPROC


The keys used are the same as in the monophonic program and pressing function keys f1 to f4 will put the keyboard under control of that envelope number. Program 8.2 produces a suitable display to go with this program.

Program notes

There is more than one way in which this program could have been written. One way, the brute force method, would be to include 26 fines such as:

390 IF KeysPressed>3 ENDPROC ELSE IF INKEY (-17)
Note=33:PROCSound:KeysPressed:KeysPressed+1

At least such a method would be quite easy to understand. A more sophisticated method is also doubtless possible but at the expense of comprehension. This program tries to tread a middle path. Once you understand the principles involved you can experiment and write your own - as simple or as sophisticated as you wish. To minimise the time taken by the program to interpret the BASIC code, integer variables and short variable names have been used.
The way the program works is described first, followed by individual sections and aspects which may need clarification.
We have substituted the 26 possible lines mentioned above by an array, KBoard%, which contains the negative INKEY values of the keys we want the program to respond to. A second array, KFlag%, keeps track of whether a key is currently pressed or not. The array, CH%,, keeps track of which channel is being used to produce which note. Pitch% sets the basic root pitch and E% is the envelope number.
The REPEAT loop between lines 370 and 410 cycles through the 26 negative INKEY values in the KBoard% array. The KFlag% array checks to see if there has been any change in keys pressed since the last loop and if there has the program is diverted to PROCP.
N% refers to how far up the scale we are. If N% equals 23, 24, 25 or 26, one of the function keys is being pressed and the program is diverted to PROCE which simply sets E% to a new envelope number. If N% is less than 23 it means a note is required.
As we can't sound more than three notes at once, the program checks, in line 460, to see how many keys are currently pressed. If there are already three keys down and another key has been pressed, control is immediately passed back to the REPEAT loop. (See the User Guide pages 89 and 100 for more information about the use of TRUE and FALSE.)
If control gets to fine 480, there is an empty channel and a key has been pressed telling the program to make a sound. Chan% is incremented by 1 until it finds an empty channel. This is given the value of N%o which tells the program which key enabled that particular channel and it plays a sound at the required pitch. KPressed%, is also incremented to keep track of how many keys are down. Lastly, the KFlag% variable is changed in line 500. If KFlag%(N%) was TRUE, ie pressed down, it is set to FALSE. The next time the loop looks at this value of N% in line 390 it will be looking to see if the key has been lifted.
If a key has been lifted, control passes to line 490 instead of 480. Chan'% is incremented until the program finds which channel was responsible for the sound produced by the key which has just been lifted. When the channel has been found, it is flushed. Notice the use of the dummy note parameter to allow the release phase to occur.
KPressed% is decremented to show that a sound channel has been freed. KFlag%(N%) is changed again by line 500 to TRUE.

How the program works and making modifications

The use of KFlag% ensures that a channel is not given a sound request until the key responsible for the present sound on that channel is lifted. This prevents a stream of continuous information going to the sound channels as in the monophonic program, and it permits envelope controL.
The sound command in line 480 which produces the sound has been given an infinite duration. If the AS phase of the envelope is 0, the note will continue until you take your finger off the key. The channel will then be flushed the next time around the loop by line 490.
You will notice that we have not needed to use an ADVAL function to check if the sound channels are full because, if a channel is being used, the program does not allow any further commands to get through.
The use of Kpressed% in line 460 to terminate the procedure if too many keys are down can be altered. As it is, if three keys are down and you press another, control just passes back to the REPEAT loop. Some synthesisers have a high, a low or a last note priority which means that the three highest, lowest or the three last notes take precedence over any others. You can achieve this by altering the '3 keys down' criteria in this fine and you will probably also have to alter the channel allocation, according to your aims.
If you want to try some dazzling fingerwork, you may find the response a little slow; and you may notice a very small time lag between the notes of a chord if you press three keys exactly together. You will see that the program does not attempt to synchronize any notes. This is a result of the program design and the fact that each note has to run through a lot of BASIC programming before it is heard. This tiny delay is not likely to be a problem but you can cut the response time by compressing the coding, using multi-statement fines and single letter integer variables.
As a modification, if you wanted to synchronize the notes, instead of calling PROCP with every note pressed you could call a PROCGetNotes to count the keys pressed and work out the pitch values. At the end of the FOR . . . NEXT loop you could call a PROCPlay which would carry out the information gathered by PROCGetNotes and synchronize the notes if necessary. The same effect could probably be put into PROCP as it stands with a little clever coding.
You can add more commands via the negative INKEY function. These can be used to increase the range of the keyboard and to access more envelopes. Detection of, say, the SHIFT key could increase the pitch by an octave. Include the relevant key numbers (User Guide page 275) in the DATA statements following line 230. The arrays, initiating loops and the repeating FOR . . . NEXT loop will need to be altered, too.

Further additions to the musical keyboard: a bass sequencer

A sequencer is a device which can be programmed with a set of notes and used to control a synthesiser module to produce a repeating riff or sequence of notes. Sequencers vary in their sophistication - some can only store a dozen notes, others can store several thousand.
As most synthesisers control pitch by voltage (the higher the voltage the higher the pitch) sequencers actually store a list of voltages. These can be used to control any voltage controllable part of the synthesiser. Most synthesiser modules are designed to be governed by voltages and are called such things as VCO (Voltage Controlled Oscillator), VCA (Voltage Controlled Amplifier) and VCF (Voltage Controlled Filter).
Every time we use a DATA statement to read in a string of notes we are, in effect, using a sequencer.
We can add a Bass Sequencer to the last program, which will play a riff and allow us to improvise over the top of it. This is common in electronic music and the use of sequencers has been popularised by such musicians as Tangerine Dream, Kraftwerk and Jean-Michel Jarre. The next listing shows the additions and alterations necessary to Program 8.3.

10 REM PROGRAM 8.4

20 REM Bass Sequencer with

30 REM Duophonic Keyboard

40 REM Alter 460: Add 345, 375 &

50 REM 560 plus in PROGRAM 8.3

60

345 Env%=1

375 PROCBass

560 DEF PROCBass

570 IF ADVAL(-8)<1 ENDPROC

580 READ P%,D%:IF P%=-1 RESTORE 620:RE

AD P%,D%

590 SOUND3,Env%,P%,D%

600 ENDPROC

610

620 DATA 33,4,33,4,45,4,53,4,-1,-1

Program notes

Env% at line 345 selects the envelope the sequencer will use. PROCBass is inserted in the REPEAT loop of the main program. As one channel is taken up with the sequence, we can only use two channels now, so fine 460 is altered to take care of that.
The sequencer uses ADVAL(-8) to keep it supplied with notes and to ensure that the program does not grind to a halt. It also allows us to interrupt the main loop with calls to different envelopes and instructions to channels 1 and 2 without disturbing the sequence.

Altering the bass riff

The bass riff in the program is very simple but it can be extended to any length by adding more data. If you alter the pitch data, P%, to intervals instead of notes and add a BassPitch% variable such as:

346 BassPitch%=33
590 SOUND3,Env%,BassPitch%+P%,D%
620 DATA 0,4,0,4,12,4,20,4,-1,-1

you can alter the pitch of the sequence by changing BassPitch% during the program. Remember to alter all the loop lengths to accommodate the extra keys.
Due to the queuing of the commands on channel 3, the stored notes at the old Basspitch% will play before changing. To overcome this you could reduce the number of queued notes by raising the number of free spaces in the buffer as detected by the ADVAL statement at line 570, only changing to the new BassPitch%, when the data is RESTOREd.
You could program the sequencer to play the complete bass fine of a tune and play along with it and you could also add some rhythm to the sequencer like this:

565 IF ADVAL(5)>0 SOUND0,Env%,4,2

If the bass sequence is now louder than the keyboard, give the drums a separate, quieter envelope
It should not be too difficult to combine this program with the Rhythm Unit program in Chapter 7 and to incorporate also the envelopes and effects illustrated in the last two or three chapters. Here are some more bass lines to try:

REM Key G Minor
620 DATA 33,4,81,4,49,4,53,4,57,4,61,4,13,4,61,4,-1,1

REM Key G Minor
620 DATA 33,4,45,4,65,4,61,4,-1,-1

REM Key G Major
620 DATA 33,8,49 ,2,61,2,81,4,73,4,61,4,73,4,89,4,-1,-1

REM Key A Minor/G Major
620 DATA 41,4,49 ,4,53,4,33,4,49,4,61,4,-1,-1

REM Key C Minorish!: Set Env%=4 or Similar
620 DATA 5,16,17,16,13,16,9,16,-1,-1

Developing the sequencer

Apart from adding more envelopes, rhythms, sequences and effects, you might like to put a memory capability into the program so that it remembers what you have played and plays it back. This could be very useful. If you are improvising and play a good sequence of notes it is not always easy to remember later which notes you played.
To accomplish this, it would be necessary to include an incrementing variable in the program and to record the variable's value whenever a key is pressed or released. The notes would be stored in an array, the variable providing the subscript.
Taking the program even further, if you added editing facilities, allowed envelope changes during playback and had facilities for altering pitch and tempo you would be on the way to a miniature recording console. It is certainly a worthwhile exercise.
If you want to control and alter music to such a fine degree, the difficulty in playing the QWERTY keyboard does not make your job easy. Perhaps a better and more suitable solution is to preprogram the entire piece and let the computer manage the difficult passages. This is what we look at in the next chapter.


Next     Top