diff options
| author | Serge Zaitsev <zaitsev.serge@gmail.com> | 2017-10-02 16:20:13 +0300 |
|---|---|---|
| committer | Stephen Sinclair <radarsat1@users.noreply.github.com> | 2017-10-02 10:20:13 -0300 |
| commit | 5c69780f4bf67e26ed370cea39418b2d82df119e (patch) | |
| tree | baef2b425ca0dd7a5a266d7f631247ebc636bca6 /rtaudio_c.cpp | |
| parent | 802179520e2d464f87389e34699510927a4a0ab3 (diff) | |
add rtaudio c api wrappers (#98)
add rtaudio c api wrappers
Diffstat (limited to 'rtaudio_c.cpp')
| -rw-r--r-- | rtaudio_c.cpp | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/rtaudio_c.cpp b/rtaudio_c.cpp new file mode 100644 index 0000000..090cbf9 --- /dev/null +++ b/rtaudio_c.cpp @@ -0,0 +1,261 @@ +#include "rtaudio_c.h" +#include "RtAudio.h" + +#include <cstring> + +#define MAX_ERROR_MESSAGE_LENGTH 512 + +struct rtaudio { + RtAudio *audio; + + rtaudio_cb_t cb; + void *userdata; + + int has_error; + char errmsg[MAX_ERROR_MESSAGE_LENGTH]; +}; + +static const rtaudio_api_t compiled_api[] = { +#if defined(__UNIX_JACK__) + RTAUDIO_API_UNIX_JACK, +#endif +#if defined(__LINUX_ALSA__) + RTAUDIO_API_LINUX_ALSA, +#endif +#if defined(__LINUX_PULSE__) + RTAUDIO_API_LINUX_PULSE, +#endif +#if defined(__LINUX_OSS__) + RTAUDIO_API_LINUX_OSS, +#endif +#if defined(__WINDOWS_ASIO__) + RTAUDIO_API_WINDOWS_ASIO, +#endif +#if defined(__WINDOWS_WASAPI__) + RTAUDIO_API_WINDOWS_WASAPI, +#endif +#if defined(__WINDOWS_DS__) + RTAUDIO_API_WINDOWS_DS, +#endif +#if defined(__MACOSX_CORE__) + RTAUDIO_API_MACOSX_CORE, +#endif +#if defined(__RTAUDIO_DUMMY__) + RTAUDIO_API_DUMMY, +#endif + RTAUDIO_API_UNSPECIFIED, +}; + +const char *rtaudio_version() { return RTAUDIO_VERSION; } + +const rtaudio_api_t *rtaudio_compiled_api() { return compiled_api; } + +const char *rtaudio_error(rtaudio_t audio) { + if (audio->has_error) { + return audio->errmsg; + } + return NULL; +} + +rtaudio_t rtaudio_create(rtaudio_api_t api) { + rtaudio_t audio = new struct rtaudio(); + try { + audio->audio = new RtAudio((RtAudio::Api)api); + } catch (RtAudioError &err) { + audio->has_error = 1; + strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1); + } + return audio; +} + +void rtaudio_destroy(rtaudio_t audio) { delete audio->audio; } + +rtaudio_api_t rtaudio_current_api(rtaudio_t audio) { + return (rtaudio_api_t)audio->audio->getCurrentApi(); +} + +int rtaudio_device_count(rtaudio_t audio) { + return audio->audio->getDeviceCount(); +} + +rtaudio_device_info_t rtaudio_get_device_info(rtaudio_t audio, int i) { + rtaudio_device_info_t result = {}; + try { + audio->has_error = 0; + RtAudio::DeviceInfo info = audio->audio->getDeviceInfo(i); + result.probed = info.probed; + result.output_channels = info.outputChannels; + result.input_channels = info.inputChannels; + result.duplex_channels = info.duplexChannels; + result.is_default_output = info.isDefaultOutput; + result.is_default_input = info.isDefaultInput; + result.native_formats = info.nativeFormats; + result.preferred_sample_rate = info.preferredSampleRate; + strncpy(result.name, info.name.c_str(), sizeof(result.name) - 1); + for (unsigned int j = 0; j < info.sampleRates.size(); j++) { + if (j < sizeof(result.sample_rates) / sizeof(result.sample_rates[0])) { + result.sample_rates[j] = info.sampleRates[j]; + } + } + } catch (RtAudioError &err) { + audio->has_error = 1; + strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1); + } + return result; +} + +unsigned int rtaudio_get_default_output_device(rtaudio_t audio) { + return audio->audio->getDefaultOutputDevice(); +} + +unsigned int rtaudio_get_default_input_device(rtaudio_t audio) { + return audio->audio->getDefaultInputDevice(); +} + +static int proxy_cb_func(void *out, void *in, unsigned int nframes, double time, + RtAudioStreamStatus status, void *userdata) { + rtaudio_t audio = (rtaudio_t)userdata; + return audio->cb(out, in, nframes, time, (rtaudio_stream_status_t)status, + audio->userdata); +} + +int rtaudio_open_stream(rtaudio_t audio, + rtaudio_stream_parameters_t *output_params, + rtaudio_stream_parameters_t *input_params, + rtaudio_format_t format, unsigned int sample_rate, + unsigned int *buffer_frames, rtaudio_cb_t cb, + void *userdata, rtaudio_stream_options_t *options, + rtaudio_error_cb_t /*errcb*/) { + try { + audio->has_error = 0; + RtAudio::StreamParameters *in = NULL; + RtAudio::StreamParameters *out = NULL; + RtAudio::StreamOptions *opts = NULL; + + RtAudio::StreamParameters inparams; + RtAudio::StreamParameters outparams; + RtAudio::StreamOptions stream_opts; + + if (input_params != NULL) { + inparams.deviceId = input_params->device_id; + inparams.nChannels = input_params->num_channels; + inparams.firstChannel = input_params->first_channel; + in = &inparams; + } + if (output_params != NULL) { + outparams.deviceId = output_params->device_id; + outparams.nChannels = output_params->num_channels; + outparams.firstChannel = output_params->first_channel; + out = &outparams; + } + + if (options != NULL) { + stream_opts.flags = (RtAudioStreamFlags)options->flags; + stream_opts.numberOfBuffers = options->num_buffers; + stream_opts.priority = options->priority; + if (strlen(options->name) > 0) { + stream_opts.streamName = std::string(options->name); + } + opts = &stream_opts; + } + audio->cb = cb; + audio->userdata = userdata; + audio->audio->openStream(out, in, (RtAudioFormat)format, sample_rate, + buffer_frames, proxy_cb_func, (void *)audio, opts, + NULL); + return 0; + } catch (RtAudioError &err) { + audio->has_error = 1; + strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1); + return -1; + } +} + +void rtaudio_close_stream(rtaudio_t audio) { audio->audio->closeStream(); } + +int rtaudio_start_stream(rtaudio_t audio) { + try { + audio->has_error = 0; + audio->audio->startStream(); + } catch (RtAudioError &err) { + audio->has_error = 1; + strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1); + } + return 0; +} + +int rtaudio_stop_stream(rtaudio_t audio) { + try { + audio->has_error = 0; + audio->audio->stopStream(); + } catch (RtAudioError &err) { + audio->has_error = 1; + strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1); + } + return 0; +} + +int rtaudio_abort_stream(rtaudio_t audio) { + try { + audio->has_error = 0; + audio->audio->abortStream(); + } catch (RtAudioError &err) { + audio->has_error = 1; + strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1); + } + return 0; +} + +int rtaudio_is_stream_open(rtaudio_t audio) { + return !!audio->audio->isStreamOpen(); +} + +int rtaudio_is_stream_running(rtaudio_t audio) { + return !!audio->audio->isStreamRunning(); +} + +double rtaudio_get_stream_time(rtaudio_t audio) { + try { + audio->has_error = 0; + return audio->audio->getStreamTime(); + } catch (RtAudioError &err) { + audio->has_error = 1; + strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1); + return 0; + } +} + +void rtaudio_set_stream_time(rtaudio_t audio, double time) { + try { + audio->has_error = 0; + audio->audio->setStreamTime(time); + } catch (RtAudioError &err) { + audio->has_error = 1; + strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1); + } +} + +int rtaudio_get_stream_latency(rtaudio_t audio) { + try { + audio->has_error = 0; + return audio->audio->getStreamLatency(); + } catch (RtAudioError &err) { + audio->has_error = 1; + strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1); + return -1; + } +} + +unsigned int rtaudio_get_stream_sample_rate(rtaudio_t audio) { + try { + return audio->audio->getStreamSampleRate(); + } catch (RtAudioError &err) { + audio->has_error = 1; + strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1); + return -1; + } +} + +void rtaudio_show_warnings(rtaudio_t audio, int show) { + audio->audio->showWarnings(!!show); +} |
