Author Topic: Invalid handle when re-initializing device  (Read 250 times)

Bello

  • Posts: 39
Invalid handle when re-initializing device
« on: 30 Jun '18 - 23:35 »
My application should be playing 24/7. However it sometimes can occur that a sound device is not available for a short time by mistake (e.g. because the cable of an USB device has a bad contact or has been pulled by mistake.)
In the application, there are one or more mixers, each with a number of streams with sync-points, splitters, sub-mixers...

When I detect the device has stopped playing and has become available again, I would like to reinitialize the device and continue playing (without having to rebuild the mixers, which would require a huge architectural change...)

The code to accomplish this looks something like this:

Code: [Select]
if (Bass.BASS_ChannelIsActive(hMixer) != BASSActive.BASS_ACTIVE_PLAYING)
{
Bass.BASS_SetDevice(2); // Set context first
Bass.BASS_ChannelStop(hMixer);
Bass.BASS_Free();

Bass.BASS_Init(2, 44100, BASSInit.BASS_DEVICE_SPEAKERS, hDSWindow);

int result = Bass.BASS_ChannelPlay(hMixer, false);
if (!result)
{
   error = Bass.BASS_ErrorGetCode(); // BASS_ERROR_HANDLE !!!
}
}
However when trying to play the mixer again, I get an invalid handle error.

Is there a way to work around this?

Chris

  • Posts: 1846
Re: Invalid handle when re-initializing device
« Reply #1 on: 1 Jul '18 - 09:33 »
Hi why are you calling Bass_free?
Normally only if you are closing your application.
Because  with Bass_Free the current thread's device will freed .
 
So I think the Bass_free in your call makes no Sense.

So maybe something like that makes more sense

Code: [Select]
If not Bass_SetDevice(2) and ((Bass_ErrorGetCode()=BASS_ERROR_DEVICE) or (Bass_ErrorGetCode()=BASS_ERROR_INIT)) then
Bass_Init..........
« Last Edit: 1 Jul '18 - 09:48 by Chris »

Bello

  • Posts: 39
Re: Invalid handle when re-initializing device
« Reply #2 on: 1 Jul '18 - 11:54 »
Hi Chris,


Thanks for responding.
That was what I initially tried.

In that scenario, when the USB device becomes available again, it is still initialized, so we don't do the BASS_Init call.

