Sound executes more than once.

Hello!

2 Questions!

#1: When I trigger a media.newEventSound, sometimes it plays twice? Does anyone know why?

local scoreSound = media.newEventSound("scoresound.wav")  
media.playEventSound(scoreSound)  

#2: I have a game with balls that bounce and everytime they bounce and depending on what they hit I fire a sound like so:

local bounces = {  
[1] = media.newEventSound("duns1.wav"),  
[2] = media.newEventSound("duns2.wav"),  
[3] = media.newEventSound("duns3.wav"),  
[4] = media.newEventSound("duns4.wav"),  
[5] = media.newEventSound("duns5.wav"),  
[6] = media.newEventSound("duns6.wav"),  
[7] = media.newEventSound("bollduns1.wav"),  
[8] = media.newEventSound("bollduns2.wav"),  
[9] = media.newEventSound("bollduns3.wav"),  
[10] = media.newEventSound("bollduns4.wav"),  
[11] = media.newEventSound("bollduns5.wav"),  
[12] = media.newEventSound("bollduns6.wav")  
}  
  
local function randomSound1 ()  
local choice = math.random( 1, 6 )  
media.playEventSound( bounces[choice] )  
 end  
local function randomSound2()  
local choice2 = math.random( 7, 12 )  
 media.playEventSound( bounces[choice2] )  
end  
--sound effects on bounce  
local function onCollision( event )  
 if ( event.phase == "began" ) then  
  
 if(event.object1.name == nil) then -- if ball hits a wall.  
 randomSound2()  
  
 elseif (event.object1.Group == "Ball") then  
 randomSound1()  
 end  
 end  

I am using director class for screen transitioning and if I replay the level a couple of times the sounds fire multiple times.
I have made a cleaning function to remove the eventlistener before replay but maybe its not working?

How come the sounds go off multiple times?
Hope to hear from you guys! Bye! [import]uid: 199163 topic_id: 33673 reply_id: 333673[/import]

Not sure why you are getting the sound twice, you should put some print statements in the if statements in the onCollision function, and in the randomSound() functions to see if you can narrow it down.

On a separate note, you probably don’t need 2 separate random sound functions, why not combing them into one with an argument? That way if you need to make changes later on you only have 1 function to deal with.

[code]
local function randomSound (num)

–we want random to start at 1 or 7. Since it may already be 1, we only need to change if it’s 2.
if num == 2 then
num = 7
end

–either 1-6, or 7-12
local choice = math.random( num, num+5 )
media.playEventSound( bounces[choice] )
end
–sound effects on bounce
local function onCollision( event )
if ( event.phase == “began” ) then

if(event.object1.name == nil) then – if ball hits a wall.
randomSound (2)

elseif (event.object1.Group == “Ball”) then
randomSound (1)
end
end
end

[/code] [import]uid: 84115 topic_id: 33673 reply_id: 133898[/import]

Is there a particular reason your using media.* API calls instead of audio.* API Calls?
[import]uid: 199310 topic_id: 33673 reply_id: 133951[/import]

Hey!

AlanPlantPot. Thanks, Ill do some printing and try and find the reason. And thanks for the snippet!

RobMiracle. The reason is simply that I found a good guide for Media that worked out straight away. Ill try using Sound instead and see if the same thing occurs.

Cheers guys. [import]uid: 199163 topic_id: 33673 reply_id: 133996[/import]

Okay.

I figured out that its my collision detection that fire my score sound and winning sound more than once. Annoying as hell, but at least it wasnt the media thing. (changed to sound but same thing happened)

I want to clean up my bounces table every time I replay. How would I do that?

audio.stop(bounces)  
audio.dispose(bounces)  
bounces = nil  
bounces{}  

This is what i have now, but it seems it ain’t doin nothin.

What am I doing wrong? [import]uid: 199163 topic_id: 33673 reply_id: 134034[/import]

Hi @DPN Sweden,

Managing audio is a bit tricky, and you need to read the documentation on each API call very, very carefully. Sometimes the argument you pass to an API is a sound CHANNEL, and sometimes it’s a sound HANDLE (name). It varies by API which one to use, and while it might seem confusing and totally random, there are very specific reasons why the APIs were designed this way, from an audio engineering standpoint in OpenAL.

