Generally, the sound capabilities of a retrocomputer are a bit limited,
but ugBASIC sound commands could operate independently from
other routines (on many targets), so that they could never interfere with
your programming.
On the contrary, they should enhance your work in any way that you chose,
acting as markers, adding realism, shooting, shocking or providing
comic relief.
Audio, notes and sound effects can be used in an ugBASIC program.
There are three common sound effects that can be called up by their
own commands, and used for testing and punctuating your routines.
BOOM
command plays a realistic explosive sound effect.
On many targets, or if DEFINE AUDIO ASYNC
pragma is used
and supported, this does not delay the program at all, so it may be necessary
to use
WAIT
between successive explosions, or to create specific
audio effects. Otherwise, on other targets or if you are using the
DEFINE AUDIO SYNC
, this will not happen.
In any case, it is possible to give a duration (in milliseconds) for the audio effect.DEFINE AUDIO ASYNC
CENTRE "Thunderbolt and Lightning"
BOOM : WAIT 1000 MS: BOOM: CLS
CENTRE "Very Very Frightening"
WAIT 500 MS: BOOM
DEFINE AUDIO SYNC
CENTRE "Thunderbolt and Lightning"
BOOM 1000 MS: BOOM 500 MS: CLS
CENTRE "Very Very Frightening"
BOOM
SHOOT
command generates a (shorter)
sound effect in exactly the same way as BOOM
.DEFINE AUDIO ASYNC
SHOOT: WAIT 1000 MS: SHOOT: PRINT "Ouch!"
DEFINE AUDIO SYNC
SHOOT: WAIT 750 MS: SHOOT: PRINT "Ouch!"
BELL
produces a simple pure tone. To better explain the meaning of the
parameter that can be given to the BELL
command,
it is essential to introduce at least a hint about the concept of
frequency, "pitch" and note.OCT 0 | OCT 1 | OCT 2 | OCT 3 | OCT 4 | OCT 5 | OCT 6 | OCT 7 | |
---|---|---|---|---|---|---|---|---|
C | 0 | 12 | 24 | 36 | 48 | 60 | 72 | 84 |
C#/Db | 1 | 13 | 25 | 37 | 49 | 61 | 73 | 85 |
D | 2 | 14 | 26 | 38 | 50 | 62 | 74 | 86 |
D#/Eb | 3 | 15 | 27 | 39 | 51 | 63 | 75 | 87 |
E | 4 | 16 | 28 | 40 | 52 | 64 | 76 | 88 |
F | 5 | 17 | 29 | 41 | 53 | 65 | 77 | 89 |
F#/Gb | 6 | 18 | 30 | 42 | 54 | 66 | 78 | 90 |
G | 7 | 19 | 31 | 43 | 55 | 67 | 79 | 91 |
G#/Ab | 8 | 20 | 32 | 44 | 56 | 68 | 80 | 92 |
A | 9 | 21 | 33 | 45 | 57 | 69 | 81 | 93 |
A#/Bb | 10 | 22 | 34 | 46 | 58 | 70 | 82 | 94 |
B | 11 | 23 | 35 | 47 | 59 | 71 | 83 | 95 |
BELL
command, ranging from 0
for a very deep sound, up to
higher values, for an ultra high pitched sound.DEFINE AUDIO ASYNC
FOR f=60 TO 71
BELL f
WAIT 1000 MS
NEXT
DEFINE AUDIO SYNC
FOR f=60 TO 71
BELL f
NEXT
SOUND
command. This command can accept various
parameters, depending on the use you want to make of it.SOUND 440, 1000 MS :'(reproduce a 440 Hz sound for 1 second)
SOUND OFF
command.SOUND 440
FOR i=0 TO 10 : PRINT "OK!": WAIT 500 MS : NEXT
SOUND OFF
SOUND
command also accepts
a third parameter prefixed by the keyword ON
, which is
a bitmask with the mapping of the voices.SOUND 440, 1000 MS ON %0010 (reproduce a 440 Hz sound for 1 second on voice 1)
SOUND 440 ON %0001: SOUND 480 ON %0010
FOR i=0 TO 10 : PRINT "OK!": WAIT 500 MS : NEXT
SOUND OFF
The values from 0
to 107
that are used
to control the pitch of the BELL
sound correspond to
the notes on the keyboard of a piano. The white key at the extreme
left-hand side of the keyboard is known as "Bottom C", and corresponds
to pitch value 0
. Value 1
is the equivalent
to the black note next to it, which is a C#, and so on up to “Middle C”
at pitch value 6
, then all the way up to 107.
In reality, grand piano keyboards run out of notes after 88
,
and most synthesizer keyboards have a lot less than that.
In Western music, notes are given their own code letter so that
musicians can all refer to the same pitch when they try and play
together. These letters repeat themselves after twelve notes, and
each group of twelve is known as an “octave”.
To indicate a specific note (of middle octave) you can use the NOTE
command, like NOTE C#
or NOTE D
. In order to
indicate the octave, you can use the NOTE C4
annotation.
So you can use the following command to sound a bell with A
note:
BELL NOTE A4
The retrocomputer produces sound like a river, and ugBASIC
allows you to split this river into various separate channels, all pouring
out at the same time, but each capable of individual control. These channels
can be heard individually, or mixed together, or directed to the left and
right creating stereo sound. They can also be individually increased and
decreased in volume, or dammed up altogether. Obviously, it depends on
the specific chipset capabilities if these channels can be given a different
"voice", and each voice can be controlled in terms of volume and direction.
The VOLUME
command controls the level of sound flowing through
one or more channels, ranging from MIN VOLUME
(complete silence)
up to MAX VOLUME
(ear-splitting), like this:
FOR level=VOLUME MIN TO VOLUME MAX
VOLUME level
BELL NOTE C4
WAIT 500 MS
NEXT
Once the VOLUME
level has been set, all future sound effects
and music will be delivered at that level, across all four channels.
In order to create "stereo" effects and perfect sound mixes, each of
the voices needs to be adjusted independently from one another.
The volume of each voice can now be controlled by specifying voices
and volumes, like this:
VOLUME 63 ON %0001
BOOM : WAIT 100 MS
VOLUME 5 ON %1110
BOOM : WAIT 50 MS
BELL 40 : WAIT 50
VOLUME 60: BELL 40
Patterns of individual notes can be played, allocated to any voice,
given a pitch and delayed for pause, using just one PLAY
command:
PLAY voice, note, delay
The voice parameter is optional, allowing notes to be played through any
combination of the retrocomputer voices, and is set by the usual bitmap
format. The note parameter uses the values from 0
to 107
,
or by using the NOTE
annotation. The parameter delay
sets the length of any pause between this PLAY
command and the
next instruction in the program, with a value of zero starting the note
and immediately going on to the next command.
The next example demonstrates this technique, including stereo harmonies:
PLAY 40, 0 ON 1: PLAY 50, 0 ON 2
WAIT KEY
PLAY 50, 15 ON 1: PLAY 50, 15 ON 2
DO
v = RND(5)
p = RND(108)
PLAY p, 3 ON v
LOOP
PLAY
is not restricted to pure notes. It is possible to assign
complex wave forms to voices, using the WAVE
and NOISE
commands, which are explained next. To stop the playing process, simply
turn it off like this:
PLAY OFF
Some audio chipsets have the ability to define the waveform of the sound
that will be output, to make it look like an instrument. Others have the
ability to use actual "samples", which will then be reproduced at certain
frequencies. The ugBASIC language provides a set of
primitives that allow you to take advantage of this feature.
The most useful (and easy) command is INSTRUMENT
. This command
allows you to modify the waveform of one of the voices, so that subsequent
commands such as SOUND
or PLAY
modify the sound.
The syntax is quite easy:
INSTRUMENT $42 ON %0001
: ' Use the saxophone on voice 1
The instrument can also be indicated symbolically.
The ugBASIC music system allows soundtracks in background to be added to any program. Music can be created from a variety of sources, including MIDI and PSG files.
The ugBASIC language is able to use directly the
MIDI file format. This kind of file is converted into internal
format (called IMF - Isomorphic Music Format), that is a format
that the hardware is able to use almost directly. So, actually,
the file inside the executable is IMF format and not MIDI.
MIDI files can be loaded using the LOAD MUSIC
command:
soundtrack := LOAD MUSIC("some.mid")
Once load, they can be played anytime using the MUSIC
command:
MUSIC soundtrack
The volume is controlled by MUSIC VOLUME
,
and speed (used during conversion) by MUSIC TEMPO
.
Individual music passages can be suspended by using the
MUSIC PAUSE
,
and resumed by MUSIC RESUME
.
Moreover, it can be stopeed by MUSIC STOP
instruction.
The ugBASIC language is able to load the SJ2 files. The format consists of
a 1-bit sample stream of samples for two independent voices, which can be played synchronously
with the 1-bit DAC. The player is based on the highly optimized algorithm called
"2 voice squarewave pattern", developed by Simon "invisibleman" Jonassen
and adapted for ugBASIC.
The audio card is properly emulated by the latest version of XRoar emulator.
The file can be loaded as:
soundtrack := LOAD("some.sj2")
Once loaded, they can be played anytime using the MUSIC ... SJ2
command:
MUSIC soundtrack SJ2
Since they are played synchronously, the tracks can't be suspended,
resumed or stopped.
The ugBASIC language is able to load the PSG files with
the target that has a SN-76489 audio chipset. For TRS-80 Color Computer 1/2 and 3
it means that a Game Master Cartridge should be attached to slot 0.
The audio card is properly emulated by the latest version of XRoar emulator.
For Olivetti Prodest PC128 it means
that an external soundcard should be attached, like the one built by Dino Florenzi.
The audio card is properly emulated by the latest version of DC MOTO emulator.
The file can be loaded as:
soundtrack := LOAD("some.psg")
Once loaded, they can be played anytime using the MUSIC ... PSG
command:
MUSIC soundtrack PSG
Individual music tracks can be suspended by using the
MUSIC PAUSE
,
and resumed by MUSIC RESUME
.
Moreover, it can be stopeed by MUSIC STOP
instruction.
If you have found a problem, if you think there is a bug or, more
simply, you would like something to be improved, write a topic on the official forum, or open an issue on GitHub.
Thank you!