However, in that case, the BASS_ChannelPlay call fails with error BASS_ERROR_BUFLOST.
Therefore I figured the device needed to be re-initialized. But BASS_Init only succeeds after BASS_Free has been called…  :(

Chris

  • Posts: 1846
Re: Invalid handle when re-initializing device
« Reply #3 on: 1 Jul '18 - 18:30 »
By the way what is hDSWindow? a Formhandle ?
or is it a Terminal Program?

Bello

  • Posts: 39
Re: Invalid handle when re-initializing device
« Reply #4 on: 2 Jul '18 - 06:06 »
hDSWindow is the handle to a window, created for Bass playout at the start of the application. The window is used by all audio devices and is only destroyed when the application terminates.
« Last Edit: 2 Jul '18 - 12:57 by Bello »

Ian @ un4seen

  • Administrator
  • Posts: 20903
Re: Invalid handle when re-initializing device
« Reply #5 on: 2 Jul '18 - 13:16 »
...
However when trying to play the mixer again, I get an invalid handle error.

The BASS_ERROR_HANDLE error is a result of calling BASS_Free, which would have freed the mixer (assuming the mixer was on device #2).

What BASS versions are you using? It sounds like you may be using an old version because the BASS_ERROR_BUFLOST error only applies when using DirectSound output, while the latest BASS version defaults to using WASAPI output (on Vista and above). When using WASAPI output, it may be possible to restart the device via BASS_Start (once the device is available again), without having to reinitialize it via BASS_Free and BASS_Init. So if you aren't currently using that, you could give it a try.

Bello

  • Posts: 39
Re: Invalid handle when re-initializing device
« Reply #6 on: 2 Jul '18 - 13:38 »
Thanks Ian, I will try that.
But if I use the new version's fallback to directsound, I will still get the BUFLOSt error?

Chris

  • Posts: 1846
Re: Invalid handle when re-initializing device
« Reply #7 on: 2 Jul '18 - 18:03 »
I think by your app is WASAPI the better Resolution.
Or are you working under the outdated XP ?

Bello

  • Posts: 39
Re: Invalid handle when re-initializing device
« Reply #8 on: 2 Jul '18 - 18:40 »
@Chris: I still support Windows XP at the moment. But that should not be an issue, as I understand Bass 2.4.13 has a fallback to DirectSound.

@Ian: With the latest version, detecting the issue has become a bigger problem: BASS_ChannelIsActive continues returning BASS_ACTIVE_PLAYING, so there is no indication that the device has stopped playing.
When I force it to stop the channel and play it again, without depending on BASS_ChannelIsActive, BASS_ChannelPlay does not return an error, however playout is not resumed.  :'(

Is there any way to make the application robust against sound devices becoming unavailable? (and available again)

Chris

  • Posts: 1846
Re: Invalid handle when re-initializing device
« Reply #9 on: 3 Jul '18 - 13:44 »
Maybe you can do something like this (Quick and Dirty)
Take a   Timer in the Background

catch inside the Timer the latest Position of the Mixer so long the (in your example) Device2 is active...
Var
 FLatestPos:int64;
If (Bass_GetDevice > DW_ERROR) and (Bass_GetDevice = 2) then // we have the correct device
 LatestPos:= .........Catch the latest Pos from the Mixer
else.......Device is not active....
so if the Device 2 is online again set the MixerPos with  FLatestpos   .....

@Ian maybe its possible that you can add a possible Sync  inside Bass aka.......On_Device_Lost....... ?
or does in Wasapi/Directsound exist a possible Message that we can Catch......



« Last Edit: 3 Jul '18 - 13:48 by Chris »

Bello

  • Posts: 39
Re: Invalid handle when re-initializing device
« Reply #10 on: 3 Jul '18 - 13:52 »
At the mixer-level this will not work, because the mixers are created with the BASS_MIXER_NONSTOP flag. But I can do this (and am doing this) at the level of the streams that are plugged into the mixers. (Although I would rather have that I can keep this local to the part of the application that manages the audiodevices…)


However, the biggest issue is that -even with the latest BASS version- I am not able to restart the mixer's stream so that it (and the streams plugged into it) continue playing.

Ian @ un4seen

  • Administrator
  • Posts: 20903
Re: Invalid handle when re-initializing device
« Reply #11 on: 3 Jul '18 - 15:02 »
@Ian: With the latest version, detecting the issue has become a bigger problem: BASS_ChannelIsActive continues returning BASS_ACTIVE_PLAYING, so there is no indication that the device has stopped playing.
When I force it to stop the channel and play it again, without depending on BASS_ChannelIsActive, BASS_ChannelPlay does not return an error, however playout is not resumed.  :'(

Is there any way to make the application robust against sound devices becoming unavailable? (and available again)

I have been planning to add a new sync type in the next BASS release, for when the device stops. I'll look into that this week and then come back with an update for you to try.

However, the biggest issue is that -even with the latest BASS version- I am not able to restart the mixer's stream so that it (and the streams plugged into it) continue playing.

You can use BASS_Start to restart the output once the device becomes available again, but there is still the issue of knowing when the device becomes unavailable. The next update should help with that.

Bello

  • Posts: 39
Re: Invalid handle when re-initializing device
« Reply #12 on: 3 Jul '18 - 22:33 »
Thanks Ian. I will be looking forward to that version.

A question: re-starting a device with BASS_Start after is has been disabled/disconnected, should that also work with DirectSound drivers (and e.g. with Bass v. 2.4.12)?
I did a quick test with 2.4.12.1, and there was not much difference: I would still get BUFLOST when calling BASS_ChannelPlay on the mixer handle...

Ian @ un4seen

  • Administrator
  • Posts: 20903
Re: Invalid handle when re-initializing device
« Reply #13 on: 4 Jul '18 - 13:25 »
Restarting the output with BASS_Start only applies when using WASAPI output. When using DirectSound output, you will need to reinitialize the device (call BASS_Free and BASS_Init) to get it working again.

Note you can avoid having to recreate the mixer sources when reinitializing the device by creating them on the "No Sound" device (device 0), so that they don't get freed. You will then only need to recreate the mixer and plug the sources back in. When there are multiple devices initialized, you will need to use BASS_SetDevice to set the device context for certain calls; see the BASS_SetDevice documentation for details. Another option is to disassociate the sources from any device via BASS_ChannelSetDevice (with BASS_NODEVICE).

Ian @ un4seen

  • Administrator
  • Posts: 20903
Re: Invalid handle when re-initializing device
« Reply #14 on: 9 Jul '18 - 17:44 »
Here's a BASS update for you to try:

   www.un4seen.com/stuff/bass.zip

It adds a few new things. There is a BASS_SYNC_DEV_FAIL sync, which gets triggered if the channel's device stops unexpectedly, ie. not by BASS_Free/Stop/Pause. There is also a new BASS_IsStarted function to check whether the device output is started. The device will be stopped when it fails, so this function can be used to check if that has happened. There is also a new BASS_ACTIVE_PAUSED_DEVICE value that will be returned by BASS_ChannelIsActive when the channel is paused because of the device; playback will resume when BASS_Start is called.

This stuff hasn't been tested a lot yet, so please report how you get on with it. If you can, please try both WASAPI and DirectSound output; there are likely to be some differences, eg. having to reinitialize (rather than just calling BASS_Start) after the device fails when using DirectSound.

Bello

  • Posts: 39
Re: Invalid handle when re-initializing device
« Reply #15 on: 10 Jul '18 - 22:30 »
Thanks Ian!

I am going to check it out and do some testing.
This will probably be after the weekend.

radio42

  • Posts: 4603
Re: Invalid handle when re-initializing device
« Reply #16 on: 11 Jul '18 - 07:50 »
So just for clarity...
The new BASS_SYNC_DEV_FAIL might be used to detect the failure of a device (e.g. because a USB cable was disconnected).
You would then need to periodically call BASS_Start in order to try to 'restart' the failed device - BASS_Start will return true on success resp. false if there is still an error - if successful, any (WASAPI) stream created on that device would automatically resume playing resp. continue to work with its previous handle as if no failure ever happened?!

In the above scenario the mentioned BASS_ChannelIsActive wouldn't even be needed; except you don't want to use the new SYNC, but eg. check the status manually.

Ian @ un4seen

  • Administrator
  • Posts: 20903
Re: Invalid handle when re-initializing device
« Reply #17 on: 11 Jul '18 - 17:34 »
So just for clarity...
The new BASS_SYNC_DEV_FAIL might be used to detect the failure of a device (e.g. because a USB cable was disconnected).

That is correct.

You would then need to periodically call BASS_Start in order to try to 'restart' the failed device - BASS_Start will return true on success resp. false if there is still an error - if successful, any (WASAPI) stream created on that device would automatically resume playing resp. continue to work with its previous handle as if no failure ever happened?!

The BASS_Start call will currently succeed even if the device isn't available again yet. That's because the WASAPI output is reinitialized asynchronously (not in BASS_Start). If it fails then the BASS_SYNC_DEV_FAIL syncs will be triggered again. If it succeeds then the channels that were playing will indeed automatically resume.

In the above scenario the mentioned BASS_ChannelIsActive wouldn't even be needed; except you don't want to use the new SYNC, but eg. check the status manually.

Yes, if you use a BASS_SYNC_DEV_FAIL sync then you won't really need to check BASS_ChannelIsActive or BASS_IsStarted.

Note the new BASS_ACTIVE_PAUSED_DEVICE value will also be returned by BASS_ChannelIsActive if the device has been paused via BASS_Pause, ie. it indicates that BASS_Start will resume playback of the channel.

radio42

  • Posts: 4603
Re: Invalid handle when re-initializing device
« Reply #18 on: 11 Jul '18 - 20:31 »
THX - that's clear now!