RISCOS.com

www.riscos.com Technical Support:
BBC BASIC Reference Manual

 


Sound


The computer contains a sound synthesizer which enables you to emulate up to eight different instruments playing at once, giving either mono or stereo sound production for each instrument.

Activating the sound system

The sound system can be activated or de-activated using the statements SOUND ON and SOUND OFF.

Selecting sound channels

You can select how many different sound channels you want to use. The default value is 1, but you can alter this by typing

VOICES n

The maximum number allowed is eight. Any number between one and eight can be specified, but the number which the computer can handle has to be a power of two, and so the number you give is rounded up by the computer to either one, two, four or eight.

Allocating a wave-form to each voice

After you have specified the number of voices you require, you will need to allocate a wave-form to each voice. This is done with *CHANNELVOICE, the syntax of which is:

*CHANNELVOICE channel voicename

It is important to realise that what is termed the voice in BASIC is called the channel by RISC OS, while RISC OS refers to the wave-form as the voice.

Since the bell uses channel 1, you can get an idea of how the command works by entering

*CHANNELVOICE 1 Percussion-Snare

and then sounding the bell by typing Ctrl-G.

As you will notice, the sound of the bell has changed, since the sound channel has been allocated a new voice - in this case a percussion snare sound.

A full list of the resident voices can be obtained, along with their channel allocations, using the *VOICES command. With voice 8 allocated to channel 1, the list appears as follows:

        Voice Name
            1 WaveSynth-Beep
            2 StringLib-Soft
            3 StringLib-Pluck
            4 StringLib-Steel
            5 StringLib-Hard
            6 Percussion-Soft
            7 Percussion-Medium
1           8 Percussion-Snare
            9 Percussion-Noise
^^^^^^^ Channel Allocation Map

Note that *VOICES indicates only the mapping of voices to channels - it does not specify how many channels have been selected with BASIC's VOICES command.

Setting the stereo position

For each active channel, the stereo position of the sound can be altered using:

STEREO chan, pos

pos can take any value between -127 (indicating the sound is fully to the left) and +127 (indicating the sound is fully to the right). The default value for each channel is zero which gives central (mono) production.

Although the range of the pos argument in the STEREO keyword is -127 to 127, there are actually only seven discrete stereo positions. These are:

-127 to -80 Full left
-79 to -48 2/3 left
-47 to -16 1/3 left
-15 to +15 Central
+16 to +47 1/3 right
+48 to +79 2/3 right
+80 to +127 Full right

Creating a note

BASIC provides a SOUND statement to create a note on any of the channels. This requires four parameters which can be summarised as follows:

SOUND channel, amplitude, pitch, duration [, after]

Channel

There are eight different channels, numbered 1 to 8. Each of these is identical, except for the voice assigned to it.

Setting the volume

The second parameter amplitude determines how loud a note is to be played. You set the amplitude to an integer between 0 and -15. -15 is the loudest, -7 is half-volume and zero produces silence.

Alternatively, a logarithmic scale can be used, by giving a value between 256 (&100) and 383 (&17F). A change of 16 represents a doubling or halving of the volume.

Pitch

The pitch can be controlled in steps of a quarter of a semitone by giving a value between 0 and 255. The lowest note (0) is the A# one octave and two semitones below middle C. The highest note is the D four octaves and a tone above middle C. A value of 53 produces middle C itself. The following table is a quick reference guide to help you find the pitch you require:

Note Octave number
1 2 3 4 5 6
A 41 89 137 185 233
A# 0 45 93 141 189 237
B 1 49 97 145 193 241
C 5 53 101 149 197 245
C# 9 57 105 153 201 249
D 13 61 109 157 205 253
D# 17 65 113 161 209
E 21 69 117 165 213
F 25 73 121 169 217
F# 29 77 125 173 221
G 33 81 129 177 225
G# 37 85 133 181 229

Alternatively, a finer control is available by giving a value between 256 (&0100) and 32767 (&7FFF). Each number consists of 15 bits. The left-most three bits control the octave number. The bottom 12 bits control the fractional part of the octave. This means that each octave is split up into 4096 different pitch levels. Middle C has the value 16384 (&4000).

Using hexadecimal notation is a particularly useful way of seeing what pitch a given value defines. Each value in hexadecimal notation comprises four digits. The left-most one gives the octave number and the right-most the fractional part of the octave. The following table illustrates this:

Note Octave number
1 2 3 4 5 6 7 8 9
A &0C00 &1C00 &2C00 &3C00 &4C00 &5C00 &6C00 &7C00
A# &0D55 &1D55 &2D55 &3D55 &4D55 &5D55 &6D55 &7D55
B &0EAA &1EAA &2EAA &3EAA &4EAA &5EAA &6EAA &7EAA
C &1000 &2000 &3000 &4000 &5000 &6000 &7000
C# &0155 &1155 &2155 &3155 &4155 &5155 &6155 &7155
D &02AA &12AA &22AA &32AA &42AA &52AA &62AA &72AA
D# &0400 &1400 &2400 &3400 &4400 &5400 &6400 &7400
E &0555 &1555 &2555 &3555 &4555 &5555 &6555 &7555
F &06AA &16AA &26AA &36AA &46AA &56AA &66AA &76AA
F# &0800 &1800 &2800 &3800 &4800 &5800 &6800 &7800
G &0955 &1955 &2955 &39AA &49AA &59AA &69AA &79AA
G# &0AAA &1AAA &2AAA &3AAA &4AAA &5AAA &6AAA &7AAA

Duration of sound

The fourth SOUND parameter determines the duration of a sound. A value of 0 to 254 specifies the duration in twentieths of a second. For example, a value of 20 causes the note to sound for one second. A value of 255 causes the note to sound continuously, stopping only when you press Esc. Values between 256 and 32767 also give the duration in 20ths of a second.

Synchronising the channels

The channels can be synchronised by using the beat counter. The counter increases from zero to a set limit, then starts again at zero. Typically, you would use the time it takes for the counter to complete one cycle to represent a 'bar' in the music, and use the after parameter in the SOUND statement to determine where in the bar the note is sounded.

You can set the value that this counter will count up to by typing

BEATS n

The counter then counts from 0 to n-1 and when it reaches n it resets itself to zero.

To find the current beat counter value, type

PRINT BEATS

Increasing the number of beats increases the time taken before two notes are repeated. It has no effect on the time interval between the two notes themselves.

Finding the value of the current beat

In addition, the current beat value is found by typing

PRINT BEAT

Finding the current tempo

The rate at which the beat counter counts depends on the tempo which can be set as follows:

TEMPO n

n is a hexadecimal fractional number, in which the three least-significant digits are the fractional part. A value of &1000 corresponds to a tempo of one tempo beat per centi-second; doubling the value (&2000) causes the tempo to double (2 tempo beats per centi-second), halving the value (&800) halves the tempo (to half a beat per centi-second).

Suppose you are working in 4/4 time, and want to have a resolution of 8 computer beats per musical beat (i.e. there are 32 computer beats to the bar). Furthermore, suppose you want the musical tempo to be 125 beats per minute. This is 125*8/60 computer beats per second, or 125*8/60/100 computer beats per centi second. If you calculate this, you obtain 0.6666667 computer beats per centi-second. Multiply this by the scaling factor of &1000 (4096), and you get a TEMPO value of 683. Therefore you would use the following two commands:

TEMPO 683
BEATS 32

To find the current tempo, type

PRINT TEMPO

Increasing the tempo decreases both the time taken before two notes are repeated and the time interval between the two notes.

Executing a sound on a beat

Sounds can be scheduled to execute a given number of beats from the last beat counter reset by giving the fifth parameter after to the SOUND statement.

The optional after parameter in the SOUND statement specifies the number of beats which should elapse before the sound is made. The beats are counted from the last time the beat counter was set to zero (i.e. the start of the bar). If the beat counter is not enabled (because no BEATS statement has been issued), the beats are counted from the time the statement was executed.

For example, the listing below repeatedly waits for the start of the bar, then schedules the sounds to be made after 50 beats and 150 beats respectively. If a bar is 200 beats long, this corresponds to the second and fourth beat of a 4/4 time:

10 BEATS 200
15 VOICES 2
20 *CHANNELVOICE 1 1
30 *CHANNELVOICE 2 1
40 REPEAT
50   REPEAT UNTIL BEAT=0
60   SOUND 1, -15, 100, 5, 50
70   SOUND 2, -15, 200, 5, 150
80   REPEAT UNTIL BEAT<>0
90 UNTIL FALSE

Having scheduled the sounds, the program waits in another REPEAT loop until the current beat is not zero. This prevents the sounds from being scheduled more than once in a bar.

Note: Where other things are happening in a program, such as screen updating, it is not safe to test for BEAT=0, in case the program misses the short period where that was true. It is better to test, for example, for BEAT<10 and treat beat 10 as the 'start' of the bar.

Synchronising sounds

If you give -1 as the after parameter, the sound, instead of being scheduled for a given number of beats, is synchronised with the last sound that was scheduled. For example,

SOUND 1,-10,200,20,100
SOUND 2,-10,232,20,-1

will cause two sounds, an octave apart, to be made 100 beats from the present moment, assuming that at least two channels are active and have voices assigned.

Note: If you alter the sound system, you should restore it before returning to the desktop, or running any other programs.

This edition Copyright © 3QD Developments Ltd 2015
Last Edit: Tue,03 Nov 2015