elseif love.keyboard.isDown('x') and player.dir == "right" then -- jump
love.audio.play(audiosrc.jump)
curranim = anim.jumpright
jumping = true
elseif love.keyboard.isDown('x') and player.dir == "left" then
love.audio.play(audiosrc.jump)
curranim = anim.jumpleft
jumping = true
I know the jump code is ugly right now, but when the player jump's it play's the sound just fine, but only once. I can jump about 4-5 times after the first sound and hear nothing, but after a certain amount of time (like 3-5sec) it will play on another jump. Anyone know what's causing this?
EDIT: After adding "love.audio.stop()" to the "else" if no key is down it works but only if I keep held the jump button. So I'm assuming there needs to be some sort of duration?
Last edited by Ryne on Sat Dec 11, 2010 7:28 pm, edited 2 times in total.
If a given sound source is currently playing and you call play again, it won't start over. You have to either wait until it's done, or call 'stop' on it.
If you want another instance of the same sound to sound to play, such that it overlaps with the current sound, then you need to create a new instance of the audio source and play *that*.
Like Mud said, a sound source can only be playing one at a time. I'll steal a metaphor I read somewhere and tell it to you:
Think of sound sources like a trumpet. The trumpet can't play the more than once at a time. So, what do you do to solve this issue?
You add more trumpets.
The easiest way to do this is to use a library like Soundmanager (LÖVE-class also has this functionality) to create and play sources for you on demand.
Basically, you need to create your sound as a SoundData, and when you want to play it, create a Source from the SoundData and play that.
love.audio.play(sounds[soundcounter])
soundcounter = soundcounter + 1
if soundcounter > table.getn(sounds) then
soundcounter = 1
end
Kinda cheesy, and you're still limited to whatever amount of sounds you have in the table playing at the same time, but for smaller low mem sounds it workd pretty good for me.
love.audio.play(sounds[soundcounter])
soundcounter = soundcounter + 1
if soundcounter > table.getn(sounds) then
soundcounter = 1
end
Kinda cheesy, and you're still limited to whatever amount of sounds you have in the table playing at the same time, but for smaller low mem sounds it workd pretty good for me.
To be honest, I actually thought of doing that on my own, I just assumed I was working with sounds wrong, and therefore it wouldn't be as complicated as that.
EDIT: Actually When I use this code outside of update it doesn't work, once inside update it cause sever lag, about 2 fps in the game. This only happens if the iterator is inside of update:
I'm going to pull a Zac and post an entire block of code: this is a pared-down version of what I use in my game, hopefully you can adapt it to your needs.
The problem I foresee with the 10 second war method is that if you have 10 sounds going at once, that will work, but if you have 10 sounds followed by another 10 sounds quickly, the last 10 sounds will go unheard.
require "subclass/class.lua"
soundfx = class:new()
function soundfx:init()
self.jump = love.audio.newSource("media/sfx/jump.ogg", "static")
self.break = love.audio.newSource("media/sfx/break.ogg", "static")
self.death = love.audio.newSource("media/sfx/death.ogg", "static")
end
function soundfx:play(sound)
love.audio.stop(self[sound])
love.audio.play(self[sound])
end
What the best solution is depends on what you want: for example, the sound of your own death is likely just played once, so you wouldn't want to use stop(). If it is the sound of the death of a random mook, you'll want to take the soundmanager approach, like thelinx pointed out, which scales well.
require "subclass/class.lua"
soundfx = class:new()
function soundfx:init()
self.jump = love.audio.newSource("media/sfx/jump.ogg", "static")
self.break = love.audio.newSource("media/sfx/break.ogg", "static")
self.death = love.audio.newSource("media/sfx/death.ogg", "static")
end
function soundfx:play(sound)
love.audio.stop(self[sound])
love.audio.play(self[sound])
end
What the best solution is depends on what you want: for example, the sound of your own death is likely just played once, so you wouldn't want to use stop(). If it is the sound of the death of a random mook, you'll want to take the soundmanager approach, like thelinx pointed out, which scales well.
@Robin: Thanks, I appreciate it. I didn't use that method before because it pooped out when I first tested it, but now I realize it's because "break" is a keyword in Lua... doh. All I have to do is rename break to something like "crunch" and it works perfectly. I love the way that half of programming (for me) is fixing dumb errors that I should have seen the first time around.
TechnoCat wrote:The problem I foresee with the 10 second war method is that if you have 10 sounds going at once, that will work, but if you have 10 sounds followed by another 10 sounds quickly, the last 10 sounds will go unheard.
Yeah, my solution was to use the same circular buffer idea, but start with only 1 source and allocate others only if necessary. The worst case usage establishes how many sources you buffer for a particular sound. Once that's hit, there's no more allocating sources, just cycling through existing ones. If a sound is played infrequently, you end up with only one source, and the fast path to it is reasonably direct:
function Sound:play()
repeat
if sources[self.current]:isStopped() then
love.audio.play(sources[self.current])
return
-- check others sources, starting with oldest moving toward most recently played
Sound = class()
function Sound:init(filename)
self.raw = love.sound.newSoundData(filename)
self.sources = { love.audio.newSource(self.raw, 'static') }
self.current = 1
end
function Sound:play()
local start, sources = self.current, self.sources
repeat
if sources[self.current]:isStopped() then
love.audio.play(sources[self.current])
return
end
self.current = self.current % #sources + 1
until self.current == start
-- no free sources available, create a new one
self.current = #sources + 1
sources[self.current] = love.audio.newSource(self.raw, 'static')
love.audio.play(sources[self.current])
end