Add missing apostrophe and parentheses
[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_error(rtaudio_t audio) {
54   if (audio->has_error) {
55     return audio->errmsg;
56   }
57   return NULL;
58 }
59
60 rtaudio_t rtaudio_create(rtaudio_api_t api) {
61   rtaudio_t audio = new struct rtaudio();
62   try {
63     audio->audio = new RtAudio((RtAudio::Api)api);
64   } catch (RtAudioError &err) {
65     audio->has_error = 1;
66     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
67   }
68   return audio;
69 }
70
71 void rtaudio_destroy(rtaudio_t audio) { delete audio->audio; }
72
73 rtaudio_api_t rtaudio_current_api(rtaudio_t audio) {
74   return (rtaudio_api_t)audio->audio->getCurrentApi();
75 }
76
77 int rtaudio_device_count(rtaudio_t audio) {
78   return audio->audio->getDeviceCount();
79 }
80
81 rtaudio_device_info_t rtaudio_get_device_info(rtaudio_t audio, int i) {
82   rtaudio_device_info_t result;
83   std::memset(&result, 0, sizeof(result));
84   try {
85     audio->has_error = 0;
86     RtAudio::DeviceInfo info = audio->audio->getDeviceInfo(i);
87     result.probed = info.probed;
88     result.output_channels = info.outputChannels;
89     result.input_channels = info.inputChannels;
90     result.duplex_channels = info.duplexChannels;
91     result.is_default_output = info.isDefaultOutput;
92     result.is_default_input = info.isDefaultInput;
93     result.native_formats = info.nativeFormats;
94     result.preferred_sample_rate = info.preferredSampleRate;
95     strncpy(result.name, info.name.c_str(), sizeof(result.name) - 1);
96     for (unsigned int j = 0; j < info.sampleRates.size(); j++) {
97       if (j < sizeof(result.sample_rates) / sizeof(result.sample_rates[0])) {
98         result.sample_rates[j] = info.sampleRates[j];
99       }
100     }
101   } catch (RtAudioError &err) {
102     audio->has_error = 1;
103     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
104   }
105   return result;
106 }
107
108 unsigned int rtaudio_get_default_output_device(rtaudio_t audio) {
109   return audio->audio->getDefaultOutputDevice();
110 }
111
112 unsigned int rtaudio_get_default_input_device(rtaudio_t audio) {
113   return audio->audio->getDefaultInputDevice();
114 }
115
116 static int proxy_cb_func(void *out, void *in, unsigned int nframes, double time,
117                          RtAudioStreamStatus status, void *userdata) {
118   rtaudio_t audio = (rtaudio_t)userdata;
119   return audio->cb(out, in, nframes, time, (rtaudio_stream_status_t)status,
120                    audio->userdata);
121 }
122
123 int rtaudio_open_stream(rtaudio_t audio,
124                         rtaudio_stream_parameters_t *output_params,
125                         rtaudio_stream_parameters_t *input_params,
126                         rtaudio_format_t format, unsigned int sample_rate,
127                         unsigned int *buffer_frames, rtaudio_cb_t cb,
128                         void *userdata, rtaudio_stream_options_t *options,
129                         rtaudio_error_cb_t /*errcb*/) {
130   try {
131     audio->has_error = 0;
132     RtAudio::StreamParameters *in = NULL;
133     RtAudio::StreamParameters *out = NULL;
134     RtAudio::StreamOptions *opts = NULL;
135
136     RtAudio::StreamParameters inparams;
137     RtAudio::StreamParameters outparams;
138     RtAudio::StreamOptions stream_opts;
139
140     if (input_params != NULL) {
141       inparams.deviceId = input_params->device_id;
142       inparams.nChannels = input_params->num_channels;
143       inparams.firstChannel = input_params->first_channel;
144       in = &inparams;
145     }
146     if (output_params != NULL) {
147       outparams.deviceId = output_params->device_id;
148       outparams.nChannels = output_params->num_channels;
149       outparams.firstChannel = output_params->first_channel;
150       out = &outparams;
151     }
152
153     if (options != NULL) {
154       stream_opts.flags = (RtAudioStreamFlags)options->flags;
155       stream_opts.numberOfBuffers = options->num_buffers;
156       stream_opts.priority = options->priority;
157       if (strlen(options->name) > 0) {
158         stream_opts.streamName = std::string(options->name);
159       }
160       opts = &stream_opts;
161     }
162     audio->cb = cb;
163     audio->userdata = userdata;
164     audio->audio->openStream(out, in, (RtAudioFormat)format, sample_rate,
165                              buffer_frames, proxy_cb_func, (void *)audio, opts,
166                              NULL);
167     return 0;
168   } catch (RtAudioError &err) {
169     audio->has_error = 1;
170     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
171     return -1;
172   }
173 }
174
175 void rtaudio_close_stream(rtaudio_t audio) { audio->audio->closeStream(); }
176
177 int rtaudio_start_stream(rtaudio_t audio) {
178   try {
179     audio->has_error = 0;
180     audio->audio->startStream();
181   } catch (RtAudioError &err) {
182     audio->has_error = 1;
183     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
184   }
185   return 0;
186 }
187
188 int rtaudio_stop_stream(rtaudio_t audio) {
189   try {
190     audio->has_error = 0;
191     audio->audio->stopStream();
192   } catch (RtAudioError &err) {
193     audio->has_error = 1;
194     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
195   }
196   return 0;
197 }
198
199 int rtaudio_abort_stream(rtaudio_t audio) {
200   try {
201     audio->has_error = 0;
202     audio->audio->abortStream();
203   } catch (RtAudioError &err) {
204     audio->has_error = 1;
205     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
206   }
207   return 0;
208 }
209
210 int rtaudio_is_stream_open(rtaudio_t audio) {
211   return !!audio->audio->isStreamOpen();
212 }
213
214 int rtaudio_is_stream_running(rtaudio_t audio) {
215   return !!audio->audio->isStreamRunning();
216 }
217
218 double rtaudio_get_stream_time(rtaudio_t audio) {
219   try {
220     audio->has_error = 0;
221     return audio->audio->getStreamTime();
222   } catch (RtAudioError &err) {
223     audio->has_error = 1;
224     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
225     return 0;
226   }
227 }
228
229 void rtaudio_set_stream_time(rtaudio_t audio, double time) {
230   try {
231     audio->has_error = 0;
232     audio->audio->setStreamTime(time);
233   } catch (RtAudioError &err) {
234     audio->has_error = 1;
235     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
236   }
237 }
238
239 int rtaudio_get_stream_latency(rtaudio_t audio) {
240   try {
241     audio->has_error = 0;
242     return audio->audio->getStreamLatency();
243   } catch (RtAudioError &err) {
244     audio->has_error = 1;
245     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
246     return -1;
247   }
248 }
249
250 unsigned int rtaudio_get_stream_sample_rate(rtaudio_t audio) {
251   try {
252     return audio->audio->getStreamSampleRate();
253   } catch (RtAudioError &err) {
254     audio->has_error = 1;
255     strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
256     return -1;
257   }
258 }
259
260 void rtaudio_show_warnings(rtaudio_t audio, int show) {
261   audio->audio->showWarnings(!!show);
262 }