The ENVELOPE command is arguably one of the most difficult commands to master in BBC BASIC. Part of the problem lies in the fact that it must be followed by 14 parameters and used in conjunction with the SOUND command. This alone gives us a myriad of possibilities to choose from and the chances of getting things wrong are considerable.
The advantages of knowing what to do when searching for an effect, as opposed to resorting to a trial and effort method, cannot be overemphasised - unless you have a lot of time on your hands; and when does time pass more quickly than when you're programming your computer?
Chapter 7 explores the trial and effort method and how to get the most out of it - with the minimum of effort. This chapter explores the systematic method, one you will find infinitely rewarding once you are able to think of a sound and know immediately how to produce it.
The ENVELOPE command has two separate functions. The first is to control the amplitude of the sound and the second is to modulate the pitch. When a SOUND command is controlled by an envelope, amplitude control is automatically passed to the envelope. In order to produce a sound, the envelope must be configured to do so. Control over pitch is optional and can safely be ignored when experimenting with the amplitude parameters. The Hawaiian Guitar program in Chapter 3 demonstrates pitch control.
Using the notation on page 245 of the User Guide, the ENVELOPE command is followed by 14 parameters and described as follows:
ENVELOPE N,T,PI1,PI2, PI3,PN1,PN2,PN3,AA,AD,AS,
AR,ALA,ALD
The parameter names could have been slightly better chosen but, as these are in common use and many people will be used to thinking in these terms, there is little point in adding further complexities to the situation by introducing new ones. I think of the parameters in these terms:
Number of envelope
Time of each step
PItch 1
PItch 2
PItch 3
Pitch Number of steps 1
Pitch Number of steps 2
Pitch Number of steps 3
Amplitude change during Attack
Amplitude change during Decay
Amplitude change during Sustain
Amplitude change during Release
Amplitude Level for Attack phase
Amplitude Level for Decay phase
They may help, or you may have your own mnemonics. The parameters, their ranges and functions are fisted in Figure 5.1 for easy reference.
Exploration of the two aspects of envelope control will be much easier if they are considered separately and, if the six pitch parameters are set to 0, we can observe the effects of altering the amplitude section.
First, we will see how the loudness contour of a sound can be broken down into sections.
ADSR or Attack, Decay, Sustain and Release, has been mentioned in previous chapters in relation to the way in which the volume of a note varies during production. Although the ADSR principle is most commonly used to describe instrument characteristics, the favourite example used to explain it is that of a car approaching us along a straight road. We hear it very quietly at first and it gradually becomes louder until it draws level with us at which point it is as loud as it is going to get. The volume then immediately begins to decrease. If it stops a little further on for the driver to ask directions, the engine volume will remain constant. When it drives off again the volume will gradually fade to nothing. If we plot the volume against time, the resulting graph might well look like Figure 5.2.
This example is obviously very coarse and long (in terms of time), but the principle behind the volume variations involved are exactly the same as those which occur when an instrument produces a note. The note envelope, however, will usually be over in one or two seconds, often less.
Figure 5.1
Figure 5.2
For convenience, the loudness contour is divided into phases called attack, decay, sustain and release. In practice, some sounds have more phases but details of this nature will be of more interest to synthesists and are generally beyond the scope of the BBC micro - although such effects can be obtained by using two envelopes in succession.
This is when the sound first begins. It refers to the length of time required for the sound to reach a particular, usually maximum, volume. In the case of the car, the attack phase is long and builds up slowly. Most string instruments have a slow attack phase which might be around a quarter of a second. In contrast percussion instruments, such as the piano and drums, and plucked string instruments, like the guitar, have a fast attack phase and their sound reaches maximum volume immediately upon playing. Their attack phase might be as short as one hundredth of a second. Brass and woodwind have an attack rate somewhere in between.
If you have ever played a synthesiser, this is the sound you hear when you first hit a key.
This is what happens immediately after the attack phase and is the length of time taken for the volume to reach a second, usually lower, specific level. As its name implies, the sound usually decays or drops in volume during this phase, but it can remain the same or even increase. Notes from musical instruments tend to reduce in volume although some will stay the same.
The decay phase is often longer than the attack phase because whatever is producing the sound, be it a trumpet or a tin can, will be resonating or oscillating and the vibrations can't usually be stopped dead. A useful analogy, again, is the car which cannot pull to a halt without first slowing down - unless it hits a brick wall which takes us into another area of sound effects altogether. Instrumental sounds generally need at least a hundredth of a second or so to dampen down. This helps to explain why a backwards recording of ar} instrument sounds so strange - it dies away too rapidly. In fact, it doesn't die away, it's cut off. This is easily duplicated by electronic means and the ENVELOPE command makes it easy to produce on the BBC micro.
We have now touched upon the final stage of a sound - the release phase - and you will often find that the decay phase slides into the release phase. There is a difference, though, which will soon become apparent.
After the decay phase, the sound enters the sustain phase. As its name implies, the volume is sustained at a constant level and, because the sustain phase is not a measurement of time and the attack and decay phases are, it sometimes causes confusion. It may help to think of it as the volume level the sound is at after the decay phase and it could more accurately be termed a 'volume level'.
The BBC micro adds a further complication by allowing the volume to reduce during this phase. This is not in keeping with the technical definition of sustain phase and a reduction in volume is not always possible even on synthesisers.
On the BBC micro, the sustain parameter is 0 or a negative number. The length of the phase is determined by the duration parameter, D, of the SOUND command and the note will continue for that length of time unless the sustain parameter is a negative number and the volume reaches 0 before the duration time is up. When given a negative number, the sustain phase behaves like a second decay phase with a target level of 0.
For synthesiser players, the sustain phase is the volume at which the note continues to sound until you take your finger off the key.
If these descriptions seem to be getting a little involved and complicated, it is because of the flexibility of the amplitude envelope. The next program and accompanying explanations allow you to see and hear what we are talking about, so don't give up.
When the sound has gone through all the above phases, it reaches the stage where it will either continue forever or terminate. If it terminates, it can die away slowly or it can be cut off suddenly. This is the release phase.
The vibraphone and many percussion instruments have long release times and fade away slowly. String instruments don't take quite so long but you can still hear the note hanging there a little before it dies completely. This phase is a measurement of time, like the attack and decay phases, and determines how quickly the sound finally fades away.
The previous remarks describing why decay times are usually longer than attack times apply here, too. The release phase, in fact, is what many people would refer to as the decay of a note. ADSR is just a convenient way of subdividing the amplitude envelope into manageable sections and it is unlikely that confusion will arise over terminology as the meaning will usually be clear from the context.
On a synthesiser, the release phase begins when you remove your finger from the key. If you immediately hit another key, the release will not sound and the attack phase of the next note will occur. Like a synthesiser, the ENVELOPE command on the BBC micro allows the note to continue indefinitely or to fade at a predetermined rate. If another note is waiting in the sound queue, the release phase will not occur and the new note will sound immediately after the sustain phase.
The loudness contour of most instruments and many other sounds can be duplicated quite accurately by controlling the ADSR phases of the envelope.
You will probably have realised that not all sounds require all four phases. An electric organ for example has an attack, sustain and release phase but no decay. A wood block has an attack and a quick release and a plucked string on a guitar or banjo has an attack and a somewhat slower release. Some sample envelopes are shown in Figure 5.3.
You may have realised, or at least you will when you run the next program, that it is not always possible to determine where one phase ends and another begins. Sometimes the decay phase will lead straight into the release phase and the resulting sound will be just one long decay - or release. For a single note, the difference is not important but, if a note is followed by another one and its decay effect is produced by the release section of the envelope, it will be cut short.
You can program sounds without a decay phase or a sustain phase if you wish. Some synthesisers have a simplified envelope generator known as an AR generator which only allows the creation of an attack and a release phase.
Figure 5.3
We will now see how the ENVELOPE command tackles the problem of creating an ADSR envelope.
The best way to explore the ENVELOPE command is to be able to hear and see what is happening as you read about it. The following program allows you to alter the ADSR parameters and see and hear the resulting envelope. The program fines increment by 10. Even if you do not enter all the REM statements, put the fine numbers in so that you can easily add the Pitch Graph Generator described later in the chapter. To create a blank fine, enter the fine number, hit the space bar and RETURN.
10 REM PROGRAM 5.1
20 REM ADSR Graph Generator
30
40 *TV255,1
50 MODE1
60 PROCSetUp
70 PROCAxis
80 Input$="":PROCReset:PROCPrintEnv
90
100 REPEAT
110 *FX15,1
120 Input$=GET$
130 IF Input$=" " PROCSound
140 IF Input$>="1" AND Input$<="8" PRO
CEnv
150 IF Input$="C" PROCAxis
160 UNTIL Input$="Q"
170 END
180
190 DEF PROCSetUp
200 REM Set Text Window
210 VDU28,0,4,39,0
220 REM Set Graphics Window
230 VDU24,0;0;1279;860;
240 REM Background=Yellow
250 GCOL0,130:CLG
260 REM Foreground=Black
270 GCOL0,0
280 REM Set COLOUR 1 to Flashing
290 VDU19,1,9,0,0,0
300
310 REM Set Initial Parameters
320 PI1=0:PI2=0:PI3=0
330 PN1=0:PN2=0:PN3=0
340 T=20:T1=T:Pitch=10:Pit1=Pitch
350 AA=126:AD=-4:AS=-1:AR=-6
360 ALA=126:ALD=80:Duration=80
370 REM Marker for X Axis
380 VDU23,224,128,128,128,128,128,128,
128,128
390 ENDPROC
400
410 DEF PROCAxis
420 YScale=6
430 CLG
440 VDU29,0;0;
450 MOVE50,0:DRAW50,860
460 MOVE0,50:DRAW1279,50
470 VDU5
480 FOR Mark%=0 TO 780 STEP YScale*10
490 MOVE20,Mark%+YScale*10:PRINT"-"
500 NEXT Mark%
510 FOR Mark%=50 TO 1250 STEP 100
520 MOVEMark%,50:PRINTCHR$224
530 NEXT Mark%
540 VDU 4
550 REM Set Graphics Origin
560 VDU29,50;50;
570 ENDPROC
580
590 DEF PROCEnv
600 PROCReset
610 IF Input$="1" t=1
620 IF Input$="2" aa=1
630 IF Input$="3" ad=1
640 IF Input$="4" as=1
650 IF Input$="5" ar=1
660 IF Input$="6" ala=1
670 IF Input$="7" ald=1
680 IF Input$="8" dur=1
690 PROCPrintEnv
700 PROCAlter
710 PROCPrintEnv
720 ENDPROC
730
740 DEF PROCReset
750 b=3:t=3:aa=3:ad=3:as=3:ar=3
760 ala=3:ald=3:dur=3
770 ENDPROC
780
790 DEF PROCPrintEnv
800 COLOURb:PRINTTAB(0,0)"ENV1,";:COLO
URt:PRINT;T;
810 COLOURb:PRINT;",";PI1;",";PI2;",";
PI3;",";PN1;",";PN2;",";PN3;",";
820 COLOURaa:PRINT;AA;:COLOURb:PRINT;"
,";:COLOURad:PRINT;AD;:COLOURb:PRINT;","
;
830 COLOURas:PRINT;AS;:COLOURb:PRINT;"
,";:COLOURar:PRINT;AR;:COLOURb:PRINT",";
840 COLOURala:PRINT;ALA;:COLOURb:PRINT
;",";:COLOURald:PRINT;ALD:COLOURb
850 COLOURdur:PRINTTAB(14,1)SPC(4)TAB(
10,1)"Dur=";Duration:COLOURb
860 ENDPROC
870
880 DEF PROCAlter
890 INPUT NewVal$:PRINTTAB(0,2)SPC(6)
900 IF NewVal$="" PROCReset:PROCPrintE
nv:ENDPROC
910 NewVal=EVAL(NewVal$)
920 PRINTTAB(30,0)SPC(20)
930 ON EVAL(Input$) GOTO940,950,960,97
0,980,990,1000,1010
940 T=NewVal:T1=T:ENDPROC
950 AA=NewVal:ENDPROC
960 AD=NewVal:ENDPROC
970 AS=NewVal:ENDPROC
980 AR=NewVal:ENDPROC
990 ALA=NewVal:ENDPROC
1000 ALD=NewVal:ENDPROC
1010 Duration=NewVal:ENDPROC
1020
1030 DEF PROCSound
1040 ENVELOPE1,T,PI1,PI2,PI3,PN1,PN2,PN
3,AA,AD,AS,AR,ALA,ALD
1050 SOUND1,1,Pit1,Duration
1060 REM Clear Last Timing Results
1070 PRINTTAB(0,4)SPC(39);:PRINTTAB(0,4
);
1080 IF T=0 T1=1
1090 IF T=128MT1=129
1100 Time=0:Amp=0
1110 MOVE0,0
1120 YScale=6
1130 PROCAttack
1140 PROCPrint("A",8,32)
1150 IF OverTime GOTO 1210
1160 PROCDecay
1170 PROCPrint("D",8,32)
1180 IF OverTime GOTO 1210
1190 PROCSustain
1200 PROCPrint("S",8,32)
1210 PROCPrint("r",40,16)
1220 PROCRelease
1230 PROCPrint("R",0,0)
1240 PRINT;"Secs";
1250 ENDPROC
1260
1270 DEF PROCAttack
1280 REPEAT
1290 Amp=Amp+AA
1300 IF Amp>ALA Amp=ALA
1310 DRAW Time,Amp*YScale
1320 Time=Time+T1 MOD128
1330 PROCTimeCheck:IF OverTime GOTO1350
1340 DRAW Time,Amp*YScale
1350 UNTIL OverTime OR Amp=ALA
1360 ENDPROC
1370
1380 DEF PROCDecay
1390 REPEAT
1400 Amp=Amp+AD
1410 IF ALD
1430 IF ALD=ALA Amp=ALD
1440 DRAW Time,Amp*YScale
1450 Time=Time+T1 MOD128
1460 PROCTimeCheck:IF OverTime GOTO1480
1470 DRAW Time,Amp*YScale
1480 UNTIL OverTime OR Amp=ALD
1490 ENDPROC
1500
1510 DEF PROCSustain
1520 REPEAT
1530 Amp=Amp+AS
1540 IF Amp<0 Amp=0
1550 DRAW Time,Amp*YScale
1560 Time=Time+T1 MOD128
1570 PROCTimeCheck:IF OverTime GOTO1590
1580 DRAW Time,Amp*YScale
1590 UNTIL OverTime OR Amp=0
1600 ENDPROC
1610
1620 DEF PROCRelease
1630 REPEAT
1640 Amp=Amp+AR
1650 IF Amp<0 Amp=0
1660 DRAW Time,Amp*YScale
1670 IF Amp=0 GOTO1700
1680 Time=Time+T1 MOD128
1690 DRAW Time,Amp*YScale
1700 UNTIL Amp=0
1710 ENDPROC
1720
1730 DEF PROCTimeCheck
1740 OverTime=FALSE
1750 IF Time>Duration*5 Time=Duration*5
:OverTime=TRUE
1760 ENDPROC
1770
1780 DEF PROCPrint(Phase$,Oset1,Oset2)
1790 IF Phase$="R" GOTO1860
1800 VDU5
1810 MOVE Time+Oset1,Amp*YScale+Oset2
1820 PRINTPhase$
1830 MOVE Time,Amp*YScale
1840 VDU4
1850 IF Phase$="r" ENDPROC
1860 PRINTPhase$;"=";Time/100;" ";
1870 ENDPROC
When run, the program will print envelope parameters along the top of the screen and a duration value just below. The pitch values have been set to 0 but can be altered in PROCSetUp. They can't be altered during the course of the program and will not effect the graph which shows only the ADSR envelope.
If you press the space bar, the current envelope will sound and its ADSR graph will be displayed on the screen. The Y (vertical) axis is scaled in amplitude units of 10. The X (horizontal) axis is in seconds. The keys 1 to 8 allow you to alter the amplitude and duration parameters. 1 will alter T, 2 will alter AA, 3 will alter AD, etc. 8 alters the duration. Selection of one of these will cause the present value to flash on and off in red and cyan and a '?' prompt will appear under the envelope. Input the new value and press RETURN and the new envelope will be displayed. If you press RETURN without entering a figure the option will be cancelled and the envelope will remain the same.
10 REM PROGRAM 5.1A
20 REM Function Key SetUp for
30 REM ADSR Graph Generator
40
50 REM CLEAR
60 *KEY0 C
70 REM T
80 *KEY1 1
90 REM AA
100 *KEY2 2
110 REM AD
120 *KEY3 3
130 REM AS
140 *KEY4 4
150 REM AR
160 *KEY5 5
170 REM ALA
180 *KEY6 6
190 REM ALD
200 *KEY7 7
210 REM Duration
220 *KEY8 8
230 REM SOUND
240 *KEY9 " "
PROCSetUp and PROCAxis are self-explanatory. The main program works through the REPEAT loop in lines 100 to 160.
It is as well to point out now that the volume level can only vary through 16 states which range from - 15 (maximum volume) to 0 (off). The parameters we feed into the ENVELOPE command would have us believe otherwise but you can hear the 16 discrete intervals quite easily with large values of T. Rather than try to show volume variations in terms of these 16 steps, the program produces steps according to the ENVELOPE parameters.
If you follow the parameter ranges listed in Figure 5.1, you will not go out of bounds but there are other things you need to be aware of:
1) The T parameter determines the length of each step in hundredths of a second. This affects both the amplitude and the pitch envelopes and is critical to both. It determines how often the sound is updated by the OS. With T set to 1, the sound is checked and updated every hundredth of a second. If T is 5, it is only updated every twentieth of a second. The update is in the form of a new pitch or volume command. This supersedes the old value and, when T is greater than I, you can hear the new value taking over from the old one. This results in the stepped effect which we have discussed.
2) AA can have a positive or a negative value. A negative value is only of use if it can decrement a positive value. IF a sound follows a sound with a positive amplitude (eg a one whose volume has not yet fallen to zero) then AA can be negative but ALA must be set below the existing amplitude level. This can't be clearly shown in this program as it only deals with one SOUND and ENVELOPE command at a time and all new sounds begin with an amplitude of 0. If, however, you attempt to reach a positive ALA level with a negative AA value, the amplitude level will simply jump to the ALA value. The program, of course, will try to draw it - unsuccessfully.
3) Likewise, AD can take a positive or negative value. Usually it is negative but, if ALA is below the 126 maximum, it can have a positive value and the amplitude will continue to increase. If AD is set to 0 the sound will continue at the ALA level until the sustain phase is reached, regardless of the ALD value.
4) AS must be 0 or negative. This controls how quickly the sound decays over the remainder of the duration period. The target amplitude for the sustain and release phases is always 0.
5) AR must also be 0 or negative. If it is 0 and the amplitude has not reached 0, the sound will continue indefinitely and the graph will try to draw it. AR comes into play as soon as the duration period has expired and you will notice that, if any phase fails to complete before the duration has expired, the sound immediately passes to the release phase.
6) A duration of 255 will also make the sound last indefinitely.
The best way to discover how the ADSR envelope works is to experiment with the program. You can add extra error-checking routines if you wish. This will be easy if they simply restrict inputs to the ranges in Figure 5.1, but, for complete error-checking, this is not enough. It would be necessary to ensure, for example, that a positive AD value leads to an ALD value higher than ALA. You could also add a scaling feature so that envelopes over 12 seconds would fit the screen. It is possible to produce envelopes lasting several minutes although they may be monotonous to listen to. The program will draw most envelopes.
Attack Time=ALA/AA*T
To calculate the decay time we need to take into account the amplitude at the start of the decay phase:
Decay Time=ABS(ALA-ALD)/ABS(AD)*T
The ABS function (see User Guide page 200) ensures all values are positive.
You may be relieved to know that this is slightly easier to understand than the amplitude envelope. This is the part of the envelope which allows us to create many weird and wonderful effects as well as more subtle musical sounds.
The six pitch parameters are paired up, PI1 with PN1, etc, and each set of two acts in the same way PI determines the change of pitch per step much as AA and AD, etc determine the change of amplitude per step. The PN parameter determines the number of steps in its corresponding PI section and has no direct amplitude envelope equivalent. If it did, it would be calculated from the formulae given above, but omitting T from the calculation.
Figure 5.4
Figure 5.5a
Figure 5.5b
When you write your own programs, be careful not to include PI as a variable or it will be taken as the constant PI with a value of 3.14159265. The use of PH and PI2, etc is quite acceptable.
After running the previous program, you will now want to see what the pitch envelope looks like. The following additions can be made to the last program and will allow you to alter the pitch and pitch envelope parameters in a similar way to the ADSR parameters in the last program. Seven fines need to be added to the body of the program, two need to be altered and the rest is added to the end.
9 REM PROGRAM 5.2 (Combined)
10 REM PROGRAM 5.1
19 REM ADSR & PITCH Graph Generator
20 REM ADSR Graph Generator
24 REM Added Line Numbers are not
25 REM Multiples of 10 and are+
26 REM 75,145,762,764,855,1242,1244
27 REM Plus 2000 to 2670
29 REM Altered Lines=150,810
35
75 PROCAxis2
145 IF Input$>="!" AND Input$<="'" Inp
ut=ASC(Input$):PROCPitEnv
762 pi1=3:pi2=3:pi3=3
764 pn1=3:pn2=3:pn3=3:p=3
810 COLOURb:PRINT;",";:COLOURpi1:PRINT
;PI1;:COLOURb:PRINT;",";:COLOURpi2:PRINT
;PI2;:COLOURb:PRINT;",";:COLOURpi3:PRINT
;PI3;:COLOURb:PRINT;",";:COLOURpn1:PRINT
;PN1;:COLOURb:PRINT;",";:COLOURpn2:PRINT
;PN2;:COLOURb:PRINT;",";:COLOURpn3:PRINT
;PN3;:COLOURb:PRINT;",";
855 COLOURp:PRINTTAB(23,1)SPC(6)TAB(18
,1)"Pitch=";Pit1:COLOURb
1242 FinalTime=Time
1244 PROCPitchEnv
2000 DEF PROCAxis2
2010 YScale=3
2020 VDU29,0;0;
2030 VDU5
2040 FOR Mark%=60 TO 780 STEP YScale*10
2050 MOVE40,Mark%+YScale*10:PRINT"-"
2060 NEXT Mark%
2070 VDU4
2080 VDU29,50;50;
2090 ENDPROC
2100
2110 DEF PROCP(pi,pn)
2120 FOR P%=1 TO pn
2130 Pitch=Pitch+pi
2140 IF Pitch>255 Pitch=Pitch MOD256
2150 IF Pitch<0 Pitch=Pitch+256
2160 DRAW Time,Pitch*YScale
2170 Time=Time+T1 MOD128
2180 PROCFinalTimeCheck:IF FTime P%=pn
2190 DRAW Time,Pitch*YScale
2200 NEXT P%
2210 ENDPROC
2220
2230 DEF PROCPitEnv
2240 PROCReset
2250 IF Input=33 pi1=1
2260 IF Input=34 pi2=1
2270 IF Input=35 pi3=1
2280 IF Input=36 pn1=1
2290 IF Input=37 pn2=1
2300 IF Input=38 pn3=1
2310 IF Input=39 pn3=1
2320 PROCPrintEnv
2330 PROCAlterPit
2340 PROCPrintEnv
2350 ENDPROC
The combined programs are quite long and disk users may get a No Room error when running, especially if the function key program has been added. The extra memory required is not a lot and the problem is most quickly solved by lowering PAGE before loading and running. Enter:
PAGE=&1100
before loading. The program will sit in memory quite easily; it is only when MODE 1 is selected that it discovers it has not enough room. Do not press BREAK otherwise PAGE will be reset and you will probably lose the program.
You now have control over pitch and the six pitch envelope parameters. These are accessed by pressing SHIFT and the keys 1 to 7, ie the characters !, ", #, $, %, & and '. You may find it more convenient to use the function keys to control the ADSR parameters, set SHIFT LOCK and use the number keys for the pitch parameters. In practice, once you are familiar with the ADSR envelope, you will probably leave it set (alter the initial parameters in lines 340 to 360) and concentrate on the pitch envelope
The main additions are PROCAxis2 to draw the second Y axis and the inclusion of p, pi and pn colour values in PROCReset in fines 762 and 764. Line 810 puts them into PROCPrintEnv. Note the change of YScale in line 2010 and 2520 during the drawing of the pitch graph.
It is worth demonstrating that, although the three PI and PN parameters perform the same functions, they do not always behave as you might expect - and hope. For example try this:
10 ENVELOPE1,20,4,0 ,0,1,0,0,126,-1,0,-6,126,80
It is the same as this:
10 ENVELOPE1,20,4,0,0,1,0,1,126,-1,0,-6,126,80
The value of PI1, 4, takes the pitch up a semitone and it stays there. One might expect the same result to follow from this:
10 ENVELOPE1,20,0,0,4,0,0,1,126,- 1,0,-6,126,80
All we've done is to transfer the working parameters to another of the three PI/PN sets. Even more peculiar is this:
10 ENVELOPE1,20 ,0,0,4,1,0,1,126,- 1,0, -6,126,80
This envelope produces an oscillating effect while the second example doesn't because the T parameter is set to auto repeat and, when the pitch phase completes, the pitch is set back to its original value before beginning again. In the second example, PI1 acts immediately upon the pitch to raise it a semitone. This is one factor which can cause a few problems when trying to work out a precise pitch effect and on such occasions it is always worth trying out the envelope with no repeat.
The User Guide tells us that if bit 7 of T is set to 0 the pitch envelope will auto repeat, and if it is set to 1 it will only sound once. This was mentioned in the ADSR section but now we will examine it more closely.
Apart from idiosyncracies you may come across in the SOUND and ENVELOPE commands, you will find that being able to relate the numbers to a visual representation of the sound is a great help in mastering the commands. If you are searching for a specific effect and can see a visual result of your efforts, you will find it easier to make adjustments and find out why a sound may not be behaving as you expect.
1045 SOUND 0,-15,3,254
If you set the ADSR parameters to 0 you will hear the results of the pitch envelope on channel 1 working through channel 0. The noise channel is examined more thoroughly in Chapter 7.
To aid further experiments, Figure 5.6 describes the characteristics of some common instruments which you may like to convert into envelope parameters.
Figure 5.6
You do not have to try to faithfully imitate an instrument - create your own. The characteristics are there for information only, feel free to use them or ignore them completely, according to your musical tastee 5.6
If you want to take your interest in music and the BBC micro even further, there are ways to produce waveforms other than the square wave of the sound chip. These involve connecting a digital to analogue converter to your system, and setting up the computer to produce cycles of a particular wave in a similar way to the Sine Wave Plotter program in the first chapter. The cycles are generated by rapidly altering the contents of a series of memory locations and you need to program in assembly language to produce the cycles fast enough to be of use.How to use the program
You can alter parameters and draw one envelope over another. Pressing 'C' will clear the screen for a new graph. Press 'Q' to quit the program.
If you wish, you can define the function keys to produce the required input and label them accordingly. This will be useful particularly if you add the Pitch Graph Generator program later in the chapter.
Run this before loading the ADSR Graph Program, or renumber and add it to the end of the main program as a separate procedure. When the graph is displayed, the letters A, D and S will appear on the screen at a point immediately following completion of that part of the envelope phase. The letter r will appear when the release phase begins. A release phase will always end at 0 (except when it is infinite) unless it is prematurely terminated by another SOUND command or unless the channel is flushed. This will not happen in this program as we are dealing with only one note at a time.
A running total of the time taken so far, in seconds, is printed after each phase along the bottom of the text screen, the time after R is the total time taken for the execution of the envelope. This includes the release phase. Very fast attack times will be printed in exponent format (see the User Guide pages 225 and 236 for details of print formats).
Program notes
PROCSound produces the sound you have set up in the envelope and then initiates the graph-drawing procedures.
The Pitch and T variables are given assistants in Pitl and Tl. This is so that we can modify these parameters to make allowances for the way these values work in the ENVELOPE command, as in lines 1080 and 1090, without disturbing the original values.
YScale increases the Y values of the graph so it fills the screen. The X axis represents seconds and one X displacement represents one hundredth of a second.
PROCAttack, PROCDecay, PROCSustain and PROCRelease are similar and a description of PROCAttack will cover the principles involved. The amplitude is first incremented by AA, checked to see it is not greater than the ALA level and then drawn. Time is incremented by Tl - MOD 128 so that it stays within amplitude boundaries - and checked to see if it is greater than the D parameter. If not, it is drawn along the 3£ axis. These two DRAW commands produce the stepped effect which you will hear with anything but the smallest values of T.
If the input is a number it calls PROCEnv which controls the text display and the alteration of parameters. The parameters flash because they are given their own colour value which is used with the COLOUR command just before printing in PROCPrintEnv. PROCReset sets all colours to white and PROCEnv sets the selected parameter's colour to flash. PROCAlter accepts a new input and allocates it to the selected parameter. PROCPrintEnv prints the new envelope and returns to the main loop.
PROCPrint prints A, D, S and r at the appropriate time and place upon completion of the appropriate phases.
In order to keep the program to a reasonable length there is no scaling, so sounds which last more than 12 seconds will run off the graph, and there is no error-checking. You can input almost any value and get some sort of sound from the program but, unless the values follow the parameter ranges set out in Figure 5.1, the graph will not always follow the sound accurately
The volume range: hardware and software differences
The important areas of the graph are the start and end points of the various phases. The steps will indicate the amount of software movement produced by the envelope, not by the sound chip.
Now, having mentioned it, it will probably be better to ignore it. You will find it easier to construct envelopes as if the volume varied through the whole envelope range and, in practice, you will find that the difference will have little effect upon your envelopes. This information will be of use if you want to write direct to the sound chip (apart from which it explains why you can only hear l6 pitch variations)
A detailed look at the amplitude commands
When T equals 0 it produces the same effect as when it is set to 1 and the resulting sounds will be the same.
Values of T over 127 determine whether or not the pitch envelope repeats. A value of 129 produces the same amplitude envelope as a value of 1. A value of 128 is the same as a value of 0 (which is the same as a value of 1). Large values of T will run off the screen.
It is worth noting that, to move from an ALA of 126 to an ALD of, say, 100, setting AD to - 126 will get you there no quicker than setting it to -26 as it only needs to be reduced by 26 to reach the ALE) and it will only take one T step to do so.
Using the program and further suggestions
The program is also useful for calculating the exact time taken by particular phases of the envelope and it is interesting to alter just one parameter and compare the resulting effects. Synthesists may find it easier to relate to a specific attack time rather than an attack increment. The times taken by the attack and decay phases are not explicitly stated in the ENVELOPE command. Both phases end when the amplitude has reached its preset value or when the duration has expired. Apart from using the program, the attack time can be calculated by the following, assuming the duration is long enough to allow it to complete:
I haven't included any sample envelope parameters - discovering your own is far better and far more interesting - but the instrument characteristics table near the end of this chapter may give you some ideas to experiment with.
The pitch envelope
As the amplitude envelope varies the volume of the note over a period of time, so the pitch envelope varies the pitch of the note. The initial frequency on which the pitch envelope works is determined by the value of P in the SOUND statement.
PI and PN: the pitch change and the number of steps
The change of pitch referred to by PI is in quarter of a semitone increments, the same as the SOUND statement, so a value of 4 will produce a pitch change of a semitone.
Figure 5.4 shows how a single PI/PN pair might affect the pitch. Figure 5.5 illustrates two complete pitch envelopes. Note that the value of T does not affect the actual pitch changes, only the speed with which they alter and whether or not the envelope repeats. Large values of T will make the individual changes more obvious.
The Pitch Graph Generator program
When entering line 810, enter PRINT in its abbreviated form (ie P.) otherwise it will not fit into one line. (See the User Guide page 484.)
The removal of REM statements is another alternative but beware of coming back to the program a few weeks later and wondering what the various sections do. Cassette users will have no memory problems.
Using the program
A second set of points along the Y axis indicates the pitch values and is scaled in units of 10. The X axis is still the same and is in seconds. The ADSR graph is drawn first, followed by the pitch graph. Some envelopes can take quite a while to draw and when superimposing one graph on another it is not always possible to tell when a graph is finished. So, when complete, a double '??' prompt indicates that the program is ready for further instructions.
Program notes
The input at line 145 allows us to input a string containing the double quotes character (") but this is changed to an ASCII value to allow easy handling of the input.
PROCPitEnv serves the same purpose as PROCEnv, and PROCAlterPit is similar to PROCAlter.
Like T, Pitch has an assistant in Pit1, so whatever value the pitch actually reaches during the envelope execution, the program knows the original pitch value. See lines 2490, 2530, 2580 and the original 340.
The drawing is done by PROCP which is the same for all three PI/PN pairs and is called with the three sets of parameters by PROCPitchEnv. In line 2590, if T is greater than 127, ie the envelope is set not to repeat, the pitch envelope is only drawn once.
The total duration of the sound after the ADSR graph has been drawn is put into FinalTime as the pitch envelope will continue until the release phase completes. PROCFinalTimeCheck performs a similar function to PROCOverTime.
There is still no error-checking and out of range parameters will produce incorrect graphs, but we do not have to worry about whether or not we are moving up or down to ALA or ALD levels.
Apparent peculiarities of the pitch envelope
20 SOUND1,1,101,80
20 SOUND1,1,101,80
20 SOUND1,l,101,80
20 SOUNDl.1.10l.80
You may wonder why you would want to set a PN parameter if its corresponding PI value is 0. Even with a PI value of 0 the PN parameter creates a gap or time span with no new pitch change. This can be used to create a delay before a pitch modulation.
Notice also that, if a pitch envelope tries to take the pitch over 255 or under 0, it will add or subtract 256 to bring it within range. This can produce some fascinating effects which can be seen on the graph.
The value of T and bit 7
To understand what a bit is, it is necessary to know a little about the binary system. A complete discussion is beyond the scope of this book but the following explanation may help a little.
Bit stands for BInary digiT, which is the term given to the individual digits which go to make up a binary number. For a variety of reasons it is convenient to work with binary numbers containing eight digits. Computers count, more often than not, beginning at 0, unlike humans who tend to start counting at 1. These eight digits or bits are numbered 0 to 7 from right to left. Bit 7, therefore, is the leftmost digit which will have a value of 128 (2^7) in the binary system. If this bit is set to 1, ie 1*2^7, then the value will be increased by 128.
On page 245 the User Guide gives the range of T as being from 0 to 127, and on page 182 from 1 to 127. If T equals 0, the envelope operates as though T equals 1 and I suggest 1 to 127 as the correct range. If you add 128 to the value of T you are setting the seventh bit to 1. As far as the ADSR envelope is concerned, it reduces any value over 128 by the MOD command (see User Guide paige 299) so 128 MOD 128=0 or, as I would have it, the upper range should run from 129 so we would say 129 MOD 128=1. By this reckoning, 130 has the same effect as 2, 131 as 3, etc. If you put larger values in, they are still reduced so, for example, 12345 MOD 128=57.
The pitch envelope does the same thing only it takes note of whether or not the seventh bit has been set. If it has not, it repeats its envelope.
Experimenting with the programs
Further experiments can be done by including the noise channel and controlling its frequency from channel I by setting the P parameter to 3 or 7 as follows:
Instrument characteristics
Bearing in mind the limitations of the sound chip, you are unlikely to produce exact imitations; but remember that one man's clarinet is another man's oboe so do program sounds which you like. With the addition of a few frills, courtesy of the pitch envelope, you can create a most acceptable micro orchestra. The next chapter looks at how to create and use such frills, which we refer to as musical ornaments.
The octave range in Figure 5.6 refers to the notes on the staves in figure 2.4. For example, the octave range 2 to 4 extends from pitch number 53 to 193. As we have offset the keyboard in Figure 2.4 to compensate for the predominantly high notes of the sound chip, remember that the actual instruments are pitched an octave lower.
The envelope shapes are described in terms of attack and decay. In this context, the decay refers to the release phase. Our ADSR decay phase will run along similar lines to the sample instrument envelopes in Figure 5.3. The sustain phase will vary. An organ note can have an infinite sustain, a guitar string has none and a trumpet can last as long as the player can keep blowing.
Producing other waveforms
The information required to implement such a process would fill several more chapters, if not a book, and is mentioned here only to illustrate the possibilities open to the experimenter.
The addition of a proper musical keyboard and separate synthesiser voice modules is another possibility but we'll leave all that to the more experienced and adventurous explorer.