How To: Music and sounds
In this tutorial you will learn how to work with the Audio sub system. You can set playback of any music in a section and escape the limits of the SMBX engine.
Note: Some features which are presented in this page (such as Audio namespace) are available since LunaLUA version v0.7.
Sounds
Playing built-in sounds
You can play any available sounds by it's ID by using this function:
SFX.play(23)
This example will play the SMBX's sound with ID 23. The full list of built-in SMBX's sounds is listed here.
Playing custom sounds
You can play any custom sounds that you've place in your custom level folder:
SFX.play("my ultra-mega cool sfx.ogg")
When you will call this function, the sound file "my ultra-mega cool sfx.ogg" will be played once. You can use any files of supported formats.
You also can make advanced usage of sounds if you will use Mix_Chunk pointers (SFX.open()):
function locoBellSound()
--Load the sound chunk into buffer and get pointer to them
locoBell = SFX.open("loco bell.ogg")
--Play the loco bell sound 3 times, and set the volume of playing sound
locoBell_ch = SFX.play(locoBell,75,3)
--First argument - is a pointer to opened music chunk which you opened with SFX.open() function
--Second argument - is the volume of the sound.
--Third argument - is a number of loops (0 - loop forever, 1 - play once, 2 - play twice).
end
This example will play a "loco bell.ogg" file 3 times when this function will be called
Playing custom sound loops
This is an example SFX loop usage:
local planeSnd = Audio.newMix_Chunk()
local planeSnd_ch = -1
-- Play flying plane SFX loop with fade-in 1500 ms
function HeyHeyHereIsAPlane()
--Start playing of forever loop of plane sound in 1'st channel with fade-in in 1.5 sec.
planeSnd_ch = Audio.SfxFadeInCh(-1, planeSnd, -1, 1500)
--Set maximal volume for mixer channel where sound is playing
Audio.SfxVolume(planeSnd_ch, 128)
end
-- Fade out plane SFX Loop with fade-out 2000 ms
function PlaneFlyOut()
--Stop playing loop in 1'st channel with fade-out in 2 sec.
Audio.SfxFadeOut(planeSnd_ch, 2000);
end
--Plane sound timer
planeTime = 0
function onStart()
--Open sound file and store chunk pointer into special variable
planeSnd = Audio.SfxOpen("plane.ogg")
--Set playing timeout
planeTime = 10*65;
--Launch plane sound
HeyHeyHereIsAPlane()
end
function onTick()
--While timer is in use
if(planeTime~=0) then
--Decrease timer value
planeTime = planeTime-1
--If timer exited, fade out plane sound loop
if(planeTime==0) then
PlaneFlyOut()
end
end
end
This is a little example of a plane sound which flies above us and go out after 10 seconds.
Music
Play music from another section
The simplest method of music playback usage is a using of musics from another sections
playMusic(4)
This function will play a configured music from 5th section
Set custom music on the fly and play it
You have the ability to play any available custom music file from your level's custom directory if you use a special function:
local section = 0
-- Changes music of 0'th section into given custom and starts it's playback if player is in 0'th section
Audio.MusicChange(section, "My Nice Level/music file.ogg")
Stop music
You can stop playing of current music by setting the silence into the current section:
local section = 0
-- Changes music of 0'th section into silence and stop music playback
Audio.MusicChange(section, 0)
Fade In music
Now, let's play same music file with fade-in effect in 5 seconds:
local section = 0
-- Changes music of 0'th section into given custom and starts it's playback if player is in 0'th section, fade-in effect with 5 seconds delay
Audio.MusicChange(section, "My Nice Level/music file.ogg", 5000)
Adding one extra argument will give you the fade-in effect! The value is in milliseconds. Tip: When you setting the music ID into 0 (aka Silence), you'll run the fade-out effect.
Fade Out music
You can turn the silence beautifully! You only need to call the next function:
local section = 0
-- Changes music of 0'th section into silence and run the fade-out effect with 5 seconds delay on currently playing music
Audio.MusicFadeOut(section, 5000)
Example: Playlist
This is an example of usage multiple musics in one section
-- Timer
local TickTack = 0
-- Music track
local CurTrack = 1
-- Music folder path
local MusicFolder = "MyMusicIsHere/"
-- playlist
Tracks = {
"i_bach_joke.it",
"schwing.mod",
"Double_Cherry_Pass.it",
"ice_ow.mid",
"AliBaba_4Cumbia.mp3",
"the_reincarnation_of_yammah.s3m",
"backtoth.mod",
"8bitenized.xm",
"monkey_island_v1.xm",
"D_MESSAG.it"
}
function switchMusic(sectionWhere)
-- If timer was exited
if(TickTack<=0)then
CurTrack = math.random(table.getn(Tracks))
-- Set custom music of given section and start it's playing with fade-in effect
Audio.MusicChange(sectionWhere, MusicFolder .. Tracks[CurTrack], 1500)
-- Set timeout 20 sec.
TickTack = 20*65
-- Set max volume
Audio.MusicVolume(128)
else
-- Decrement timer
TickTack=TickTack-1
end
if(TickTack==130)then
-- fade out music on last 2 sec.
Audio.MusicFadeOut(sectionWhere, 2000)
end
-- Print the filename of currently playing music file
printText(Tracks[CurTrack], 10, 10);
end
function resumeMusic(sectionWhere)
Audio.MusicChange(sectionWhere, MusicFolder .. Tracks[CurTrack])
Audio.MusicVolume(128)
end
-- Play all custom musics in the second section
function onLoadSection1(playerIndex)
if(playerIndex==1) then
-- Open current track to overwrite previous music file
resumeMusic(1)
end
end
-- Do loop in second section
function onLoopSection1(playerIndex)
if(playerIndex==1) then
switchMusic(1)
end
end
This is an example of shuffle music player for 2'nd section which plays each 20 seconds new music from play-list - an array which contain the list of music files which presented in the level custom folder.
Music (Deprecated manuals)
Advanced way (for old LunaLua older than 0.7.2.3)
You have the ability to play any available custom music file from your level's custom directory if you use a special function:
-- Loads a music file into music stream
Audio.MusicOpen("music file.ogg")
-- Starts playback of current music in stream
Audio.MusicPlay()
Note 1: Some music formats supports extra arguments (for example, track number in the music file, or synthesizer flags, more detailed info and how to use here)
Note 2: To take working a custom musics by Lua code, you should set current music of target section to any default music and insert into the onLoad() event function the call of special function:
Audio.SeizeStream(0)
This example seizing the music stream for 1'st section. When your character in 1'st section, you will have able to correctly use the musicOpen and any other functions.
Note: Don't forget to set to the target section any default music to confuse SMBX engine to take it think than "music is playing". This way will prevent appear of a bugs on switching between another applications.
Example: Playlist (for old LunaLua older than 0.7.2.3)
This is an example of usage multiple musics in one section
-- Timer
TickTack = 0
-- Music track
CurTrack = 1
-- playlist
Tracks = {
"i_bach_joke.it",
"schwing.mod",
"Double_Cherry_Pass.it",
"ice_ow.mid",
"AliBaba_4Cumbia.mp3",
"the_reincarnation_of_yammah.s3m",
"backtoth.mod",
"8bitenized.xm",
"monkey_island_v1.xm",
"D_MESSAG.it"
}
function switchMusic()
-- If timer was exited
if(TickTack<=0)then
CurTrack = math.random(table.getn(Tracks))
-- Open sound track and store into stream
Audio.MusicOpen(Tracks[CurTrack])
-- Set timeout 20 sec.
TickTack = 20*65
-- Set max volume
Audio.MusicVolume(128)
-- Start playback with fade-in effect
Audio.MusicPlayFadeIn(1500)
else
-- Decrement timer
TickTack=TickTack-1
end
if(TickTack==130)then
-- fade out music on last 2 sec.
Audio.MusicStopFadeOut(2000)
end
-- Print the filename of currently playing music file
printText(Tracks[CurTrack], 10, 10);
end
function resumeMusic()
Audio.MusicOpen(Tracks[CurTrack])
Audio.MusicVolume(127)
Audio.MusicPlay()
end
function onLoad()
--Seize music stream for 2'nd section
Audio.SeizeStream(1)
end
-- Play all custom musics in the second section
function onLoadSection1(playerIndex)
if(playerIndex==1) then
-- Open current track to overwrite previous music file
resumeMusic()
end
end
-- Do loop in second section
function onLoopSection1(playerIndex)
if(playerIndex==1) then
switchMusic()
end
end
This is an example of shuffle music player for 2'nd section which plays each 20 seconds new music from play-list - an array which contain the list of music files which presented in the level custom folder.