Skip to content

Conversation

@radarsat1
Copy link
Contributor

This is proposed as a (hopefully) less hacky alternative to #232.

After some thought I elected to add a function instead of adding it as a member to StreamOptions. This allows to return a pointer to where we already kept this info in the first place (the internal API-specfic "handle" structs.) And also I feel that StreamOptions is an "input" to openStream() and shouldn't contain "output values".

In cases where the caller really needs access to the API-specific
handle (e.g. jack_client_t*), then it can be returned in a derived
struct.

Since this means that API headers must be included before RtAudio.h,
it is not enabled by default; the caller must include them him/herself
and define RTAUDIO_API_SPECIFIC, or RTAUDIO_API_SPECIFIC_JACK, etc.,
before including RtAudio.h. Then, getDeviceHandle() returns a pointer
that can be safely dynamic_cast<> so that if there is an API mismatch,
nullptr is returned.

This commit implements it for Jack and Pulse Audio only!

Example:

#include <jack/jack.h>
#define RTAUDIO_API_SPECIFIC_JACK
#include <RtAudio.h>

...
RtAudio audio(RtAudio::UNIX_JACK);
.. after openStream
RtAudioClientHandle *h = audio.getClientHandle();
RtAudioClientHandleJack *h_jack =
  dynamic_cast<RtAudioClientHandleJack*>(h);
if (h_jack) {
  .. my_function_needing_jack_client_t(h_jack.client);
}

Note that the above code will not crash if RtAudio::LINUX_PULSE was
selected, and only call Jack-specific functions if indeed Jack is the
current API.

In cases where the caller really needs access to the API-specific
handle (e.g. jack_client_t*), then it can be returned in a derived
struct.

Since this means that API headers must be included before RtAudio.h,
it is not enabled by default; the caller must include them him/herself
and define RTAUDIO_API_SPECIFIC, or RTAUDIO_API_SPECIFIC_JACK, etc.,
before including RtAudio.h.  Then, getDeviceHandle() returns a pointer
that can be safely dynamic_cast<> so that if there is an API mismatch,
nullptr is returned.

This commit implements it for Jack and Pulse Audio only!

Example:

    #include <jack/jack.h>
    #define RTAUDIO_API_SPECIFIC_JACK
    #include <RtAudio.h>

    ...
    RtAudio audio(RtAudio::UNIX_JACK);
    .. after openStream
    RtAudioClientHandle *h = audio.getClientHandle();
    RtAudioClientHandleJack *h_jack =
      dynamic_cast<RtAudioClientHandleJack*>(h);
    if (h_jack) {
      .. my_function_needing_jack_client_t(h_jack.client);
    }

Note that the above code will not crash if RtAudio::LINUX_PULSE was
selected, and only call Jack-specific functions if indeed Jack is the
current API.
@radarsat1 radarsat1 force-pushed the expose-client-handles branch from 3035f22 to 4f7a17a Compare June 7, 2020 11:38
@gvnnz
Copy link

gvnnz commented Dec 12, 2020

This PR completely slipped under my radar! Anyway, the proposed solution looks good to me. Any plans to merge it?

@garyscavone
Copy link
Contributor

This is more complicated than I would have preferred, especially with the preprocessor definition changes. I guess one issue is that the necessary pointers needed by the user to actually do something useful in a given API is API-specific (thus the need to create API-specific handle structures)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants