Handling Audio just a quick question with a simple answer

Hi all :smiley:

I have a couple of simple questions about handling audio.

I started out having serious problems with my audio but that was inexperience and sloppy code, I’m much better now and have no audio issues, but I do have a couple of gaps in my knowledge on this subject and I’m hoping some nice people here on Corona can give me the answers.

I load all my sounds in a separate module called sfx.lua

In every scene I declare all my audio local and give every channel a handle like so…

local sfx = require(“sfx”)

local backsound = audio.play(sfx.backSound, {loops=-1})
       audio.setVolume( 0.6, { channel=backSound } )

I normally stop all the sound in the exit scene with audio.stop()

Then I dispose of all the audio files in the sfx table…

for i = 1, 16 do
        audio.dispose(i)
    end

Then I delete the package sfx

package.loaded[“sfx”] = nil

My question is this, do I need to nil out all the audio handles like so…

backsound = nil

winsound = nil

My logic is because all the handles are local and they are all inside the Storyboard enterScene does not Storyboard nil them out anyway? Also true with local variables and local functions()? :huh:

And another thing I’m concerned about is reserving audio channels…

audio.reserveChannels( 16 )

So far I have 16 sounds in my sfx.lua module and will probably add more.

Is it necessary to reserve a channel for each sound you load?

sfx.backSound = audio.loadSound( “sounds/ambience.ogg”, {channel=5} )

Should I be using .ogg or would .wav be more universally accepted?

Because I give every sound a name in each scene and stop and start them and fade them in and out with their name(handle) not their channel number, would just loading the sounds without channels make any difference?

Let’s start with the memory management.  If the audio.play is returning a channel number, then it’s a simple variable.  No block of memory is allocated.  Let me step back:

local a = 10

local b = {}

local c = nil

all take up 4 bytes of memory (or whatever size Lua uses. C int’s are 4 bytes).  “b” contains a pointer to the data of the table, not the the table itself.  When you create a display.newImage() object or an audio.loadSound() you’re putting a table in the variable and that table has allocated memory.  These have to be disposed of.  When you :removeSelf() on a display object or .dispose on a piece of audio, the allocated memory is freed up, but the table and all it’s members is still there and needs nilled out (and it signals garbage collection to do its thing).   However once you nil the table, its the same memory usage as just putting an integer in it.  In other words nilling an int doesn’t change anything memory wise, just the value of the variable.

