Mastering Sound Using BASIC Part 4
Files:
MM4PROG - BASIC
In this article we hope to re-establish in a concise form what we have already covered to bring up-to-date new subscribers, and to provide an easy reference for previous followers of the series.
The SOUND Command. (BBC User Guide page 347 or Master Welcome guide page 97)
The SOUND command uses four parameters to define its action. The command is used as follows :
SOUND &HSFC,A,P,D
The parameters have the following meaning :
&HSFC - this is a four digit hexadecimal number, each digit is used to indicate a different action of the sound command.
C - This refers to the sound channel [0..3] which the command is instructing. A sound channel is a part of the computer's hardware which can generate a single sound (more than 1 can be used to create chords etc).
H - Continuation [0..1] - If this is a 0 then the following parameters are used to generate a new note, if this is a 1 then they are ignored and the command produces a continuation of the previous note played on that channel.
S - Synchronization [0..3] - instructs the computer to hold the current commands execution until "S" number of other channels have a command given to them.
F - Flush [0..1] - if this is 1, it causes the current command to take effect immediately without waiting for any note on the sound channel (or waiting to be played on the channel) to finish. (0 has no effect)
N.B. Leading zeros may be removed from hexadecimal numbers (eg &0011 can be &11). Numbers also can be converted to decimal (eg &1203 can be given as 4611). Note that &0=0, &1=1, &2=2, &3=3.
A - Amplitude/envelope [-15..16] - when in the range [-15..0] indicates volume (-15 - loudest, 0 - silent), when in range [1..16] indicates envelope.
P - Pitch [0..255] represents the pitch of the note to play in eighth tones. Middle C is 53.
D - Duration [1..255] this is how long the note should play for (in 20ths of a second).
Channel 0 is a special channel called the noise channel it can produce either a hissing noise or can produce deep bass notes when used in conjunction with channel 1.
There are eight possibilities for the pitch value used with the noise channel :
0 - General bass sound (High frequency)
1 - General bass sound (Med frequency)
2 - General bass sound (Low frequency)
3 - Bass sound (frequency dependant on frequency of current sound on channel 1)
4 - High hiss
5 - Medium hiss
6 - Low hiss
7 - Hiss (frequency dependant on frequency of current sound on channel 1)
N.B. Pitch values for other 3 channels can be found in user guides.
Envelopes
The envelope affects the way in which the volume and frequency of a note are altered through the duration of the sound command.
Volume Alteration
This is based on values called the ADSR values.
A - Attack - rate at which the note hits maximum volumes and definition of that maximum.
D - Decay - the rate at which the note initially dies away and where it stops decaying.
S - Sustain - rate at which the note's volume changes during most of its duration.
R - Release - rate at which the note dies away to nothing after its defined duration is complete.
Pitch Alteration
The changing of pitch during the duration of a note can be used for special effects such as vibrato or wacky noises.
The ENVELOPE Command. (BBC User Guide Page 244)
The ENVELOPE command has 14 parameters following it. These are commonly referenced as :
N, T, PI1, PI2, PI3, PN1, PN2, PN3, AA, AD, AS, AR, ALA, ALD
N - This is the envelope number [1...16].
T - Length of each step in centiseconds [0...127]. (add 128 to the value if the pitch envelope is not to be repeated).
PI1 - Pitch change per step in pitch section one [-128...127].
PI2 - Pitch change per step in pitch section two [-128...127].
PI3 - Pitch change per step in pitch section three [-128...127].
PN1 - Number of steps in pitch section one [0...255]
PN2 - Number of steps in pitch section one [0...255]
PN3 - Number of steps in pitch section one [0...255]
AA - Change of volume per step during attack phase (attack rate) [-127...127]
AD - Change of volume per step during decay phase (decay rate) [-127...127]
AS - Change of volume per step during sustain phase [-127...0]
AR - Change of volume per step during release phase [-127...0]
ALA - The volume which the attack phase brings the note to [0..126]
ALD - The volume which the decay phase brings the note to [0...126]
How The Parameters Are Used
The envelope command works in steps. Each step is of equal length and is defined by "T" (centiseconds). The current volume on the channel is used as the start. The envelope's attack and decay phases are performed for as long as the duration will allow if these are complete before the end of the duration of the note, the sustain phase is performed. After the duration, the release phase is performed.
The pitch envelope has three sections, each is acted upon in turn (repeated only if T<128). Each section can be given a number of steps that it will be active for, and can be given a value that it alters the pitch by each step.
Music Programs
The above commands may be used to produce music. One method is to string several commands together to play a tune. However, this is very long-winded. Therefore, a program which uses data to hold the parameters for the sound commands can be used for space efficiency.
The simplest method of doing this is to have all of the HSFC,A,P,D values in data statements at the end of a program which reads them and places them into sound commands. This can work but can also waste space and be difficult to edit.
One possible method would be to standardise the duration of every channels' notes (using continuation for longer notes) and to store data for each of the channels' pitches/envelopes (in sets of four in standard order). With a standard duration, this means that each set of four can be used to reconfigure all of the sound channels each beat or fraction of (depending on duration), and the computer will only have to store the pitch and envelope since it will know the channel and duration data. Since the computer is always playing groups of four notes together a synchronization of value 3 will be used, and flushes would not be necessary. Some special pitch value (eg -1) could be used to indicate a continuation (H) rather than a new note.
An example of the data required to play some music might be :
1,3, 2,53, 3,69, 2,81
0,-1, 2,53, 0,-1, 0,-1
1,3, 2,73, 3,89, 2,101
0,-1, 0,-1, 3,89, 0,-1
This is confusing to say the least.
1,2,3,2
"3 3 "
"==B "
"A FF"
"D I "
The above looks just as confusing until we study it in detail. The first line contains the envelope numbers that will be used by each of the channels in turn, and each COLUMN of the preceding four lines represents a beat's worth of channel reconfiguration. It is now quite easy to see when each channel is playing a new note (a space denotes a continuation). Each character used represents a single pitch.
Eg. "=" - middle C
"A" - E
This method is illustrated by the program below.
10 ENVELOPE 1,2,0,0,0,0,0,0,126,-2,0,-1,126,110
20 ENVELOPE 2,1,0,0,0,0,0,0,100,-3,0,-3,100,80
30 DIM e(3)
40 DIM frame$(3)
50 noofframes=1
60 key=1
70 FORread = 1 TO noofframes
80 READ e(0),e(1),e(2),e(3)
90 READ frame$(0),frame$(1),frame$(2),frame$(3)
100 length=LEN(frame$(0))
110 FORcolumn=1 TO length
120 FORchannel=1 TO 3
130 ascii=ASCMID$(frame$(channel),column,1)
140 pitch=((ascii-48)*4)+key
150 IF ascii=-1 OR ascii=32 THEN H=&1000 ELSE H=0
160 SOUND H+&300+channel,e(channel),pitch,1
170 NEXTchannel
180 ascii=ASCMID$(frame$(0),column,1)
190 pitch=ascii-48
200 IF ascii=32 THEN H=&1000 ELSE H=0
210 SOUND H+&300,e(0),pitch,1
220 FORtime=1TO200:NEXTtime
230 NEXTcolumn
240 NEXTread
250 END
260 DATA 2,1,1,1
270 DATA "5 5 5 5 5 5 5 5 "
280 DATA "1 3 5 6 8 : < = "
290 DATA "5 8 8 "
300 DATA "8 6 5 "
The variable noofframes is used to indicate how many blocks of data are to be read.
Imagine that you want to play the first block of data twice and then play the third followed by the second and then the first again. You are unable to do this without repeating the individual blocks. Therefore a device to specify the order of playing the blocks must be used. This is a string at the beginning of the program which contains a number of characters. Each character refers to a single block. The reading program goes through the string character by character and plays the block specified by it.
Below is a program which uses that method :
10 ENVELOPE 1,2,0,0,0,0,0,0,126,-2,0,-1,126,110
20 ENVELOPE 2,1,0,0,0,0,0,0,100,-3,0,-3,100,80
30 DIM e(3)
40 DIM frame$(3)
50 P$="001101"
60 key=1
70 FORread = 1 TO LEN(P$)
80 char$=MID$(P$,read,1)
90 blockline=((ASC(char$)-48)*50)+290
100 RESTORE blockline
110 READ e(0),e(1),e(2),e(3)
120 READ frame$(0),frame$(1),frame$(2),frame$(3)
130 length=LEN(frame$(0))
140 FORcolumn=1 TO length
150 FORchannel=1 TO 3
160 ascii=ASCMID$(frame$(channel),column,1)
170 pitch=((ascii-48)*4)+key
180 IF ascii=-1 OR ascii=32 THEN H=&1000 ELSE H=0
190 SOUND H+&300+channel,e(channel),pitch,1
200 NEXTchannel
210 ascii=ASCMID$(frame$(0),column,1)
220 pitch=ascii-48
230 IF ascii=32 THEN H=&1000 ELSE H=0
240 SOUND H+&300,e(0),pitch,1
250 FORtime=1TO200:NEXTtime
260 NEXTcolumn
270 NEXTread
280 END
290 DATA 2,1,1,1
300 DATA "5 5 5 5 5 5 5 5 "
310 DATA "1 3 5 6 8 : < = "
320 DATA "5 8 8 "
330 DATA "8 6 5 "
340 DATA 2,1,1,1
350 DATA "5 5 5 5 5 5 5 5 "
360 DATA "= < : 8 6 5 3 1 "
370 DATA "8 8 5 "
380 DATA "5 6 8 "
The blockline variable is set to a value that refers to the start of the data for the block to be played, which is how the P$ is used.
Volumes
Sometimes it is useful to be able to alter the volume of a piece of music without redefining all of the envelopes therefore a variable can be set to a value to subtract from the maximum volumes of the envelope to alter the overall volume of the music.
e.g. VOL = 10
ENVELOPE 1,2,0,0,0,0,0,0,126-VOL,-2,0,-1,126-VOL,110-VOL
The above allows the envelopes volume to be easily controlled by a single variable.
The example program uses the above music reader program to play a tune.