Skip to main content

Instrument Macros

Software macros add tick-time motion to instruments: volume shapes, pitch drops, arpeggios, and (where the chip supports it) duty/timbre steps. The same authoring style works across chips — availability and exact meaning of each field depend on the active chip.

Common fields

FieldTypical use
vol_envPer-frame volume (or chip-specific volume path)
pitch_envPer-frame semitone offsets
arp_envPer-frame arpeggio offsets
duty_envPer-frame duty/timbre index (where the chip has duty)

Syntax

Arrays list per-frame values. Play once and hold the last value, or loop from index N with |N:

inst lead type=pulse1 duty=25 vol=10 pitch_env=[3,2,1,0,0,0,0,0]
inst swell type=pulse1 duty=50 vol_env=[1,2,3,4,5,6,7,8,9,10|9]
inst chord type=pulse2 duty=50 vol=8 arp_env=[0,4,7|0]
inst wah type=pulse1 duty=50 vol=10 duty_env=[2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0|0]

One macro frame is typically 1/60 s on NTSC-style playback (chip guides note any exceptions). Prefer ending one-shot vol_env sequences at 0 (or silence) so the voice does not hang on the last level.

By chip

ChipMacrosNotes
NESvol_env, arp_env, pitch_env, duty_envFamiTracker-style; vol_env overrides hardware env decay
SMS / Game Gearvol_env, arp_env, pitch_env, noise_rate_envNo hardware ADSR — macros are the main articulation
Spectrum 128 / CPCarp_env, pitch_env; vol_env is often the shared hardware envelopeWatch R6 / R11–R13 conflicts
Game Boypitch_env, vol_env, duty_env, arp_envAlso exports to hUGE subpatterns; optional native subpat (below)

Chip pages list which instrument types accept which macros.

Playable examples (Game Boy)

Pitch + volume envelope (kick)

pitch_env drops the noise clock over a few ticks; vol_env fades the hit. Short pattern tokens keep it punchy:

pitch_env + vol_env kick

Interactive playback loads in the browser.

# pitch_env drops the noise clock; vol_env fades the hit
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]
# Short hits so the pitch drop + volume decay read as a kick
pat kicks = kick . . . kick . kick . kick . . . kick . . .

Looping volume swell

Looping vol_env

Interactive playback loads in the browser.

# Looping volume swell — |9 loops from index 9
inst swell type=pulse1 duty=50 vol_env=[1,2,3,4,5,6,7,8,9,10|9]
pat hold = C5:16 # hold long enough to hear the loop

Arpeggio envelope

arp_env chord

Interactive playback loads in the browser.

# Per-frame arpeggio offsets (major triad), looping
inst chord type=pulse2 duty=50 vol=10 arp_env=[0,4,7|0]
pat hold = C4:16

Duty envelope (wah)

duty_env wah

Interactive playback loads in the browser.

# Alternate duty indexes for a wah / pulse-width sweep
inst wah type=pulse1 duty=50 vol=12 duty_env=[2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0|0]
pat hold = C5:16

Native subpat

On Game Boy you can author a tick program directly with subpat (instead of macro arrays). Attach it with subpat=name on an inst. Native subpat wins if macros are also set on that instrument.

subpat kick_body =
.
+0 vol:15
-2 vol:12 jump:5
-4 vol:8
-6 vol:4
-6 vol:0
halt

inst kick type=noise gb:width=7 uge_note=C-6 subpat=kick_body
Native subpat kick

Interactive playback loads in the browser.

# Native subpat: empty first row, pitch offsets, mid-program jump, volume decay
subpat kick_body =
.
+0 vol:15
-2 vol:12 jump:5
-4 vol:10
-4 vol:8
-6 vol:4
-6 vol:0
halt
inst kick type=noise gb:width=7 env=14,down,1 length=16 uge_note=C-6 subpat=kick_body
# Instrument name as a pattern token triggers the subpat on each hit
pat kicks = kick . . . kick . kick . kick . . . kick . . .

How macros and subpat map into hUGETracker instrument subpatterns is covered under UGE export.

See also