Getting buffers
To create a Buffer
, you can use the control.createBuffer()
API.
The high-level music API in arcade creates and processes melodies as a sequence of
notes following a syntax form for each note. The melodies are authored using the
music.Melody
class in arcade which encodes them into a string with this syntax.
For some examples of formatted melodies, see the mixer extension/package.
Melodies are constructed with a series of commands outlined below.
To play a note:
[ABCDEFG] (\d+) (:\d+) (-\d+)
note octave length tempo
The octave, length, and tempo are all optional parameters. Here are some examples:
A5:2-120
(play note A
in octave 5
for 2
beats and set the tempo to 120
bpm)C
(play note C
for one beat at the current tempo)g5:1
(play note G
in octave 5
for 1
beat at the current tempo)To rest:
[R] (:\d+)
For example:
R
(rest for 1
beat at current tempo)R:3
(rest for 3
beats at current tempo)To play a frequency for a duration in ms:
!\d+,\d+
For example:
!262,500
(play frequency 262
Hz for 500
ms)To set the ADSR envelope for the played sounds:
@\d+,\d+,\d+,\d+
Where the four values indicate:
For more information on envelopes, check the Wikipedia article here_envelope).
To set the waveform for the generated notes:
~\d+
Where the number refers to one of the waveforms in the table below:
Waveform | Value |
---|---|
triangle | 1 |
sawtooth | 2 |
sine | 3 |
tunable noise | 4 |
noise | 5 |
square (10%) | 11 |
square (20%) | 12 |
square (30%) | 13 |
square (40%) | 14 |
square (50%) | 15 |
cycle 16 | 16 |
cycle 32 | 17 |
cycle 64 | 18 |
The noise
is an actual white noise. It ignores the requested frequency or note.
The tunable noise
tone contains a pseudorandom sample. At high frequency it sounds similar to white noise, at low frequency it produces irregular crackling noises.
The cycle 16
, cycle 32
, and cycle 64
waveforms are repeating pseudorandom patterns with a cycle length of 16/32/64 samples respectively. They sound like a noise-distorted square wave, with short cycles being more regular and long cycles being noisier.
To set the end for the generated notes:
^\d+
When the end frequency is set, the tone will linear ramp the frequency from the initial set frequency to the end frequency over the duration of the tone.
Here are some examples:
!2000,1000^100
will start at 2000
Hz and ramp to 100
Hz over the course of 1000
ms!1300,200^50
will start at 1300
Hz and ramp to 50
Hz over the course of 200
ms!150,500^800
will start at 150
Hz and ramp to 800
Hz over the course of 500
msThe low-level music API exposed in JavaScript revolves around sound “instructions”.
A sound instruction is a series of bytes stored in a Buffer
with the following format:
Field | Bits |
---|---|
waveform | 8 |
unused | 8 |
frequency (hz) | 16 |
duration (ms) | 16 |
start volume | 16 |
end volume | 16 |
end frequency | 16 |
Volume is a scalar value that ranges from 0 to 1024. See the table in previous section for the available values for waveform.
To play a sound buffer, use the music.playInstructions()
API. Buffers can contain
multiple instructions one after the other, so a single “effect” or “melody” should be
constructed in a single Buffer.
The arcade “hardware” has three available music “channels” that are mixed to produce
the game audio. Using the music.playInstructions()
API will automatically allocate
a channel to play the instruction and that channel remains occupied until the sound play
completes. Attempting to play too many sounds simultaneously will cause some sounds
to be dropped if all channels are currently busy.
If your music or sounds are mostly static (i.e. not created at runtime), you can save
memory by storing them in hex
buffers. These buffers are compiled into the “binary”
by the MakeCode compiler.
Note that there is currently no way to play sound samples - the buffers below would only apply to the playInstructions
format described above.
You can create static buffers using this tagged template literal syntax:
// The contents of the literal string should be data in hex-encoding
const mySound: Buffer = hex`0123456789abcdef`;