Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- audio manager
- ]]
- --sound source wrapper
- local sound = class()
- --
- function sound:new(source, volume, set)
- return self:init({
- source = source,
- set = set,
- volume = volume,
- })
- end
- --stop the sound
- function sound:stop()
- self.set:remove(self)
- end
- --todo: volume/etc controls?
- --soundset - a collection of same-audio sources that can be
- -- played/triggered as needed and managed as a single unit.
- local soundset = class()
- --create a soundset
- function soundset:new(manager, path, source_count, source_type)
- local r = self:init({
- manager = manager,
- path = path,
- source_count = source_count,
- sounds = {},
- sources = {},
- })
- for i = 1,source_count do
- table.insert(r.sources, love.audio.newSource(path, source_type))
- end
- return r
- end
- --update this set (stop sounds as needed)
- function soundset:update()
- table.foreach(self.sounds, function(sound)
- --clean up stopped sounds
- if not sound.source:isPlaying() then
- sound:stop()
- end
- end)
- end
- --play a sound
- function soundset:play(loop, reset, volume)
- if #self.sources == 0 then
- if reset then
- --shift the oldest sound and recurse
- local sound = table.remove(self.sounds, 1)
- if sound then
- self:remove(sound)
- return self:play(loop, reset, volume)
- end
- else
- --could not play
- return nil
- end
- end
- local source = table.remove(self.sources)
- --setup source params
- source:setVolume(volume * self.manager.volume)
- source:setLooping(loop)
- --start it
- love.audio.play(source)
- --init the sound
- local sound = sound:new(source, volume, self)
- --push to sound queue
- table.insert(self.sounds, sound)
- --done!
- return sound
- end
- function soundset:remove(sound)
- --stop the sound
- love.audio.stop(sound.source)
- --recycle the source
- table.insert(self.sources, sound.source)
- sound.source = nil
- --remove the sound object
- table.remove_value(self.sounds, sound)
- end
- --the actual audio manager class
- local audio = class()
- --create a new audio manager
- function audio:new()
- return self:init({
- sets = {},
- volume = 1.0,
- })
- end
- --update the audio manager
- function audio:update()
- table.foreach(self.sets, soundset.update)
- end
- --add a sound set
- function audio:add_set(name, sound_path, source_count, source_type)
- if not self.sets[name] then
- if sound_path == "" then
- error("missing sound set "..name)
- end
- self.sets[name] = soundset:new(self, sound_path, source_count, source_type)
- end
- return self.sets[name]
- end
- --play a sound set by name, returning the sound
- function audio:play(name, args)
- --(args here are default to catch unloaded sounds)
- local set = self:add_set(name, "", 1, "static")
- args = args or {}
- default(args, "loop", false)
- default(args, "reset", true)
- default(args, "volume", 1.0)
- return set:play(args.loop, args.reset, args.volume)
- end
- --stop all sounds playing for a given set name
- function audio:stop(name)
- if name == nil then
- for k,v in pairs(self.sets) do
- self:stop(k)
- end
- end
- if self.sets[name] ~= nil then
- local sounds = self.sets[name].sounds
- while #sounds > 0 do
- sounds[1]:stop() --(handles remove itself)
- end
- end
- end
- --volume handling
- --get the current master volume
- function audio:get_volume()
- return self.volume
- end
- --set the current master volume
- function audio:set_volume(volume)
- --limit
- volume = math.clamp(volume, 0, 1)
- --(avoid setting everything if no change)
- if self.volume == volume then
- return
- end
- --update volume for manager and all soundsets
- self.volume = volume
- for name, set in pairs(self.sets) do
- --update active sounds volume
- table.foreach(set.sounds, function(sound)
- sound.source:setVolume(sound.volume * volume)
- end)
- --update inactive sounds volume (maybe not needed)
- table.foreach(set.sources, function(source)
- source:setVolume(volume)
- end)
- end
- end
- return audio
Add Comment
Please, Sign In to add comment