Skip to content
Simon Larsen edited this page Nov 17, 2017 · 60 revisions

Welcome to the mmlgb wiki!

Channels

The Game Boy has four sound channels: Two square waves, one user defined wave and a noise generator. Throughout this document the channels will be referred to as channel 1 through 4.

Number Channel
1 Square 1
2 Square 2
3 Wave
4 Noise

Commands

Command Description
; Comment. Remaining part of line is ignored.
ABCD Defines current channel(s). A is square 1, B is square 2, C is wave channel and D is noise.
Multiple channels can be used e.g. AB t120 cdef...
cdefgab Play note. Append #/+ for sharp notes and - for flat notes.
r Rest. Specify length by appending number.
o Followed by number to change octave.
>,< Go one octave up or down.
l Followed by number specifies default note length.
v Followed by number 0-15 sets channel volume. Volume is not changed until note is retriggered.
Channel 3 (wave) only takes values 0-3.
t Set tempo in BPM. Affects all channels at once.
w Wait. Specify length by appending number. Similar to r but does not mute current note.
y Followed by either -1, 0 or 1 sets channel panning. -1 is left channel only, 1 is right channel only and 0 is both.
[...]n Repeat block n times.
L Set loop point.

Numbers

All numbers are assumed to be decimal numbers. Use 0x prefix for hex numbers (e.g. 0xA3 is 163) or 0b for binary (e.g. 0b10100011).

Note length

Specify length by appending number, e.g. c#4 is a C# quater note. Add ./../... for dotted and double dotted notes etc.. Supported lengths:

Value Length Frames
1 Whole note 192
2 Half note 96
3 Half triplet note 64
4 Quarter note 48
6 Quarter triplet note 32
8 Eighth note 24
12 Eighth triplet note 16
16 Sixteenth note 12
24 Sixteenth triplet note 8
32 Thirty-second note 6

Use =X to set frame specific length, e.g. c#=4 for 4 frames.

Use ^ to tie multiple note lengths together, e.g. c4^4 is equivalent to c2.

Valid notes

The following notes are valid for each channel. Using notes outside of these ranges is undefined.

Channel First note Last note
(A) Square 1 C2 B8
(B) Square 2 C2 B8
(C) Wave C2 B8
(D) Noise C1 G8

Macros

Wave data (Channel 3)

Wave channel data is defined using the @wave macro. It takes an identifier and 32 4-bit samples (values from 0-15).

A triangle wave can for instance be defined with:

@wave0 = {7 8 9 10 11 12 13 14 15 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 1 2 3 4 5 6 7}

This data can then be loaded to the channel using @wave0.

Volume envelope (Channel 1, 2, 4)

The volume envelope is changed using the @ve[length] macro, where length is a number from -7 to 7. When length < 0 the volume is decreasing, when length> 0 it is increasing.

For instance @ve-3 sets a short, decreasing envelope.

Wave pattern duty (Channel 1, 2)

Wave pattern duty is set using the @wd[duty] macro, where duty is a number from 0 to 3. For instance @wd2 sets a 50% duty cycle.

      _
0    | |             |  12.5%
     | |_____________|
      ___
1    |   |           |  25%
     |   |___________|
      _______
2    |       |       |  50%
     |       |_______|
      ___________
3    |           |   |  75%
     |           |___|

Portamento (Channel 1, 2, 4)

Portamento is enabled using the @p[speed] macro, where speed is a value from 1 to 127. Use @p0 to disable again.

Note: Portamento and pitch slide cannot be used simultaneously.

Pitch slide (Channel 1, 2, 4)

Pitch slide is enabled using the @s[speed] macro, where speed is a value from -127 to 127. Use @s0 to disable again.

Note: Portamento and pitch slide cannot be used simultaneously.

Vibrato (Channel 1, 2)

Vibrato is enabled using the @v[speed],[depth],[delay] macro, where speed is a value from 1 to 15, depth is a value from 1 to 15 and delay is a note length. The delay argument is optional and defaults to no delay if omitted.

Use @v0,0 to disable vibrato again.

Pitch offset (Channel 1, 2, 3)

Channel pitch offset is enabled using the @po[offset] macro, where offset is a value from -127 to 127.

Use @po0 to disable again.

Noise channel counter step (Channel 4)

Bit 3 of the noise channel polynomial counter can be set using the @ns[state] macro where state is either 0 or 1. Setting @ns1 will make noise appear more like tone than noise.

User macros

Users can define their own macros with @@[id] = { [data] }. Calling @@[id] is then equivalent to inserting the corresponding data.

Example

@@1 = { v13 @ve-5 @v4,5 }
A l8 cdef @@1 g
; Equivalent to
; A l8 cdef v13 @ve-5 @v4,5 g

Limitations

  • Dots must follow a length. This means A l4 c. is not allowed. Use A c4. for now.
  • Lengths of more than 255 frames are not allowed for the l command.