Author Topic: BASS_ChannelStop and BASS_SYNC_END  (Read 319 times)

Player701

  • Posts: 3
BASS_ChannelStop and BASS_SYNC_END
« on: 27 Sep '23 - 21:03 »
Greetings!

I'd like to use BASS to develop a small sound engine for a personal project, where I need to know when a sound has finished playing (in order to play the next one, as they come in sequence), but it should also be possible to interrupt the currently playing sound on request (which may come at any time).

The former seems like a perfect use case for BASS_ChannelSetSync with type BASS_SYNC_END, while the latter can be achieved with BASS_ChannelStop (NB: not ChannelFree as it may be necessary to play the same sound again at some later point in time).

Now, suppose playback reaches the end so that the SYNCPROC set by BASS_ChannelSetSync starts executing, but just a bit later BASS_ChannelStop is called. In this particular scenario, is there any guarantee that the SYNCPROC will complete before the call to BASS_ChannelStop completes, or is there no such guarantee? If not, then is it possible in this case to somehow await completion of the SYNCPROC, provided that it was actually called in the first place?

Note that the SYNCPROC is not mixtime (as it is used to signal when playback has really finished and nothing is playing anymore).

Thank you very much.


Ian @ un4seen

  • Administrator
  • Posts: 25626
Re: BASS_ChannelStop and BASS_SYNC_END
« Reply #1 on: 28 Sep '23 - 16:04 »
A BASS_ChannelStop call in another thread would not be blocked by a non-mixtime BASS_SYNC_END sync's callback. If you would like it to be, perhaps you could have the SYNCPROC function and BASS_ChannelStop call share a lock/mutex?

Player701

  • Posts: 3
Re: BASS_ChannelStop and BASS_SYNC_END
« Reply #2 on: 28 Sep '23 - 16:47 »
Thanks for the clarification.

The issue here is that I need to ensure that after BASS_ChannelStop is called, the SYNCPROC must not be able to cause any side-effects anymore. E.g. suppose it sets a "playback finished" flag, then if playback is requested to begin again immediately after a manual stop, the SYNCPROC may erroneously set this flag after it has already been reset in preparation to begin playback again. Thus, the current state of the flag would not reflect the actual playback state anymore.

The simplest way to avoid the above scenario would be to wait for any pending SYNCPROCs to complete after BASS_ChannelStop is called, but since the library does not provide a way of doing that, and we don't even know if a SYNCPROC has actually been called in the first place, this is going to be somewhat non-trivial. A simple lock would probably not help much, but perhaps it might work as part of a more sophisticated synchronization scheme, e.g. a counter variable which is incremented each time playback is started.

Ian @ un4seen

  • Administrator
  • Posts: 25626
Re: BASS_ChannelStop and BASS_SYNC_END
« Reply #3 on: 29 Sep '23 - 12:26 »
The issue here is that I need to ensure that after BASS_ChannelStop is called, the SYNCPROC must not be able to cause any side-effects anymore. E.g. suppose it sets a "playback finished" flag, then if playback is requested to begin again immediately after a manual stop, the SYNCPROC may erroneously set this flag after it has already been reset in preparation to begin playback again. Thus, the current state of the flag would not reflect the actual playback state anymore.

Setting/checking your state variable within the lock should avoid that? For example:

Code: [Select]
lock();
state = stopped;
BASS_ChannelStop(handle);
unlock();

...

void CALLBACK EndSyncProc(HSYNC handle, DWORD channel, DWORD data, void *user)
{
if (state == stopped) return;
lock();
if (state != stopped) {
...
}
unlock();
}

Player701

  • Posts: 3
Re: BASS_ChannelStop and BASS_SYNC_END
« Reply #4 on: 29 Sep '23 - 12:35 »
Perhaps not quite like that, but I've already devised a solution suitable for my particular scenario. Thanks anyway.