Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Sound

ADD ARRANGEMENT · APPLY INSTRUMENT · APPLY MUSIC · BEEP · CREATE MUSIC PATTERN · CREATE TRACK · DELETE ARRANGEMENT · DELETE INSTRUMENT · DELETE INSTRUMENT LAYER · DELETE MUSIC · DELETE MUSIC PATTERN · DELETE TRACK · FADEMUSIC · INSERT ARRANGEMENT · INSTRUMENTMODE · LOADINSTRUMENTS · LOADMUSIC · MUTE TRACK · PAUSEMUSIC · PLAY · PLAYMUSIC · RESUMEMUSIC · SAVEINSTRUMENTS · SET ARRANGEMENT · SET AUDIO · SET MUSIC · SET MUSIC PATTERN · SET TRACK · SETINSTRUMENTWAV · SOLO TRACK · SOUND · STOP PLAY · STOPMUSIC · arrangementcount · arrangementlayer · arrangementlayercount · arrangementpattern · arrangementrepeat · custominstrumentcount · custominstrumentnumber · instrumentattack · instrumentdecay · instrumentexists · instrumentlayercount · instrumentname · instrumentpan · instrumentpercussion · instrumentrelease · instrumentsustain · instrumentvolume · layerbasenote · layerdetune · layerduty · layerfeedback · layerfmdepth · layerfmtarget · layeroctave · layersample · layervolume · layerwave · lipsync · musicbeats · musicbeatunit · musicexists · musiclength · musicloop · musicpatterncount · musicpatternlength · musicpatternname · musicplaying · musicposition · musictempo · patternaudio · patternaudiovolume · songcount · songname · trackchannel · trackcount · trackgenerator · trackinstrument · trackmuted · trackname · tracknotes · trackpan · trackrepeat · tracksoloed · trackvolume


ADD ARRANGEMENT

Add a step to the end of a song’s arrangement.

ADD ARRANGEMENT song, pattern
add_arrangement(song, pattern)

Also documents: repeat, with

Parameters

  • song AS STRING - The song.
  • pattern AS STRING - The pattern.

After !!

  • repeat(value AS NUMBER) - How many times it plays.
  • with(value AS ARRAY) - Patterns that play at the same time.

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
ADD ARRANGEMENT "Overworld", "verse" !! repeat(3) with(["drums"])
PRINT arrangementcount("Overworld")
PRINT arrangementpattern("Overworld", 2), arrangementrepeat("Overworld", 2)

Notes

It’s also the function add_arrangement, for when you want what it gives back.

APPLY INSTRUMENT

Send an instrument’s edits to the audio engine now, rather than when it next plays.

APPLY INSTRUMENT number
apply_instrument(number)

Parameters

  • number AS NUMBER - The instrument’s number.

Example

SCREEN 320, 240
INSTRUMENT 70
    NAME "Blip"
    LAYER "square"
    END LAYER
END INSTRUMENT
SET INSTRUMENT 70
    VOLUME 0.5
END SET INSTRUMENT
APPLY INSTRUMENT 70
PRINT instrumentvolume(70)

Notes

It’s also the function apply_instrument, for when you want what it gives back.

APPLY MUSIC

Send a song’s edits to the audio engine now, rather than when it next plays.

APPLY MUSIC song
apply_music(song)

Parameters

  • song AS STRING - The song.

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
SET MUSIC "Overworld" !! tempo(150)
APPLY MUSIC "Overworld"
PRINT musictempo("Overworld")

Notes

It’s also the function apply_music, for when you want what it gives back.

BEEP

Beep.

BEEP
beep()

Example

SCREEN 320, 240
PRINT "Ready?"
BEEP

Notes

It’s also the function beep, for when you want what it gives back.

CREATE MUSIC PATTERN

Add an empty pattern to a song.

CREATE MUSIC PATTERN song, pattern [, length]
create_music_pattern(song, pattern [, length])

Parameters

  • song AS STRING - The song.
  • pattern AS STRING - The pattern.
  • length AS NUMBER = NULL - Its length, in beats.

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
CREATE MUSIC PATTERN "Overworld", "bridge", 16
CREATE TRACK "Overworld", "bridge" !! channel(1) notes("o4 l4 g f e d")
ADD ARRANGEMENT "Overworld", "bridge"
PRINT musicpatterncount("Overworld"), musicpatternlength("Overworld", "bridge")

Notes

It’s also the function create_music_pattern, for when you want what it gives back.

CREATE TRACK

Add a track to a pattern.

CREATE TRACK song, pattern
create_track(song, pattern)

Also documents: channel, generator, instrument, notes, pan, repeat, track_name, volume

Parameters

  • song AS STRING - The song.
  • pattern AS STRING - The pattern.

After !!

  • channel(value AS NUMBER) - Its channel.
  • generator(value AS FUNCTION) - A function that writes its notes each time the pattern plays; “” unbinds it.
  • instrument(value AS NUMBER) - Its instrument.
  • notes(value AS STRING) - Its notes, in MML.
  • pan(value AS NUMBER) - Its pan, -1 to 1.
  • repeat(on = TRUE) - Whether it repeats to fill the pattern.
  • track_name(value AS STRING) - Its name.
  • volume(value AS NUMBER) - Its volume.

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
CREATE TRACK "Overworld", "verse" !! track_name("harmony") channel(3) instrument(0) volume(50) pan(0.5) notes("o5 l4 e f g a")
n = trackcount("Overworld", "verse")
PRINT n, trackname("Overworld", "verse", n - 1)

Notes

It’s also the function create_track, for when you want what it gives back.

DELETE ARRANGEMENT

Remove a step from a song’s arrangement.

DELETE ARRANGEMENT song, index
delete_arrangement(song, index)

Parameters

  • song AS STRING - The song.
  • index AS NUMBER - Which step, from 0.

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
DELETE ARRANGEMENT "Overworld", 1
PRINT arrangementcount("Overworld")

Notes

It’s also the function delete_arrangement, for when you want what it gives back.

DELETE INSTRUMENT

Remove an instrument.

DELETE INSTRUMENT number
delete_instrument(number)

Parameters

  • number AS NUMBER - The instrument’s number.

Example

SCREEN 320, 240
INSTRUMENT 70
    NAME "Blip"
    LAYER "square"
    END LAYER
END INSTRUMENT
PRINT instrumentexists(70)
DELETE INSTRUMENT 70
PRINT instrumentexists(70)

Notes

It’s also the function delete_instrument, for when you want what it gives back.

DELETE INSTRUMENT LAYER

Remove one of an instrument’s layers.

DELETE INSTRUMENT LAYER number, index
delete_instrument_layer(number, index)

Parameters

  • number AS NUMBER - The instrument’s number.
  • index AS NUMBER - The layer’s index, from 0.

Example

SCREEN 320, 240
INSTRUMENT 70
    NAME "Stack"
    LAYER "square"
    END LAYER
    LAYER "noise" !! volume(0.25)
    END LAYER
END INSTRUMENT
DELETE INSTRUMENT LAYER 70, 1
PRINT instrumentlayercount(70), layerwave(70, 0)

Notes

It’s also the function delete_instrument_layer, for when you want what it gives back.

DELETE MUSIC

Remove a song from the music bank.

DELETE MUSIC song
delete_music(song)

Parameters

  • song AS STRING - The song.

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
DELETE MUSIC "Fanfare"
PRINT songcount(), musicexists("Fanfare")

Notes

It’s also the function delete_music, for when you want what it gives back.

DELETE MUSIC PATTERN

Remove a pattern, and the arrangement steps that play it.

DELETE MUSIC PATTERN song, pattern
delete_music_pattern(song, pattern)

Parameters

  • song AS STRING - The song.
  • pattern AS STRING - The pattern.

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
DELETE MUSIC PATTERN "Overworld", "drums"
PRINT musicpatterncount("Overworld"), arrangementlayercount("Overworld", 0)

Notes

It’s also the function delete_music_pattern, for when you want what it gives back.

DELETE TRACK

Remove a track from a pattern.

DELETE TRACK song, pattern, index
delete_track(song, pattern, index)

Parameters

  • song AS STRING - The song.
  • pattern AS STRING - The pattern.
  • index AS NUMBER - The track’s index in the pattern, from 0.

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
DELETE TRACK "Overworld", "verse", 0
PRINT trackcount("Overworld", "verse"), trackname("Overworld", "verse", 0)

Notes

It’s also the function delete_track, for when you want what it gives back.

FADEMUSIC

Fade a song in (starting it) or out over duration seconds.

FADEMUSIC direction, song, duration
fademusic(direction, song, duration)

Parameters

  • direction AS STRING - “in” or “out”.
  • song AS STRING - The song.
  • duration AS NUMBER - Seconds.

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
FADEMUSIC "in", "Overworld", 0.5
DELAY 50
FADEMUSIC "out", "Overworld", 0.5
PRINT "faded in, then out"

Notes

It’s also the function fademusic, for when you want what it gives back.

INSERT ARRANGEMENT

Insert a step into a song’s arrangement at index.

INSERT ARRANGEMENT song, index, pattern
insert_arrangement(song, index, pattern)

Also documents: repeat, with

Parameters

  • song AS STRING - The song.
  • index AS NUMBER - Where, from 0; the end appends.
  • pattern AS STRING - The pattern.

After !!

  • repeat(value AS NUMBER) - How many times it plays.
  • with(value AS ARRAY) - Patterns that play at the same time.

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
INSERT ARRANGEMENT "Overworld", 0, "drums" !! repeat(2)
FOR st = 0 ... arrangementcount("Overworld") - 1
    PRINT st, arrangementpattern("Overworld", st)
END FOR

Notes

It’s also the function insert_arrangement, for when you want what it gives back.

INSTRUMENTMODE

Choose how instruments sound: “modern” or “retro”.

INSTRUMENTMODE mode
instrumentmode(mode)

Parameters

  • mode AS STRING - “modern” or “retro”.

Example

SCREEN 320, 240
INSTRUMENTMODE "retro"
PLAY "T240 L16 O5 CEG"
INSTRUMENTMODE "modern"
PLAY "T240 L16 O5 CEG"

Notes

It’s also the function instrumentmode, for when you want what it gives back.

LOADINSTRUMENTS

Load instruments from a .cbi file (or the game’s default bank), or only one of them.

LOADINSTRUMENTS [filename]
loadinstruments([filename])

Also documents: instrument

Parameters

  • filename AS STRING = NULL - The file; omitted, the default bank.

After !!

  • instrument(value AS NUMBER) - Load only this one.

Example

SCREEN 320, 240
INSTRUMENT 70
    NAME "Blip"
    LAYER "square" !! volume(0.5)
    END LAYER
END INSTRUMENT
SAVEINSTRUMENTS "mine.cbi"
DELETE INSTRUMENT 70
LOADINSTRUMENTS "mine.cbi"
PRINT instrumentname(70)

Notes

It’s also the function loadinstruments, for when you want what it gives back.

LOADMUSIC

Load a music bank file, and/or render a song ahead of playing it (song).

LOADMUSIC [filename]
loadmusic([filename])

