Guest User

Untitled

a guest
Nov 14th, 2018
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.70 KB | None | 0 0
  1. --[[
  2. audio manager
  3. ]]
  4.  
  5. --sound source wrapper
  6. local sound = class()
  7.  
  8. --
  9. function sound:new(source, volume, set)
  10. return self:init({
  11. source = source,
  12. set = set,
  13. volume = volume,
  14. })
  15. end
  16.  
  17. --stop the sound
  18. function sound:stop()
  19. self.set:remove(self)
  20. end
  21.  
  22. --todo: volume/etc controls?
  23.  
  24. --soundset - a collection of same-audio sources that can be
  25. -- played/triggered as needed and managed as a single unit.
  26. local soundset = class()
  27.  
  28. --create a soundset
  29. function soundset:new(manager, path, source_count, source_type)
  30. local r = self:init({
  31. manager = manager,
  32. path = path,
  33. source_count = source_count,
  34. sounds = {},
  35. sources = {},
  36. })
  37. for i = 1,source_count do
  38. table.insert(r.sources, love.audio.newSource(path, source_type))
  39. end
  40. return r
  41. end
  42.  
  43. --update this set (stop sounds as needed)
  44. function soundset:update()
  45. table.foreach(self.sounds, function(sound)
  46. --clean up stopped sounds
  47. if not sound.source:isPlaying() then
  48. sound:stop()
  49. end
  50. end)
  51. end
  52.  
  53. --play a sound
  54. function soundset:play(loop, reset, volume)
  55. if #self.sources == 0 then
  56. if reset then
  57. --shift the oldest sound and recurse
  58. local sound = table.remove(self.sounds, 1)
  59. if sound then
  60. self:remove(sound)
  61. return self:play(loop, reset, volume)
  62. end
  63. else
  64. --could not play
  65. return nil
  66. end
  67. end
  68.  
  69. local source = table.remove(self.sources)
  70. --setup source params
  71. source:setVolume(volume * self.manager.volume)
  72. source:setLooping(loop)
  73. --start it
  74. love.audio.play(source)
  75. --init the sound
  76. local sound = sound:new(source, volume, self)
  77. --push to sound queue
  78. table.insert(self.sounds, sound)
  79. --done!
  80. return sound
  81. end
  82.  
  83. function soundset:remove(sound)
  84. --stop the sound
  85. love.audio.stop(sound.source)
  86. --recycle the source
  87. table.insert(self.sources, sound.source)
  88. sound.source = nil
  89. --remove the sound object
  90. table.remove_value(self.sounds, sound)
  91. end
  92.  
  93. --the actual audio manager class
  94.  
  95. local audio = class()
  96.  
  97. --create a new audio manager
  98. function audio:new()
  99. return self:init({
  100. sets = {},
  101. volume = 1.0,
  102. })
  103. end
  104.  
  105. --update the audio manager
  106. function audio:update()
  107. table.foreach(self.sets, soundset.update)
  108. end
  109.  
  110. --add a sound set
  111. function audio:add_set(name, sound_path, source_count, source_type)
  112. if not self.sets[name] then
  113. if sound_path == "" then
  114. error("missing sound set "..name)
  115. end
  116. self.sets[name] = soundset:new(self, sound_path, source_count, source_type)
  117. end
  118. return self.sets[name]
  119. end
  120.  
  121. --play a sound set by name, returning the sound
  122. function audio:play(name, args)
  123. --(args here are default to catch unloaded sounds)
  124. local set = self:add_set(name, "", 1, "static")
  125.  
  126. args = args or {}
  127. default(args, "loop", false)
  128. default(args, "reset", true)
  129. default(args, "volume", 1.0)
  130.  
  131. return set:play(args.loop, args.reset, args.volume)
  132. end
  133.  
  134.  
  135. --stop all sounds playing for a given set name
  136. function audio:stop(name)
  137. if name == nil then
  138. for k,v in pairs(self.sets) do
  139. self:stop(k)
  140. end
  141. end
  142. if self.sets[name] ~= nil then
  143. local sounds = self.sets[name].sounds
  144. while #sounds > 0 do
  145. sounds[1]:stop() --(handles remove itself)
  146. end
  147. end
  148. end
  149.  
  150. --volume handling
  151.  
  152. --get the current master volume
  153. function audio:get_volume()
  154. return self.volume
  155. end
  156.  
  157. --set the current master volume
  158. function audio:set_volume(volume)
  159. --limit
  160. volume = math.clamp(volume, 0, 1)
  161. --(avoid setting everything if no change)
  162. if self.volume == volume then
  163. return
  164. end
  165.  
  166. --update volume for manager and all soundsets
  167. self.volume = volume
  168. for name, set in pairs(self.sets) do
  169. --update active sounds volume
  170. table.foreach(set.sounds, function(sound)
  171. sound.source:setVolume(sound.volume * volume)
  172. end)
  173. --update inactive sounds volume (maybe not needed)
  174. table.foreach(set.sources, function(source)
  175. source:setVolume(volume)
  176. end)
  177. end
  178. end
  179.  
  180.  
  181. return audio
Add Comment
Please, Sign In to add comment