src/audio/ums/SDL_umsaudio.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. Audio_Available
  2. Audio_DeleteDevice
  3. Audio_CreateDevice
  4. UMS_GetAudioBuf
  5. UMS_CloseAudio
  6. UMS_PlayAudio
  7. UMS_OpenAudio
  8. UADGetBitsPerSample
  9. UADSetBitsPerSample
  10. UADSetSampleRate
  11. UADSetByteOrder
  12. UADSetAudioFormatType
  13. UADSetNumberFormat
  14. UADInitialize
  15. UADStart
  16. UADSetTimeFormat
  17. UADWriteBuffSize
  18. UADWriteBuffRemain
  19. UADWriteBuffUsed
  20. UADSetDMABufferSize
  21. UADSetVolume
  22. UADSetBalance
  23. UADSetChannels
  24. UADOpen
  25. UADWrite
  26. UADPlayRemainingData
  27. UADStop
  28. UADClose
  29. UADEnableOutput

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

/* [<][>][^][v][top][bottom][index][help] */