src/audio/SDL_audio.c
author Ryan C. Gordon
Wed, 20 Feb 2013 13:25:38 -0500
changeset 6904 9fea506e48ab
parent 6900 767690d1c013
child 6905 4882bcc19578
permissions -rw-r--r--
Allow SDL_AUDIODRIVER="pulse" to do the right thing.

(We renamed this audio target at some point; the Internet didn't get the memo.)
     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 
    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     /* Older versions of SDL had a different name for the PulseAudio target. */
   581     if (driver_name && (SDL_strcmp(driver_name, "pulse") == 0)) {
   582         driver_name = "pulseaudio";
   583     }
   584 
   585     for (i = 0; (!initialized) && (bootstrap[i]); ++i) {
   586         /* make sure we should even try this driver before doing so... */
   587         const AudioBootStrap *backend = bootstrap[i];
   588         if ((driver_name && (SDL_strncasecmp(backend->name, driver_name, SDL_strlen(driver_name)) != 0)) ||
   589             (!driver_name && backend->demand_only)) {
   590             continue;
   591         }
   592 
   593         tried_to_init = 1;
   594         SDL_memset(&current_audio, 0, sizeof(current_audio));
   595         current_audio.name = backend->name;
   596         current_audio.desc = backend->desc;
   597         initialized = backend->init(&current_audio.impl);
   598     }
   599 
   600     if (!initialized) {
   601         /* specific drivers will set the error message if they fail... */
   602         if (!tried_to_init) {
   603             if (driver_name) {
   604                 SDL_SetError("Audio target '%s' not available", driver_name);
   605             } else {
   606                 SDL_SetError("No available audio device");
   607             }
   608         }
   609 
   610         SDL_memset(&current_audio, 0, sizeof(current_audio));
   611         return (-1);            /* No driver was available, so fail. */
   612     }
   613 
   614     finalize_audio_entry_points();
   615 
   616     return (0);
   617 }
   618 
   619 /*
   620  * Get the current audio driver name
   621  */
   622 const char *
   623 SDL_GetCurrentAudioDriver()
   624 {
   625     return current_audio.name;
   626 }
   627 
   628 static void
   629 free_device_list(char ***devices, int *devCount)
   630 {
   631     int i = *devCount;
   632     if ((i > 0) && (*devices != NULL)) {
   633         while (i--) {
   634             SDL_free((*devices)[i]);
   635         }
   636     }
   637 
   638     if (*devices != NULL) {
   639         SDL_free(*devices);
   640     }
   641 
   642     *devices = NULL;
   643     *devCount = 0;
   644 }
   645 
   646 static
   647 void SDL_AddCaptureAudioDevice(const char *_name)
   648 {
   649     char *name = NULL;
   650     void *ptr = SDL_realloc(current_audio.inputDevices,
   651                           (current_audio.inputDeviceCount+1) * sizeof(char*));
   652     if (ptr == NULL) {
   653         return;  /* oh well. */
   654     }
   655 
   656     current_audio.inputDevices = (char **) ptr;
   657     name = SDL_strdup(_name);  /* if this returns NULL, that's okay. */
   658     current_audio.inputDevices[current_audio.inputDeviceCount++] = name;
   659 }
   660 
   661 static
   662 void SDL_AddOutputAudioDevice(const char *_name)
   663 {
   664     char *name = NULL;
   665     void *ptr = SDL_realloc(current_audio.outputDevices,
   666                           (current_audio.outputDeviceCount+1) * sizeof(char*));
   667     if (ptr == NULL) {
   668         return;  /* oh well. */
   669     }
   670 
   671     current_audio.outputDevices = (char **) ptr;
   672     name = SDL_strdup(_name);  /* if this returns NULL, that's okay. */
   673     current_audio.outputDevices[current_audio.outputDeviceCount++] = name;
   674 }
   675 
   676 
   677 int
   678 SDL_GetNumAudioDevices(int iscapture)
   679 {
   680     int retval = 0;
   681 
   682     if (!SDL_WasInit(SDL_INIT_AUDIO)) {
   683         return -1;
   684     }
   685 
   686     if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
   687         return 0;
   688     }
   689 
   690     if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
   691         return 1;
   692     }
   693 
   694     if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
   695         return 1;
   696     }
   697 
   698     if (iscapture) {
   699         free_device_list(&current_audio.inputDevices,
   700                          &current_audio.inputDeviceCount);
   701         current_audio.impl.DetectDevices(iscapture, SDL_AddCaptureAudioDevice);
   702         retval = current_audio.inputDeviceCount;
   703     } else {
   704         free_device_list(&current_audio.outputDevices,
   705                          &current_audio.outputDeviceCount);
   706         current_audio.impl.DetectDevices(iscapture, SDL_AddOutputAudioDevice);
   707         retval = current_audio.outputDeviceCount;
   708     }
   709 
   710     return retval;
   711 }
   712 
   713 
   714 const char *
   715 SDL_GetAudioDeviceName(int index, int iscapture)
   716 {
   717     if (!SDL_WasInit(SDL_INIT_AUDIO)) {
   718         SDL_SetError("Audio subsystem is not initialized");
   719         return NULL;
   720     }
   721 
   722     if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
   723         SDL_SetError("No capture support");
   724         return NULL;
   725     }
   726 
   727     if (index < 0) {
   728         goto no_such_device;
   729     }
   730 
   731     if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
   732         return DEFAULT_INPUT_DEVNAME;
   733     }
   734 
   735     if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
   736         return DEFAULT_OUTPUT_DEVNAME;
   737     }
   738 
   739     if (iscapture) {
   740         if (index >= current_audio.inputDeviceCount) {
   741             goto no_such_device;
   742         }
   743         return current_audio.inputDevices[index];
   744     } else {
   745         if (index >= current_audio.outputDeviceCount) {
   746             goto no_such_device;
   747         }
   748         return current_audio.outputDevices[index];
   749     }
   750 
   751 no_such_device:
   752     SDL_SetError("No such device");
   753     return NULL;
   754 }
   755 
   756 
   757 static void
   758 close_audio_device(SDL_AudioDevice * device)
   759 {
   760     device->enabled = 0;
   761     if (device->thread != NULL) {
   762         SDL_WaitThread(device->thread, NULL);
   763     }
   764     if (device->mixer_lock != NULL) {
   765         SDL_DestroyMutex(device->mixer_lock);
   766     }
   767     if (device->fake_stream != NULL) {
   768         SDL_FreeAudioMem(device->fake_stream);
   769     }
   770     if (device->convert.needed) {
   771         SDL_FreeAudioMem(device->convert.buf);
   772     }
   773     if (device->opened) {
   774         current_audio.impl.CloseDevice(device);
   775         device->opened = 0;
   776     }
   777     SDL_FreeAudioMem(device);
   778 }
   779 
   780 
   781 /*
   782  * Sanity check desired AudioSpec for SDL_OpenAudio() in (orig).
   783  *  Fills in a sanitized copy in (prepared).
   784  *  Returns non-zero if okay, zero on fatal parameters in (orig).
   785  */
   786 static int
   787 prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared)
   788 {
   789     SDL_memcpy(prepared, orig, sizeof(SDL_AudioSpec));
   790 
   791     if (orig->callback == NULL) {
   792         SDL_SetError("SDL_OpenAudio() passed a NULL callback");
   793         return 0;
   794     }
   795 
   796     if (orig->freq == 0) {
   797         const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY");
   798         if ((!env) || ((prepared->freq = SDL_atoi(env)) == 0)) {
   799             prepared->freq = 22050;     /* a reasonable default */
   800         }
   801     }
   802 
   803     if (orig->format == 0) {
   804         const char *env = SDL_getenv("SDL_AUDIO_FORMAT");
   805         if ((!env) || ((prepared->format = SDL_ParseAudioFormat(env)) == 0)) {
   806             prepared->format = AUDIO_S16;       /* a reasonable default */
   807         }
   808     }
   809 
   810     switch (orig->channels) {
   811     case 0:{
   812             const char *env = SDL_getenv("SDL_AUDIO_CHANNELS");
   813             if ((!env) || ((prepared->channels = (Uint8) SDL_atoi(env)) == 0)) {
   814                 prepared->channels = 2; /* a reasonable default */
   815             }
   816             break;
   817         }
   818     case 1:                    /* Mono */
   819     case 2:                    /* Stereo */
   820     case 4:                    /* surround */
   821     case 6:                    /* surround with center and lfe */
   822         break;
   823     default:
   824         SDL_SetError("Unsupported number of audio channels.");
   825         return 0;
   826     }
   827 
   828     if (orig->samples == 0) {
   829         const char *env = SDL_getenv("SDL_AUDIO_SAMPLES");
   830         if ((!env) || ((prepared->samples = (Uint16) SDL_atoi(env)) == 0)) {
   831             /* Pick a default of ~46 ms at desired frequency */
   832             /* !!! FIXME: remove this when the non-Po2 resampling is in. */
   833             const int samples = (prepared->freq / 1000) * 46;
   834             int power2 = 1;
   835             while (power2 < samples) {
   836                 power2 *= 2;
   837             }
   838             prepared->samples = power2;
   839         }
   840     }
   841 
   842     /* Calculate the silence and size of the audio specification */
   843     SDL_CalculateAudioSpec(prepared);
   844 
   845     return 1;
   846 }
   847 
   848 
   849 static SDL_AudioDeviceID
   850 open_audio_device(const char *devname, int iscapture,
   851                   const SDL_AudioSpec * desired, SDL_AudioSpec * obtained,
   852                   int allowed_changes, int min_id)
   853 {
   854     SDL_AudioDeviceID id = 0;
   855     SDL_AudioSpec _obtained;
   856     SDL_AudioDevice *device;
   857     SDL_bool build_cvt;
   858     int i = 0;
   859 
   860     if (!SDL_WasInit(SDL_INIT_AUDIO)) {
   861         SDL_SetError("Audio subsystem is not initialized");
   862         return 0;
   863     }
   864 
   865     if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
   866         SDL_SetError("No capture support");
   867         return 0;
   868     }
   869 
   870     if (!obtained) {
   871         obtained = &_obtained;
   872     }
   873     if (!prepare_audiospec(desired, obtained)) {
   874         return 0;
   875     }
   876 
   877     /* If app doesn't care about a specific device, let the user override. */
   878     if (devname == NULL) {
   879         devname = SDL_getenv("SDL_AUDIO_DEVICE_NAME");
   880     }
   881 
   882     /*
   883      * Catch device names at the high level for the simple case...
   884      * This lets us have a basic "device enumeration" for systems that
   885      *  don't have multiple devices, but makes sure the device name is
   886      *  always NULL when it hits the low level.
   887      *
   888      * Also make sure that the simple case prevents multiple simultaneous
   889      *  opens of the default system device.
   890      */
   891 
   892     if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
   893         if ((devname) && (SDL_strcmp(devname, DEFAULT_INPUT_DEVNAME) != 0)) {
   894             SDL_SetError("No such device");
   895             return 0;
   896         }
   897         devname = NULL;
   898 
   899         for (i = 0; i < SDL_arraysize(open_devices); i++) {
   900             if ((open_devices[i]) && (open_devices[i]->iscapture)) {
   901                 SDL_SetError("Audio device already open");
   902                 return 0;
   903             }
   904         }
   905     }
   906 
   907     if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
   908         if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) {
   909             SDL_SetError("No such device");
   910             return 0;
   911         }
   912         devname = NULL;
   913 
   914         for (i = 0; i < SDL_arraysize(open_devices); i++) {
   915             if ((open_devices[i]) && (!open_devices[i]->iscapture)) {
   916                 SDL_SetError("Audio device already open");
   917                 return 0;
   918             }
   919         }
   920     }
   921 
   922     device = (SDL_AudioDevice *) SDL_AllocAudioMem(sizeof(SDL_AudioDevice));
   923     if (device == NULL) {
   924         SDL_OutOfMemory();
   925         return 0;
   926     }
   927     SDL_memset(device, '\0', sizeof(SDL_AudioDevice));
   928     device->spec = *obtained;
   929     device->enabled = 1;
   930     device->paused = 1;
   931     device->iscapture = iscapture;
   932 
   933     /* Create a semaphore for locking the sound buffers */
   934     if (!current_audio.impl.SkipMixerLock) {
   935         device->mixer_lock = SDL_CreateMutex();
   936         if (device->mixer_lock == NULL) {
   937             close_audio_device(device);
   938             SDL_SetError("Couldn't create mixer lock");
   939             return 0;
   940         }
   941     }
   942 
   943     /* force a device detection if we haven't done one yet. */
   944     if ( ((iscapture) && (current_audio.inputDevices == NULL)) ||
   945          ((!iscapture) && (current_audio.outputDevices == NULL)) )
   946         SDL_GetNumAudioDevices(iscapture);
   947 
   948     if (!current_audio.impl.OpenDevice(device, devname, iscapture)) {
   949         close_audio_device(device);
   950         return 0;
   951     }
   952     device->opened = 1;
   953 
   954     /* Allocate a fake audio memory buffer */
   955     device->fake_stream = (Uint8 *)SDL_AllocAudioMem(device->spec.size);
   956     if (device->fake_stream == NULL) {
   957         close_audio_device(device);
   958         SDL_OutOfMemory();
   959         return 0;
   960     }
   961 
   962     /* If the audio driver changes the buffer size, accept it */
   963     if (device->spec.samples != obtained->samples) {
   964         obtained->samples = device->spec.samples;
   965         SDL_CalculateAudioSpec(obtained);
   966     }
   967 
   968     /* See if we need to do any conversion */
   969     build_cvt = SDL_FALSE;
   970     if (obtained->freq != device->spec.freq) {
   971         if (allowed_changes & SDL_AUDIO_ALLOW_FREQUENCY_CHANGE) {
   972             obtained->freq = device->spec.freq;
   973         } else {
   974             build_cvt = SDL_TRUE;
   975         }
   976     }
   977     if (obtained->format != device->spec.format) {
   978         if (allowed_changes & SDL_AUDIO_ALLOW_FORMAT_CHANGE) {
   979             obtained->format = device->spec.format;
   980         } else {
   981             build_cvt = SDL_TRUE;
   982         }
   983     }
   984     if (obtained->channels != device->spec.channels) {
   985         if (allowed_changes & SDL_AUDIO_ALLOW_CHANNELS_CHANGE) {
   986             obtained->channels = device->spec.channels;
   987         } else {
   988             build_cvt = SDL_TRUE;
   989         }
   990     }
   991     if (build_cvt) {
   992         /* Build an audio conversion block */
   993         if (SDL_BuildAudioCVT(&device->convert,
   994                               obtained->format, obtained->channels,
   995                               obtained->freq,
   996                               device->spec.format, device->spec.channels,
   997                               device->spec.freq) < 0) {
   998             close_audio_device(device);
   999             return 0;
  1000         }
  1001         if (device->convert.needed) {
  1002             device->convert.len = (int) (((double) obtained->size) /
  1003                                          device->convert.len_ratio);
  1004 
  1005             device->convert.buf =
  1006                 (Uint8 *) SDL_AllocAudioMem(device->convert.len *
  1007                                             device->convert.len_mult);
  1008             if (device->convert.buf == NULL) {
  1009                 close_audio_device(device);
  1010                 SDL_OutOfMemory();
  1011                 return 0;
  1012             }
  1013         }
  1014     }
  1015 
  1016     /* Find an available device ID and store the structure... */
  1017     for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
  1018         if (open_devices[id] == NULL) {
  1019             open_devices[id] = device;
  1020             break;
  1021         }
  1022     }
  1023 
  1024     if (id == SDL_arraysize(open_devices)) {
  1025         SDL_SetError("Too many open audio devices");
  1026         close_audio_device(device);
  1027         return 0;
  1028     }
  1029 
  1030     /* Start the audio thread if necessary */
  1031     if (!current_audio.impl.ProvidesOwnCallbackThread) {
  1032         /* Start the audio thread */
  1033         char name[64];
  1034         SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) (id + 1));
  1035 /* !!! FIXME: this is nasty. */
  1036 #if defined(__WIN32__) && !defined(HAVE_LIBC)
  1037 #undef SDL_CreateThread
  1038         device->thread = SDL_CreateThread(SDL_RunAudio, name, device, NULL, NULL);
  1039 #else
  1040         device->thread = SDL_CreateThread(SDL_RunAudio, name, device);
  1041 #endif
  1042         if (device->thread == NULL) {
  1043             SDL_CloseAudioDevice(id + 1);
  1044             SDL_SetError("Couldn't create audio thread");
  1045             return 0;
  1046         }
  1047     }
  1048 
  1049     return id + 1;
  1050 }
  1051 
  1052 
  1053 int
  1054 SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
  1055 {
  1056     SDL_AudioDeviceID id = 0;
  1057 
  1058     /* Start up the audio driver, if necessary. This is legacy behaviour! */
  1059     if (!SDL_WasInit(SDL_INIT_AUDIO)) {
  1060         if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
  1061             return (-1);
  1062         }
  1063     }
  1064 
  1065     /* SDL_OpenAudio() is legacy and can only act on Device ID #1. */
  1066     if (open_devices[0] != NULL) {
  1067         SDL_SetError("Audio device is already opened");
  1068         return (-1);
  1069     }
  1070 
  1071     if (obtained) {
  1072         id = open_audio_device(NULL, 0, desired, obtained,
  1073                                SDL_AUDIO_ALLOW_ANY_CHANGE, 1);
  1074     } else {
  1075         id = open_audio_device(NULL, 0, desired, desired, 0, 1);
  1076     }
  1077 
  1078     SDL_assert((id == 0) || (id == 1));
  1079     return ((id == 0) ? -1 : 0);
  1080 }
  1081 
  1082 SDL_AudioDeviceID
  1083 SDL_OpenAudioDevice(const char *device, int iscapture,
  1084                     const SDL_AudioSpec * desired, SDL_AudioSpec * obtained,
  1085                     int allowed_changes)
  1086 {
  1087     return open_audio_device(device, iscapture, desired, obtained,
  1088                              allowed_changes, 2);
  1089 }
  1090 
  1091 SDL_AudioStatus
  1092 SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid)
  1093 {
  1094     SDL_AudioDevice *device = get_audio_device(devid);
  1095     SDL_AudioStatus status = SDL_AUDIO_STOPPED;
  1096     if (device && device->enabled) {
  1097         if (device->paused) {
  1098             status = SDL_AUDIO_PAUSED;
  1099         } else {
  1100             status = SDL_AUDIO_PLAYING;
  1101         }
  1102     }
  1103     return (status);
  1104 }
  1105 
  1106 
  1107 SDL_AudioStatus
  1108 SDL_GetAudioStatus(void)
  1109 {
  1110     return SDL_GetAudioDeviceStatus(1);
  1111 }
  1112 
  1113 void
  1114 SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on)
  1115 {
  1116     SDL_AudioDevice *device = get_audio_device(devid);
  1117     if (device) {
  1118         device->paused = pause_on;
  1119     }
  1120 }
  1121 
  1122 void
  1123 SDL_PauseAudio(int pause_on)
  1124 {
  1125     SDL_PauseAudioDevice(1, pause_on);
  1126 }
  1127 
  1128 
  1129 void
  1130 SDL_LockAudioDevice(SDL_AudioDeviceID devid)
  1131 {
  1132     /* Obtain a lock on the mixing buffers */
  1133     SDL_AudioDevice *device = get_audio_device(devid);
  1134     if (device) {
  1135         current_audio.impl.LockDevice(device);
  1136     }
  1137 }
  1138 
  1139 void
  1140 SDL_LockAudio(void)
  1141 {
  1142     SDL_LockAudioDevice(1);
  1143 }
  1144 
  1145 void
  1146 SDL_UnlockAudioDevice(SDL_AudioDeviceID devid)
  1147 {
  1148     /* Obtain a lock on the mixing buffers */
  1149     SDL_AudioDevice *device = get_audio_device(devid);
  1150     if (device) {
  1151         current_audio.impl.UnlockDevice(device);
  1152     }
  1153 }
  1154 
  1155 void
  1156 SDL_UnlockAudio(void)
  1157 {
  1158     SDL_UnlockAudioDevice(1);
  1159 }
  1160 
  1161 void
  1162 SDL_CloseAudioDevice(SDL_AudioDeviceID devid)
  1163 {
  1164     SDL_AudioDevice *device = get_audio_device(devid);
  1165     if (device) {
  1166         close_audio_device(device);
  1167         open_devices[devid - 1] = NULL;
  1168     }
  1169 }
  1170 
  1171 void
  1172 SDL_CloseAudio(void)
  1173 {
  1174     SDL_CloseAudioDevice(1);
  1175 }
  1176 
  1177 void
  1178 SDL_AudioQuit(void)
  1179 {
  1180     SDL_AudioDeviceID i;
  1181     for (i = 0; i < SDL_arraysize(open_devices); i++) {
  1182         SDL_CloseAudioDevice(i);
  1183     }
  1184 
  1185     /* Free the driver data */
  1186     current_audio.impl.Deinitialize();
  1187     free_device_list(&current_audio.outputDevices,
  1188                      &current_audio.outputDeviceCount);
  1189     free_device_list(&current_audio.inputDevices,
  1190                      &current_audio.inputDeviceCount);
  1191     SDL_memset(&current_audio, '\0', sizeof(current_audio));
  1192     SDL_memset(open_devices, '\0', sizeof(open_devices));
  1193 }
  1194 
  1195 #define NUM_FORMATS 10
  1196 static int format_idx;
  1197 static int format_idx_sub;
  1198 static SDL_AudioFormat format_list[NUM_FORMATS][NUM_FORMATS] = {
  1199     {AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB,
  1200      AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB},
  1201     {AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB,
  1202      AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB},
  1203     {AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S32LSB,
  1204      AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8},
  1205     {AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S32MSB,
  1206      AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8},
  1207     {AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S32LSB,
  1208      AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8},
  1209     {AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_S32MSB,
  1210      AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8},
  1211     {AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S16LSB,
  1212      AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8},
  1213     {AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S16MSB,
  1214      AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8},
  1215     {AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S16LSB,
  1216      AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8},
  1217     {AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_S16MSB,
  1218      AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8},
  1219 };
  1220 
  1221 SDL_AudioFormat
  1222 SDL_FirstAudioFormat(SDL_AudioFormat format)
  1223 {
  1224     for (format_idx = 0; format_idx < NUM_FORMATS; ++format_idx) {
  1225         if (format_list[format_idx][0] == format) {
  1226             break;
  1227         }
  1228     }
  1229     format_idx_sub = 0;
  1230     return (SDL_NextAudioFormat());
  1231 }
  1232 
  1233 SDL_AudioFormat
  1234 SDL_NextAudioFormat(void)
  1235 {
  1236     if ((format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS)) {
  1237         return (0);
  1238     }
  1239     return (format_list[format_idx][format_idx_sub++]);
  1240 }
  1241 
  1242 void
  1243 SDL_CalculateAudioSpec(SDL_AudioSpec * spec)
  1244 {
  1245     switch (spec->format) {
  1246     case AUDIO_U8:
  1247         spec->silence = 0x80;
  1248         break;
  1249     default:
  1250         spec->silence = 0x00;
  1251         break;
  1252     }
  1253     spec->size = SDL_AUDIO_BITSIZE(spec->format) / 8;
  1254     spec->size *= spec->channels;
  1255     spec->size *= spec->samples;
  1256 }
  1257 
  1258 
  1259 /*
  1260  * Moved here from SDL_mixer.c, since it relies on internals of an opened
  1261  *  audio device (and is deprecated, by the way!).
  1262  */
  1263 void
  1264 SDL_MixAudio(Uint8 * dst, const Uint8 * src, Uint32 len, int volume)
  1265 {
  1266     /* Mix the user-level audio format */
  1267     SDL_AudioDevice *device = get_audio_device(1);
  1268     if (device != NULL) {
  1269         SDL_AudioFormat format;
  1270         if (device->convert.needed) {
  1271             format = device->convert.src_format;
  1272         } else {
  1273             format = device->spec.format;
  1274         }
  1275         SDL_MixAudioFormat(dst, src, format, len, volume);
  1276     }
  1277 }
  1278 
  1279 /* vi: set ts=4 sw=4 expandtab: */