Mercurial > octave-nkf
comparison libinterp/dldfcn/audiodevinfo.cc @ 19503:ea5c156aa804
audiodevinfo.cc: new file
* audiodevinfo.cc: new file implementing audiodevinfo function
author | Vytautas Jančauskas <unaudio@gmail.com> |
---|---|
date | Wed, 11 Sep 2013 20:42:15 +0300 |
parents | |
children | c2031ad6dbe7 |
comparison
equal
deleted
inserted
replaced
19502:9161b7653392 | 19503:ea5c156aa804 |
---|---|
1 #include <octave/oct.h> | |
2 #include <octave/ov-struct.h> | |
3 #include <portaudio.h> | |
4 | |
5 #include "common.h" | |
6 | |
7 DEFUN_DLD(audiodevinfo, args, , | |
8 "-*- texinfo -*-\n\ | |
9 @deftypefn{Loadable Function} @var{devinfo} = audiodevinfo\n\ | |
10 \n\ | |
11 Returns a structure with two fields called \"input\" and \"output\". \ | |
12 Each structure contains an array of structures with three fields called \ | |
13 \"Name\", \"DriverVersion\" and \"ID\". Each structure contains information \ | |
14 about a PortAudio device.\n\ | |
15 \n\ | |
16 @deftypefnx{Loadable Function} @var{devs} = audiodevinfo(@var{IO})\n\ | |
17 \n\ | |
18 Returns the number of input or output devices available. Set @var{IO} to 1 \ | |
19 for input devices and to 0 for output devices.\n\ | |
20 @deftypefnx{Loadable Function} @var{name} = audiodevinfo(@var{IO}, @var{ID})\n\ | |
21 \n\ | |
22 Returns the name of a device specified by numerical @var{ID}. Set @var{IO} \ | |
23 to 1 for input devices and to 0 for output devices.\n\ | |
24 @deftypefnx{Loadable Function} @var{id} = audiodevinfo(@var{IO}, @var{name})\n\ | |
25 \n\ | |
26 Returns the id of a device specified by name. Set @var{IO} \ | |
27 to 1 for input devices and to 0 for output devices.\n\ | |
28 @deftypefnx{Loadable Function} @var{id} = audiodevinfo(@var{IO}, @var{rate},\ | |
29 @var{bits}, @var{chans})\n\ | |
30 \n\ | |
31 Returns the id of the first device that supports playback or recording\ | |
32 using the specified sampling rate (@var{rate}), bits per sample (@var{bits})\ | |
33 and number of channels (@var{chans}). Set @var{IO} to 1 for input devices\ | |
34 ant to 0 for output devices.\ | |
35 @deftypefnx{Loadable Function} @var{supports} = audiodevinfo(@var{IO}, @var{ID},\ | |
36 @var{rate}, @var{bits}, @var{chans})\n\ | |
37 \n\ | |
38 Returns 1 if the device bearing @var{ID} supports specified sampling rate\ | |
39 (@var{rate}), bits per sample (@var{bits}) and number of channels (@var{chans}).\ | |
40 Returns 0 otherwise. Set @var{IO} to 1 for input devices and to 0 for output\ | |
41 devices.\n\ | |
42 @end deftypefn" | |
43 ) | |
44 { | |
45 int nargin = args.length(); | |
46 octave_value retval; | |
47 PaError err; | |
48 octave_scalar_map devinfo; | |
49 octave_value_list input; | |
50 octave_value_list output; | |
51 err = Pa_Initialize (); | |
52 if (err != paNoError) | |
53 { | |
54 error ("audiodevinfo: cannot initialize PortAudio"); | |
55 return retval; | |
56 } | |
57 int num_devices; | |
58 num_devices = Pa_GetDeviceCount (); | |
59 if (num_devices < 0) | |
60 { | |
61 error ("audiodevinfo: no audio device found"); | |
62 return retval; | |
63 } | |
64 octave_idx_type numinput = 0, numoutput = 0; | |
65 for (int i = 0; i < num_devices; i++) | |
66 { | |
67 const PaDeviceInfo* device_info = Pa_GetDeviceInfo (i); | |
68 | |
69 if (device_info->maxInputChannels != 0) | |
70 numinput++; | |
71 | |
72 if (device_info->maxOutputChannels != 0) | |
73 numoutput++; | |
74 } | |
75 Cell input_name (dim_vector (1, numinput)), | |
76 input_id (dim_vector (1, numinput)), | |
77 input_driver_version (dim_vector (1, numinput)), | |
78 output_name (dim_vector (1, numoutput)), | |
79 output_driver_version (dim_vector (1, numoutput)), | |
80 output_id (dim_vector (1, numoutput)); | |
81 octave_idx_type idx_i = 0, idx_o = 0; | |
82 for (int i = 0; i < num_devices; i++) | |
83 { | |
84 const PaDeviceInfo* device_info = Pa_GetDeviceInfo (i); | |
85 const char *driver; | |
86 char name[128]; | |
87 driver = Pa_GetHostApiInfo (device_info -> hostApi) -> name; | |
88 sprintf(name, "%s (%s)", device_info->name, driver); | |
89 | |
90 if (device_info->maxInputChannels != 0) | |
91 { | |
92 input_name(idx_i) = name; | |
93 input_driver_version(idx_i) = driver; | |
94 input_id(idx_i) = i; | |
95 idx_i++; | |
96 } | |
97 | |
98 if (device_info->maxOutputChannels != 0) | |
99 { | |
100 output_name(idx_o) = name; | |
101 output_driver_version(idx_o) = driver; | |
102 output_id(idx_o) = i; | |
103 idx_o++; | |
104 } | |
105 } | |
106 octave_map inputdev, outputdev; | |
107 inputdev.setfield ("Name", input_name); | |
108 inputdev.setfield ("DriverVersion", input_driver_version); | |
109 inputdev.setfield ("ID", input_id); | |
110 outputdev.setfield ("Name", output_name); | |
111 outputdev.setfield ("DriverVersion", output_driver_version); | |
112 outputdev.setfield ("ID", output_id); | |
113 devinfo.setfield ("input", inputdev); | |
114 devinfo.setfield ("output", outputdev); | |
115 // Return information about input and output audio devices and | |
116 // their properties. | |
117 if (nargin == 0) | |
118 { | |
119 retval = devinfo; | |
120 } | |
121 // Return the number of input or output devices | |
122 else if (nargin == 1) | |
123 { | |
124 if (args(0).int_value () == 0) | |
125 { | |
126 retval = octave_value (numoutput); | |
127 } | |
128 else if (args(0).int_value () == 1) | |
129 { | |
130 retval = octave_value (numinput); | |
131 } | |
132 else | |
133 { | |
134 error ("audiodevinfo: please specify 0 for output \ | |
135 and 1 for input devices"); | |
136 return retval; | |
137 } | |
138 } | |
139 // Return device name when given id or id when given device name. | |
140 else if (nargin == 2) | |
141 { | |
142 bool found = false; | |
143 int outin = args(0).int_value (); | |
144 if (args(1).is_string ()) | |
145 { | |
146 if (outin == 0) | |
147 { | |
148 for (int i = 0; i < numoutput; i++) | |
149 { | |
150 if (output_name(i).string_value () == args(1).string_value ()) | |
151 { | |
152 retval = output_id(i); | |
153 found = true; | |
154 break; | |
155 } | |
156 } | |
157 } | |
158 else if (outin == 1) | |
159 { | |
160 for (int i = 0; i < numinput; i++) | |
161 { | |
162 if (input_name(i).string_value () == args(1).string_value ()) | |
163 { | |
164 retval = input_id(i); | |
165 found = true; | |
166 break; | |
167 } | |
168 } | |
169 } | |
170 else | |
171 { | |
172 error ("audiodevinfo: please specify 0 for output \ | |
173 and 1 for input devices"); | |
174 return retval; | |
175 } | |
176 } | |
177 else | |
178 { | |
179 if (outin == 0) | |
180 { | |
181 for (int i = 0; i < numoutput; i++) | |
182 { | |
183 if (output_id(i).int_value () == args(1).int_value ()) | |
184 { | |
185 retval = output_name(i); | |
186 found = true; | |
187 break; | |
188 } | |
189 } | |
190 } | |
191 else if (outin == 1) | |
192 { | |
193 for (int i = 0; i < numinput; i++) | |
194 { | |
195 if (input_id(i).int_value () == args(1).int_value ()) | |
196 { | |
197 retval = input_name(i); | |
198 found = true; | |
199 break; | |
200 } | |
201 } | |
202 } | |
203 else | |
204 { | |
205 error ("audiodevinfo: please specify 0 for output \ | |
206 and 1 for input devices"); | |
207 return retval; | |
208 } | |
209 } | |
210 if (not found) | |
211 { | |
212 error("audiodevinfo: no device meeting the specified criteria found"); | |
213 } | |
214 } | |
215 else if (nargin == 3) | |
216 { | |
217 // | |
218 } | |
219 // Return the id of the first device meeting specified criteria. | |
220 else if (nargin == 4) | |
221 { | |
222 int io = args(0).int_value (); | |
223 int rate = args(1).int_value (); | |
224 int bits = args(2).int_value (); | |
225 int chans = args(3).int_value (); | |
226 for (int i = 0; i < num_devices; i++) | |
227 { | |
228 PaStreamParameters stream_parameters; | |
229 stream_parameters.device = i; | |
230 stream_parameters.channelCount = chans; | |
231 PaSampleFormat format = bits_to_format(bits); | |
232 if (format != 0) | |
233 { | |
234 stream_parameters.sampleFormat = format; | |
235 } | |
236 else | |
237 { | |
238 error("audiodevinfo: no such bits per sample format"); | |
239 return retval; | |
240 } | |
241 stream_parameters.suggestedLatency = | |
242 Pa_GetDeviceInfo (i)->defaultLowInputLatency; | |
243 stream_parameters.hostApiSpecificStreamInfo = NULL; | |
244 if (io == 0) | |
245 { | |
246 if (Pa_GetDeviceInfo (i)->maxOutputChannels < chans) | |
247 { | |
248 continue; | |
249 } | |
250 err = Pa_IsFormatSupported (NULL, &stream_parameters, rate); | |
251 if (err == paFormatIsSupported) | |
252 { | |
253 retval = i; | |
254 return retval; | |
255 } | |
256 } | |
257 else if (io == 1) | |
258 { | |
259 if (Pa_GetDeviceInfo (i)->maxInputChannels < chans) | |
260 { | |
261 continue; | |
262 } | |
263 err = Pa_IsFormatSupported (&stream_parameters, NULL, rate); | |
264 if (err == paFormatIsSupported) | |
265 { | |
266 retval = i; | |
267 return retval; | |
268 } | |
269 } | |
270 } | |
271 retval = -1; | |
272 } | |
273 // Check if given device supports specified playback or recording modes. | |
274 else if (nargin == 5) | |
275 { | |
276 int io = args(0).int_value (); | |
277 int id = args(1).int_value (); | |
278 int rate = args(2).int_value (); | |
279 int bits = args(3).int_value (); | |
280 int chans = args(4).int_value (); | |
281 PaStreamParameters stream_parameters; | |
282 stream_parameters.device = id; | |
283 stream_parameters.channelCount = chans; | |
284 PaSampleFormat format = bits_to_format(bits); | |
285 if (format != 0) | |
286 { | |
287 stream_parameters.sampleFormat = format; | |
288 } | |
289 else | |
290 { | |
291 error("audiodevinfo: no such bits per sample format"); | |
292 return retval; | |
293 } | |
294 stream_parameters.suggestedLatency = | |
295 Pa_GetDeviceInfo (id)->defaultLowInputLatency; | |
296 stream_parameters.hostApiSpecificStreamInfo = NULL; | |
297 if (io == 0) | |
298 { | |
299 if (Pa_GetDeviceInfo (id)->maxOutputChannels < chans) | |
300 { | |
301 retval = 0; | |
302 return retval; | |
303 } | |
304 err = Pa_IsFormatSupported (NULL, &stream_parameters, rate); | |
305 if (err == paFormatIsSupported) | |
306 { | |
307 retval = 1; | |
308 return retval; | |
309 } | |
310 } | |
311 else if (io == 1) | |
312 { | |
313 if (Pa_GetDeviceInfo (id)->maxInputChannels < chans) | |
314 { | |
315 retval = 0; | |
316 return retval; | |
317 } | |
318 err = Pa_IsFormatSupported (&stream_parameters, NULL, rate); | |
319 if (err == paFormatIsSupported) | |
320 { | |
321 retval = 1; | |
322 return retval; | |
323 } | |
324 } | |
325 else | |
326 { | |
327 error ("audiodevinfo: please specify 0 for output\ | |
328 and 1 for input devices"); | |
329 return retval; | |
330 } | |
331 retval = 0; | |
332 } | |
333 else | |
334 { | |
335 error ("audiodevinfo: wrong number of arguments"); | |
336 return retval; | |
337 } | |
338 return retval; | |
339 } | |
340 | |
341 /* | |
342 | |
343 %!test | |
344 %! devinfo = audiodevinfo; | |
345 %! assert(rows(devinfo.('input')) == 1); | |
346 %! assert(rows(devinfo.('output')) == 1); | |
347 | |
348 %!test | |
349 %! devinfo = audiodevinfo; | |
350 %! nout = audiodevinfo(0); | |
351 %! nin = audiodevinfo(1); | |
352 %! assert(columns(devinfo.('output')) == nout); | |
353 %! assert(columns(devinfo.('input')) == nin); | |
354 | |
355 %!test | |
356 %! devinfo = audiodevinfo; | |
357 %! nout = audiodevinfo(0); | |
358 %! nin = audiodevinfo(1); | |
359 %! for i=1:nout, | |
360 %! assert(devinfo.('output')(i).('Name') == audiodevinfo(0, devinfo.('output')(i).('ID'))) | |
361 %! end | |
362 %! for i=1:nin, | |
363 %! assert(devinfo.('input')(i).('Name') == audiodevinfo(0, devinfo.('input')(i).('ID'))) | |
364 %! end | |
365 | |
366 %!test | |
367 %! devinfo = audiodevinfo; | |
368 %! nout = audiodevinfo(0); | |
369 %! nin = audiodevinfo(1); | |
370 %! for i=1:nout, | |
371 %! assert(devinfo.('output')(i).('ID') == audiodevinfo(0, devinfo.('output')(i).('Name'))) | |
372 %! end | |
373 %! for i=1:nin, | |
374 %! assert(devinfo.('input')(i).('ID') == audiodevinfo(0, devinfo.('input')(i).('Name'))) | |
375 %! end | |
376 | |
377 */ |