Also documents: song

Parameters

  • filename AS STRING = NULL - A .cbm music bank in the game folder.

After !!

  • song(value AS STRING) - A song to render now, so playing it later does not wait.

Examples

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT songcount()
SCREEN 320, 240
LOADMUSIC "sound-songs.cbm" !! song("Fanfare")
PLAYMUSIC "Fanfare"

Notes

It’s also the function loadmusic, for when you want what it gives back.

MUTE TRACK

Silence a track, or let it sound again with muted off.

MUTE TRACK song, pattern, index
mute_track(song, pattern, index)

Also documents: muted

Parameters

  • song AS STRING - The song.
  • pattern AS STRING - The pattern.
  • index AS NUMBER - The track’s index in the pattern, from 0.

After !!

  • muted(on = TRUE) - Off unmutes it.

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
MUTE TRACK "Overworld", "verse", 1
PRINT trackmuted("Overworld", "verse", 1)
MUTE TRACK "Overworld", "verse", 1 !! muted(FALSE)
PRINT trackmuted("Overworld", "verse", 1)

Notes

It’s also the function mute_track, for when you want what it gives back.

PAUSEMUSIC

Pause the song that is playing.

PAUSEMUSIC
pausemusic()

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PLAYMUSIC "Overworld"
PAUSEMUSIC
PRINT musicplaying()
RESUMEMUSIC
PRINT musicplaying()

Notes

It’s also the function pausemusic, for when you want what it gives back.

PLAY

Play a tune written in MML ("T120 L8 O4 CDEFG"), waiting for it unless background is on.

PLAY mml
play(mml)

Also documents: background

Parameters

  • mml AS STRING - The tune, in MML.

After !!

  • background(on = TRUE) - Play it without waiting.

Examples

SCREEN 320, 240
PLAY "T240 L16 O4 CDEFG"
PRINT "the tune has finished"
SCREEN 320, 240
PLAY "T120 O3 L4 [CEG] [FAC] [GBD] [CEG]" !! background
PRINT "the tune keeps playing while this runs"
STOP PLAY

Notes

It’s also the function play, for when you want what it gives back.

PLAYMUSIC

Play a song; loop overrides whether it loops.

PLAYMUSIC song
playmusic(song)

Also documents: loop

Parameters

  • song AS STRING - The song’s name.

After !!

  • loop(on = TRUE) - Loop it or play it once.

Examples

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PLAYMUSIC "Overworld"
PRINT musicplaying()
SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PLAYMUSIC "Fanfare" !! loop
STOPMUSIC
PLAYMUSIC "Overworld" !! loop(FALSE)

Notes

It’s also the function playmusic, for when you want what it gives back.

RESUMEMUSIC

Resume a paused song.

RESUMEMUSIC
resumemusic()

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PLAYMUSIC "Overworld"
PAUSEMUSIC
DELAY 50
RESUMEMUSIC
PRINT musicplaying()

Notes

It’s also the function resumemusic, for when you want what it gives back.

SAVEINSTRUMENTS

Save the instruments (or one, INSTRUMENT) to a .cbi file.

SAVEINSTRUMENTS filename
saveinstruments(filename)

Also documents: author, description, instrument, name

Parameters

  • filename AS STRING - The file.

After !!

  • author(value AS STRING) - Its author.
  • description(value AS STRING) - A description.
  • instrument(value AS NUMBER) - Save only this one.
  • name(value AS STRING) - The bank’s name.

Example

SCREEN 320, 240
INSTRUMENT 70
    NAME "Blip"
    LAYER "square" !! volume(0.5)
    END LAYER
END INSTRUMENT
SAVEINSTRUMENTS "blip.cbi" !! instrument(70) name("My sounds") author("Ada") description("One blip")
PRINT EXISTS("blip.cbi")

Notes

It’s also the function saveinstruments, for when you want what it gives back.

SET ARRANGEMENT

Replace a song’s arrangement: its patterns, in order, once each.

SET ARRANGEMENT song, patterns
set_arrangement(song, patterns)

Parameters

  • song AS STRING - The song.
  • patterns AS ARRAY - The patterns, in order.

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
SET ARRANGEMENT "Overworld", ["drums", "verse", "verse"]
FOR st = 0 ... arrangementcount("Overworld") - 1
    PRINT arrangementpattern("Overworld", st)
END FOR

Notes

It’s also the function set_arrangement, for when you want what it gives back.

SET AUDIO

Change the volume or pan of a sound that is playing (a WAV, an MP3 or the music).

SET AUDIO name
set_audio(name)

Also documents: pan, volume

Parameters

  • name AS STRING - The sound.

After !!

  • pan(value) - Pan: -1 (left) to 1 (right), or (x, y).
  • volume(value AS NUMBER) - Volume, 0 to 1.

Example

SCREEN 320, 240
LOADWAV "explosion.wav", "boom"
PLAYWAV "boom"
SET AUDIO "boom" !! volume(0.5) pan(-1)

Notes

It’s also the function set_audio, for when you want what it gives back.

SET MUSIC

Change a song’s tempo, looping or time signature.

SET MUSIC song
set_music(song)

Also documents: loop, tempo, timesig

Parameters

  • song AS STRING - The song.

After !!

  • loop(on = TRUE) - Loop it or not.
  • tempo(value AS NUMBER) - Beats per minute.
  • timesig(value AS COORDINATE) - (beats, unit).

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
SET MUSIC "Fanfare" !! tempo(180) loop timesig((4, 4))
PRINT musictempo("Fanfare"), musicloop("Fanfare"), musicbeats("Fanfare")

Notes

