cycfi / q

C++ Library for Audio Digital Signal Processing
MIT License
1.17k stars 151 forks source link

patch: update devices in one loop #30

Closed Andersama closed 2 years ago

Andersama commented 3 years ago

This change may allow all devices to be unlisted*

djowel commented 3 years ago

Nice! Were you able to check if this actually worked when you physically add/remove devices?

Andersama commented 3 years ago

Ah, no did not do that, should be easy to test, let me see what happens.

Andersama commented 3 years ago

It seems like once port_audio is initialized its list of audio devices doesn't change? I'll try to figure out what the process is to relist devices in portaudio.

Andersama commented 3 years ago

Ok, I confirmed that if you terminate and initialize port audio you can relist devices, and this relists the devices as it should. Without digging too deep into port audio I'd bet there's an edit or two that could be made so that terminate (which closes all streams), wouldn't need to be called.

djowel commented 3 years ago

Just as I suspected. This is one thing I dislike about port audio. Would you be interested in digging deeper how this can work? It is very common to add/remove devices any time.

Andersama commented 3 years ago

Well I've got other issues with portaudio so I've not used it in a long time and I'm not inclined to fix, it can't handle multiple asio devices, something which I use and the Juce library offers. If my hunch is right, they're creating a device list for lookups that their api is dependant on. Part of the issue from what I remember of connecting and disconnecting devices is that you generally have to work with the assumption that the device name is unique if you can't get a hardware id of some sort from the device, and that may or may not work, I think wasapi for example allows multiple devices with the same name.

Andersama commented 3 years ago

It might not be so bad*, the part responsible for working out the device listings is clearly this bit in pa_front.c

    for( i=0; i< initializerCount; ++i )
    {
        hostApis_[hostApisCount_] = NULL;

        PA_DEBUG(( "before paHostApiInitializers[%d].\n",i));

        result = paHostApiInitializers[i]( &hostApis_[hostApisCount_], hostApisCount_ );
        if( result != paNoError )
            goto error;

Probably could create a similar set of functions only responsible for relisting devices.

Andersama commented 3 years ago

I don't think this is exposed to the main part of the api, but inside port audio's windows host for wasapi there's this:

static PaError UpdateDeviceList()

Seems like it was supposed to be public?

#if defined(PA_WASAPI_MAX_CONST_DEVICE_COUNT) && (PA_WASAPI_MAX_CONST_DEVICE_COUNT > 0)
PaError PaWasapi_UpdateDeviceList()
{
    return UpdateDeviceList();
}
#endif
Andersama commented 3 years ago

There seems to be a bit of work involved to make a function per api host to handle this, although wasapi already has that helper function the other apis would probably need some work to get to that point.