Use short lower-case names as API identifiers
[rtaudio-cdist.git] / rtaudio_c.cpp
1 #include "rtaudio_c.h"
2 #include "RtAudio.h"
3
4 #include <cstring>
5
6 #define MAX_ERROR_MESSAGE_LENGTH 512
7
8 struct rtaudio {
9   RtAudio *audio;
10
11   rtaudio_cb_t cb;
12   void *userdata;
13
14   int has_error;
15   char errmsg[MAX_ERROR_MESSAGE_LENGTH];
16 };
17
18 static const rtaudio_api_t compiled_api[] = {
19 #if defined(__UNIX_JACK__)
20     RTAUDIO_API_UNIX_JACK,
21 #endif
22 #if defined(__LINUX_ALSA__)
23     RTAUDIO_API_LINUX_ALSA,
24 #endif
25 #if defined(__LINUX_PULSE__)
26     RTAUDIO_API_LINUX_PULSE,
27 #endif
28 #if defined(__LINUX_OSS__)
29     RTAUDIO_API_LINUX_OSS,
30 #endif
31 #if defined(__WINDOWS_ASIO__)
32     RTAUDIO_API_WINDOWS_ASIO,
33 #endif
34 #if defined(__WINDOWS_WASAPI__)
35     RTAUDIO_API_WINDOWS_WASAPI,
36 #endif
37 #if defined(__WINDOWS_DS__)
38     RTAUDIO_API_WINDOWS_DS,
39 #endif
40 #if defined(__MACOSX_CORE__)
41     RTAUDIO_API_MACOSX_CORE,
42 #endif
43 #if defined(__RTAUDIO_DUMMY__)
44     RTAUDIO_API_DUMMY,
45 #endif
46     RTAUDIO_API_UNSPECIFIED,
47 };
48
49 const char *rtaudio_version() { return RTAUDIO_VERSION; }
50
51 const rtaudio_api_t *rtaudio_compiled_api() { return compiled_api; }
52
53 const char *rtaudio_compiled_api_name(rtaudio_api_t api) {
54     const std::string &name = RtAudio::getCompiledApiName((RtAudio::Api)api);
55     return name.empty() ? NULL : name.c_str();
56 }
57
58 const char *rtaudio_compiled_api_display_name(rtaudio_api_t api)
59 {
60     const std::string &name = RtAudio::getCompiledApiDisplayName((RtAudio::Api)api);
61     return name.empty() ? NULL : name.c_str();
62 }
63
64 rtaudio_api_t rtaudio_compiled_api_by_name(const char *name) {
65     RtAudio::Api api = RtAudio::UNSPECIFIED;
66     if (name) {
67         api = RtAudio::getCompiledApiByName(name);
68     }
69     return (rtaudio_api_t)api;
70 }
71
72 const char *rtaudio_error(rtaudio_t audio) {
73   if (audio->has_error) {
74     return audio->errmsg;
75   }
76   return NULL;
77 }
78
79 rtaudio_t rtaudio_create(rtaudio_api_t api) {
80   rtaudio_t audio = new struct rtaudio();
81   try {
82     audio->audio = new RtAudio((RtAudio::Api)api);
83   } catch (RtAudioError &err) {
84     audio->has_error = 1;
85     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
86   }
87   return audio;
88 }
89
90 void rtaudio_destroy(rtaudio_t audio) { delete audio->audio; }
91
92 rtaudio_api_t rtaudio_current_api(rtaudio_t audio) {
93   return (rtaudio_api_t)audio->audio->getCurrentApi();
94 }
95
96 int rtaudio_device_count(rtaudio_t audio) {
97   return audio->audio->getDeviceCount();
98 }
99
100 rtaudio_device_info_t rtaudio_get_device_info(rtaudio_t audio, int i) {
101   rtaudio_device_info_t result;
102   std::memset(&result, 0, sizeof(result));
103   try {
104     audio->has_error = 0;
105     RtAudio::DeviceInfo info = audio->audio->getDeviceInfo(i);
106     result.probed = info.probed;
107     result.output_channels = info.outputChannels;
108     result.input_channels = info.inputChannels;
109     result.duplex_channels = info.duplexChannels;
110     result.is_default_output = info.isDefaultOutput;
111     result.is_default_input = info.isDefaultInput;
112     result.native_formats = info.nativeFormats;
113     result.preferred_sample_rate = info.preferredSampleRate;
114     strncpy(result.name, info.name.c_str(), sizeof(result.name) - 1);
115     for (unsigned int j = 0; j < info.sampleRates.size(); j++) {
116       if (j < sizeof(result.sample_rates) / sizeof(result.sample_rates[0])) {
117         result.sample_rates[j] = info.sampleRates[j];
118       }
119     }
120   } catch (RtAudioError &err) {
121     audio->has_error = 1;
122     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
123   }
124   return result;
125 }
126
127 unsigned int rtaudio_get_default_output_device(rtaudio_t audio) {
128   return audio->audio->getDefaultOutputDevice();
129 }
130
131 unsigned int rtaudio_get_default_input_device(rtaudio_t audio) {
132   return audio->audio->getDefaultInputDevice();
133 }
134
135 static int proxy_cb_func(void *out, void *in, unsigned int nframes, double time,
136                          RtAudioStreamStatus status, void *userdata) {
137   rtaudio_t audio = (rtaudio_t)userdata;
138   return audio->cb(out, in, nframes, time, (rtaudio_stream_status_t)status,
139                    audio->userdata);
140 }
141
142 int rtaudio_open_stream(rtaudio_t audio,
143                         rtaudio_stream_parameters_t *output_params,
144                         rtaudio_stream_parameters_t *input_params,
145                         rtaudio_format_t format, unsigned int sample_rate,
146                         unsigned int *buffer_frames, rtaudio_cb_t cb,
147                         void *userdata, rtaudio_stream_options_t *options,
148                         rtaudio_error_cb_t /*errcb*/) {
149   try {
150     audio->has_error = 0;
151     RtAudio::StreamParameters *in = NULL;
152     RtAudio::StreamParameters *out = NULL;
153     RtAudio::StreamOptions *opts = NULL;
154
155     RtAudio::StreamParameters inparams;
156     RtAudio::StreamParameters outparams;
157     RtAudio::StreamOptions stream_opts;
158
159     if (input_params != NULL) {
160       inparams.deviceId = input_params->device_id;
161       inparams.nChannels = input_params->num_channels;
162       inparams.firstChannel = input_params->first_channel;
163       in = &inparams;
164     }
165     if (output_params != NULL) {
166       outparams.deviceId = output_params->device_id;
167       outparams.nChannels = output_params->num_channels;
168       outparams.firstChannel = output_params->first_channel;
169       out = &outparams;
170     }
171
172     if (options != NULL) {
173       stream_opts.flags = (RtAudioStreamFlags)options->flags;
174       stream_opts.numberOfBuffers = options->num_buffers;
175       stream_opts.priority = options->priority;
176       if (strlen(options->name) > 0) {
177         stream_opts.streamName = std::string(options->name);
178       }
179       opts = &stream_opts;
180     }
181     audio->cb = cb;
182     audio->userdata = userdata;
183     audio->audio->openStream(out, in, (RtAudioFormat)format, sample_rate,
184                              buffer_frames, proxy_cb_func, (void *)audio, opts,
185                              NULL);
186     return 0;
187   } catch (RtAudioError &err) {
188     audio->has_error = 1;
189     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
190     return -1;
191   }
192 }
193
194 void rtaudio_close_stream(rtaudio_t audio) { audio->audio->closeStream(); }
195
196 int rtaudio_start_stream(rtaudio_t audio) {
197   try {
198     audio->has_error = 0;
199     audio->audio->startStream();
200   } catch (RtAudioError &err) {
201     audio->has_error = 1;
202     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
203   }
204   return 0;
205 }
206
207 int rtaudio_stop_stream(rtaudio_t audio) {
208   try {
209     audio->has_error = 0;
210     audio->audio->stopStream();
211   } catch (RtAudioError &err) {
212     audio->has_error = 1;
213     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
214   }
215   return 0;
216 }
217
218 int rtaudio_abort_stream(rtaudio_t audio) {
219   try {
220     audio->has_error = 0;
221     audio->audio->abortStream();
222   } catch (RtAudioError &err) {
223     audio->has_error = 1;
224     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
225   }
226   return 0;
227 }
228
229 int rtaudio_is_stream_open(rtaudio_t audio) {
230   return !!audio->audio->isStreamOpen();
231 }
232
233 int rtaudio_is_stream_running(rtaudio_t audio) {
234   return !!audio->audio->isStreamRunning();
235 }
236
237 double rtaudio_get_stream_time(rtaudio_t audio) {
238   try {
239     audio->has_error = 0;
240     return audio->audio->getStreamTime();
241   } catch (RtAudioError &err) {
242     audio->has_error = 1;
243     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
244     return 0;
245   }
246 }
247
248 void rtaudio_set_stream_time(rtaudio_t audio, double time) {
249   try {
250     audio->has_error = 0;
251     audio->audio->setStreamTime(time);
252   } catch (RtAudioError &err) {
253     audio->has_error = 1;
254     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
255   }
256 }
257
258 int rtaudio_get_stream_latency(rtaudio_t audio) {
259   try {
260     audio->has_error = 0;
261     return audio->audio->getStreamLatency();
262   } catch (RtAudioError &err) {
263     audio->has_error = 1;
264     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
265     return -1;
266   }
267 }
268
269 unsigned int rtaudio_get_stream_sample_rate(rtaudio_t audio) {
270   try {
271     return audio->audio->getStreamSampleRate();
272   } catch (RtAudioError &err) {
273     audio->has_error = 1;
274     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
275     return -1;
276   }
277 }
278
279 void rtaudio_show_warnings(rtaudio_t audio, int show) {
280   audio->audio->showWarnings(!!show);
281 }