Author Topic: Stopping a sound effect  (Read 153 times)

alexgleason

  • Jr. Member
  • **
  • Posts: 72
  • Vegan on a Desert Island
    • View Profile
    • Vegan on a Desert Island
Stopping a sound effect
« on: October 21, 2018, 07:17:12 pm »
Hi all, wondering if there's any way to do this or any plans to add it? I have an item that should make a continuous sound until stopped.
RIP Aaron Swartz

llamazing

  • Full Member
  • ***
  • Posts: 139
    • View Profile
Re: Stopping a sound effect
« Reply #1 on: October 21, 2018, 07:35:09 pm »
If your sound has a short loop then it should simply be a matter of having a timer looping continuously until stopped that plays the sound over and over.

If the sound has a long loop this could be problematic because once you stop the timer the sound would still continue playing until the end of the loop.

alexgleason

  • Jr. Member
  • **
  • Posts: 72
  • Vegan on a Desert Island
    • View Profile
    • Vegan on a Desert Island
Re: Stopping a sound effect
« Reply #2 on: October 21, 2018, 07:39:05 pm »
If your sound has a short loop then it should simply be a matter of having a timer looping continuously until stopped that plays the sound over and over.

If the sound has a long loop this could be problematic because once you stop the timer the sound would still continue playing until the end of the loop.

It's a vacuum sound, with multiple phases as the power of the vacuum increases the longer you hold the button. Guess I'm gonna try breaking my sfx into tiny pieces and use timers. Thanks!
RIP Aaron Swartz

Max

  • Full Member
  • ***
  • Posts: 173
    • View Profile
Re: Stopping a sound effect
« Reply #3 on: October 22, 2018, 03:06:35 am »
Not sure if this is feasible, but the reason a vacuum sound sounds higher or lower is the speed of the rotation. Idk if it'd work, but if you decreased the time between each vacuum sample being played, the pitch would raise. But we're talking playing this sample every 1-3ms, which might likely break something. But it's worth a shot because you could increase the frequency of the sound kind of realistically. Maybe.

alexgleason

  • Jr. Member
  • **
  • Posts: 72
  • Vegan on a Desert Island
    • View Profile
    • Vegan on a Desert Island
Re: Stopping a sound effect
« Reply #4 on: October 29, 2018, 08:14:50 pm »
Sooo, I tried both methods (Max's and llamazing's). I thought Max's idea was pretty bright but I was getting all kinds of audio buffer errors. It also had a choppy sound. Code was basically this:

Code: Lua
  1. function item:_play_sound()
  2.   local speed = 390 / self._power
  3.   sol.audio.play_sound("alex/vacuum_2")
  4.   self._sound_timers[self._power] = sol.timer.start(self, speed, function()
  5.     self._sound_timers[self._power] = nil
  6.     self:_play_sound()
  7.   end)
  8. end

Maybe there was a way to make this work right, but I'm not sure. Anyway I ended up breaking it up into 3 different sounds and writing this monstrous code:

Code: Lua
  1. -- Handle repeating sfx
  2. -- FIXME: Make this code not horrible!
  3. -- See: https://gitlab.com/solarus-games/solarus/issues/1289
  4. function item:_play_sound()
  5.   if self._power == 1 and not self._sound_timers[1] then
  6.     log("sfx start: Vacuum 1")
  7.     sol.audio.play_sound("vacuum_1")
  8.     self._sound_timers[1] = sol.timer.start(self, 180, function()
  9.       self._sound_timers[1] = nil
  10.       item:_play_sound()
  11.     end)
  12.   elseif self._power == 2 and not self._sound_timers[2] then
  13.     log("sfx start: Vacuum 2")
  14.     sol.audio.play_sound("vacuum_2")
  15.     self._sound_timers[2] = sol.timer.start(self, 125, function()
  16.       self._sound_timers[2] = nil
  17.       item:_play_sound()
  18.     end)
  19.   elseif self._power == 3 and not self._sound_timers[3] then
  20.     log("sfx start: Vacuum 3")
  21.     sol.audio.play_sound("vacuum_3")
  22.     self._sound_timers[3] = sol.timer.start(self, 125, function()
  23.       self._sound_timers[3] = nil
  24.       item:_play_sound()
  25.     end)
  26.   end
  27. end

I may go back and encapsulate the repeating parts into a function, but this was bad code anyway. ::)

I also had to do this when the item command was released, which I don't totally understand.

Code: Lua
  1.   -- Set all sound timers to nil
  2.   -- FIXME: I don't understand why looping through them didn't work
  3.   self._sound_timers[1] = nil
  4.   self._sound_timers[2] = nil
  5.   self._sound_timers[3] = nil

Ultimately, _play_sound() is called whenever the vacuum's power level is changed, so that's nice. It syncs the sound up to the vacuum quite nicely. Each clip is also <200ms so it feels like a pretty immediate stop when you release the button.

Here's the full commit if anyone is interested: https://gitlab.com/voadi/voadi/commit/497699088b4db58860213ca3acc3577acd1dbd09
RIP Aaron Swartz