Now for the channels thing.  You use a channel for each sound that’s currently playing.  Normally I will reserve 1-2 channels depending on the app.  I keep the background audio on channel 1, maybe use channel 2 for voice overs.  For other short lived sound effects, I just call audio.findFreeChanel() (http://docs.coronalabs.com/api/library/audio/findFreeChannel.html) to grab a channel out of the remaining pool of 3-32.

.wav is more universally playable.  .oog I think only works on Android and not iOS.  .mp3 is also generally widely used.  Of course .wav files are big and .mp3 has potential patent issues, so you need to decide on the tradeoffs.  If you’re only building for one platform, then you can use the best audio for that operating system you’re building for, or you can use logic and have the best for each.

Rob

That’s good information Rob, I’ve written it down.

I’m still a little confused because I’m not loading my audio in a straight forward way, I’m using a module then calling it.

local sfx = require(“sfx”)

local backsound = audio.play(sfx.backSound, {loops=-1})
 audio.setVolume( 0.6, { channel=backSound } )

I’m setting the channel using the backsound handle, what is this doing?

Is it using the channel set inside the sfx module?

sfx.lua

sfx.backSound = audio.loadSound( “sounds/ambience.ogg”, {channel=5} )

If so, if I remove the {channel=5} can I still use: audio.setVolume( 0.6, { channel=backSound } ) ?

Or do I leave the channel thing out completely?

If so can I still use these commands…

audio.stop(backSound) and this, audio.fadeOut( { channel=backSound, time=2000 } )

I need to stop and start other sounds in the main chunk and this is the only method that has worked for me.

If you have a lot of audio, then WAV should not be an option.  You could quickly go over the WiFi download limit.

I do separate builds for iOS and Android, using .OGG for Android and .M4A for iOS.  Works well.  You can code it so that you append the appropriate file extension based on the platform and only include the needed files for the platform.

Thanks for that GDog, that’s good to know and a question I needed answered, I am currently writing my app as if it would be for any platfrom so good to know I can seperate the audio files.

What are your thoughts on stopping and starting short audio clips, how do you handle them?

I love the simplistic method I’ve been using, it’s fool proof…

local backsound = audio.play(sfx.backSound, {loops=-1})

 audio.setVolume( 0.6, { channel=backSound } )

audio.stop(backSound) and audio.fadeOut( { channel=backSound, time=2000 } )

audio.play returns a number value, which is the channel the sound was played on.  This is why you can use “backSound” later as a channel value.  This will be a number between 1 and 32.  It’s a simple value and does not need to be nilled unless you need it for game logic.

Rob

I would listen to what Rob suggests as far as stopping.  I don’t normally ever need to stop sounds, but I was doing it like you showed.

As for creating the files, I use the free, open-source Audacity to edit my files, then I export as .M4A and .OGG, keeping the same file name.  Makes it eady to quickly switch between the two as needed.

GDog and Rob thankyou very much for taking the time to help me out, you have answered all my questions and I can now cross that one off my list of things to know.

Good luck with your future projects!

Let’s start with the memory management.  If the audio.play is returning a channel number, then it’s a simple variable.  No block of memory is allocated.  Let me step back:

local a = 10

local b = {}

local c = nil

all take up 4 bytes of memory (or whatever size Lua uses. C int’s are 4 bytes).  “b” contains a pointer to the data of the table, not the the table itself.  When you create a display.newImage() object or an audio.loadSound() you’re putting a table in the variable and that table has allocated memory.  These have to be disposed of.  When you :removeSelf() on a display object or .dispose on a piece of audio, the allocated memory is freed up, but the table and all it’s members is still there and needs nilled out (and it signals garbage collection to do its thing).   However once you nil the table, its the same memory usage as just putting an integer in it.  In other words nilling an int doesn’t change anything memory wise, just the value of the variable.

Now for the channels thing.  You use a channel for each sound that’s currently playing.  Normally I will reserve 1-2 channels depending on the app.  I keep the background audio on channel 1, maybe use channel 2 for voice overs.  For other short lived sound effects, I just call audio.findFreeChanel() (http://docs.coronalabs.com/api/library/audio/findFreeChannel.html) to grab a channel out of the remaining pool of 3-32.

.wav is more universally playable.  .oog I think only works on Android and not iOS.  .mp3 is also generally widely used.  Of course .wav files are big and .mp3 has potential patent issues, so you need to decide on the tradeoffs.  If you’re only building for one platform, then you can use the best audio for that operating system you’re building for, or you can use logic and have the best for each.

Rob

That’s good information Rob, I’ve written it down.

I’m still a little confused because I’m not loading my audio in a straight forward way, I’m using a module then calling it.

local sfx = require(“sfx”)

local backsound = audio.play(sfx.backSound, {loops=-1})
 audio.setVolume( 0.6, { channel=backSound } )

I’m setting the channel using the backsound handle, what is this doing?

Is it using the channel set inside the sfx module?

sfx.lua

sfx.backSound = audio.loadSound( “sounds/ambience.ogg”, {channel=5} )

If so, if I remove the {channel=5} can I still use: audio.setVolume( 0.6, { channel=backSound } ) ?

Or do I leave the channel thing out completely?

If so can I still use these commands…

audio.stop(backSound) and this, audio.fadeOut( { channel=backSound, time=2000 } )

I need to stop and start other sounds in the main chunk and this is the only method that has worked for me.

If you have a lot of audio, then WAV should not be an option.  You could quickly go over the WiFi download limit.

I do separate builds for iOS and Android, using .OGG for Android and .M4A for iOS.  Works well.  You can code it so that you append the appropriate file extension based on the platform and only include the needed files for the platform.

Thanks for that GDog, that’s good to know and a question I needed answered, I am currently writing my app as if it would be for any platfrom so good to know I can seperate the audio files.

What are your thoughts on stopping and starting short audio clips, how do you handle them?

I love the simplistic method I’ve been using, it’s fool proof…

local backsound = audio.play(sfx.backSound, {loops=-1})

 audio.setVolume( 0.6, { channel=backSound } )

audio.stop(backSound) and audio.fadeOut( { channel=backSound, time=2000 } )

audio.play returns a number value, which is the channel the sound was played on.  This is why you can use “backSound” later as a channel value.  This will be a number between 1 and 32.  It’s a simple value and does not need to be nilled unless you need it for game logic.

Rob

I would listen to what Rob suggests as far as stopping.  I don’t normally ever need to stop sounds, but I was doing it like you showed.

As for creating the files, I use the free, open-source Audacity to edit my files, then I export as .M4A and .OGG, keeping the same file name.  Makes it eady to quickly switch between the two as needed.

GDog and Rob thankyou very much for taking the time to help me out, you have answered all my questions and I can now cross that one off my list of things to know.

Good luck with your future projects!