src/audio/SDL_audio.c
author Sam Lantinga
Sat, 06 Oct 2012 12:16:32 -0700
changeset 6566 dd7e57847ea9
parent 6430 48d519500f7e
child 6885 700f1b25f77f
permissions -rw-r--r--
Add flags to the vidmode debug output
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "SDL_config.h"
    22 
    23 /* Allow access to a raw mixing buffer */
    24 
    25 #include "SDL.h"
    26 #include "SDL_audio.h"
    27 #include "SDL_audio_c.h"
    28 #include "SDL_audiomem.h"
    29 #include "SDL_sysaudio.h"
    30 
    31 #define _THIS SDL_AudioDevice *_this
    32 
    33 static SDL_AudioDriver current_audio;
    34 static SDL_AudioDevice *open_devices[16];
    35 
    36 /* !!! FIXME: These are wordy and unlocalized... */
    37 #define DEFAULT_OUTPUT_DEVNAME "System audio output device"
    38 #define DEFAULT_INPUT_DEVNAME "System audio capture device"
    39 
    40 
    41 /*
    42  * Not all of these will be compiled and linked in, but it's convenient
    43  *  to have a complete list here and saves yet-another block of #ifdefs...
    44  *  Please see bootstrap[], below, for the actual #ifdef mess.
    45  */
    46 extern AudioBootStrap BSD_AUDIO_bootstrap;
    47 extern AudioBootStrap DSP_bootstrap;
    48 extern AudioBootStrap ALSA_bootstrap;
    49 extern AudioBootStrap PULSEAUDIO_bootstrap;
    50 extern AudioBootStrap QSAAUDIO_bootstrap;
    51 extern AudioBootStrap SUNAUDIO_bootstrap;
    52 extern AudioBootStrap ARTS_bootstrap;
    53 extern AudioBootStrap ESD_bootstrap;
    54 extern AudioBootStrap NAS_bootstrap;
    55 extern AudioBootStrap XAUDIO2_bootstrap;
    56 extern AudioBootStrap DSOUND_bootstrap;
    57 extern AudioBootStrap WINMM_bootstrap;
    58 extern AudioBootStrap PAUDIO_bootstrap;
    59 extern AudioBootStrap BEOSAUDIO_bootstrap;
    60 extern AudioBootStrap COREAUDIO_bootstrap;
    61 extern AudioBootStrap SNDMGR_bootstrap;
    62 extern AudioBootStrap DISKAUD_bootstrap;
    63 extern AudioBootStrap DUMMYAUD_bootstrap;
    64 extern AudioBootStrap DCAUD_bootstrap;
    65 extern AudioBootStrap DART_bootstrap;
    66 extern AudioBootStrap NDSAUD_bootstrap;
    67 extern AudioBootStrap FUSIONSOUND_bootstrap;
    68 extern AudioBootStrap ANDROIDAUD_bootstrap;
    69 
    70 
    71 /* Available audio drivers */
    72 static const AudioBootStrap *const bootstrap[] = {
    73 #if SDL_AUDIO_DRIVER_PULSEAUDIO
    74     &PULSEAUDIO_bootstrap,
    75 #endif
    76 #if SDL_AUDIO_DRIVER_ALSA
    77     &ALSA_bootstrap,
    78 #endif
    79 #if SDL_AUDIO_DRIVER_BSD
    80     &BSD_AUDIO_bootstrap,
    81 #endif
    82 #if SDL_AUDIO_DRIVER_OSS
    83     &DSP_bootstrap,
    84 #endif
    85 #if SDL_AUDIO_DRIVER_QSA
    86     &QSAAUDIO_bootstrap,
    87 #endif
    88 #if SDL_AUDIO_DRIVER_SUNAUDIO
    89     &SUNAUDIO_bootstrap,
    90 #endif
    91 #if SDL_AUDIO_DRIVER_ARTS
    92     &ARTS_bootstrap,
    93 #endif
    94 #if SDL_AUDIO_DRIVER_ESD
    95     &ESD_bootstrap,
    96 #endif
    97 #if SDL_AUDIO_DRIVER_NAS
    98     &NAS_bootstrap,
    99 #endif
   100 #if SDL_AUDIO_DRIVER_XAUDIO2
   101     &XAUDIO2_bootstrap,
   102 #endif
   103 #if SDL_AUDIO_DRIVER_DSOUND
   104     &DSOUND_bootstrap,
   105 #endif
   106 #if SDL_AUDIO_DRIVER_WINMM
   107     &WINMM_bootstrap,
   108 #endif
   109 #if SDL_AUDIO_DRIVER_PAUDIO
   110     &PAUDIO_bootstrap,
   111 #endif
   112 #if SDL_AUDIO_DRIVER_BEOSAUDIO
   113     &BEOSAUDIO_bootstrap,
   114 #endif
   115 #if SDL_AUDIO_DRIVER_COREAUDIO
   116     &COREAUDIO_bootstrap,
   117 #endif
   118 #if SDL_AUDIO_DRIVER_DISK
   119     &DISKAUD_bootstrap,
   120 #endif
   121 #if SDL_AUDIO_DRIVER_DUMMY
   122     &DUMMYAUD_bootstrap,
   123 #endif
   124 #if SDL_AUDIO_DRIVER_NDS
   125     &NDSAUD_bootstrap,
   126 #endif
   127 #if SDL_AUDIO_DRIVER_FUSIONSOUND
   128     &FUSIONSOUND_bootstrap,
   129 #endif
   130 #if SDL_AUDIO_DRIVER_ANDROID
   131     &ANDROIDAUD_bootstrap,
   132 #endif
   133     NULL
   134 };
   135 
   136 static SDL_AudioDevice *
   137 get_audio_device(SDL_AudioDeviceID id)
   138 {
   139     id--;
   140     if ((id >= SDL_arraysize(open_devices)) || (open_devices[id] == NULL)) {
   141         SDL_SetError("Invalid audio device ID");
   142         return NULL;
   143     }
   144 
   145     return open_devices[id];
   146 }
   147 
   148 
   149 /* stubs for audio drivers that don't need a specific entry point... */
   150 static void
   151 SDL_AudioDetectDevices_Default(int iscapture, SDL_AddAudioDevice addfn)
   152 {                               /* no-op. */
   153 }
   154 
   155 static void
   156 SDL_AudioThreadInit_Default(_THIS)
   157 {                               /* no-op. */
   158 }
   159 
   160 static void
   161 SDL_AudioWaitDevice_Default(_THIS)
   162 {                               /* no-op. */
   163 }
   164 
   165 static void
   166 SDL_AudioPlayDevice_Default(_THIS)
   167 {                               /* no-op. */
   168 }
   169 
   170 static Uint8 *
   171 SDL_AudioGetDeviceBuf_Default(_THIS)
   172 {
   173     return NULL;
   174 }
   175 
   176 static void
   177 SDL_AudioWaitDone_Default(_THIS)
   178 {                               /* no-op. */
   179 }
   180 
   181 static void
   182 SDL_AudioCloseDevice_Default(_THIS)
   183 {                               /* no-op. */
   184 }
   185 
   186 static void
   187 SDL_AudioDeinitialize_Default(void)
   188 {                               /* no-op. */
   189 }
   190 
   191 static int
   192 SDL_AudioOpenDevice_Default(_THIS, const char *devname, int iscapture)
   193 {
   194     return 0;
   195 }
   196 
   197 static void
   198 SDL_AudioLockDevice_Default(SDL_AudioDevice * device)
   199 {
   200     if (device->thread && (SDL_ThreadID() == device->threadid)) {
   201         return;
   202     }
   203     SDL_mutexP(device->mixer_lock);
   204 }
   205 
   206 static void
   207 SDL_AudioUnlockDevice_Default(SDL_AudioDevice * device)
   208 {
   209     if (device->thread && (SDL_ThreadID() == device->threadid)) {
   210         return;
   211     }
   212     SDL_mutexV(device->mixer_lock);
   213 }
   214 
   215 
   216 static void
   217 finalize_audio_entry_points(void)
   218 {
   219     /*
   220      * Fill in stub functions for unused driver entry points. This lets us
   221      *  blindly call them without having to check for validity first.
   222      */
   223 
   224 #define FILL_STUB(x) \
   225         if (current_audio.impl.x == NULL) { \
   226             current_audio.impl.x = SDL_Audio##x##_Default; \
   227         }
   228     FILL_STUB(DetectDevices);
   229     FILL_STUB(OpenDevice);
   230     FILL_STUB(ThreadInit);
   231     FILL_STUB(WaitDevice);
   232     FILL_STUB(PlayDevice);
   233     FILL_STUB(GetDeviceBuf);
   234     FILL_STUB(WaitDone);
   235     FILL_STUB(CloseDevice);
   236     FILL_STUB(LockDevice);
   237     FILL_STUB(UnlockDevice);
   238     FILL_STUB(Deinitialize);
   239 #undef FILL_STUB
   240 }
   241 
   242 /* Streaming functions (for when the input and output buffer sizes are different) */
   243 /* Write [length] bytes from buf into the streamer */
   244 static void
   245 SDL_StreamWrite(SDL_AudioStreamer * stream, Uint8 * buf, int length)
   246 {
   247     int i;
   248 
   249     for (i = 0; i < length; ++i) {
   250         stream->buffer[stream->write_pos] = buf[i];
   251         ++stream->write_pos;
   252     }
   253 }
   254 
   255 /* Read [length] bytes out of the streamer into buf */
   256 static void
   257 SDL_StreamRead(SDL_AudioStreamer * stream, Uint8 * buf, int length)
   258 {
   259     int i;
   260 
   261     for (i = 0; i < length; ++i) {
   262         buf[i] = stream->buffer[stream->read_pos];
   263         ++stream->read_pos;
   264     }
   265 }
   266 
   267 static int
   268 SDL_StreamLength(SDL_AudioStreamer * stream)
   269 {
   270     return (stream->write_pos - stream->read_pos) % stream->max_len;
   271 }
   272 
   273 /* Initialize the stream by allocating the buffer and setting the read/write heads to the beginning */
   274 #if 0
   275 static int
   276 SDL_StreamInit(SDL_AudioStreamer * stream, int max_len, Uint8 silence)
   277 {
   278     /* First try to allocate the buffer */
   279     stream->buffer = (Uint8 *) SDL_malloc(max_len);
   280     if (stream->buffer == NULL) {
   281         return -1;
   282     }
   283 
   284     stream->max_len = max_len;
   285     stream->read_pos = 0;
   286     stream->write_pos = 0;
   287 
   288     /* Zero out the buffer */
   289     SDL_memset(stream->buffer, silence, max_len);
   290 
   291     return 0;
   292 }
   293 #endif
   294 
   295 /* Deinitialize the stream simply by freeing the buffer */
   296 static void
   297 SDL_StreamDeinit(SDL_AudioStreamer * stream)
   298 {
   299     if (stream->buffer != NULL) {
   300         SDL_free(stream->buffer);
   301     }
   302 }
   303 
   304 #if defined(ANDROID)
   305 #include <android/log.h>
   306 #endif
   307 
   308 /* The general mixing thread function */
   309 int SDLCALL
   310 SDL_RunAudio(void *devicep)
   311 {
   312     SDL_AudioDevice *device = (SDL_AudioDevice *) devicep;
   313     Uint8 *stream;
   314     int stream_len;
   315     void *udata;
   316     void (SDLCALL * fill) (void *userdata, Uint8 * stream, int len);
   317     Uint32 delay;
   318     /* For streaming when the buffer sizes don't match up */
   319     Uint8 *istream;
   320     int istream_len = 0;
   321 
   322     /* The audio mixing is always a high priority thread */
   323     SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
   324 
   325     /* Perform any thread setup */
   326     device->threadid = SDL_ThreadID();
   327     current_audio.impl.ThreadInit(device);
   328 
   329     /* Set up the mixing function */
   330     fill = device->spec.callback;
   331     udata = device->spec.userdata;
   332 
   333     /* By default do not stream */
   334     device->use_streamer = 0;
   335 
   336     if (device->convert.needed) {
   337 #if 0                           /* !!! FIXME: I took len_div out of the structure. Use rate_incr instead? */
   338         /* If the result of the conversion alters the length, i.e. resampling is being used, use the streamer */
   339         if (device->convert.len_mult != 1 || device->convert.len_div != 1) {
   340             /* The streamer's maximum length should be twice whichever is larger: spec.size or len_cvt */
   341             stream_max_len = 2 * device->spec.size;
   342             if (device->convert.len_mult > device->convert.len_div) {
   343                 stream_max_len *= device->convert.len_mult;
   344                 stream_max_len /= device->convert.len_div;
   345             }
   346             if (SDL_StreamInit(&device->streamer, stream_max_len, silence) <
   347                 0)
   348                 return -1;
   349             device->use_streamer = 1;
   350 
   351             /* istream_len should be the length of what we grab from the callback and feed to conversion,
   352                so that we get close to spec_size. I.e. we want device.spec_size = istream_len * u / d
   353              */
   354             istream_len =
   355                 device->spec.size * device->convert.len_div /
   356                 device->convert.len_mult;
   357         }
   358 #endif
   359 
   360         /* stream_len = device->convert.len; */
   361         stream_len = device->spec.size;
   362     } else {
   363         stream_len = device->spec.size;
   364     }
   365 
   366     /* Calculate the delay while paused */
   367     delay = ((device->spec.samples * 1000) / device->spec.freq);
   368 
   369     /* Determine if the streamer is necessary here */
   370     if (device->use_streamer == 1) {
   371         /* This code is almost the same as the old code. The difference is, instead of reading
   372            directly from the callback into "stream", then converting and sending the audio off,
   373            we go: callback -> "istream" -> (conversion) -> streamer -> stream -> device.
   374            However, reading and writing with streamer are done separately:
   375            - We only call the callback and write to the streamer when the streamer does not
   376            contain enough samples to output to the device.
   377            - We only read from the streamer and tell the device to play when the streamer
   378            does have enough samples to output.
   379            This allows us to perform resampling in the conversion step, where the output of the
   380            resampling process can be any number. We will have to see what a good size for the
   381            stream's maximum length is, but I suspect 2*max(len_cvt, stream_len) is a good figure.
   382          */
   383         while (device->enabled) {
   384 
   385             if (device->paused) {
   386                 SDL_Delay(delay);
   387                 continue;
   388             }
   389 
   390             /* Only read in audio if the streamer doesn't have enough already (if it does not have enough samples to output) */
   391             if (SDL_StreamLength(&device->streamer) < stream_len) {
   392                 /* Set up istream */
   393                 if (device->convert.needed) {
   394                     if (device->convert.buf) {
   395                         istream = device->convert.buf;
   396                     } else {
   397                         continue;
   398                     }
   399                 } else {
   400 /* FIXME: Ryan, this is probably wrong.  I imagine we don't want to get
   401  * a device buffer both here and below in the stream output.
   402  */
   403                     istream = current_audio.impl.GetDeviceBuf(device);
   404                     if (istream == NULL) {
   405                         istream = device->fake_stream;
   406                     }
   407                 }
   408 
   409                 /* Read from the callback into the _input_ stream */
   410                 SDL_mutexP(device->mixer_lock);
   411                 (*fill) (udata, istream, istream_len);
   412                 SDL_mutexV(device->mixer_lock);
   413 
   414                 /* Convert the audio if necessary and write to the streamer */
   415                 if (device->convert.needed) {
   416                     SDL_ConvertAudio(&device->convert);
   417                     if (istream == NULL) {
   418                         istream = device->fake_stream;
   419                     }
   420                     /*SDL_memcpy(istream, device->convert.buf, device->convert.len_cvt); */
   421                     SDL_StreamWrite(&device->streamer, device->convert.buf,
   422                                     device->convert.len_cvt);
   423                 } else {
   424                     SDL_StreamWrite(&device->streamer, istream, istream_len);
   425                 }
   426             }
   427 
   428             /* Only output audio if the streamer has enough to output */
   429             if (SDL_StreamLength(&device->streamer) >= stream_len) {
   430                 /* Set up the output stream */
   431                 if (device->convert.needed) {
   432                     if (device->convert.buf) {
   433                         stream = device->convert.buf;
   434                     } else {
   435                         continue;
   436                     }
   437                 } else {
   438                     stream = current_audio.impl.GetDeviceBuf(device);
   439                     if (stream == NULL) {
   440                         stream = device->fake_stream;
   441                     }
   442                 }
   443 
   444                 /* Now read from the streamer */
   445                 SDL_StreamRead(&device->streamer, stream, stream_len);
   446 
   447                 /* Ready current buffer for play and change current buffer */
   448                 if (stream != device->fake_stream) {
   449                     current_audio.impl.PlayDevice(device);
   450                     /* Wait for an audio buffer to become available */
   451                     current_audio.impl.WaitDevice(device);
   452                 } else {
   453                     SDL_Delay(delay);
   454                 }
   455             }
   456 
   457         }
   458     } else {
   459         /* Otherwise, do not use the streamer. This is the old code. */
   460 
   461         /* Loop, filling the audio buffers */
   462         while (device->enabled) {
   463 
   464             if (device->paused) {
   465                 SDL_Delay(delay);
   466                 continue;
   467             }
   468 
   469             /* Fill the current buffer with sound */
   470             if (device->convert.needed) {
   471                 if (device->convert.buf) {
   472                     stream = device->convert.buf;
   473                 } else {
   474                     continue;
   475                 }
   476             } else {
   477                 stream = current_audio.impl.GetDeviceBuf(device);
   478                 if (stream == NULL) {
   479                     stream = device->fake_stream;
   480                 }
   481             }
   482 
   483             SDL_mutexP(device->mixer_lock);
   484             (*fill) (udata, stream, stream_len);
   485             SDL_mutexV(device->mixer_lock);
   486 
   487             /* Convert the audio if necessary */
   488             if (device->convert.needed) {
   489                 SDL_ConvertAudio(&device->convert);
   490                 stream = current_audio.impl.GetDeviceBuf(device);
   491                 if (stream == NULL) {
   492                     stream = device->fake_stream;
   493                 }
   494                 SDL_memcpy(stream, device->convert.buf,
   495                            device->convert.len_cvt);
   496             }
   497 
   498             /* Ready current buffer for play and change current buffer */
   499             if (stream != device->fake_stream) {
   500                 current_audio.impl.PlayDevice(device);
   501                 /* Wait for an audio buffer to become available */
   502                 current_audio.impl.WaitDevice(device);
   503             } else {
   504                 SDL_Delay(delay);
   505             }
   506         }
   507     }
   508 
   509     /* Wait for the audio to drain.. */
   510     current_audio.impl.WaitDone(device);
   511 
   512     /* If necessary, deinit the streamer */
   513     if (device->use_streamer == 1)
   514         SDL_StreamDeinit(&device->streamer);
   515 
   516     return (0);
   517 }
   518 
   519 
   520 static SDL_AudioFormat
   521 SDL_ParseAudioFormat(const char *string)
   522 {
   523 #define CHECK_FMT_STRING(x) if (SDL_strcmp(string, #x) == 0) return AUDIO_##x
   524     CHECK_FMT_STRING(U8);
   525     CHECK_FMT_STRING(S8);
   526     CHECK_FMT_STRING(U16LSB);
   527     CHECK_FMT_STRING(S16LSB);
   528     CHECK_FMT_STRING(U16MSB);
   529     CHECK_FMT_STRING(S16MSB);
   530     CHECK_FMT_STRING(U16SYS);
   531     CHECK_FMT_STRING(S16SYS);
   532     CHECK_FMT_STRING(U16);
   533     CHECK_FMT_STRING(S16);
   534     CHECK_FMT_STRING(S32LSB);
   535     CHECK_FMT_STRING(S32MSB);
   536     CHECK_FMT_STRING(S32SYS);
   537     CHECK_FMT_STRING(S32);
   538     CHECK_FMT_STRING(F32LSB);
   539     CHECK_FMT_STRING(F32MSB);
   540     CHECK_FMT_STRING(F32SYS);
   541     CHECK_FMT_STRING(F32);
   542 #undef CHECK_FMT_STRING
   543     return 0;
   544 }
   545 
   546 int
   547 SDL_GetNumAudioDrivers(void)
   548 {
   549     return (SDL_arraysize(bootstrap) - 1);
   550 }
   551 
   552 const char *
   553 SDL_GetAudioDriver(int index)
   554 {
   555     if (index >= 0 && index < SDL_GetNumAudioDrivers()) {
   556         return (bootstrap[index]->name);
   557     }
   558     return (NULL);
   559 }
   560 
   561 int
   562 SDL_AudioInit(const char *driver_name)
   563 {
   564     int i = 0;
   565     int initialized = 0;
   566     int tried_to_init = 0;
   567 
   568     if (SDL_WasInit(SDL_INIT_AUDIO)) {
   569         SDL_AudioQuit();        /* shutdown driver if already running. */
   570     }
   571 
   572     SDL_memset(&current_audio, '\0', sizeof(current_audio));
   573     SDL_memset(open_devices, '\0', sizeof(open_devices));
   574 
   575     /* Select the proper audio driver */
   576     if (driver_name == NULL) {
   577         driver_name = SDL_getenv("SDL_AUDIODRIVER");
   578     }
   579 
   580     for (i = 0; (!initialized) && (bootstrap[i]); ++i) {
   581         /* make sure we should even try this driver before doing so... */
   582         const AudioBootStrap *backend = bootstrap[i];
   583         if (((driver_name) && (SDL_strcasecmp(backend->name, driver_name))) ||
   584             ((!driver_name) && (backend->demand_only))) {
   585             continue;
   586         }
   587 
   588         tried_to_init = 1;
   589         SDL_memset(&current_audio, 0, sizeof(current_audio));
   590         current_audio.name = backend->name;
   591         current_audio.desc = backend->desc;
   592         initialized = backend->init(&current_audio.impl);
   593     }
   594 
   595     if (!initialized) {
   596         /* specific drivers will set the error message if they fail... */
   597         if (!tried_to_init) {
   598             if (driver_name) {
   599                 SDL_SetError("Audio target '%s' not available", driver_name);
   600             } else {
   601                 SDL_SetError("No available audio device");
   602             }
   603         }
   604 
   605         SDL_memset(&current_audio, 0, sizeof(current_audio));
   606         return (-1);            /* No driver was available, so fail. */
   607     }
   608 
   609     finalize_audio_entry_points();
   610 
   611     return (0);
   612 }
   613 
   614 /*
   615  * Get the current audio driver name
   616  */
   617 const char *
   618 SDL_GetCurrentAudioDriver()
   619 {
   620     return current_audio.name;
   621 }
   622 
   623 static void
   624 free_device_list(char ***devices, int *devCount)
   625 {
   626     int i = *devCount;
   627     if ((i > 0) && (*devices != NULL)) {
   628         while (i--) {
   629             SDL_free((*devices)[i]);
   630         }
   631     }
   632 
   633     if (*devices != NULL) {
   634         SDL_free(*devices);
   635     }
   636 
   637     *devices = NULL;
   638     *devCount = 0;
   639 }
   640 
   641 static
   642 void SDL_AddCaptureAudioDevice(const char *_name)
   643 {
   644     char *name = NULL;
   645     void *ptr = SDL_realloc(current_audio.inputDevices,
   646                           (current_audio.inputDeviceCount+1) * sizeof(char*));
   647     if (ptr == NULL) {
   648         return;  /* oh well. */
   649     }
   650 
   651     current_audio.inputDevices = (char **) ptr;
   652     name = SDL_strdup(_name);  /* if this returns NULL, that's okay. */
   653     current_audio.inputDevices[current_audio.inputDeviceCount++] = name;
   654 }
   655 
   656 static
   657 void SDL_AddOutputAudioDevice(const char *_name)
   658 {
   659     char *name = NULL;
   660     void *ptr = SDL_realloc(current_audio.outputDevices,
   661                           (current_audio.outputDeviceCount+1) * sizeof(char*));
   662     if (ptr == NULL) {
   663         return;  /* oh well. */
   664     }
   665 
   666     current_audio.outputDevices = (char **) ptr;
   667     name = SDL_strdup(_name);  /* if this returns NULL, that's okay. */
   668     current_audio.outputDevices[current_audio.outputDeviceCount++] = name;
   669 }
   670 
   671 
   672 int
   673 SDL_GetNumAudioDevices(int iscapture)
   674 {
   675     int retval = 0;
   676 
   677     if (!SDL_WasInit(SDL_INIT_AUDIO)) {
   678         return -1;
   679     }
   680 
   681     if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
   682         return 0;
   683     }
   684 
   685     if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
   686         return 1;
   687     }
   688 
   689     if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
   690         return 1;
   691     }
   692 
   693     if (iscapture) {
   694         free_device_list(&current_audio.inputDevices,
   695                          &current_audio.inputDeviceCount);
   696         current_audio.impl.DetectDevices(iscapture, SDL_AddCaptureAudioDevice);
   697         retval = current_audio.inputDeviceCount;
   698     } else {
   699         free_device_list(&current_audio.outputDevices,
   700                          &current_audio.outputDeviceCount);
   701         current_audio.impl.DetectDevices(iscapture, SDL_AddOutputAudioDevice);
   702         retval = current_audio.outputDeviceCount;
   703     }
   704 
   705     return retval;
   706 }
   707 
   708 
   709 const char *
   710 SDL_GetAudioDeviceName(int index, int iscapture)
   711 {
   712     if (!SDL_WasInit(SDL_INIT_AUDIO)) {
   713         SDL_SetError("Audio subsystem is not initialized");
   714         return NULL;
   715     }
   716 
   717     if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
   718         SDL_SetError("No capture support");
   719         return NULL;
   720     }
   721 
   722     if (index < 0) {
   723         goto no_such_device;
   724     }
   725 
   726     if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
   727         return DEFAULT_INPUT_DEVNAME;
   728     }
   729 
   730     if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
   731         return DEFAULT_OUTPUT_DEVNAME;
   732     }
   733 
   734     if (iscapture) {
   735         if (index >= current_audio.inputDeviceCount) {
   736             goto no_such_device;
   737         }
   738         return current_audio.inputDevices[index];
   739     } else {
   740         if (index >= current_audio.outputDeviceCount) {
   741             goto no_such_device;
   742         }
   743         return current_audio.outputDevices[index];
   744     }
   745 
   746 no_such_device:
   747     SDL_SetError("No such device");
   748     return NULL;
   749 }
   750 
   751 
   752 static void
   753 close_audio_device(SDL_AudioDevice * device)
   754 {
   755     device->enabled = 0;
   756     if (device->thread != NULL) {
   757         SDL_WaitThread(device->thread, NULL);
   758     }
   759     if (device->mixer_lock != NULL) {
   760         SDL_DestroyMutex(device->mixer_lock);
   761     }
   762     if (device->fake_stream != NULL) {
   763         SDL_FreeAudioMem(device->fake_stream);
   764     }
   765     if (device->convert.needed) {
   766         SDL_FreeAudioMem(device->convert.buf);
   767     }
   768     if (device->opened) {
   769         current_audio.impl.CloseDevice(device);
   770         device->opened = 0;
   771     }
   772     SDL_FreeAudioMem(device);
   773 }
   774 
   775 
   776 /*
   777  * Sanity check desired AudioSpec for SDL_OpenAudio() in (orig).
   778  *  Fills in a sanitized copy in (prepared).
   779  *  Returns non-zero if okay, zero on fatal parameters in (orig).
   780  */
   781 static int
   782 prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared)
   783 {
   784     SDL_memcpy(prepared, orig, sizeof(SDL_AudioSpec));
   785 
   786     if (orig->callback == NULL) {
   787         SDL_SetError("SDL_OpenAudio() passed a NULL callback");
   788         return 0;
   789     }
   790 
   791     if (orig->freq == 0) {
   792         const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY");
   793         if ((!env) || ((prepared->freq = SDL_atoi(env)) == 0)) {
   794             prepared->freq = 22050;     /* a reasonable default */
   795         }
   796     }
   797 
   798     if (orig->format == 0) {
   799         const char *env = SDL_getenv("SDL_AUDIO_FORMAT");
   800         if ((!env) || ((prepared->format = SDL_ParseAudioFormat(env)) == 0)) {
   801             prepared->format = AUDIO_S16;       /* a reasonable default */
   802         }
   803     }
   804 
   805     switch (orig->channels) {
   806     case 0:{
   807             const char *env = SDL_getenv("SDL_AUDIO_CHANNELS");
   808             if ((!env) || ((prepared->channels = (Uint8) SDL_atoi(env)) == 0)) {
   809                 prepared->channels = 2; /* a reasonable default */
   810             }
   811             break;
   812         }
   813     case 1:                    /* Mono */
   814     case 2:                    /* Stereo */
   815     case 4:                    /* surround */
   816     case 6:                    /* surround with center and lfe */
   817         break;
   818     default:
   819         SDL_SetError("Unsupported number of audio channels.");
   820         return 0;
   821     }
   822 
   823     if (orig->samples == 0) {
   824         const char *env = SDL_getenv("SDL_AUDIO_SAMPLES");
   825         if ((!env) || ((prepared->samples = (Uint16) SDL_atoi(env)) == 0)) {
   826             /* Pick a default of ~46 ms at desired frequency */
   827             /* !!! FIXME: remove this when the non-Po2 resampling is in. */
   828             const int samples = (prepared->freq / 1000) * 46;
   829             int power2 = 1;
   830             while (power2 < samples) {
   831                 power2 *= 2;
   832             }
   833             prepared->samples = power2;
   834         }
   835     }
   836 
   837     /* Calculate the silence and size of the audio specification */
   838     SDL_CalculateAudioSpec(prepared);
   839 
   840     return 1;
   841 }
   842 
   843 
   844 static SDL_AudioDeviceID
   845 open_audio_device(const char *devname, int iscapture,
   846                   const SDL_AudioSpec * desired, SDL_AudioSpec * obtained,
   847                   int allowed_changes, int min_id)
   848 {
   849     SDL_AudioDeviceID id = 0;
   850     SDL_AudioSpec _obtained;
   851     SDL_AudioDevice *device;
   852     SDL_bool build_cvt;
   853     int i = 0;
   854 
   855     if (!SDL_WasInit(SDL_INIT_AUDIO)) {
   856         SDL_SetError("Audio subsystem is not initialized");
   857         return 0;
   858     }
   859 
   860     if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
   861         SDL_SetError("No capture support");
   862         return 0;
   863     }
   864 
   865     if (!obtained) {
   866         obtained = &_obtained;
   867     }
   868     if (!prepare_audiospec(desired, obtained)) {
   869         return 0;
   870     }
   871 
   872     /* If app doesn't care about a specific device, let the user override. */
   873     if (devname == NULL) {
   874         devname = SDL_getenv("SDL_AUDIO_DEVICE_NAME");
   875     }
   876 
   877     /*
   878      * Catch device names at the high level for the simple case...
   879      * This lets us have a basic "device enumeration" for systems that
   880      *  don't have multiple devices, but makes sure the device name is
   881      *  always NULL when it hits the low level.
   882      *
   883      * Also make sure that the simple case prevents multiple simultaneous
   884      *  opens of the default system device.
   885      */
   886 
   887     if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
   888         if ((devname) && (SDL_strcmp(devname, DEFAULT_INPUT_DEVNAME) != 0)) {
   889             SDL_SetError("No such device");
   890             return 0;
   891         }
   892         devname = NULL;
   893 
   894         for (i = 0; i < SDL_arraysize(open_devices); i++) {
   895             if ((open_devices[i]) && (open_devices[i]->iscapture)) {
   896                 SDL_SetError("Audio device already open");
   897                 return 0;
   898             }
   899         }
   900     }
   901 
   902     if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
   903         if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) {
   904             SDL_SetError("No such device");
   905             return 0;
   906         }
   907         devname = NULL;
   908 
   909         for (i = 0; i < SDL_arraysize(open_devices); i++) {
   910             if ((open_devices[i]) && (!open_devices[i]->iscapture)) {
   911                 SDL_SetError("Audio device already open");
   912                 return 0;
   913             }
   914         }
   915     }
   916 
   917     device = (SDL_AudioDevice *) SDL_AllocAudioMem(sizeof(SDL_AudioDevice));
   918     if (device == NULL) {
   919         SDL_OutOfMemory();
   920         return 0;
   921     }
   922     SDL_memset(device, '\0', sizeof(SDL_AudioDevice));
   923     device->spec = *obtained;
   924     device->enabled = 1;
   925     device->paused = 1;
   926     device->iscapture = iscapture;
   927 
   928     /* Create a semaphore for locking the sound buffers */
   929     if (!current_audio.impl.SkipMixerLock) {
   930         device->mixer_lock = SDL_CreateMutex();
   931         if (device->mixer_lock == NULL) {
   932             close_audio_device(device);
   933             SDL_SetError("Couldn't create mixer lock");
   934             return 0;
   935         }
   936     }
   937 
   938     /* force a device detection if we haven't done one yet. */
   939     if ( ((iscapture) && (current_audio.inputDevices == NULL)) ||
   940          ((!iscapture) && (current_audio.outputDevices == NULL)) )
   941         SDL_GetNumAudioDevices(iscapture);
   942 
   943     if (!current_audio.impl.OpenDevice(device, devname, iscapture)) {
   944         close_audio_device(device);
   945         return 0;
   946     }
   947     device->opened = 1;
   948 
   949     /* Allocate a fake audio memory buffer */
   950     device->fake_stream = (Uint8 *)SDL_AllocAudioMem(device->spec.size);
   951     if (device->fake_stream == NULL) {
   952         close_audio_device(device);
   953         SDL_OutOfMemory();
   954         return 0;
   955     }
   956 
   957     /* If the audio driver changes the buffer size, accept it */
   958     if (device->spec.samples != obtained->samples) {
   959         obtained->samples = device->spec.samples;
   960         SDL_CalculateAudioSpec(obtained);
   961     }
   962 
   963     /* See if we need to do any conversion */
   964     build_cvt = SDL_FALSE;
   965     if (obtained->freq != device->spec.freq) {
   966         if (allowed_changes & SDL_AUDIO_ALLOW_FREQUENCY_CHANGE) {
   967             obtained->freq = device->spec.freq;
   968         } else {
   969             build_cvt = SDL_TRUE;
   970         }
   971     }
   972     if (obtained->format != device->spec.format) {
   973         if (allowed_changes & SDL_AUDIO_ALLOW_FORMAT_CHANGE) {
   974             obtained->format = device->spec.format;
   975         } else {
   976             build_cvt = SDL_TRUE;
   977         }
   978     }
   979     if (obtained->channels != device->spec.channels) {
   980         if (allowed_changes & SDL_AUDIO_ALLOW_CHANNELS_CHANGE) {
   981             obtained->channels = device->spec.channels;
   982         } else {
   983             build_cvt = SDL_TRUE;
   984         }
   985     }
   986     if (build_cvt) {
   987         /* Build an audio conversion block */
   988         if (SDL_BuildAudioCVT(&device->convert,
   989                               obtained->format, obtained->channels,
   990                               obtained->freq,
   991                               device->spec.format, device->spec.channels,
   992                               device->spec.freq) < 0) {
   993             close_audio_device(device);
   994             return 0;
   995         }
   996         if (device->convert.needed) {
   997             device->convert.len = (int) (((double) obtained->size) /
   998                                          device->convert.len_ratio);
   999 
  1000             device->convert.buf =
  1001                 (Uint8 *) SDL_AllocAudioMem(device->convert.len *
  1002                                             device->convert.len_mult);
  1003             if (device->convert.buf == NULL) {
  1004                 close_audio_device(device);
  1005                 SDL_OutOfMemory();
  1006                 return 0;
  1007             }
  1008         }
  1009     }
  1010 
  1011     /* Find an available device ID and store the structure... */
  1012     for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
  1013         if (open_devices[id] == NULL) {
  1014             open_devices[id] = device;
  1015             break;
  1016         }
  1017     }
  1018 
  1019     if (id == SDL_arraysize(open_devices)) {
  1020         SDL_SetError("Too many open audio devices");
  1021         close_audio_device(device);
  1022         return 0;
  1023     }
  1024 
  1025     /* Start the audio thread if necessary */
  1026     if (!current_audio.impl.ProvidesOwnCallbackThread) {
  1027         /* Start the audio thread */
  1028         char name[64];
  1029         SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) (id + 1));
  1030 /* !!! FIXME: this is nasty. */
  1031 #if defined(__WIN32__) && !defined(HAVE_LIBC)
  1032 #undef SDL_CreateThread
  1033         device->thread = SDL_CreateThread(SDL_RunAudio, name, device, NULL, NULL);
  1034 #else
  1035         device->thread = SDL_CreateThread(SDL_RunAudio, name, device);
  1036 #endif
  1037         if (device->thread == NULL) {
  1038             SDL_CloseAudioDevice(id + 1);
  1039             SDL_SetError("Couldn't create audio thread");
  1040             return 0;
  1041         }
  1042     }
  1043 
  1044     return id + 1;
  1045 }
  1046 
  1047 
  1048 int
  1049 SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
  1050 {
  1051     SDL_AudioDeviceID id = 0;
  1052 
  1053     /* Start up the audio driver, if necessary. This is legacy behaviour! */
  1054     if (!SDL_WasInit(SDL_INIT_AUDIO)) {
  1055         if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
  1056             return (-1);
  1057         }
  1058     }
  1059 
  1060     /* SDL_OpenAudio() is legacy and can only act on Device ID #1. */
  1061     if (open_devices[0] != NULL) {
  1062         SDL_SetError("Audio device is already opened");
  1063         return (-1);
  1064     }
  1065 
  1066     if (obtained) {
  1067         id = open_audio_device(NULL, 0, desired, obtained,
  1068                                SDL_AUDIO_ALLOW_ANY_CHANGE, 1);
  1069     } else {
  1070         id = open_audio_device(NULL, 0, desired, desired, 0, 1);
  1071     }
  1072 
  1073     SDL_assert((id == 0) || (id == 1));
  1074     return ((id == 0) ? -1 : 0);
  1075 }
  1076 
  1077 SDL_AudioDeviceID
  1078 SDL_OpenAudioDevice(const char *device, int iscapture,
  1079                     const SDL_AudioSpec * desired, SDL_AudioSpec * obtained,
  1080                     int allowed_changes)
  1081 {
  1082     return open_audio_device(device, iscapture, desired, obtained,
  1083                              allowed_changes, 2);
  1084 }
  1085 
  1086 SDL_AudioStatus
  1087 SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid)
  1088 {
  1089     SDL_AudioDevice *device = get_audio_device(devid);
  1090     SDL_AudioStatus status = SDL_AUDIO_STOPPED;
  1091     if (device && device->enabled) {
  1092         if (device->paused) {
  1093             status = SDL_AUDIO_PAUSED;
  1094         } else {
  1095             status = SDL_AUDIO_PLAYING;
  1096         }
  1097     }
  1098     return (status);
  1099 }
  1100 
  1101 
  1102 SDL_AudioStatus
  1103 SDL_GetAudioStatus(void)
  1104 {
  1105     return SDL_GetAudioDeviceStatus(1);
  1106 }
  1107 
  1108 void
  1109 SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on)
  1110 {
  1111     SDL_AudioDevice *device = get_audio_device(devid);
  1112     if (device) {
  1113         device->paused = pause_on;
  1114     }
  1115 }
  1116 
  1117 void
  1118 SDL_PauseAudio(int pause_on)
  1119 {
  1120     SDL_PauseAudioDevice(1, pause_on);
  1121 }
  1122 
  1123 
  1124 void
  1125 SDL_LockAudioDevice(SDL_AudioDeviceID devid)
  1126 {
  1127     /* Obtain a lock on the mixing buffers */
  1128     SDL_AudioDevice *device = get_audio_device(devid);
  1129     if (device) {
  1130         current_audio.impl.LockDevice(device);
  1131     }
  1132 }
  1133 
  1134 void
  1135 SDL_LockAudio(void)
  1136 {
  1137     SDL_LockAudioDevice(1);
  1138 }
  1139 
  1140 void
  1141 SDL_UnlockAudioDevice(SDL_AudioDeviceID devid)
  1142 {
  1143     /* Obtain a lock on the mixing buffers */
  1144     SDL_AudioDevice *device = get_audio_device(devid);
  1145     if (device) {
  1146         current_audio.impl.UnlockDevice(device);
  1147     }
  1148 }
  1149 
  1150 void
  1151 SDL_UnlockAudio(void)
  1152 {
  1153     SDL_UnlockAudioDevice(1);
  1154 }
  1155 
  1156 void
  1157 SDL_CloseAudioDevice(SDL_AudioDeviceID devid)
  1158 {
  1159     SDL_AudioDevice *device = get_audio_device(devid);
  1160     if (device) {
  1161         close_audio_device(device);
  1162         open_devices[devid - 1] = NULL;
  1163     }
  1164 }
  1165 
  1166 void
  1167 SDL_CloseAudio(void)
  1168 {
  1169     SDL_CloseAudioDevice(1);
  1170 }
  1171 
  1172 void
  1173 SDL_AudioQuit(void)
  1174 {
  1175     SDL_AudioDeviceID i;
  1176     for (i = 0; i < SDL_arraysize(open_devices); i++) {
  1177         SDL_CloseAudioDevice(i);
  1178     }
  1179 
  1180     /* Free the driver data */
  1181     current_audio.impl.Deinitialize();
  1182     free_device_list(&current_audio.outputDevices,
  1183                      &current_audio.outputDeviceCount);
  1184     free_device_list(&current_audio.inputDevices,
  1185                      &current_audio.inputDeviceCount);
  1186     SDL_memset(&current_audio, '\0', sizeof(current_audio));
  1187     SDL_memset(open_devices, '\0', sizeof(open_devices));
  1188 }
  1189 
  1190 #define NUM_FORMATS 10
  1191 static int format_idx;
  1192 static int format_idx_sub;
  1193 static SDL_AudioFormat format_list[NUM_FORMATS][NUM_FORMATS] = {
  1194     {AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB,
  1195      AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB},
  1196     {AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB,
  1197      AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB},
  1198     {AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S32LSB,
  1199      AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8},
  1200     {AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S32MSB,
  1201      AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8},
  1202     {AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S32LSB,
  1203      AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8},
  1204     {AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_S32MSB,
  1205      AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8},
  1206     {AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S16LSB,
  1207      AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8},
  1208     {AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S16MSB,
  1209      AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8},
  1210     {AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S16LSB,
  1211      AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8},
  1212     {AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_S16MSB,
  1213      AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8},
  1214 };
  1215 
  1216 SDL_AudioFormat
  1217 SDL_FirstAudioFormat(SDL_AudioFormat format)
  1218 {
  1219     for (format_idx = 0; format_idx < NUM_FORMATS; ++format_idx) {
  1220         if (format_list[format_idx][0] == format) {
  1221             break;
  1222         }
  1223     }
  1224     format_idx_sub = 0;
  1225     return (SDL_NextAudioFormat());
  1226 }
  1227 
  1228 SDL_AudioFormat
  1229 SDL_NextAudioFormat(void)
  1230 {
  1231     if ((format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS)) {
  1232         return (0);
  1233     }
  1234     return (format_list[format_idx][format_idx_sub++]);
  1235 }
  1236 
  1237 void
  1238 SDL_CalculateAudioSpec(SDL_AudioSpec * spec)
  1239 {
  1240     switch (spec->format) {
  1241     case AUDIO_U8:
  1242         spec->silence = 0x80;
  1243         break;
  1244     default:
  1245         spec->silence = 0x00;
  1246         break;
  1247     }
  1248     spec->size = SDL_AUDIO_BITSIZE(spec->format) / 8;
  1249     spec->size *= spec->channels;
  1250     spec->size *= spec->samples;
  1251 }
  1252 
  1253 
  1254 /*
  1255  * Moved here from SDL_mixer.c, since it relies on internals of an opened
  1256  *  audio device (and is deprecated, by the way!).
  1257  */
  1258 void
  1259 SDL_MixAudio(Uint8 * dst, const Uint8 * src, Uint32 len, int volume)
  1260 {
  1261     /* Mix the user-level audio format */
  1262     SDL_AudioDevice *device = get_audio_device(1);
  1263     if (device != NULL) {
  1264         SDL_AudioFormat format;
  1265         if (device->convert.needed) {
  1266             format = device->convert.src_format;
  1267         } else {
  1268             format = device->spec.format;
  1269         }
  1270         SDL_MixAudioFormat(dst, src, format, len, volume);
  1271     }
  1272 }
  1273 
  1274 /* vi: set ts=4 sw=4 expandtab: */