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