Corona SDK Pro Tip of the Day #18
Music crossfading

Instead of instant change, crossfade your background music.

Usually games have main menu background music and actual gameplay music. When level is loaded you might just instantly stop menu music and play another track, however if you ease it with cross fade, it will sound much better to an ear.

This is a logical continue to my previous pro tip about simple sounds.

local _M = {}

_M.music_on = true

local sounds = {}  
sounds['menu'] = 'sounds/menu.ogg'

local audioChannel, otherAudioChannel, currentMusicPath = 1, 2  
function audio.crossFadeBackground(path, force)  
    if not _M.music_on then return end
    path = sounds[path]
    if currentMusicPath == path and audio.getVolume{channel = audioChannel} > 0.1 and not force then return false end
    audio.fadeOut{channel = audioChannel, time = 1000}
    audioChannel, otherAudioChannel = otherAudioChannel, audioChannel
    audio.setVolume(0.5, {channel = audioChannel})
    audio.play(audio.loadStream(path), {channel = audioChannel, loops = -1, fadein = 1000})
    currentMusicPath = path
end  
audio.reserveChannels(2)

return _M  

It uses the same sounds table and also checks for user option app.music_on.

This code reserves fisrt two sound channels (1 and 2) and plays fadind music on both of them. One channel is for fading out, another one for fading in.

It doesn't cache music files with audio.load(), because it is not advised to load entire music files into memory, instead you use audio.loadStream() which can play large files by small chunks.

Sample usage:

audio.crossFadeBackground('menu')  
...
audio.crossFadeBackground('game')  
...
--pause
...
audio.crossFadeBackground('game', true)  

force parameter is needed to force reloading of the stream if it's currently the active one. I use it inside unpause or turn on music buttons handlers.

Indie Game Developer