For example, audio.stop( [channel] ) requires, as you can see, a CHANNEL number (or just supply no argument to stop all audio channels, a useful technique!). On the other hand, audio.dispose( [audioHandle] ) requires the named audio HANDLE that you used when you loaded the sound using audio.loadSound() or audio.loadStream()

I know, at first it seems confusing, but just study the audio API documentation carefully and you’ll soon get it working. :slight_smile:

http://docs.coronalabs.com/api/library/audio/index.html

Brent [import]uid: 200026 topic_id: 33673 reply_id: 134055[/import]

Not sure why you are getting the sound twice, you should put some print statements in the if statements in the onCollision function, and in the randomSound() functions to see if you can narrow it down.

On a separate note, you probably don’t need 2 separate random sound functions, why not combing them into one with an argument? That way if you need to make changes later on you only have 1 function to deal with.

[code]
local function randomSound (num)

–we want random to start at 1 or 7. Since it may already be 1, we only need to change if it’s 2.
if num == 2 then
num = 7
end

–either 1-6, or 7-12
local choice = math.random( num, num+5 )
media.playEventSound( bounces[choice] )
end
–sound effects on bounce
local function onCollision( event )
if ( event.phase == “began” ) then

if(event.object1.name == nil) then – if ball hits a wall.
randomSound (2)

elseif (event.object1.Group == “Ball”) then
randomSound (1)
end
end
end

[/code] [import]uid: 84115 topic_id: 33673 reply_id: 133898[/import]

Hey Brent!

Thank you (again if read the other thread before this…) for the helping hand.
My day will be dedicated to fixing the audioleak, and with your help I might succeed.

Peace [import]uid: 199163 topic_id: 33673 reply_id: 134134[/import]

Hello again.
The day is over and I did not manage to fix the leaks.
Can anyone show me?

local bounces = {  
[1] = media.newEventSound("duns1.wav"),  
[2] = media.newEventSound("duns2.wav"),  
[3] = media.newEventSound("duns3.wav"),  
[4] = media.newEventSound("duns4.wav"),  
[5] = media.newEventSound("duns5.wav"),  
[6] = media.newEventSound("duns6.wav"),  
[7] = media.newEventSound("bollduns1.wav"),  
[8] = media.newEventSound("bollduns2.wav"),  
[9] = media.newEventSound("bollduns3.wav"),  
[10] = media.newEventSound("bollduns4.wav"),  
[11] = media.newEventSound("bollduns5.wav"),  
[12] = media.newEventSound("bollduns6.wav")  
}  
   
local function randomSound1 ()  
local choice = math.random( 1, 6 )  
media.playEventSound( bounces[choice] )  
 end  
local function randomSound2()  
local choice2 = math.random( 7, 12 )  
 media.playEventSound( bounces[choice2] )  
end  
--sound effects on bounce  
local function onCollision( event )  
 if ( event.phase == "began" ) then  
  
 if(event.object1.name == nil) then -- if ball hits a wall.  
 randomSound2()  
  
 elseif (event.object1.Group == "Ball") then  
 randomSound1()  
 end  
 end  
  

How would I clean this up?
Thank you guys. [import]uid: 199163 topic_id: 33673 reply_id: 134180[/import]

Is there a particular reason your using media.* API calls instead of audio.* API Calls?
[import]uid: 199310 topic_id: 33673 reply_id: 133951[/import]

Hmmm…it doesn’t look like you have changed anything since you posted this a few days ago, but never-the-less…

I think the problem is that as you mentioned in an earlier post, your collisions are triggering too often. You have to keep in mind that if an object has a shallow bounce, it will hit the ground/platform/whatever a few times in quick succession (which is to be expected) - and you are asking it to play a sound every time this happens.

If you want to just limit the sound effect easily you could try using a bool to state whether or not the sound can be played, and a timer.performWithDelay() to reset it after 200ms or something.

[code]

–Unless you have a good reason, you don’t really need to manually number each entry in the table
–they will automatically be numbered starting from 1.
–Also I’ve changed these from media.newEventSound to audio.loadSound. since I never use media. newEventSound and so I can’t really advise on whether or not that would work, whereas I know how audio.loadSound / audio.play works.

local bounces = {
audio.loadSound(“duns1.wav”),
audio.loadSound(“duns2.wav”),
audio.loadSound(“duns3.wav”),
audio.loadSound(“duns4.wav”),
audio.loadSound(“duns5.wav”),
audio.loadSound(“duns6.wav”),
audio.loadSound(“bollduns1.wav”),
audio.loadSound(“bollduns2.wav”),
audio.loadSound(“bollduns3.wav”),
audio.loadSound(“bollduns4.wav”),
audio.loadSound(“bollduns5.wav”),
audio.loadSound(“bollduns6.wav”)
}
local canPlaySound = true

local function resetSoundBool()
canPlaySound = true
end

local function randomSound (num)
–we want random to start at 1 or 7. Since it may already be 1, we only need to change if it’s 2.
if num == 2 then
num = 7
end

–either 1-6, or 7-12
local choice = math.random( num, num+5 )
audio.play( bounces[choice] )
end

–sound effects on bounce
local function onCollision( event )
if ( event.phase == “began” ) then

if(event.object1.name == nil) then – if ball hits a wall.
if canPlaySound then
randomSound (2)
canPlaySound = false
timer.performWithDelay(200, resetSoundBool, 1 )
–for the line above you could use this instead:
–timer.performWithDelay(200, function() canPlaySound = true end, 1 )
–then you wouldn’t need to create the resetSoundBool function above
end

elseif (event.object1.Group == “Ball”) then
if canPlaySound then
randomSound (1)
canPlaySound = false
timer.performWithDelay(200, resetSoundBool, 1 )
end
end
end
end
[/code] [import]uid: 84115 topic_id: 33673 reply_id: 134185[/import]

Hey!

AlanPlantPot. Thanks, Ill do some printing and try and find the reason. And thanks for the snippet!

RobMiracle. The reason is simply that I found a good guide for Media that worked out straight away. Ill try using Sound instead and see if the same thing occurs.

Cheers guys. [import]uid: 199163 topic_id: 33673 reply_id: 133996[/import]

Okay.

I figured out that its my collision detection that fire my score sound and winning sound more than once. Annoying as hell, but at least it wasnt the media thing. (changed to sound but same thing happened)

I want to clean up my bounces table every time I replay. How would I do that?

audio.stop(bounces)  
audio.dispose(bounces)  
bounces = nil  
bounces{}  

This is what i have now, but it seems it ain’t doin nothin.

What am I doing wrong? [import]uid: 199163 topic_id: 33673 reply_id: 134034[/import]

Hi @DPN Sweden,

Managing audio is a bit tricky, and you need to read the documentation on each API call very, very carefully. Sometimes the argument you pass to an API is a sound CHANNEL, and sometimes it’s a sound HANDLE (name). It varies by API which one to use, and while it might seem confusing and totally random, there are very specific reasons why the APIs were designed this way, from an audio engineering standpoint in OpenAL.

For example, audio.stop( [channel] ) requires, as you can see, a CHANNEL number (or just supply no argument to stop all audio channels, a useful technique!). On the other hand, audio.dispose( [audioHandle] ) requires the named audio HANDLE that you used when you loaded the sound using audio.loadSound() or audio.loadStream()

I know, at first it seems confusing, but just study the audio API documentation carefully and you’ll soon get it working. :slight_smile:

http://docs.coronalabs.com/api/library/audio/index.html

Brent [import]uid: 200026 topic_id: 33673 reply_id: 134055[/import]

Hey Brent!

Thank you (again if read the other thread before this…) for the helping hand.
My day will be dedicated to fixing the audioleak, and with your help I might succeed.

Peace [import]uid: 199163 topic_id: 33673 reply_id: 134134[/import]

Hello again.
The day is over and I did not manage to fix the leaks.
Can anyone show me?

