How To: Music and sounds

From PGE Wiki
Jump to: navigation, search

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:

Audio.playSFX(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:

Audio.playSFX("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:

-- Create a global pointer for a sound chunk
local locoBell = Audio.newMix_Chunk()
-- A current Mixer's channel where sound is playing
local locoBell_ch = -1;

function locoBellSound()
    --Load the sound chunk into buffer and get pointer to them
	locoBell = Audio.SfxOpen("loco bell.ogg")
    --Play the loco bell sound trice
	locoBell_ch = Audio.SfxPlayCh(-1, locoBell, 2)
	--Set the volume of playing sound
	Audio.SfxVolume(locoBell_ch, 75)
	--First argument - is a number of mixing channel which you can use to play sounds in parallel.
    --  -1 means automatically select any free channel. It's number will be returned.
	--If this argument will be equal to -1, will be used any free channel which will be returned by this function.
    --Second argument - is a pointer to opened music chunk which you opened with SfxOpen() function
    --Third argument - is a number of loops (0 - play once, 1 - play twice, -1 - loop forever.
    --To take able to break loop you will need to save the number of channel into any variable)
end

This example will play a "loco bell.ogg" file trice 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 onLoad()
    --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 onLoop()
    --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.

Further Reading