You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

256 lines
7.4KB

  1. #include "rtaudio_c.h"
  2. #include "RtAudio.h"
  3. #include <cstring>
  4. #define MAX_ERROR_MESSAGE_LENGTH 512
  5. struct rtaudio {
  6. RtAudio *audio;
  7. rtaudio_cb_t cb;
  8. void *userdata;
  9. int has_error;
  10. char errmsg[MAX_ERROR_MESSAGE_LENGTH];
  11. };
  12. const char *rtaudio_version() { return RTAUDIO_VERSION; }
  13. extern "C" const rtaudio_api_t rtaudio_compiled_apis[]; // casting from RtAudio::Api[]
  14. extern "C" const unsigned int rtaudio_num_compiled_apis;
  15. const rtaudio_api_t *rtaudio_compiled_api() { return rtaudio_compiled_apis; }
  16. extern "C" const char* rtaudio_api_names[][2];
  17. const char *rtaudio_api_name(rtaudio_api_t api) {
  18. if (api < 0 || api >= RTAUDIO_API_NUM)
  19. return NULL;
  20. return rtaudio_api_names[api][0];
  21. }
  22. const char *rtaudio_api_display_name(rtaudio_api_t api)
  23. {
  24. if (api < 0 || api >= RTAUDIO_API_NUM)
  25. return "Unknown";
  26. return rtaudio_api_names[api][1];
  27. }
  28. rtaudio_api_t rtaudio_compiled_api_by_name(const char *name) {
  29. RtAudio::Api api = RtAudio::UNSPECIFIED;
  30. if (name) {
  31. api = RtAudio::getCompiledApiByName(name);
  32. }
  33. return (rtaudio_api_t)api;
  34. }
  35. const char *rtaudio_error(rtaudio_t audio) {
  36. if (audio->has_error) {
  37. return audio->errmsg;
  38. }
  39. return NULL;
  40. }
  41. rtaudio_t rtaudio_create(rtaudio_api_t api) {
  42. rtaudio_t audio = new struct rtaudio();
  43. try {
  44. audio->audio = new RtAudio((RtAudio::Api)api);
  45. } catch (RtAudioError &err) {
  46. audio->has_error = 1;
  47. strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
  48. }
  49. return audio;
  50. }
  51. void rtaudio_destroy(rtaudio_t audio) { delete audio->audio; }
  52. rtaudio_api_t rtaudio_current_api(rtaudio_t audio) {
  53. return (rtaudio_api_t)audio->audio->getCurrentApi();
  54. }
  55. int rtaudio_device_count(rtaudio_t audio) {
  56. return audio->audio->getDeviceCount();
  57. }
  58. rtaudio_device_info_t rtaudio_get_device_info(rtaudio_t audio, int i) {
  59. rtaudio_device_info_t result;
  60. std::memset(&result, 0, sizeof(result));
  61. try {
  62. audio->has_error = 0;
  63. RtAudio::DeviceInfo info = audio->audio->getDeviceInfo(i);
  64. result.probed = info.probed;
  65. result.output_channels = info.outputChannels;
  66. result.input_channels = info.inputChannels;
  67. result.duplex_channels = info.duplexChannels;
  68. result.is_default_output = info.isDefaultOutput;
  69. result.is_default_input = info.isDefaultInput;
  70. result.native_formats = info.nativeFormats;
  71. result.preferred_sample_rate = info.preferredSampleRate;
  72. strncpy(result.name, info.name.c_str(), sizeof(result.name) - 1);
  73. for (unsigned int j = 0; j < info.sampleRates.size(); j++) {
  74. if (j < sizeof(result.sample_rates) / sizeof(result.sample_rates[0])) {
  75. result.sample_rates[j] = info.sampleRates[j];
  76. }
  77. }
  78. } catch (RtAudioError &err) {
  79. audio->has_error = 1;
  80. strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
  81. }
  82. return result;
  83. }
  84. unsigned int rtaudio_get_default_output_device(rtaudio_t audio) {
  85. return audio->audio->getDefaultOutputDevice();
  86. }
  87. unsigned int rtaudio_get_default_input_device(rtaudio_t audio) {
  88. return audio->audio->getDefaultInputDevice();
  89. }
  90. static int proxy_cb_func(void *out, void *in, unsigned int nframes, double time,
  91. RtAudioStreamStatus status, void *userdata) {
  92. rtaudio_t audio = (rtaudio_t)userdata;
  93. return audio->cb(out, in, nframes, time, (rtaudio_stream_status_t)status,
  94. audio->userdata);
  95. }
  96. int rtaudio_open_stream(rtaudio_t audio,
  97. rtaudio_stream_parameters_t *output_params,
  98. rtaudio_stream_parameters_t *input_params,
  99. rtaudio_format_t format, unsigned int sample_rate,
  100. unsigned int *buffer_frames, rtaudio_cb_t cb,
  101. void *userdata, rtaudio_stream_options_t *options,
  102. rtaudio_error_cb_t /*errcb*/) {
  103. try {
  104. audio->has_error = 0;
  105. RtAudio::StreamParameters *in = NULL;
  106. RtAudio::StreamParameters *out = NULL;
  107. RtAudio::StreamOptions *opts = NULL;
  108. RtAudio::StreamParameters inparams;
  109. RtAudio::StreamParameters outparams;
  110. RtAudio::StreamOptions stream_opts;
  111. if (input_params != NULL) {
  112. inparams.deviceId = input_params->device_id;
  113. inparams.nChannels = input_params->num_channels;
  114. inparams.firstChannel = input_params->first_channel;
  115. in = &inparams;
  116. }
  117. if (output_params != NULL) {
  118. outparams.deviceId = output_params->device_id;
  119. outparams.nChannels = output_params->num_channels;
  120. outparams.firstChannel = output_params->first_channel;
  121. out = &outparams;
  122. }
  123. if (options != NULL) {
  124. stream_opts.flags = (RtAudioStreamFlags)options->flags;
  125. stream_opts.numberOfBuffers = options->num_buffers;
  126. stream_opts.priority = options->priority;
  127. if (strlen(options->name) > 0) {
  128. stream_opts.streamName = std::string(options->name);
  129. }
  130. opts = &stream_opts;
  131. }
  132. audio->cb = cb;
  133. audio->userdata = userdata;
  134. audio->audio->openStream(out, in, (RtAudioFormat)format, sample_rate,
  135. buffer_frames, proxy_cb_func, (void *)audio, opts,
  136. NULL);
  137. return 0;
  138. } catch (RtAudioError &err) {
  139. audio->has_error = 1;
  140. strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
  141. return -1;
  142. }
  143. }
  144. void rtaudio_close_stream(rtaudio_t audio) { audio->audio->closeStream(); }
  145. int rtaudio_start_stream(rtaudio_t audio) {
  146. try {
  147. audio->has_error = 0;
  148. audio->audio->startStream();
  149. } catch (RtAudioError &err) {
  150. audio->has_error = 1;
  151. strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
  152. }
  153. return 0;
  154. }
  155. int rtaudio_stop_stream(rtaudio_t audio) {
  156. try {
  157. audio->has_error = 0;
  158. audio->audio->stopStream();
  159. } catch (RtAudioError &err) {
  160. audio->has_error = 1;
  161. strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
  162. }
  163. return 0;
  164. }
  165. int rtaudio_abort_stream(rtaudio_t audio) {
  166. try {
  167. audio->has_error = 0;
  168. audio->audio->abortStream();
  169. } catch (RtAudioError &err) {
  170. audio->has_error = 1;
  171. strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
  172. }
  173. return 0;
  174. }
  175. int rtaudio_is_stream_open(rtaudio_t audio) {
  176. return !!audio->audio->isStreamOpen();
  177. }
  178. int rtaudio_is_stream_running(rtaudio_t audio) {
  179. return !!audio->audio->isStreamRunning();
  180. }
  181. double rtaudio_get_stream_time(rtaudio_t audio) {
  182. try {
  183. audio->has_error = 0;
  184. return audio->audio->getStreamTime();
  185. } catch (RtAudioError &err) {
  186. audio->has_error = 1;
  187. strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
  188. return 0;
  189. }
  190. }
  191. void rtaudio_set_stream_time(rtaudio_t audio, double time) {
  192. try {
  193. audio->has_error = 0;
  194. audio->audio->setStreamTime(time);
  195. } catch (RtAudioError &err) {
  196. audio->has_error = 1;
  197. strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
  198. }
  199. }
  200. int rtaudio_get_stream_latency(rtaudio_t audio) {
  201. try {
  202. audio->has_error = 0;
  203. return audio->audio->getStreamLatency();
  204. } catch (RtAudioError &err) {
  205. audio->has_error = 1;
  206. strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
  207. return -1;
  208. }
  209. }
  210. unsigned int rtaudio_get_stream_sample_rate(rtaudio_t audio) {
  211. try {
  212. return audio->audio->getStreamSampleRate();
  213. } catch (RtAudioError &err) {
  214. audio->has_error = 1;
  215. strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
  216. return -1;
  217. }
  218. }
  219. void rtaudio_show_warnings(rtaudio_t audio, int show) {
  220. audio->audio->showWarnings(!!show);
  221. }