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:

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()

function locoBellSound()
        --Load the sound chunk into buffer and get pointer to them
	locoBell = Audio.SfxOpen("loco bell.ogg")
        --Set the volume of 1-st channel
	Audio.SfxVolume(1, 75)
        --Play the loco bell sound trice
	Audio.SfxPlayCh(1, locoBell, 2)
	--First argument - is a number of mixing channel which you can use to play sounds in parallel
	--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()

-- Play flying plane SFX loop with fade-in 1500 ms
function HeyHeyHereIsAPlane()
        --Set maximal volume for 1'st mixer channel
	Audio.SfxVolume(1, 128)
        --Start playing of forever loop of plane sound in 1'st channel with fade-in in 1.5 sec.
	Audio.SfxFadeInCh(1, planeSnd, -1, 1500)
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(1, 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

Simple way

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

Advanced way

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

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