268 lines
8.0 KiB
C++
268 lines
8.0 KiB
C++
#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;
|
|
|
|
rtaudio_error_t errtype;
|
|
char errmsg[MAX_ERROR_MESSAGE_LENGTH];
|
|
};
|
|
|
|
const char *rtaudio_version() { return RTAUDIO_VERSION; }
|
|
|
|
extern "C" const RtAudio::Api rtaudio_compiled_apis[];
|
|
const rtaudio_api_t *rtaudio_compiled_api() {
|
|
return (rtaudio_api_t *) &rtaudio_compiled_apis[0];
|
|
}
|
|
|
|
extern "C" const unsigned int rtaudio_num_compiled_apis;
|
|
unsigned int rtaudio_get_num_compiled_apis(void) {
|
|
return rtaudio_num_compiled_apis;
|
|
}
|
|
|
|
extern "C" const char* rtaudio_api_names[][2];
|
|
const char *rtaudio_api_name(rtaudio_api_t api) {
|
|
if (api < 0 || api >= RTAUDIO_API_NUM)
|
|
return NULL;
|
|
return rtaudio_api_names[api][0];
|
|
}
|
|
|
|
const char *rtaudio_api_display_name(rtaudio_api_t api)
|
|
{
|
|
if (api < 0 || api >= RTAUDIO_API_NUM)
|
|
return "Unknown";
|
|
return rtaudio_api_names[api][1];
|
|
}
|
|
|
|
rtaudio_api_t rtaudio_compiled_api_by_name(const char *name) {
|
|
RtAudio::Api api = RtAudio::UNSPECIFIED;
|
|
if (name) {
|
|
api = RtAudio::getCompiledApiByName(name);
|
|
}
|
|
return (rtaudio_api_t)api;
|
|
}
|
|
|
|
const char *rtaudio_error(rtaudio_t audio) {
|
|
if (audio->errtype == RTAUDIO_NO_ERROR) {
|
|
return NULL;
|
|
}
|
|
return audio->errmsg;
|
|
}
|
|
|
|
rtaudio_error_t rtaudio_error_type(rtaudio_t audio) {
|
|
return audio->errtype;
|
|
}
|
|
|
|
rtaudio_t rtaudio_create(rtaudio_api_t api) {
|
|
rtaudio_t audio = new struct rtaudio();
|
|
try {
|
|
audio->errtype = RTAUDIO_NO_ERROR;
|
|
audio->audio = new RtAudio((RtAudio::Api)api);
|
|
} catch (RtAudioError &err) {
|
|
audio->errtype = (rtaudio_error_t)err.getType();
|
|
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;
|
|
std::memset(&result, 0, sizeof(result));
|
|
try {
|
|
audio->errtype = RTAUDIO_NO_ERROR;;
|
|
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->errtype = (rtaudio_error_t)err.getType();
|
|
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->errtype = RTAUDIO_NO_ERROR;;
|
|
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->errtype = (rtaudio_error_t)err.getType();
|
|
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->errtype = RTAUDIO_NO_ERROR;;
|
|
audio->audio->startStream();
|
|
} catch (RtAudioError &err) {
|
|
audio->errtype = (rtaudio_error_t)err.getType();
|
|
strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int rtaudio_stop_stream(rtaudio_t audio) {
|
|
try {
|
|
audio->errtype = RTAUDIO_NO_ERROR;;
|
|
audio->audio->stopStream();
|
|
} catch (RtAudioError &err) {
|
|
audio->errtype = (rtaudio_error_t)err.getType();
|
|
strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int rtaudio_abort_stream(rtaudio_t audio) {
|
|
try {
|
|
audio->errtype = RTAUDIO_NO_ERROR;;
|
|
audio->audio->abortStream();
|
|
} catch (RtAudioError &err) {
|
|
audio->errtype = (rtaudio_error_t)err.getType();
|
|
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->errtype = RTAUDIO_NO_ERROR;;
|
|
return audio->audio->getStreamTime();
|
|
} catch (RtAudioError &err) {
|
|
audio->errtype = (rtaudio_error_t)err.getType();
|
|
strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void rtaudio_set_stream_time(rtaudio_t audio, double time) {
|
|
try {
|
|
audio->errtype = RTAUDIO_NO_ERROR;;
|
|
audio->audio->setStreamTime(time);
|
|
} catch (RtAudioError &err) {
|
|
audio->errtype = (rtaudio_error_t)err.getType();
|
|
strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
|
|
}
|
|
}
|
|
|
|
int rtaudio_get_stream_latency(rtaudio_t audio) {
|
|
try {
|
|
audio->errtype = RTAUDIO_NO_ERROR;
|
|
return audio->audio->getStreamLatency();
|
|
} catch (RtAudioError &err) {
|
|
audio->errtype = (rtaudio_error_t)err.getType();
|
|
strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
unsigned int rtaudio_get_stream_sample_rate(rtaudio_t audio) {
|
|
try {
|
|
audio->errtype = RTAUDIO_NO_ERROR;
|
|
return audio->audio->getStreamSampleRate();
|
|
} catch (RtAudioError &err) {
|
|
audio->errtype = (rtaudio_error_t)err.getType();
|
|
strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
void rtaudio_show_warnings(rtaudio_t audio, int show) {
|
|
audio->audio->showWarnings(!!show);
|
|
}
|