Instruments
In this section we will give Tutorial Groove its sound: define instruments with inst for each Game Boy voice (pulse, wave, and noise), then assign them to channels. Instrument names can also be used as pattern tokens (especially useful for percussion), and you can switch instruments inside a pattern with inst(name) or inst(name,N).
Instrument type (type=) and its fields are chip-specific. This tutorial uses the Game Boy sound chip. For other chips see Sound Chip Plugins.
A common Game Boy layout for instruments (and the one Tutorial Groove uses) is:
| Channel | Type | Role |
|---|---|---|
| 1 | pulse1 | Lead melody |
| 2 | pulse2 | Harmony / counter |
| 3 | wave | Bass |
| 4 | noise | Drums |
Note: the patterns below use the note syntax from Notes and lengths (C4, C4:4, ., _).
Pulse 1
Channel 1 is a pulse oscillator. Set type=pulse1, pick a duty, and give it a hardware envelope with env:
Interactive playback loads in the browser.
…
inst lead type=pulse1 duty=50 env=gb:13,down,1 gm=81
pat lead_pat = E5 . G5 C6 . G5 E5 . D5 . F5 A5 . G5 . .
…| Field | Notes |
|---|---|
duty | Pulse timbre — the fraction of each wave cycle that is “on” (high). Game Boy allows only 12.5, 25, 50, or 75 (percent). This shapes the sound, not how long a note lasts in a pattern. 12.5 / 25 sound thinner; 50 is a balanced square; 75 sounds darker/thicker (like 25% flipped). |
env | Hardware volume envelope: gb:<initial>,<up|down>,<period>. initial is starting volume (0–15); up/down is the direction; period is how fast it steps (1–7). Use period=0 to hold a constant volume. Short periods sound plucky; longer ones fade more slowly. Example: gb:13,down,1. |
gm | Optional General Midi (GM) program 0–127 - this is only used for MIDI export instrument mapping |
Hardware sweep
Pulse 1 can also slide pitch with a hardware frequency sweep: sweep=<time>,<up|down>,<shift> (Pulse 2 cannot). Example: sweep=7,up,3. Use a constant envelope (env period 0) so the note stays loud while the pitch moves:
Interactive playback loads in the browser.
…
inst riser type=pulse1 duty=50 sweep=7,up,3 env=gb:15,down,0
pat rise = C3:16
…| Field | Notes |
|---|---|
time | How often the sweep steps (0–7). Higher values update more slowly. |
direction | up raises pitch; down lowers it. |
shift | How strongly each step changes frequency (0–7). Larger values move pitch faster/further. |
Hardware sweep is more often used for sound effects rather than music.
Pulse 2
Channel 2 is the second pulse — same duty and envelope options, but no hardware sweep. It is typically used to add harmony / counter under the lead:
Interactive playback loads in the browser.
…
inst harmony type=pulse2 duty=25 env=gb:10,down,2 gm=80
pat harmony_pat = C4:4 E4:4 G4:4 E4:4
…Wave
Channel 3 plays a custom wavetable — 32 samples that define the waveform itself. Shape the table and you can get smooth basses, soft pads, bright leads, bells, or metallic / organ-like tones; Tutorial Groove uses a gentle triangle-like table for bass.
Provide the table as 32 nibbles (0–15), a 16-value shorthand (tiled to 32), or a 32-character hex string. Output level is set with volume= — only 0, 25, 50, or 100:
Interactive playback loads in the browser.
…
inst bass type=wave volume=100 wave=[0,2,4,6,8,10,12,14,15,14,12,10,8,6,4,2] gm=33
pat bass_pat = C3 . . C3 G2 . . G2 A2 . . A2 F2 . G2 .
…Noise
Channel 4 is LFSR noise — random-ish hiss shaped by the sound chip. In songs it is typically used for percussion (kicks, snares, hats, toms) and short FX hits rather than pitched melody.
The noise channel does not play musical pitch the way pulse and wave do. Timbre comes mainly from gb:width and the envelope; how “high” or “low” the noise sounds is set by a clock rate. On Game Boy that clock is chosen with uge_note= (hUGETracker note names like C-7), so BeatBax playback and UGE export stay in sync. Patterns still write ordinary notes (e.g. C6) for when each hit fires.
On Game Boy, snares usually use gb:width=7 (metallic crack); hi-hats use gb:width=15 (broader white noise). A short pitch “pop” (via pitch_env — covered under Instrument macros below) helps the snare read as a hit:
Interactive playback loads in the browser.
…
inst snare type=noise gb:width=7 env=gb:13,down,1 length=16 uge_note=C-7 pitch_env=[0,7,0] vol_env=[13,10,6,2]
pat hits = C6 . C6 . C6 C6 . .
…| Field | Notes |
|---|---|
gb:width | 7 = metallic (snares/toms); 15 = white noise (hats/cymbals) |
uge_note= | Noise clock in hUGETracker notation (e.g. C-7). Controls how high/low the noise sounds in BeatBax and what is written to UGE. Prefer this for percussion you care about hearing correctly. |
env | Hardware envelope, e.g. gb:13,down,1 |
Instrument macros
Software macros (pitch_env, vol_env, …) add per-tick motion on top of the hardware voice. On Game Boy they also feed hUGETracker UGE subpatterns.
The first four hits below are a plain noise kick; the next four use the same notes with a pitch drop and volume decay — listen for the difference. (inst(name) switches which instrument plays the following notes; more on that in Sequencing.)
Interactive playback loads in the browser.
…
inst kick_plain type=noise gb:width=7 uge_note=C-6 length=16
inst kick type=noise gb:width=7 uge_note=C-6 length=16 pitch_env=[0,-2,-4,-6] vol_env=[15,12,8,4]
# Several plain hits, then the same notes with macros (pitch drop + volume decay)
pat kicks = inst(kick_plain) C5:4 . C5:4 . C5:4 . C5:4 . inst(kick) C5:4 . C5:4 . C5:4 . C5:4 .
…For full details see: Instrument macros.
Percussion with named tokens
Writing C5 / C6 on every drum hit works, but it is clearer to use the instrument name as the pattern token (kick, snare, hat). Add note= so each name has a default pitch; keep uge_note= for the noise clock (as above).
Interactive playback loads in the browser.
…
inst kick type=noise gb:width=7 uge_note=C-6 length=16 pitch_env=[0,-2,-4,-6] vol_env=[15,12,8,4]
inst snare type=noise gb:width=7 env=gb:13,down,1 length=16 uge_note=C-7 note=C6 pitch_env=[0,7,0] vol_env=[13,10,6,2]
inst hat type=noise gb:width=15 env=gb:5,down,1 uge_note=C-8 note=C6
pat drums = kick . hat . snare . hat hat kick . hat . snare hat hat .
…More detail: Instrument note mapping.
Sharing instruments
As well as defining instruments from scratch in each song you can also reuse instruments
defined in other files with the import "…" directive. See Imports for more information.
Putting it together
Defining instruments is not enough on its own — BeatBax only plays a voice when you assign it with a channel line. Each line maps one chip voice to:
- a default instrument (
inst …) - the music it should play (
pat …for a single pattern, orseq …for a list of patterns)
Tutorial Groove uses all four Game Boy voices — pulse lead, pulse harmony, wave bass, and noise drums. The Game Boy can play at most these four voices at once; other chips may have fewer or more channels (see Sound Chip Plugins).
channel 1 => inst lead seq lead_pat
channel 2 => inst harmony seq harmony_pat
channel 3 => inst bass seq bass_pat
channel 4 => inst snare seq drums_pat
You need one channel line per voice you want to hear. Patterns, named sequences, and other channel forms are covered in Sequencing. Here is the full song so far:
Interactive playback loads in the browser.
song name "Tutorial Groove"
song artist "BeatBax Tutorial"
song description "Built step by step in the BeatBax Game Boy tutorial."
song tags "tutorial, gameboy"
chip gameboy
bpm 140
inst lead type=pulse1 duty=50 env=gb:13,down,1 gm=81
inst harmony type=pulse2 duty=25 env=gb:10,down,2 gm=80
inst bass type=wave volume=100 wave=[0,2,4,6,8,10,12,14,15,14,12,10,8,6,4,2] gm=33
inst kick type=noise gb:width=7 uge_note=C-6 length=16 pitch_env=[0,-2,-4,-6] vol_env=[15,12,8,4]
inst snare type=noise gb:width=7 env=gb:13,down,1 length=16 uge_note=C-7 note=C6 pitch_env=[0,7,0] vol_env=[13,10,6,2]
inst hat type=noise gb:width=15 env=gb:5,down,1 uge_note=C-8 note=C6
pat lead_pat = E5 . G5 C6 . G5 E5 . D5 . F5 A5 . G5 . .
pat harmony_pat = C4:4 E4:4 G4:4 E4:4
pat bass_pat = C3 . . C3 G2 . . G2 A2 . . A2 F2 . G2 .
pat drums_pat = kick . hat . snare . hat hat kick . hat . snare hat hat .
channel 1 => inst lead seq lead_pat
channel 2 => inst harmony seq harmony_pat
channel 3 => inst bass seq bass_pat
channel 4 => inst snare seq drums_pat
playNext
Continue with Sequencing — how pat and seq work in more detail, and how to chain different patterns so each part can vary instead of looping a single bar.