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