It’s also the function set_music, for when you want what it gives back.

SET MUSIC PATTERN

Change a pattern’s length.

SET MUSIC PATTERN song, pattern, length
set_music_pattern(song, pattern, length)

Parameters

  • song AS STRING - The song.
  • pattern AS STRING - The pattern.
  • length AS NUMBER - Its length, in beats.

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
SET MUSIC PATTERN "Overworld", "verse", 16
PRINT musicpatternlength("Overworld", "verse")

Notes

It’s also the function set_music_pattern, for when you want what it gives back.

SET TRACK

Change a track: only what is given changes.

SET TRACK song, pattern, index
set_track(song, pattern, index)

Also documents: channel, generator, instrument, notes, pan, repeat, track_name, volume

Parameters

  • song AS STRING - The song.
  • pattern AS STRING - The pattern.
  • index AS NUMBER - The track’s index in the pattern, from 0.

After !!

  • channel(value AS NUMBER) - Its channel.
  • generator(value AS FUNCTION) - A function that writes its notes each time the pattern plays; “” unbinds it.
  • instrument(value AS NUMBER) - Its instrument.
  • notes(value AS STRING) - Its notes, in MML.
  • pan(value AS NUMBER) - Its pan, -1 to 1.
  • repeat(on = TRUE) - Whether it repeats to fill the pattern.
  • track_name(value AS STRING) - Its name.
  • volume(value AS NUMBER) - Its volume.

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
SET TRACK "Overworld", "verse", 0 !! volume(20) notes("o5 l8 c e g e")
PRINT trackvolume("Overworld", "verse", 0), tracknotes("Overworld", "verse", 0)

Notes

It’s also the function set_track, for when you want what it gives back.

SETINSTRUMENTWAV

Play a loaded WAV as an instrument’s sample.

SETINSTRUMENTWAV instrument, handle
setinstrumentwav(instrument, handle)

Also documents: basepitch, layer, loop

Parameters

  • instrument AS NUMBER - The instrument.
  • handle AS STRING - The WAV (loadwav).

After !!

  • basepitch(value) - The note it was recorded at.
  • layer(value AS NUMBER) - Which layer; omitted, the first.
  • loop(value AS RANGE) - start ... end of the loop, in samples.

Example

SCREEN 320, 240
LOADWAV "explosion.wav", "boom"
INSTRUMENT 70
    NAME "Boom"
    LAYER "sine"
    END LAYER
END INSTRUMENT
SETINSTRUMENTWAV 70, "boom" !! basepitch(60)
PRINT layersample(70, 0), layerbasenote(70, 0)

Notes

It’s also the function setinstrumentwav, for when you want what it gives back.

SOLO TRACK

Play only the soloed tracks, or stop soloing this one with soloed off.

SOLO TRACK song, pattern, index
solo_track(song, pattern, index)

Also documents: soloed

Parameters

  • song AS STRING - The song.
  • pattern AS STRING - The pattern.
  • index AS NUMBER - The track’s index in the pattern, from 0.

After !!

  • soloed(on = TRUE) - Off unsolos it.

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
SOLO TRACK "Overworld", "verse", 1
PRINT tracksoloed("Overworld", "verse", 0), tracksoloed("Overworld", "verse", 1)
SOLO TRACK "Overworld", "verse", 1 !! soloed(FALSE)
PRINT tracksoloed("Overworld", "verse", 1)

Notes

It’s also the function solo_track, for when you want what it gives back.

SOUND

Play a tone of frequency Hz for duration.

SOUND frequency, duration
sound(frequency, duration)

Parameters

  • frequency AS NUMBER - Hz.
  • duration AS NUMBER - How long.

Example

SCREEN 320, 240
SOUND 440, 0.1
SOUND 880, 0.1
PRINT "two tones"

Notes

It’s also the function sound, for when you want what it gives back.

STOP PLAY

Stop a tune play is playing.

STOP PLAY
stop_play()

Example

SCREEN 320, 240
PLAY "T60 O4 L1 C D E F" !! background
DELAY 50
STOP PLAY
PRINT "quiet again"

Notes

It’s also the function stop_play, for when you want what it gives back.

STOPMUSIC

Stop the music.

STOPMUSIC
stopmusic()

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PLAYMUSIC "Overworld"
STOPMUSIC
PRINT musicplaying()

Notes

It’s also the function stopmusic, for when you want what it gives back.

arrangementcount

Number of steps in a song’s arrangement.

arrangementcount(song)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)

Examples

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT arrangementcount("Overworld")
SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
FOR st = 0 ... arrangementcount("Overworld") - 1
    PRINT st, arrangementpattern("Overworld", st), arrangementrepeat("Overworld", st)
END FOR

arrangementlayer

One of the patterns an arrangement step layers on top of its main pattern.

arrangementlayer(song, step, layer)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • step - Zero-based arrangement step index
  • layer - Zero-based index into that step’s WITH list

Examples

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT arrangementlayer("Overworld", 0, 0)
SCREEN 320, 240
MUSIC "groove"
    PATTERN "beat"
        TRACK !! channel(10) notes("o3 c4 c4 c4 c4")
    END PATTERN
    PATTERN "bass"
        TRACK !! channel(2) notes("o2 c2 g2")
    END PATTERN
    PATTERN "lead"
        TRACK !! channel(1) notes("o5 e4 d4 c2")
    END PATTERN
    ARRANGEMENT
        PLAY "beat" !! with("bass", "lead")
    END ARRANGEMENT
END MUSIC
FOR i = 0 ... arrangementlayercount("groove", 0) - 1
    PRINT arrangementlayer("groove", 0, i)
END FOR

arrangementlayercount

How many patterns one arrangement step layers on top of its main pattern (its WITH list).

arrangementlayercount(song, step)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • step - Zero-based arrangement step index

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT arrangementlayercount("Overworld", 0)
PRINT arrangementlayercount("Overworld", 1)

arrangementpattern

The pattern played by one arrangement step.

arrangementpattern(song, step)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • step - Zero-based arrangement step index

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT arrangementpattern("Overworld", 0)

arrangementrepeat

How many consecutive times one arrangement step plays its pattern.

arrangementrepeat(song, step)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • step - Zero-based arrangement step index

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT arrangementrepeat("Overworld", 0)
PRINT arrangementrepeat("Overworld", 1)

custominstrumentcount

How many instruments this program has defined or changed — the ones a .cbi export would contain. Built-ins you never touched are not counted.

custominstrumentcount

Example

SCREEN 320, 240
// A bank in the game's folder (instruments.cbi) counts too
before = custominstrumentcount()
INSTRUMENT 70
    NAME "Blip"
    LAYER "square" !! volume(0.5)
    END LAYER
END INSTRUMENT
PRINT custominstrumentcount() - before, "more"

custominstrumentnumber

The instrument number at index in your custom set, ordered lowest number first. Pairs with CUSTOMINSTRUMENTCOUNT() to walk everything you have built.

custominstrumentnumber(index)

Parameters

  • index - Zero-based position in the custom instrument list

Example

SCREEN 320, 240
INSTRUMENT 71
    NAME "Pad"
    LAYER "triangle"
    END LAYER
END INSTRUMENT
INSTRUMENT 70
    NAME "Blip"
    LAYER "square"
    END LAYER
END INSTRUMENT
// In number order. A bank in the game's folder (instruments.cbi) has its
// own, below 70: show only this program's.
FOR i = 0 ... custominstrumentcount() - 1
    n = custominstrumentnumber(i)
    IF n >= 70 THEN PRINT n, instrumentname(n)
END FOR

instrumentattack

The amplitude envelope’s attack time in seconds.

instrumentattack(number)

Parameters

  • number - Instrument number

Examples

SCREEN 320, 240
PRINT instrumentattack(0)
SCREEN 320, 240
INSTRUMENT 70
    NAME "Swell"
    ENVELOPE !! attack(0.5) decay(0.25) sustain(0.75) release(1)
    LAYER "sawtooth"
    END LAYER
END INSTRUMENT
PRINT instrumentattack(70)

instrumentdecay

The amplitude envelope’s decay time in seconds.

instrumentdecay(number)

Parameters

  • number - Instrument number

Example

SCREEN 320, 240
INSTRUMENT 70
    NAME "Swell"
    ENVELOPE !! attack(0.5) decay(0.25) sustain(0.75) release(1)
    LAYER "sawtooth"
    END LAYER
END INSTRUMENT
PRINT instrumentdecay(70)

instrumentexists

Returns TRUE if that instrument number can be played — either a built-in or one you defined. The one query that never errors on an unknown number, so use it to guard the others.

instrumentexists(number)

Parameters

  • number - Instrument number

Examples

SCREEN 320, 240
PRINT instrumentexists(0)
PRINT instrumentexists(999)
SCREEN 320, 240
wanted = 120
IF NOT instrumentexists(wanted)
    wanted = 0
END IF
PRINT instrumentname(wanted)

instrumentlayercount

How many layers the instrument has. Layer indices run from 0 to this minus 1 — the range every SET INSTRUMENT LAYER and every LAYER… query takes, and what FMTARGET counts.

instrumentlayercount(number)

Parameters

  • number - Instrument number

Example

SCREEN 320, 240
INSTRUMENT 40
    NAME "FM Bass"
    LAYER "sine" !! volume(1)
    END LAYER
    LAYER "sine" !! volume(1) fmtarget(0) fmdepth(1.5)
    END LAYER
END INSTRUMENT
PRINT instrumentlayercount(40)
FOR i = 0 ... instrumentlayercount(40) - 1
    PRINT i, layerwave(40, i), layerfmtarget(40, i)
END FOR

instrumentname

The instrument’s name. Metadata — it is what the IDE shows and what an exported .cbi records; nothing in code is addressed by it. An instrument that was never given a name reads as "Unnamed".

instrumentname(number)

Parameters

  • number - Instrument number

Examples

SCREEN 320, 240
PRINT instrumentname(0)
SCREEN 320, 240
INSTRUMENT 70
    LAYER "square"
    END LAYER
END INSTRUMENT
PRINT instrumentname(70)

instrumentpan

The instrument’s stereo position, -1.0 (left) to 1.0 (right).

instrumentpan(number)

Parameters

  • number - Instrument number

Example

SCREEN 320, 240
INSTRUMENT 70
    NAME "Left Blip"
    PAN -0.5
    LAYER "square"
    END LAYER
END INSTRUMENT
PRINT instrumentpan(70)

instrumentpercussion

TRUE if the instrument ignores the played pitch and always sounds at its fixed frequency.

instrumentpercussion(number)

Parameters

  • number - Instrument number

Example

SCREEN 320, 240
INSTRUMENT 70
    NAME "Kick"
    PERCUSSION TRUE
    LAYER "sine"
    END LAYER
END INSTRUMENT
PRINT instrumentpercussion(70)
PRINT instrumentpercussion(0)

instrumentrelease

The amplitude envelope’s release time in seconds.

instrumentrelease(number)

Parameters

  • number - Instrument number

Example

SCREEN 320, 240
INSTRUMENT 70
    NAME "Swell"
    ENVELOPE !! attack(0.5) decay(0.25) sustain(0.75) release(1)
    LAYER "sawtooth"
    END LAYER
END INSTRUMENT
PRINT instrumentrelease(70)

instrumentsustain

The amplitude envelope’s sustain level, 0.0 to 1.0.

instrumentsustain(number)

Parameters

  • number - Instrument number

Example

SCREEN 320, 240
INSTRUMENT 70
    NAME "Swell"
    ENVELOPE !! attack(0.5) decay(0.25) sustain(0.75) release(1)
    LAYER "sawtooth"
    END LAYER
END INSTRUMENT
PRINT instrumentsustain(70)

instrumentvolume

The instrument’s overall level, 0.0 to 1.0.

instrumentvolume(number)

Parameters

  • number - Instrument number

Example

SCREEN 320, 240
PRINT instrumentvolume(0)
INSTRUMENT 70
    NAME "Quiet"
    VOLUME 0.25
    LAYER "sine"
    END LAYER
END INSTRUMENT
PRINT instrumentvolume(70)

layerbasenote

The MIDI note a sampled layer’s recording sits at — what the sample is resampled from. Reads 0 on a layer with no sample.

layerbasenote(number, index)

Parameters

  • number - Instrument number
  • index - Zero-based layer index within that instrument

Examples

SCREEN 320, 240
PRINT layerbasenote(0, 0)
SCREEN 320, 240
INSTRUMENT 70
    NAME "Boom"
    LAYER "sine"
        SAMPLE "explosion.wav" !! basenote(60)
    END LAYER
END INSTRUMENT
PRINT layerbasenote(70, 0)

layerdetune

The layer’s pitch offset in cents. 100 cents is a semitone.

layerdetune(number, index)

Parameters

  • number - Instrument number
  • index - Zero-based layer index within that instrument

Example

SCREEN 320, 240
INSTRUMENT 41
    NAME "Wide Lead"
    LAYER "sawtooth" !! volume(0.5) detune(-7)
    END LAYER
    LAYER "sawtooth" !! volume(0.5) detune(7)
    END LAYER
END INSTRUMENT
PRINT layerdetune(41, 0), layerdetune(41, 1)

layerduty

The layer’s pulse width, for a PULSE waveform. Reads 0 on a layer that has none set.

layerduty(number, index)

Parameters

  • number - Instrument number
  • index - Zero-based layer index within that instrument

Example

SCREEN 320, 240
INSTRUMENT 70
    NAME "Thin Pulse"
    LAYER "pulse" !! duty(0.25)
    END LAYER
END INSTRUMENT
PRINT layerwave(70, 0), layerduty(70, 0)

layerfeedback

The layer’s operator self-feedback amount. 0 is a clean waveform; higher values warp it toward a buzzy saw.

layerfeedback(number, index)

Parameters

  • number - Instrument number
  • index - Zero-based layer index within that instrument

Example

SCREEN 320, 240
INSTRUMENT 40
    NAME "FM Bass"
    LAYER "sine" !! volume(1)
    END LAYER
    LAYER "sine" !! volume(1) fmtarget(0) fmdepth(1.5) feedback(2.5)
    END LAYER
END INSTRUMENT
PRINT layerfeedback(40, 1)
PRINT layerfeedback(40, 0)

layerfmdepth

How hard this layer modulates its FM target. Reads 0 on a layer that is not a modulator.

layerfmdepth(number, index)

Parameters

  • number - Instrument number
  • index - Zero-based layer index within that instrument

Example

SCREEN 320, 240
INSTRUMENT 40
    NAME "FM Bass"
    LAYER "sine" !! volume(1)
    END LAYER
    LAYER "sine" !! volume(1) fmtarget(0) fmdepth(1.5)
    END LAYER
END INSTRUMENT
PRINT layerfmdepth(40, 1)
PRINT layerfmdepth(40, 0)

layerfmtarget

The index of the layer this one modulates, or -1 if it is an audible layer rather than an FM modulator. Setting it to -1 turns a modulator back into an audible layer.

layerfmtarget(number, index)

Parameters

  • number - Instrument number
  • index - Zero-based layer index within that instrument

Example

SCREEN 320, 240
INSTRUMENT 40
    NAME "FM Bass"
    LAYER "sine" !! volume(1)
    END LAYER
    LAYER "sine" !! volume(1) fmtarget(0) fmdepth(1.5)
    END LAYER
END INSTRUMENT
IF layerfmtarget(40, 1) = 0
    PRINT "layer 1 modulates layer 0"
END IF
PRINT layerfmtarget(40, 0)

layeroctave

The layer’s octave offset from the played note.

layeroctave(number, index)

Parameters

  • number - Instrument number
  • index - Zero-based layer index within that instrument

Example

SCREEN 320, 240
INSTRUMENT 70
    NAME "Sub"
    LAYER "square"
    END LAYER
    LAYER "sine" !! octave(-1)
    END LAYER
END INSTRUMENT
PRINT layeroctave(70, 1)

layersample

The file this layer’s sample came from. A layer bound with SETINSTRUMENTWAV to a handle that has no file behind it (loaded with BASE64TOWAV) reports that handle instead, so a bound layer is never indistinguishable from an unbound one. Empty when the layer uses its oscillator or a wavetable.

layersample(number, index)

Parameters

  • number - Instrument number
  • index - Zero-based layer index within that instrument

Examples

SCREEN 320, 240
PRINT "[" + layersample(0, 0) + "]"
SCREEN 320, 240
LOADWAV "explosion.wav", "boom"
INSTRUMENT 70
    NAME "Boom"
    LAYER "sine"
    END LAYER
END INSTRUMENT
SETINSTRUMENTWAV 70, "boom" !! layer(0)
PRINT layersample(70, 0)

layervolume

The layer’s level within the stack, 0.0 to 1.0.

layervolume(number, index)

Parameters

  • number - Instrument number
  • index - Zero-based layer index within that instrument

Example

SCREEN 320, 240
INSTRUMENT 41
    NAME "Wide Lead"
    LAYER "sawtooth" !! volume(0.5) detune(-7)
    END LAYER
    LAYER "sawtooth" !! volume(0.25) detune(7)
    END LAYER
END INSTRUMENT
PRINT layervolume(41, 0), layervolume(41, 1)

layerwave

The layer’s waveform as a lowercase string — "sine", "square", "triangle", "sawtooth", "pulse", "noise" or "custom". A layer playing a sample or a wavetable still reports the waveform it would otherwise use.

layerwave(number, index)

Parameters

  • number - Instrument number
  • index - Zero-based layer index within that instrument

Examples

SCREEN 320, 240
PRINT layerwave(0, 0)
SCREEN 320, 240
INSTRUMENT 70
    NAME "Stack"
    LAYER "square"
    END LAYER
    LAYER "triangle"
    END LAYER
    LAYER "noise" !! volume(0.25)
    END LAYER
END INSTRUMENT
FOR i = 0 ... instrumentlayercount(70) - 1
    PRINT layerwave(70, i)
END FOR

lipsync

Analyzes a WAV or MP3 audio file and returns an array of timestamped mouth shapes (visemes) for lip sync animation. Each element is an object with TIME (absolute seconds from the start of the audio file, as a float) and SHAPE (viseme code). The optional sensitivity parameter (0.0 to 1.0, default 0.5) controls how much audio is detected: 1.0 picks up the quietest sounds, 0.0 picks up almost nothing. Increase sensitivity for quiet recordings; decrease it to ignore background noise. Uses FFT-based formant analysis to classify vowel and consonant mouth shapes.

lipsync(path, sensitivity = NULL)

Parameters

  • path - Path to a WAV or MP3 audio file
  • sensitivity = NULL - Optional. Detection sensitivity from 0.0 (picks up nothing) to 1.0 (picks up everything). Default is 0.5; a missing or non-numeric value falls back to 0.5

Example

SCREEN 320, 240
shapes = lipsync("ready.mp3", 0.7)
PRINT LEN(shapes), "mouth shapes"
FOR v = shapes
    PRINT v.time, v.shape
END FOR

musicbeats

Beats per measure — the top number of the song’s time signature.

musicbeats(song)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT musicbeats("Fanfare"), "beats a bar"

musicbeatunit

Beat unit — the bottom number of the song’s time signature (4 = quarter notes, 8 = eighth notes).

musicbeatunit(song)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT musicbeats("Fanfare") + "/" + musicbeatunit("Fanfare")

musicexists

Returns TRUE if the named song is in the music bank. The one query that never errors on an unknown name — use it to guard the others.

musicexists(song)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)

Examples

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT musicexists("overworld")
PRINT musicexists("Boss")
SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
IF musicexists("Boss")
    PLAYMUSIC "Boss"
ELSE
    PLAYMUSIC "Overworld"
END IF

musiclength

Total length of a song in ticks (4 ticks per beat), measured from the last audible note of its fully expanded arrangement.

musiclength(song)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
ticks = musiclength("Overworld")
PRINT ticks, "ticks"
PRINT ticks / 4, "beats"

musicloop

TRUE if the song is set to loop when played.

musicloop(song)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT musicloop("Overworld"), musicloop("Fanfare")

musicpatterncount

Number of patterns defined in a song.

musicpatterncount(song)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT musicpatterncount("Overworld")

musicpatternlength

A pattern’s declared length in beats, or 0 if it sizes itself automatically from its longest track.

musicpatternlength(song, pattern)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • pattern - Name of a pattern within that song (matched ignoring case)

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT musicpatternlength("Overworld", "verse")
PRINT musicpatternlength("Overworld", "drums")

musicpatternname

Name of one of a song’s patterns. Patterns are ordered alphabetically ignoring case, so enumeration is stable from run to run.

musicpatternname(song, index)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • index - Zero-based pattern index

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
FOR i = 0 ... musicpatterncount("Overworld") - 1
    PRINT musicpatternname("Overworld", i)
END FOR

musicplaying

Returns whether multi-track music is currently playing. Returns 1 (TRUE) if music is playing, 0 (FALSE) if not playing or paused. (A non-looping song that finishes on its own still reads as playing until you call STOPMUSIC — the engine sends no end-of-song notification.)

musicplaying

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT musicplaying()
PLAYMUSIC "Overworld"
PRINT musicplaying()
STOPMUSIC
PRINT musicplaying()

musicposition

Current playback position of the multi-track song, in ticks — the same unit MUSICLENGTH reports, so the two divide into a progress fraction.

musicposition

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PLAYMUSIC "Overworld"
DELAY 100
length = musiclength("Overworld")
progress = 0
IF length > 0
    progress = musicposition() / length
END IF
PRINT ROUND(progress * 100), "%"
STOPMUSIC

musictempo

A song’s tempo in beats per minute.

musictempo(song)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT musictempo("Overworld")
PRINT 60 / musictempo("Overworld") / 4, "seconds a tick"

patternaudio

The LOADMP3 / LOADWAV handle of the recording a pattern mixes, or an empty string if the pattern has no AUDIO clip — so IF patternaudio(s, p) <> "" THEN is the has-a-recording test.

patternaudio(song, pattern)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • pattern - Name of a pattern within that song (matched ignoring case)

Examples

SCREEN 320, 240
LOADWAV "explosion.wav", "boom"
MUSIC "intro"
    PATTERN "open"
        TRACK !! channel(1) volume(80) notes("o4 c d e")
        AUDIO "boom" !! volume(60)
    END PATTERN
    ARRANGEMENT
        PLAY "open"
    END ARRANGEMENT
END MUSIC
PRINT patternaudio("intro", "open")
SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
IF patternaudio("Overworld", "verse") = ""
    PRINT "verse is synth only"
END IF

patternaudiovolume

The mix level of a pattern’s AUDIO clip, 0 to 100.

patternaudiovolume(song, pattern)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • pattern - Name of a pattern within that song (matched ignoring case)

Example

SCREEN 320, 240
LOADWAV "explosion.wav", "boom"
MUSIC "intro"
    PATTERN "open"
        AUDIO "boom" !! volume(60)
    END PATTERN
    ARRANGEMENT
        PLAY "open"
    END ARRANGEMENT
END MUSIC
PRINT patternaudiovolume("intro", "open")

songcount

Number of songs in the music bank.

songcount

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT songcount()

songname

Name of a song in the bank. Songs are ordered alphabetically ignoring case, so enumeration is stable from run to run.

songname(index)

Parameters

  • index - Zero-based song index

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
FOR i = 0 ... songcount() - 1
    PRINT songname(i)
END FOR

trackchannel

A track’s MIDI channel, 1 to 16.

trackchannel(song, pattern, index)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • pattern - Name of a pattern within that song (matched ignoring case)
  • index - Zero-based track index within the pattern

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT trackchannel("Overworld", "verse", 1)

trackcount

Number of tracks in a pattern. Valid track indices are 0 to TRACKCOUNT - 1.

trackcount(song, pattern)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • pattern - Name of a pattern within that song (matched ignoring case)

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
FOR i = 0 ... trackcount("Overworld", "verse") - 1
    PRINT i, trackname("Overworld", "verse", i)
END FOR

trackgenerator

The name of the BASIC function bound to a track as its generator, or the empty string if it has none. Reads back exactly as it was written.

trackgenerator(song, pattern, index)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • pattern - Name of a pattern within that song (matched ignoring case)
  • index - Zero-based track index within the pattern

Example

SCREEN 320, 240
FUNCTION bass(pattern, track, pass)
    RETURN "o2 c8 c8 g8 g8"
END FUNCTION

MUSIC "groove"
    PATTERN "a"
        TRACK !! channel(2) generator(bass)
    END PATTERN
    ARRANGEMENT
        PLAY "a"
    END ARRANGEMENT
END MUSIC
PRINT trackgenerator("groove", "a", 0)

trackinstrument

A track’s instrument number.

trackinstrument(song, pattern, index)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • pattern - Name of a pattern within that song (matched ignoring case)
  • index - Zero-based track index within the pattern

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT trackinstrument("Overworld", "verse", 0)

trackmuted

TRUE if the track is muted. Lets a program read its own mixer state back instead of shadowing it in variables.

trackmuted(song, pattern, index)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • pattern - Name of a pattern within that song (matched ignoring case)
  • index - Zero-based track index within the pattern

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT trackmuted("Overworld", "drums", 0)
PRINT trackmuted("Overworld", "verse", 0)

trackname

A track’s label, or the empty string if it has none.

trackname(song, pattern, index)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • pattern - Name of a pattern within that song (matched ignoring case)
  • index - Zero-based track index within the pattern

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT trackname("Overworld", "verse", 1)
PRINT "[" + trackname("Fanfare", "hit", 0) + "]"

tracknotes

A track’s MML, as the program wrote it. For a generator track this is its written NOTES (empty if it has none), not what the generator produces: a generator runs each time the song is played — once per repeat, so every pass can differ — and its output goes only to what is played; it is never stored in the song.

tracknotes(song, pattern, index)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • pattern - Name of a pattern within that song (matched ignoring case)
  • index - Zero-based track index within the pattern

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT tracknotes("Overworld", "verse", 0)

trackpan

A track’s stereo position, -1.0 (left) to 1.0 (right).

trackpan(song, pattern, index)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • pattern - Name of a pattern within that song (matched ignoring case)
  • index - Zero-based track index within the pattern

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT trackpan("Overworld", "verse", 1)

trackrepeat

TRUE if the track tiles to fill its pattern’s length.

trackrepeat(song, pattern, index)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • pattern - Name of a pattern within that song (matched ignoring case)
  • index - Zero-based track index within the pattern

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT trackrepeat("Overworld", "verse", 0)
PRINT trackrepeat("Overworld", "verse", 1)

tracksoloed

TRUE if the track is soloed.

tracksoloed(song, pattern, index)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • pattern - Name of a pattern within that song (matched ignoring case)
  • index - Zero-based track index within the pattern

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
SOLO TRACK "Overworld", "verse", 1
PRINT tracksoloed("Overworld", "verse", 0), tracksoloed("Overworld", "verse", 1)

trackvolume

A track’s volume, 0 to 100.

trackvolume(song, pattern, index)

Parameters

  • song - Name of the song in the music bank (matched ignoring case)
  • pattern - Name of a pattern within that song (matched ignoring case)
  • index - Zero-based track index within the pattern

Example

SCREEN 320, 240
LOADMUSIC "sound-songs.cbm"
PRINT trackvolume("Overworld", "verse", 0)
SET TRACK "Overworld", "verse", 0 !! volume(20)
PRINT trackvolume("Overworld", "verse", 0)