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
.cbmmusic 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 ... endof 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)