local bounces = {  
[1] = media.newEventSound("duns1.wav"),  
[2] = media.newEventSound("duns2.wav"),  
[3] = media.newEventSound("duns3.wav"),  
[4] = media.newEventSound("duns4.wav"),  
[5] = media.newEventSound("duns5.wav"),  
[6] = media.newEventSound("duns6.wav"),  
[7] = media.newEventSound("bollduns1.wav"),  
[8] = media.newEventSound("bollduns2.wav"),  
[9] = media.newEventSound("bollduns3.wav"),  
[10] = media.newEventSound("bollduns4.wav"),  
[11] = media.newEventSound("bollduns5.wav"),  
[12] = media.newEventSound("bollduns6.wav")  
}  
   
local function randomSound1 ()  
local choice = math.random( 1, 6 )  
media.playEventSound( bounces[choice] )  
 end  
local function randomSound2()  
local choice2 = math.random( 7, 12 )  
 media.playEventSound( bounces[choice2] )  
end  
--sound effects on bounce  
local function onCollision( event )  
 if ( event.phase == "began" ) then  
  
 if(event.object1.name == nil) then -- if ball hits a wall.  
 randomSound2()  
  
 elseif (event.object1.Group == "Ball") then  
 randomSound1()  
 end  
 end  
  

How would I clean this up?
Thank you guys. [import]uid: 199163 topic_id: 33673 reply_id: 134180[/import]

Hmmm…it doesn’t look like you have changed anything since you posted this a few days ago, but never-the-less…

I think the problem is that as you mentioned in an earlier post, your collisions are triggering too often. You have to keep in mind that if an object has a shallow bounce, it will hit the ground/platform/whatever a few times in quick succession (which is to be expected) - and you are asking it to play a sound every time this happens.

If you want to just limit the sound effect easily you could try using a bool to state whether or not the sound can be played, and a timer.performWithDelay() to reset it after 200ms or something.

[code]

–Unless you have a good reason, you don’t really need to manually number each entry in the table
–they will automatically be numbered starting from 1.
–Also I’ve changed these from media.newEventSound to audio.loadSound. since I never use media. newEventSound and so I can’t really advise on whether or not that would work, whereas I know how audio.loadSound / audio.play works.

local bounces = {
audio.loadSound(“duns1.wav”),
audio.loadSound(“duns2.wav”),
audio.loadSound(“duns3.wav”),
audio.loadSound(“duns4.wav”),
audio.loadSound(“duns5.wav”),
audio.loadSound(“duns6.wav”),
audio.loadSound(“bollduns1.wav”),
audio.loadSound(“bollduns2.wav”),
audio.loadSound(“bollduns3.wav”),
audio.loadSound(“bollduns4.wav”),
audio.loadSound(“bollduns5.wav”),
audio.loadSound(“bollduns6.wav”)
}
local canPlaySound = true

local function resetSoundBool()
canPlaySound = true
end

local function randomSound (num)
–we want random to start at 1 or 7. Since it may already be 1, we only need to change if it’s 2.
if num == 2 then
num = 7
end

–either 1-6, or 7-12
local choice = math.random( num, num+5 )
audio.play( bounces[choice] )
end

–sound effects on bounce
local function onCollision( event )
if ( event.phase == “began” ) then

if(event.object1.name == nil) then – if ball hits a wall.
if canPlaySound then
randomSound (2)
canPlaySound = false
timer.performWithDelay(200, resetSoundBool, 1 )
–for the line above you could use this instead:
–timer.performWithDelay(200, function() canPlaySound = true end, 1 )
–then you wouldn’t need to create the resetSoundBool function above
end

elseif (event.object1.Group == “Ball”) then
if canPlaySound then
randomSound (1)
canPlaySound = false
timer.performWithDelay(200, resetSoundBool, 1 )
end
end
end
end
[/code] [import]uid: 84115 topic_id: 33673 reply_id: 134185[/import]

Thanks Alan! The reason I did not change the code was becuase I tried to focus on memory leaks, and then I wrote here and pretty much forgot my own question. sigh.
You code works great. Thank you.
[import]uid: 199163 topic_id: 33673 reply_id: 134472[/import]

Thanks Alan! The reason I did not change the code was becuase I tried to focus on memory leaks, and then I wrote here and pretty much forgot my own question. sigh.
You code works great. Thank you.
[import]uid: 199163 topic_id: 33673 reply_id: 134472[/import]