Skip to main content


WASM-4's sound system has 4 independent channels. Each channel is dedicated to a different type of audio waveform.

  • 2 pulse wave (square wave) channels. The classic chiptune sound.
  • 1 triangle wave channel. A softer sound, great for bass.
  • 1 noise channel. A harsh sound, for percussion and effects.

WASM-4's sound system is closely inspired by the architecture of the Nintendo NES and Gameboy.

Playing a Tone#

The tone() function is used to play a tone with a given frequency on a given channel.

tone (frequency, duration, volume, flags)

  • Frequency is the "pitch", measured in hertz.
  • Durations are measured in frames, 1/60ths of a second.
  • Volume ranges from 0 (silent) to 100 (full volume).

For example, to play a one second (60 frames) tone of 262 Hz (middle C) on the first pulse wave channel:

w4.tone(262, 60, 100, w4.TONE_PULSE1);

Duty Cycle#

The duty cycle of the pulse channels can be controlled with additional flags:

FlagDuty Cycle
TONE_MODE112.5% (default)

For example, to play at 50% duty cycle (square wave):

w4.tone(262, 60, 100, w4.TONE_PULSE1 | w4.TONE_MODE3);

Frequency Slide#

We can actually pass two different frequencies to tone(). The high 16 bits of the frequency parameter is used for a second frequency. If non-zero, it specifies the frequency to slide to over the duration of the tone.

For example, to slide the tone starting from 262 Hz and up to 523 Hz:

w4.tone(262 | (523 << 16), 60, 100, w4.TONE_PULSE1);

ADSR Envelope#

ADSR describes how the volume changes over time, and has 4 time components:

Attack24The time it takes to initially ramp up from 0 volume to 100% volume.
Decay16The time taken to ramp down from 100% volume to the tone volume parameter.
Sustain0The time to hold the tone steady at volume.
Release8The time to ramp back down to 0 volume.

These times are all measured in frames (1/60th of a second), and can be packed into the duration parameter.

For example, to play a tone that sustains for one second and releases over half a second (30 frames):

w4.tone(262, 60 | (30 << 8), 100, w4.TONE_PULSE1);

Sound Tool#

The sound demo is a great way to quickly experiment with different sounds and find values to plug into your game: