Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add getDeviceHandle() to expose client-specific structs. #251

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

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.
@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