|
1 /* |
|
2 SDL - Simple DirectMedia Layer |
|
3 Copyright (C) 1997-2006 Sam Lantinga |
|
4 |
|
5 This library is free software; you can redistribute it and/or |
|
6 modify it under the terms of the GNU Lesser General Public |
|
7 License as published by the Free Software Foundation; either |
|
8 version 2.1 of the License, or (at your option) any later version. |
|
9 |
|
10 This library is distributed in the hope that it will be useful, |
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
13 Lesser General Public License for more details. |
|
14 |
|
15 You should have received a copy of the GNU Lesser General Public |
|
16 License along with this library; if not, write to the Free Software |
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
18 |
|
19 Carsten Griwodz |
|
20 griff@kom.tu-darmstadt.de |
|
21 |
|
22 based on linux/SDL_dspaudio.c by Sam Lantinga |
|
23 */ |
|
24 #include "SDL_config.h" |
|
25 |
|
26 /* Allow access to a raw mixing buffer */ |
|
27 |
|
28 #include <errno.h> |
|
29 #include <unistd.h> |
|
30 #include <fcntl.h> |
|
31 #include <sys/types.h> |
|
32 #include <sys/time.h> |
|
33 #include <sys/ioctl.h> |
|
34 #include <sys/stat.h> |
|
35 #include <sys/mman.h> |
|
36 |
|
37 #include "SDL_audio.h" |
|
38 #include "../SDL_audio_c.h" |
|
39 #include "../SDL_audiodev_c.h" |
|
40 #include "SDL_umsaudio.h" |
|
41 |
|
42 /* The tag name used by UMS audio */ |
|
43 #define UMS_DRIVER_NAME "ums" |
|
44 |
|
45 #define DEBUG_AUDIO 1 |
|
46 |
|
47 /* Audio driver functions */ |
|
48 static int UMS_OpenAudio(_THIS, SDL_AudioSpec *spec); |
|
49 static void UMS_PlayAudio(_THIS); |
|
50 static Uint8 *UMS_GetAudioBuf(_THIS); |
|
51 static void UMS_CloseAudio(_THIS); |
|
52 |
|
53 static UMSAudioDevice_ReturnCode UADOpen(_THIS, string device, string mode, long flags); |
|
54 static UMSAudioDevice_ReturnCode UADClose(_THIS); |
|
55 static UMSAudioDevice_ReturnCode UADGetBitsPerSample(_THIS, long* bits); |
|
56 static UMSAudioDevice_ReturnCode UADSetBitsPerSample(_THIS, long bits); |
|
57 static UMSAudioDevice_ReturnCode UADSetSampleRate(_THIS, long rate, long* set_rate); |
|
58 static UMSAudioDevice_ReturnCode UADSetByteOrder(_THIS, string byte_order); |
|
59 static UMSAudioDevice_ReturnCode UADSetAudioFormatType(_THIS, string fmt); |
|
60 static UMSAudioDevice_ReturnCode UADSetNumberFormat(_THIS, string fmt); |
|
61 static UMSAudioDevice_ReturnCode UADInitialize(_THIS); |
|
62 static UMSAudioDevice_ReturnCode UADStart(_THIS); |
|
63 static UMSAudioDevice_ReturnCode UADStop(_THIS); |
|
64 static UMSAudioDevice_ReturnCode UADSetTimeFormat(_THIS, UMSAudioTypes_TimeFormat fmt ); |
|
65 static UMSAudioDevice_ReturnCode UADWriteBuffSize(_THIS, long* buff_size ); |
|
66 static UMSAudioDevice_ReturnCode UADWriteBuffRemain(_THIS, long* buff_size ); |
|
67 static UMSAudioDevice_ReturnCode UADWriteBuffUsed(_THIS, long* buff_size ); |
|
68 static UMSAudioDevice_ReturnCode UADSetDMABufferSize(_THIS, long bytes, long* bytes_ret ); |
|
69 static UMSAudioDevice_ReturnCode UADSetVolume(_THIS, long volume ); |
|
70 static UMSAudioDevice_ReturnCode UADSetBalance(_THIS, long balance ); |
|
71 static UMSAudioDevice_ReturnCode UADSetChannels(_THIS, long channels ); |
|
72 static UMSAudioDevice_ReturnCode UADPlayRemainingData(_THIS, boolean block ); |
|
73 static UMSAudioDevice_ReturnCode UADEnableOutput(_THIS, string output, long* left_gain, long* right_gain); |
|
74 static UMSAudioDevice_ReturnCode UADWrite(_THIS, UMSAudioTypes_Buffer* buff, long samples, long* samples_written); |
|
75 |
|
76 /* Audio driver bootstrap functions */ |
|
77 static int Audio_Available(void) |
|
78 { |
|
79 return 1; |
|
80 } |
|
81 |
|
82 static void Audio_DeleteDevice(_THIS) |
|
83 { |
|
84 if(this->hidden->playbuf._buffer) SDL_free(this->hidden->playbuf._buffer); |
|
85 if(this->hidden->fillbuf._buffer) SDL_free(this->hidden->fillbuf._buffer); |
|
86 _somFree( this->hidden->umsdev ); |
|
87 SDL_free(this->hidden); |
|
88 SDL_free(this); |
|
89 } |
|
90 |
|
91 static SDL_AudioDevice *Audio_CreateDevice(int devindex) |
|
92 { |
|
93 SDL_AudioDevice *this; |
|
94 |
|
95 /* |
|
96 * Allocate and initialize management storage and private management |
|
97 * storage for this SDL-using library. |
|
98 */ |
|
99 this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); |
|
100 if ( this ) { |
|
101 SDL_memset(this, 0, (sizeof *this)); |
|
102 this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc((sizeof *this->hidden)); |
|
103 } |
|
104 if ( (this == NULL) || (this->hidden == NULL) ) { |
|
105 SDL_OutOfMemory(); |
|
106 if ( this ) { |
|
107 SDL_free(this); |
|
108 } |
|
109 return(0); |
|
110 } |
|
111 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); |
|
112 #ifdef DEBUG_AUDIO |
|
113 fprintf(stderr, "Creating UMS Audio device\n"); |
|
114 #endif |
|
115 |
|
116 /* |
|
117 * Calls for UMS env initialization and audio object construction. |
|
118 */ |
|
119 this->hidden->ev = somGetGlobalEnvironment(); |
|
120 this->hidden->umsdev = UMSAudioDeviceNew(); |
|
121 |
|
122 /* |
|
123 * Set the function pointers. |
|
124 */ |
|
125 this->OpenAudio = UMS_OpenAudio; |
|
126 this->WaitAudio = NULL; /* we do blocking output */ |
|
127 this->PlayAudio = UMS_PlayAudio; |
|
128 this->GetAudioBuf = UMS_GetAudioBuf; |
|
129 this->CloseAudio = UMS_CloseAudio; |
|
130 this->free = Audio_DeleteDevice; |
|
131 |
|
132 #ifdef DEBUG_AUDIO |
|
133 fprintf(stderr, "done\n"); |
|
134 #endif |
|
135 return this; |
|
136 } |
|
137 |
|
138 AudioBootStrap UMS_bootstrap = { |
|
139 UMS_DRIVER_NAME, "AIX UMS audio", |
|
140 Audio_Available, Audio_CreateDevice |
|
141 }; |
|
142 |
|
143 static Uint8 *UMS_GetAudioBuf(_THIS) |
|
144 { |
|
145 #ifdef DEBUG_AUDIO |
|
146 fprintf(stderr, "enter UMS_GetAudioBuf\n"); |
|
147 #endif |
|
148 return this->hidden->fillbuf._buffer; |
|
149 /* |
|
150 long bufSize; |
|
151 UMSAudioDevice_ReturnCode rc; |
|
152 |
|
153 rc = UADSetTimeFormat(this, UMSAudioTypes_Bytes ); |
|
154 rc = UADWriteBuffSize(this, bufSize ); |
|
155 */ |
|
156 } |
|
157 |
|
158 static void UMS_CloseAudio(_THIS) |
|
159 { |
|
160 UMSAudioDevice_ReturnCode rc; |
|
161 |
|
162 #ifdef DEBUG_AUDIO |
|
163 fprintf(stderr, "enter UMS_CloseAudio\n"); |
|
164 #endif |
|
165 rc = UADPlayRemainingData(this, TRUE); |
|
166 rc = UADStop(this); |
|
167 rc = UADClose(this); |
|
168 } |
|
169 |
|
170 static void UMS_PlayAudio(_THIS) |
|
171 { |
|
172 UMSAudioDevice_ReturnCode rc; |
|
173 long samplesToWrite; |
|
174 long samplesWritten; |
|
175 UMSAudioTypes_Buffer swpbuf; |
|
176 |
|
177 #ifdef DEBUG_AUDIO |
|
178 fprintf(stderr, "enter UMS_PlayAudio\n"); |
|
179 #endif |
|
180 samplesToWrite = this->hidden->playbuf._length/this->hidden->bytesPerSample; |
|
181 do |
|
182 { |
|
183 rc = UADWrite(this, &this->hidden->playbuf, |
|
184 samplesToWrite, |
|
185 &samplesWritten ); |
|
186 samplesToWrite -= samplesWritten; |
|
187 |
|
188 /* rc values: UMSAudioDevice_Success |
|
189 * UMSAudioDevice_Failure |
|
190 * UMSAudioDevice_Preempted |
|
191 * UMSAudioDevice_Interrupted |
|
192 * UMSAudioDevice_DeviceError |
|
193 */ |
|
194 if ( rc == UMSAudioDevice_DeviceError ) { |
|
195 #ifdef DEBUG_AUDIO |
|
196 fprintf(stderr, "Returning from PlayAudio with devices error\n"); |
|
197 #endif |
|
198 return; |
|
199 } |
|
200 } |
|
201 while(samplesToWrite>0); |
|
202 |
|
203 SDL_LockAudio(); |
|
204 SDL_memcpy( &swpbuf, &this->hidden->playbuf, sizeof(UMSAudioTypes_Buffer) ); |
|
205 SDL_memcpy( &this->hidden->playbuf, &this->hidden->fillbuf, sizeof(UMSAudioTypes_Buffer) ); |
|
206 SDL_memcpy( &this->hidden->fillbuf, &swpbuf, sizeof(UMSAudioTypes_Buffer) ); |
|
207 SDL_UnlockAudio(); |
|
208 |
|
209 #ifdef DEBUG_AUDIO |
|
210 fprintf(stderr, "Wrote audio data and swapped buffer\n"); |
|
211 #endif |
|
212 } |
|
213 |
|
214 #if 0 |
|
215 // /* Set the DSP frequency */ |
|
216 // value = spec->freq; |
|
217 // if ( ioctl(this->hidden->audio_fd, SOUND_PCM_WRITE_RATE, &value) < 0 ) { |
|
218 // SDL_SetError("Couldn't set audio frequency"); |
|
219 // return(-1); |
|
220 // } |
|
221 // spec->freq = value; |
|
222 #endif |
|
223 |
|
224 static int UMS_OpenAudio(_THIS, SDL_AudioSpec *spec) |
|
225 { |
|
226 char* audiodev = "/dev/paud0"; |
|
227 long lgain; |
|
228 long rgain; |
|
229 long outRate; |
|
230 long outBufSize; |
|
231 long bitsPerSample; |
|
232 long samplesPerSec; |
|
233 long success; |
|
234 Uint16 test_format; |
|
235 int frag_spec; |
|
236 UMSAudioDevice_ReturnCode rc; |
|
237 |
|
238 #ifdef DEBUG_AUDIO |
|
239 fprintf(stderr, "enter UMS_OpenAudio\n"); |
|
240 #endif |
|
241 rc = UADOpen(this, audiodev,"PLAY", UMSAudioDevice_BlockingIO); |
|
242 if ( rc != UMSAudioDevice_Success ) { |
|
243 SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); |
|
244 return -1; |
|
245 } |
|
246 |
|
247 rc = UADSetAudioFormatType(this, "PCM"); |
|
248 |
|
249 success = 0; |
|
250 test_format = SDL_FirstAudioFormat(spec->format); |
|
251 do |
|
252 { |
|
253 #ifdef DEBUG_AUDIO |
|
254 fprintf(stderr, "Trying format 0x%4.4x\n", test_format); |
|
255 #endif |
|
256 switch ( test_format ) |
|
257 { |
|
258 case AUDIO_U8: |
|
259 /* from the mac code: better ? */ |
|
260 /* sample_bits = spec->size / spec->samples / spec->channels * 8; */ |
|
261 success = 1; |
|
262 bitsPerSample = 8; |
|
263 rc = UADSetSampleRate(this, spec->freq << 16, &outRate ); |
|
264 rc = UADSetByteOrder(this, "MSB"); /* irrelevant */ |
|
265 rc = UADSetNumberFormat(this, "UNSIGNED"); |
|
266 break; |
|
267 case AUDIO_S8: |
|
268 success = 1; |
|
269 bitsPerSample = 8; |
|
270 rc = UADSetSampleRate(this, spec->freq << 16, &outRate ); |
|
271 rc = UADSetByteOrder(this, "MSB"); /* irrelevant */ |
|
272 rc = UADSetNumberFormat(this, "SIGNED"); |
|
273 break; |
|
274 case AUDIO_S16LSB: |
|
275 success = 1; |
|
276 bitsPerSample = 16; |
|
277 rc = UADSetSampleRate(this, spec->freq << 16, &outRate ); |
|
278 rc = UADSetByteOrder(this, "LSB"); |
|
279 rc = UADSetNumberFormat(this, "SIGNED"); |
|
280 break; |
|
281 case AUDIO_S16MSB: |
|
282 success = 1; |
|
283 bitsPerSample = 16; |
|
284 rc = UADSetSampleRate(this, spec->freq << 16, &outRate ); |
|
285 rc = UADSetByteOrder(this, "MSB"); |
|
286 rc = UADSetNumberFormat(this, "SIGNED"); |
|
287 break; |
|
288 case AUDIO_U16LSB: |
|
289 success = 1; |
|
290 bitsPerSample = 16; |
|
291 rc = UADSetSampleRate(this, spec->freq << 16, &outRate ); |
|
292 rc = UADSetByteOrder(this, "LSB"); |
|
293 rc = UADSetNumberFormat(this, "UNSIGNED"); |
|
294 break; |
|
295 case AUDIO_U16MSB: |
|
296 success = 1; |
|
297 bitsPerSample = 16; |
|
298 rc = UADSetSampleRate(this, spec->freq << 16, &outRate ); |
|
299 rc = UADSetByteOrder(this, "MSB"); |
|
300 rc = UADSetNumberFormat(this, "UNSIGNED"); |
|
301 break; |
|
302 default: |
|
303 break; |
|
304 } |
|
305 if ( ! success ) { |
|
306 test_format = SDL_NextAudioFormat(); |
|
307 } |
|
308 } |
|
309 while ( ! success && test_format ); |
|
310 |
|
311 if ( success == 0 ) { |
|
312 SDL_SetError("Couldn't find any hardware audio formats"); |
|
313 return -1; |
|
314 } |
|
315 |
|
316 spec->format = test_format; |
|
317 |
|
318 for ( frag_spec = 0; (0x01<<frag_spec) < spec->size; ++frag_spec ); |
|
319 if ( (0x01<<frag_spec) != spec->size ) { |
|
320 SDL_SetError("Fragment size must be a power of two"); |
|
321 return -1; |
|
322 } |
|
323 if ( frag_spec > 2048 ) frag_spec = 2048; |
|
324 |
|
325 this->hidden->bytesPerSample = (bitsPerSample / 8) * spec->channels; |
|
326 samplesPerSec = this->hidden->bytesPerSample * outRate; |
|
327 |
|
328 this->hidden->playbuf._length = 0; |
|
329 this->hidden->playbuf._maximum = spec->size; |
|
330 this->hidden->playbuf._buffer = (unsigned char*)SDL_malloc(spec->size); |
|
331 this->hidden->fillbuf._length = 0; |
|
332 this->hidden->fillbuf._maximum = spec->size; |
|
333 this->hidden->fillbuf._buffer = (unsigned char*)SDL_malloc(spec->size); |
|
334 |
|
335 rc = UADSetBitsPerSample(this, bitsPerSample ); |
|
336 rc = UADSetDMABufferSize(this, frag_spec, &outBufSize ); |
|
337 rc = UADSetChannels(this, spec->channels); /* functions reduces to mono or stereo */ |
|
338 |
|
339 lgain = 100; /*maximum left input gain*/ |
|
340 rgain = 100; /*maimum right input gain*/ |
|
341 rc = UADEnableOutput(this, "LINE_OUT",&lgain,&rgain); |
|
342 rc = UADInitialize(this); |
|
343 rc = UADStart(this); |
|
344 rc = UADSetVolume(this, 100); |
|
345 rc = UADSetBalance(this, 0); |
|
346 |
|
347 /* We're ready to rock and roll. :-) */ |
|
348 return 0; |
|
349 } |
|
350 |
|
351 |
|
352 static UMSAudioDevice_ReturnCode UADGetBitsPerSample(_THIS, long* bits) |
|
353 { |
|
354 return UMSAudioDevice_get_bits_per_sample( this->hidden->umsdev, |
|
355 this->hidden->ev, |
|
356 bits ); |
|
357 } |
|
358 |
|
359 static UMSAudioDevice_ReturnCode UADSetBitsPerSample(_THIS, long bits) |
|
360 { |
|
361 return UMSAudioDevice_set_bits_per_sample( this->hidden->umsdev, |
|
362 this->hidden->ev, |
|
363 bits ); |
|
364 } |
|
365 |
|
366 static UMSAudioDevice_ReturnCode UADSetSampleRate(_THIS, long rate, long* set_rate) |
|
367 { |
|
368 /* from the mac code: sample rate = spec->freq << 16; */ |
|
369 return UMSAudioDevice_set_sample_rate( this->hidden->umsdev, |
|
370 this->hidden->ev, |
|
371 rate, |
|
372 set_rate ); |
|
373 } |
|
374 |
|
375 static UMSAudioDevice_ReturnCode UADSetByteOrder(_THIS, string byte_order) |
|
376 { |
|
377 return UMSAudioDevice_set_byte_order( this->hidden->umsdev, |
|
378 this->hidden->ev, |
|
379 byte_order ); |
|
380 } |
|
381 |
|
382 static UMSAudioDevice_ReturnCode UADSetAudioFormatType(_THIS, string fmt) |
|
383 { |
|
384 /* possible PCM, A_LAW or MU_LAW */ |
|
385 return UMSAudioDevice_set_audio_format_type( this->hidden->umsdev, |
|
386 this->hidden->ev, |
|
387 fmt ); |
|
388 } |
|
389 |
|
390 static UMSAudioDevice_ReturnCode UADSetNumberFormat(_THIS, string fmt) |
|
391 { |
|
392 /* possible SIGNED, UNSIGNED, or TWOS_COMPLEMENT */ |
|
393 return UMSAudioDevice_set_number_format( this->hidden->umsdev, |
|
394 this->hidden->ev, |
|
395 fmt ); |
|
396 } |
|
397 |
|
398 static UMSAudioDevice_ReturnCode UADInitialize(_THIS) |
|
399 { |
|
400 return UMSAudioDevice_initialize( this->hidden->umsdev, |
|
401 this->hidden->ev ); |
|
402 } |
|
403 |
|
404 static UMSAudioDevice_ReturnCode UADStart(_THIS) |
|
405 { |
|
406 return UMSAudioDevice_start( this->hidden->umsdev, |
|
407 this->hidden->ev ); |
|
408 } |
|
409 |
|
410 static UMSAudioDevice_ReturnCode UADSetTimeFormat(_THIS, UMSAudioTypes_TimeFormat fmt ) |
|
411 { |
|
412 /* |
|
413 * Switches the time format to the new format, immediately. |
|
414 * possible UMSAudioTypes_Msecs, UMSAudioTypes_Bytes or UMSAudioTypes_Samples |
|
415 */ |
|
416 return UMSAudioDevice_set_time_format( this->hidden->umsdev, |
|
417 this->hidden->ev, |
|
418 fmt ); |
|
419 } |
|
420 |
|
421 static UMSAudioDevice_ReturnCode UADWriteBuffSize(_THIS, long* buff_size ) |
|
422 { |
|
423 /* |
|
424 * returns write buffer size in the current time format |
|
425 */ |
|
426 return UMSAudioDevice_write_buff_size( this->hidden->umsdev, |
|
427 this->hidden->ev, |
|
428 buff_size ); |
|
429 } |
|
430 |
|
431 static UMSAudioDevice_ReturnCode UADWriteBuffRemain(_THIS, long* buff_size ) |
|
432 { |
|
433 /* |
|
434 * returns amount of available space in the write buffer |
|
435 * in the current time format |
|
436 */ |
|
437 return UMSAudioDevice_write_buff_remain( this->hidden->umsdev, |
|
438 this->hidden->ev, |
|
439 buff_size ); |
|
440 } |
|
441 |
|
442 static UMSAudioDevice_ReturnCode UADWriteBuffUsed(_THIS, long* buff_size ) |
|
443 { |
|
444 /* |
|
445 * returns amount of filled space in the write buffer |
|
446 * in the current time format |
|
447 */ |
|
448 return UMSAudioDevice_write_buff_used( this->hidden->umsdev, |
|
449 this->hidden->ev, |
|
450 buff_size ); |
|
451 } |
|
452 |
|
453 static UMSAudioDevice_ReturnCode UADSetDMABufferSize(_THIS, long bytes, long* bytes_ret ) |
|
454 { |
|
455 /* |
|
456 * Request a new DMA buffer size, maximum requested size 2048. |
|
457 * Takes effect with next initialize() call. |
|
458 * Devices may or may not support DMA. |
|
459 */ |
|
460 return UMSAudioDevice_set_DMA_buffer_size( this->hidden->umsdev, |
|
461 this->hidden->ev, |
|
462 bytes, |
|
463 bytes_ret ); |
|
464 } |
|
465 |
|
466 static UMSAudioDevice_ReturnCode UADSetVolume(_THIS, long volume ) |
|
467 { |
|
468 /* |
|
469 * Set the volume. |
|
470 * Takes effect immediately. |
|
471 */ |
|
472 return UMSAudioDevice_set_volume( this->hidden->umsdev, |
|
473 this->hidden->ev, |
|
474 volume ); |
|
475 } |
|
476 |
|
477 static UMSAudioDevice_ReturnCode UADSetBalance(_THIS, long balance ) |
|
478 { |
|
479 /* |
|
480 * Set the balance. |
|
481 * Takes effect immediately. |
|
482 */ |
|
483 return UMSAudioDevice_set_balance( this->hidden->umsdev, |
|
484 this->hidden->ev, |
|
485 balance ); |
|
486 } |
|
487 |
|
488 static UMSAudioDevice_ReturnCode UADSetChannels(_THIS, long channels ) |
|
489 { |
|
490 /* |
|
491 * Set mono or stereo. |
|
492 * Takes effect with next initialize() call. |
|
493 */ |
|
494 if ( channels != 1 ) channels = 2; |
|
495 return UMSAudioDevice_set_number_of_channels( this->hidden->umsdev, |
|
496 this->hidden->ev, |
|
497 channels ); |
|
498 } |
|
499 |
|
500 static UMSAudioDevice_ReturnCode UADOpen(_THIS, string device, string mode, long flags) |
|
501 { |
|
502 return UMSAudioDevice_open( this->hidden->umsdev, |
|
503 this->hidden->ev, |
|
504 device, |
|
505 mode, |
|
506 flags ); |
|
507 } |
|
508 |
|
509 static UMSAudioDevice_ReturnCode UADWrite(_THIS, UMSAudioTypes_Buffer* buff, |
|
510 long samples, |
|
511 long* samples_written) |
|
512 { |
|
513 return UMSAudioDevice_write( this->hidden->umsdev, |
|
514 this->hidden->ev, |
|
515 buff, |
|
516 samples, |
|
517 samples_written ); |
|
518 } |
|
519 |
|
520 static UMSAudioDevice_ReturnCode UADPlayRemainingData(_THIS, boolean block ) |
|
521 { |
|
522 return UMSAudioDevice_play_remaining_data( this->hidden->umsdev, |
|
523 this->hidden->ev, |
|
524 block); |
|
525 } |
|
526 |
|
527 static UMSAudioDevice_ReturnCode UADStop(_THIS) |
|
528 { |
|
529 return UMSAudioDevice_stop( this->hidden->umsdev, |
|
530 this->hidden->ev ); |
|
531 } |
|
532 |
|
533 static UMSAudioDevice_ReturnCode UADClose(_THIS) |
|
534 { |
|
535 return UMSAudioDevice_close( this->hidden->umsdev, |
|
536 this->hidden->ev ); |
|
537 } |
|
538 |
|
539 static UMSAudioDevice_ReturnCode UADEnableOutput(_THIS, string output, long* left_gain, long* right_gain) |
|
540 { |
|
541 return UMSAudioDevice_enable_output( this->hidden->umsdev, |
|
542 this->hidden->ev, |
|
543 output, |
|
544 left_gain, |
|
545 right_gain ); |
|
546 } |
|
547 |