QB64 Phoenix Edition
Stopping _SNDPLAYCOPY ?Possible? - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Code and Stuff (https://qb64phoenix.com/forum/forumdisplay.php?fid=3)
+---- Forum: Help Me! (https://qb64phoenix.com/forum/forumdisplay.php?fid=10)
+---- Thread: Stopping _SNDPLAYCOPY ?Possible? (/showthread.php?tid=2911)

Pages: 1 2


RE: Stopping _SNDPLAYCOPY ?Possible? - TerryRitchie - 08-07-2024

(08-07-2024, 05:36 PM)DSMan195276 Wrote: I haven't tested this code, but wouldn't something like this work?

Code: (Select All)
ReDim HandleCache(20) As Long


Sub PlaySound (handle As Long)
    For i = 1 to UBOUND(HandleCache)
        If HandleCache(i) <= 0 _OrElse Not _SndPlaying(HandleCache(i)) Then
            _SndClose HandleCache(i)
            HandleCache(i) = _SndCopy(handle)
            _SndPlay HandleCache(i)
           
            Exit Sub
        End If
    Next

    ReDim HandleCache(UBOUND(HandleCache + 1)) As Long

    HandleCache(UBOUND(HandleCache)) = _SndCopy(handle)
    _SndPlay HandleCache(UBOUND(HandleCache))
End Sub

Sub KillSounds ()
    For i = 1 to Ubound(HandleCache)
        If HandleCache(i) > 0 Then
            _SndClose HandleCache(i)
            HandleCache(i) = -1
        End If
    Next
End Sub

And then you just replace the `_SndPlayCopy` calls with `PlaySound` calls and call `KillSounds` when you're done. It's not super pretty but it doesn't seem all that bad overall.
At first glance that looks about right, however, that's a lot of overhead when dealing with something like a fast-paced game with lots of sprite movements, animations, and sounds working all at once. Just as an example let's say you have 10 enemy combatants coming at you firing their machine guns at 3 rounds per second. That's 30 handles produced every second. If the sound clip is one second long you'll have up to 90 handles floating around that need looked after, not to mention the overhead of _SNDCOPY and _SNDCLOSE doing their thing. These are the scenarios I'm running into.

Off the top of my head a game I used to play a lot was BeJeweled 3 and it suffered from sound overlap when you had many explosions and movement sounds going on all at once. It can be quite distracting when as a player you notice these things. If they would have stopped all the other identical explosion sounds when say a lighting jewel was activated it would have sounded so much better instead of the muddy mess of having the many explosion sounds finish out while the lightning sound effect was going on.


RE: Stopping _SNDPLAYCOPY ?Possible? - SMcNeill - 08-07-2024

(08-07-2024, 02:48 PM)a740g Wrote: I think _SNDSTOPCOPIES may be a good idea. A fair amount of complexity is involved in getting this done on the BASIC side using arrays, _SNDCOPY & _SNDCLOSE. There is no way to stop and dispose of copies until it finishes playing. Also, the C++ side implementation is trivial.

Maybe we can have this in 3.15 when we make more audio-specific improvements. Wink

Instead of a new command, might I suggest a tweaking of the existing commands?

_SNDSTOP handle, (flags$)

Where the optional flag$ would be 
"ONLY" <-- this only stops the original
"COPIES"   <--- this would stop the original and any _SNDPLAYCOPY
"ALL"  <-- this would stop the original and and copies.

Would save creating another sound related keyword for folks to have to chug through and remember, when there's already a boatload of them out there.  Usage would be similar to:

Code: (Select All)
DIM AS LONG h, i

h = _SNDOPEN("explosion.wav")
_SNDPLAY h
_SNDPLAYCOPY h
_SNDPLAYCOPY h
_SNDPLAYCOPY h

_SNDSTOP h, "ONLY"   <-- to stop the _SNDPLAY with the original
_SNDSTOP h, "COPIES" <-- to stop all copies using that original handle
_SNDSTOP h, "BOTH"  <--- to stop both at once



RE: Stopping _SNDPLAYCOPY ?Possible? - Pete - 08-07-2024

Nope, we need a new keyword...

_TurnThat****Off

Pete Big Grin 

- I'm always here to help. Mostly myself, and always at your expense.


RE: Stopping _SNDPLAYCOPY ?Possible? - TerryRitchie - 08-08-2024

(08-07-2024, 10:30 PM)SMcNeill Wrote:
(08-07-2024, 02:48 PM)a740g Wrote: I think _SNDSTOPCOPIES may be a good idea. A fair amount of complexity is involved in getting this done on the BASIC side using arrays, _SNDCOPY & _SNDCLOSE. There is no way to stop and dispose of copies until it finishes playing. Also, the C++ side implementation is trivial.

Maybe we can have this in 3.15 when we make more audio-specific improvements. Wink

Instead of a new command, might I suggest a tweaking of the existing commands?

_SNDSTOP handle, (flags$)

Where the optional flag$ would be 
"ONLY" <-- this only stops the original
"COPIES"   <--- this would stop the original and any _SNDPLAYCOPY
"ALL"  <-- this would stop the original and and copies.

Would save creating another sound related keyword for folks to have to chug through and remember, when there's already a boatload of them out there.  Usage would be similar to:

Code: (Select All)
DIM AS LONG h, i

h = _SNDOPEN("explosion.wav")
_SNDPLAY h
_SNDPLAYCOPY h
_SNDPLAYCOPY h
_SNDPLAYCOPY h

_SNDSTOP h, "ONLY"   <-- to stop the _SNDPLAY with the original
_SNDSTOP h, "COPIES" <-- to stop all copies using that original handle
_SNDSTOP h, "BOTH"  <--- to stop both at once
That's a good solution. The second parameter would need to be optional however to avoid breaking existing code that currently uses _SNDSTOP.