SDL  2.0
SDL_audio.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2016 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_internal.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 
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  */
73 
74 
75 /* Available audio drivers */
76 static const AudioBootStrap *const bootstrap[] = {
77 #if SDL_AUDIO_DRIVER_PULSEAUDIO
79 #endif
80 #if SDL_AUDIO_DRIVER_ALSA
82 #endif
83 #if SDL_AUDIO_DRIVER_SNDIO
85 #endif
86 #if SDL_AUDIO_DRIVER_BSD
88 #endif
89 #if SDL_AUDIO_DRIVER_OSS
91 #endif
92 #if SDL_AUDIO_DRIVER_QSA
94 #endif
95 #if SDL_AUDIO_DRIVER_SUNAUDIO
97 #endif
98 #if SDL_AUDIO_DRIVER_ARTS
100 #endif
101 #if SDL_AUDIO_DRIVER_ESD
102  &ESD_bootstrap,
103 #endif
104 #if SDL_AUDIO_DRIVER_NACL
106 #endif
107 #if SDL_AUDIO_DRIVER_NAS
108  &NAS_bootstrap,
109 #endif
110 #if SDL_AUDIO_DRIVER_XAUDIO2
112 #endif
113 #if SDL_AUDIO_DRIVER_DSOUND
115 #endif
116 #if SDL_AUDIO_DRIVER_WINMM
118 #endif
119 #if SDL_AUDIO_DRIVER_PAUDIO
121 #endif
122 #if SDL_AUDIO_DRIVER_HAIKU
124 #endif
125 #if SDL_AUDIO_DRIVER_COREAUDIO
127 #endif
128 #if SDL_AUDIO_DRIVER_DISK
130 #endif
131 #if SDL_AUDIO_DRIVER_DUMMY
133 #endif
134 #if SDL_AUDIO_DRIVER_FUSIONSOUND
136 #endif
137 #if SDL_AUDIO_DRIVER_ANDROID
139 #endif
140 #if SDL_AUDIO_DRIVER_PSP
142 #endif
143 #if SDL_AUDIO_DRIVER_EMSCRIPTEN
145 #endif
146  NULL
147 };
148 
149 static SDL_AudioDevice *
151 {
152  id--;
153  if ((id >= SDL_arraysize(open_devices)) || (open_devices[id] == NULL)) {
154  SDL_SetError("Invalid audio device ID");
155  return NULL;
156  }
157 
158  return open_devices[id];
159 }
160 
161 
162 /* stubs for audio drivers that don't need a specific entry point... */
163 static void
165 {
166  /* you have to write your own implementation if these assertions fail. */
168  SDL_assert(current_audio.impl.OnlyHasDefaultInputDevice || !current_audio.impl.HasCaptureSupport);
169 
170  SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) ((size_t) 0x1));
171  if (current_audio.impl.HasCaptureSupport) {
172  SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, (void *) ((size_t) 0x2));
173  }
174 }
175 
176 static void
178 { /* no-op. */
179 }
180 
181 static void
183 { /* no-op. */
184 }
185 
186 static void
188 { /* no-op. */
189 }
190 
191 static int
193 {
194  return 0;
195 }
196 
197 static Uint8 *
199 {
200  return NULL;
201 }
202 
203 static void
205 { /* no-op. */
206 }
207 
208 static void
210 { /* no-op. */
211 }
212 
213 static void
215 { /* no-op. */
216 }
217 
218 static void
220 { /* no-op. */
221 }
222 
223 
224 static int
225 SDL_AudioOpenDevice_Default(_THIS, void *handle, const char *devname, int iscapture)
226 {
227  return SDL_Unsupported();
228 }
229 
230 static SDL_INLINE SDL_bool
232 {
233  /* The device thread locks the same mutex, but not through the public API.
234  This check is in case the application, in the audio callback,
235  tries to lock the thread that we've already locked from the
236  device thread...just in case we only have non-recursive mutexes. */
237  if (device->thread && (SDL_ThreadID() == device->threadid)) {
238  return SDL_TRUE;
239  }
240 
241  return SDL_FALSE;
242 }
243 
244 static void
246 {
247  if (!is_in_audio_device_thread(device)) {
248  SDL_LockMutex(device->mixer_lock);
249  }
250 }
251 
252 static void
254 {
255  if (!is_in_audio_device_thread(device)) {
256  SDL_UnlockMutex(device->mixer_lock);
257  }
258 }
259 
260 
261 static void
263 {
264  /*
265  * Fill in stub functions for unused driver entry points. This lets us
266  * blindly call them without having to check for validity first.
267  */
268 
269 #define FILL_STUB(x) \
270  if (current_audio.impl.x == NULL) { \
271  current_audio.impl.x = SDL_Audio##x##_Default; \
272  }
273  FILL_STUB(DetectDevices);
274  FILL_STUB(OpenDevice);
275  FILL_STUB(ThreadInit);
276  FILL_STUB(WaitDevice);
277  FILL_STUB(PlayDevice);
278  FILL_STUB(GetPendingBytes);
279  FILL_STUB(GetDeviceBuf);
280  FILL_STUB(WaitDone);
281  FILL_STUB(CloseDevice);
282  FILL_STUB(LockDevice);
283  FILL_STUB(UnlockDevice);
284  FILL_STUB(FreeDeviceHandle);
285  FILL_STUB(Deinitialize);
286 #undef FILL_STUB
287 }
288 
289 
290 /* device hotplug support... */
291 
292 static int
293 add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
294 {
295  int retval = -1;
296  const size_t size = sizeof (SDL_AudioDeviceItem) + SDL_strlen(name) + 1;
298  if (item == NULL) {
299  return -1;
300  }
301 
302  SDL_assert(handle != NULL); /* we reserve NULL, audio backends can't use it. */
303 
304  item->handle = handle;
305  SDL_strlcpy(item->name, name, size - sizeof (SDL_AudioDeviceItem));
306 
307  SDL_LockMutex(current_audio.detectionLock);
308  item->next = *devices;
309  *devices = item;
310  retval = (*devCount)++;
311  SDL_UnlockMutex(current_audio.detectionLock);
312 
313  return retval;
314 }
315 
316 static SDL_INLINE int
317 add_capture_device(const char *name, void *handle)
318 {
319  /* !!! FIXME: add this later. SDL_assert(current_audio.impl.HasCaptureSupport);*/
320  return add_audio_device(name, handle, &current_audio.inputDevices, &current_audio.inputDeviceCount);
321 }
322 
323 static SDL_INLINE int
324 add_output_device(const char *name, void *handle)
325 {
326  return add_audio_device(name, handle, &current_audio.outputDevices, &current_audio.outputDeviceCount);
327 }
328 
329 static void
330 free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
331 {
332  SDL_AudioDeviceItem *item, *next;
333  for (item = *devices; item != NULL; item = next) {
334  next = item->next;
335  if (item->handle != NULL) {
336  current_audio.impl.FreeDeviceHandle(item->handle);
337  }
338  SDL_free(item);
339  }
340  *devices = NULL;
341  *devCount = 0;
342 }
343 
344 
345 /* The audio backends call this when a new device is plugged in. */
346 void
347 SDL_AddAudioDevice(const int iscapture, const char *name, void *handle)
348 {
349  const int device_index = iscapture ? add_capture_device(name, handle) : add_output_device(name, handle);
350  if (device_index != -1) {
351  /* Post the event, if desired */
354  SDL_zero(event);
355  event.adevice.type = SDL_AUDIODEVICEADDED;
356  event.adevice.which = device_index;
357  event.adevice.iscapture = iscapture;
358  SDL_PushEvent(&event);
359  }
360  }
361 }
362 
363 /* The audio backends call this when a currently-opened device is lost. */
365 {
366  SDL_assert(get_audio_device(device->id) == device);
367 
368  if (!device->enabled) {
369  return;
370  }
371 
372  /* Ends the audio callback and mark the device as STOPPED, but the
373  app still needs to close the device to free resources. */
374  current_audio.impl.LockDevice(device);
375  device->enabled = 0;
376  current_audio.impl.UnlockDevice(device);
377 
378  /* Post the event, if desired */
381  SDL_zero(event);
382  event.adevice.type = SDL_AUDIODEVICEREMOVED;
383  event.adevice.which = device->id;
384  event.adevice.iscapture = device->iscapture ? 1 : 0;
385  SDL_PushEvent(&event);
386  }
387 }
388 
389 static void
390 mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *removedFlag)
391 {
392  SDL_AudioDeviceItem *item;
393  SDL_assert(handle != NULL);
394  for (item = devices; item != NULL; item = item->next) {
395  if (item->handle == handle) {
396  item->handle = NULL;
397  *removedFlag = SDL_TRUE;
398  return;
399  }
400  }
401 }
402 
403 /* The audio backends call this when a device is removed from the system. */
404 void
405 SDL_RemoveAudioDevice(const int iscapture, void *handle)
406 {
407  SDL_LockMutex(current_audio.detectionLock);
408  if (iscapture) {
409  mark_device_removed(handle, current_audio.inputDevices, &current_audio.captureDevicesRemoved);
410  } else {
411  mark_device_removed(handle, current_audio.outputDevices, &current_audio.outputDevicesRemoved);
412  }
413  SDL_UnlockMutex(current_audio.detectionLock);
414  current_audio.impl.FreeDeviceHandle(handle);
415 }
416 
417 
418 
419 /* buffer queueing support... */
420 
421 /* this expects that you managed thread safety elsewhere. */
422 static void
424 {
425  while (buffer) {
426  SDL_AudioBufferQueue *next = buffer->next;
427  SDL_free(buffer);
428  buffer = next;
429  }
430 }
431 
432 static void SDLCALL
433 SDL_BufferQueueDrainCallback(void *userdata, Uint8 *stream, int _len)
434 {
435  /* this function always holds the mixer lock before being called. */
436  Uint32 len = (Uint32) _len;
437  SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
439 
440  SDL_assert(device != NULL); /* this shouldn't ever happen, right?! */
441  SDL_assert(_len >= 0); /* this shouldn't ever happen, right?! */
442 
443  while ((len > 0) && ((buffer = device->buffer_queue_head) != NULL)) {
444  const Uint32 avail = buffer->datalen - buffer->startpos;
445  const Uint32 cpy = SDL_min(len, avail);
446  SDL_assert(device->queued_bytes >= avail);
447 
448  SDL_memcpy(stream, buffer->data + buffer->startpos, cpy);
449  buffer->startpos += cpy;
450  stream += cpy;
451  device->queued_bytes -= cpy;
452  len -= cpy;
453 
454  if (buffer->startpos == buffer->datalen) { /* packet is done, put it in the pool. */
455  device->buffer_queue_head = buffer->next;
456  SDL_assert((buffer->next != NULL) || (buffer == device->buffer_queue_tail));
457  buffer->next = device->buffer_queue_pool;
458  device->buffer_queue_pool = buffer;
459  }
460  }
461 
462  SDL_assert((device->buffer_queue_head != NULL) == (device->queued_bytes != 0));
463 
464  if (len > 0) { /* fill any remaining space in the stream with silence. */
465  SDL_assert(device->buffer_queue_head == NULL);
466  SDL_memset(stream, device->spec.silence, len);
467  }
468 
469  if (device->buffer_queue_head == NULL) {
470  device->buffer_queue_tail = NULL; /* in case we drained the queue entirely. */
471  }
472 }
473 
474 int
475 SDL_QueueAudio(SDL_AudioDeviceID devid, const void *_data, Uint32 len)
476 {
477  SDL_AudioDevice *device = get_audio_device(devid);
478  const Uint8 *data = (const Uint8 *) _data;
479  SDL_AudioBufferQueue *orighead;
480  SDL_AudioBufferQueue *origtail;
481  Uint32 origlen;
482  Uint32 datalen;
483 
484  if (!device) {
485  return -1; /* get_audio_device() will have set the error state */
486  }
487 
488  if (device->spec.callback != SDL_BufferQueueDrainCallback) {
489  return SDL_SetError("Audio device has a callback, queueing not allowed");
490  }
491 
492  current_audio.impl.LockDevice(device);
493 
494  orighead = device->buffer_queue_head;
495  origtail = device->buffer_queue_tail;
496  origlen = origtail ? origtail->datalen : 0;
497 
498  while (len > 0) {
499  SDL_AudioBufferQueue *packet = device->buffer_queue_tail;
500  SDL_assert(!packet || (packet->datalen <= SDL_AUDIOBUFFERQUEUE_PACKETLEN));
501  if (!packet || (packet->datalen >= SDL_AUDIOBUFFERQUEUE_PACKETLEN)) {
502  /* tail packet missing or completely full; we need a new packet. */
503  packet = device->buffer_queue_pool;
504  if (packet != NULL) {
505  /* we have one available in the pool. */
506  device->buffer_queue_pool = packet->next;
507  } else {
508  /* Have to allocate a new one! */
510  if (packet == NULL) {
511  /* uhoh, reset so we've queued nothing new, free what we can. */
512  if (!origtail) {
513  packet = device->buffer_queue_head; /* whole queue. */
514  } else {
515  packet = origtail->next; /* what we added to existing queue. */
516  origtail->next = NULL;
517  origtail->datalen = origlen;
518  }
519  device->buffer_queue_head = orighead;
520  device->buffer_queue_tail = origtail;
521  device->buffer_queue_pool = NULL;
522 
523  current_audio.impl.UnlockDevice(device);
524 
525  free_audio_queue(packet); /* give back what we can. */
526 
527  return SDL_OutOfMemory();
528  }
529  }
530  packet->datalen = 0;
531  packet->startpos = 0;
532  packet->next = NULL;
533 
534  SDL_assert((device->buffer_queue_head != NULL) == (device->queued_bytes != 0));
535  if (device->buffer_queue_tail == NULL) {
536  device->buffer_queue_head = packet;
537  } else {
538  device->buffer_queue_tail->next = packet;
539  }
540  device->buffer_queue_tail = packet;
541  }
542 
543  datalen = SDL_min(len, SDL_AUDIOBUFFERQUEUE_PACKETLEN - packet->datalen);
544  SDL_memcpy(packet->data + packet->datalen, data, datalen);
545  data += datalen;
546  len -= datalen;
547  packet->datalen += datalen;
548  device->queued_bytes += datalen;
549  }
550 
551  current_audio.impl.UnlockDevice(device);
552 
553  return 0;
554 }
555 
556 Uint32
558 {
559  Uint32 retval = 0;
560  SDL_AudioDevice *device = get_audio_device(devid);
561 
562  /* Nothing to do unless we're set up for queueing. */
563  if (device && (device->spec.callback == SDL_BufferQueueDrainCallback)) {
564  current_audio.impl.LockDevice(device);
565  retval = device->queued_bytes + current_audio.impl.GetPendingBytes(device);
566  current_audio.impl.UnlockDevice(device);
567  }
568 
569  return retval;
570 }
571 
572 void
574 {
575  SDL_AudioDevice *device = get_audio_device(devid);
577  if (!device) {
578  return; /* nothing to do. */
579  }
580 
581  /* Blank out the device and release the mutex. Free it afterwards. */
582  current_audio.impl.LockDevice(device);
583  buffer = device->buffer_queue_head;
584  device->buffer_queue_tail = NULL;
585  device->buffer_queue_head = NULL;
586  device->queued_bytes = 0;
587  current_audio.impl.UnlockDevice(device);
588 
589  free_audio_queue(buffer);
590 }
591 
592 
593 /* The general mixing thread function */
594 int SDLCALL
595 SDL_RunAudio(void *devicep)
596 {
597  SDL_AudioDevice *device = (SDL_AudioDevice *) devicep;
598  const int silence = (int) device->spec.silence;
599  const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
600  const int stream_len = (device->convert.needed) ? device->convert.len : device->spec.size;
601  Uint8 *stream;
602  void *udata = device->spec.userdata;
603  void (SDLCALL *fill) (void *, Uint8 *, int) = device->spec.callback;
604 
605  /* The audio mixing is always a high priority thread */
607 
608  /* Perform any thread setup */
609  device->threadid = SDL_ThreadID();
610  current_audio.impl.ThreadInit(device);
611 
612  /* Loop, filling the audio buffers */
613  while (!device->shutdown) {
614  /* Fill the current buffer with sound */
615  if (device->convert.needed) {
616  stream = device->convert.buf;
617  } else if (device->enabled) {
618  stream = current_audio.impl.GetDeviceBuf(device);
619  } else {
620  /* if the device isn't enabled, we still write to the
621  fake_stream, so the app's callback will fire with
622  a regular frequency, in case they depend on that
623  for timing or progress. They can use hotplug
624  now to know if the device failed. */
625  stream = NULL;
626  }
627 
628  if (stream == NULL) {
629  stream = device->fake_stream;
630  }
631 
632  /* !!! FIXME: this should be LockDevice. */
633  SDL_LockMutex(device->mixer_lock);
634  if (device->paused) {
635  SDL_memset(stream, silence, stream_len);
636  } else {
637  (*fill) (udata, stream, stream_len);
638  }
639  SDL_UnlockMutex(device->mixer_lock);
640 
641  /* Convert the audio if necessary */
642  if (device->enabled && device->convert.needed) {
643  SDL_ConvertAudio(&device->convert);
644  stream = current_audio.impl.GetDeviceBuf(device);
645  if (stream == NULL) {
646  stream = device->fake_stream;
647  } else {
648  SDL_memcpy(stream, device->convert.buf,
649  device->convert.len_cvt);
650  }
651  }
652 
653  /* Ready current buffer for play and change current buffer */
654  if (stream == device->fake_stream) {
655  SDL_Delay(delay);
656  } else {
657  current_audio.impl.PlayDevice(device);
658  current_audio.impl.WaitDevice(device);
659  }
660  }
661 
662  /* Wait for the audio to drain. */
663  current_audio.impl.WaitDone(device);
664 
665  return 0;
666 }
667 
668 
669 static SDL_AudioFormat
670 SDL_ParseAudioFormat(const char *string)
671 {
672 #define CHECK_FMT_STRING(x) if (SDL_strcmp(string, #x) == 0) return AUDIO_##x
673  CHECK_FMT_STRING(U8);
674  CHECK_FMT_STRING(S8);
675  CHECK_FMT_STRING(U16LSB);
676  CHECK_FMT_STRING(S16LSB);
677  CHECK_FMT_STRING(U16MSB);
678  CHECK_FMT_STRING(S16MSB);
679  CHECK_FMT_STRING(U16SYS);
680  CHECK_FMT_STRING(S16SYS);
681  CHECK_FMT_STRING(U16);
682  CHECK_FMT_STRING(S16);
683  CHECK_FMT_STRING(S32LSB);
684  CHECK_FMT_STRING(S32MSB);
685  CHECK_FMT_STRING(S32SYS);
687  CHECK_FMT_STRING(F32LSB);
688  CHECK_FMT_STRING(F32MSB);
689  CHECK_FMT_STRING(F32SYS);
690  CHECK_FMT_STRING(F32);
691 #undef CHECK_FMT_STRING
692  return 0;
693 }
694 
695 int
697 {
698  return SDL_arraysize(bootstrap) - 1;
699 }
700 
701 const char *
703 {
704  if (index >= 0 && index < SDL_GetNumAudioDrivers()) {
705  return bootstrap[index]->name;
706  }
707  return NULL;
708 }
709 
710 int
711 SDL_AudioInit(const char *driver_name)
712 {
713  int i = 0;
714  int initialized = 0;
715  int tried_to_init = 0;
716 
718  SDL_AudioQuit(); /* shutdown driver if already running. */
719  }
720 
721  SDL_zero(current_audio);
722  SDL_zero(open_devices);
723 
724  /* Select the proper audio driver */
725  if (driver_name == NULL) {
726  driver_name = SDL_getenv("SDL_AUDIODRIVER");
727  }
728 
729  for (i = 0; (!initialized) && (bootstrap[i]); ++i) {
730  /* make sure we should even try this driver before doing so... */
731  const AudioBootStrap *backend = bootstrap[i];
732  if ((driver_name && (SDL_strncasecmp(backend->name, driver_name, SDL_strlen(driver_name)) != 0)) ||
733  (!driver_name && backend->demand_only)) {
734  continue;
735  }
736 
737  tried_to_init = 1;
738  SDL_zero(current_audio);
739  current_audio.name = backend->name;
740  current_audio.desc = backend->desc;
741  initialized = backend->init(&current_audio.impl);
742  }
743 
744  if (!initialized) {
745  /* specific drivers will set the error message if they fail... */
746  if (!tried_to_init) {
747  if (driver_name) {
748  SDL_SetError("Audio target '%s' not available", driver_name);
749  } else {
750  SDL_SetError("No available audio device");
751  }
752  }
753 
754  SDL_zero(current_audio);
755  return -1; /* No driver was available, so fail. */
756  }
757 
758  current_audio.detectionLock = SDL_CreateMutex();
759 
761 
762  /* Make sure we have a list of devices available at startup. */
763  current_audio.impl.DetectDevices();
764 
765  return 0;
766 }
767 
768 /*
769  * Get the current audio driver name
770  */
771 const char *
773 {
774  return current_audio.name;
775 }
776 
777 /* Clean out devices that we've removed but had to keep around for stability. */
778 static void
779 clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *removedFlag)
780 {
781  SDL_AudioDeviceItem *item = *devices;
782  SDL_AudioDeviceItem *prev = NULL;
783  int total = 0;
784 
785  while (item) {
786  SDL_AudioDeviceItem *next = item->next;
787  if (item->handle != NULL) {
788  total++;
789  prev = item;
790  } else {
791  if (prev) {
792  prev->next = next;
793  } else {
794  *devices = next;
795  }
796  SDL_free(item);
797  }
798  item = next;
799  }
800 
801  *devCount = total;
802  *removedFlag = SDL_FALSE;
803 }
804 
805 
806 int
808 {
809  int retval = 0;
810 
811  if (!SDL_WasInit(SDL_INIT_AUDIO)) {
812  return -1;
813  }
814 
815  SDL_LockMutex(current_audio.detectionLock);
816  if (iscapture && current_audio.captureDevicesRemoved) {
817  clean_out_device_list(&current_audio.inputDevices, &current_audio.inputDeviceCount, &current_audio.captureDevicesRemoved);
818  }
819 
820  if (!iscapture && current_audio.outputDevicesRemoved) {
821  clean_out_device_list(&current_audio.outputDevices, &current_audio.outputDeviceCount, &current_audio.outputDevicesRemoved);
822  current_audio.outputDevicesRemoved = SDL_FALSE;
823  }
824 
825  retval = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
826  SDL_UnlockMutex(current_audio.detectionLock);
827 
828  return retval;
829 }
830 
831 
832 const char *
833 SDL_GetAudioDeviceName(int index, int iscapture)
834 {
835  const char *retval = NULL;
836 
837  if (!SDL_WasInit(SDL_INIT_AUDIO)) {
838  SDL_SetError("Audio subsystem is not initialized");
839  return NULL;
840  }
841 
842  if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
843  SDL_SetError("No capture support");
844  return NULL;
845  }
846 
847  if (index >= 0) {
848  SDL_AudioDeviceItem *item;
849  int i;
850 
851  SDL_LockMutex(current_audio.detectionLock);
852  item = iscapture ? current_audio.inputDevices : current_audio.outputDevices;
853  i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
854  if (index < i) {
855  for (i--; i > index; i--, item = item->next) {
856  SDL_assert(item != NULL);
857  }
858  SDL_assert(item != NULL);
859  retval = item->name;
860  }
861  SDL_UnlockMutex(current_audio.detectionLock);
862  }
863 
864  if (retval == NULL) {
865  SDL_SetError("No such device");
866  }
867 
868  return retval;
869 }
870 
871 
872 static void
874 {
875  device->enabled = 0;
876  device->shutdown = 1;
877  if (device->thread != NULL) {
878  SDL_WaitThread(device->thread, NULL);
879  }
880  if (device->mixer_lock != NULL) {
881  SDL_DestroyMutex(device->mixer_lock);
882  }
883  SDL_FreeAudioMem(device->fake_stream);
884  if (device->convert.needed) {
885  SDL_FreeAudioMem(device->convert.buf);
886  }
887  if (device->opened) {
888  current_audio.impl.CloseDevice(device);
889  device->opened = 0;
890  }
891 
894 
895  SDL_FreeAudioMem(device);
896 }
897 
898 
899 /*
900  * Sanity check desired AudioSpec for SDL_OpenAudio() in (orig).
901  * Fills in a sanitized copy in (prepared).
902  * Returns non-zero if okay, zero on fatal parameters in (orig).
903  */
904 static int
906 {
907  SDL_memcpy(prepared, orig, sizeof(SDL_AudioSpec));
908 
909  if (orig->freq == 0) {
910  const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY");
911  if ((!env) || ((prepared->freq = SDL_atoi(env)) == 0)) {
912  prepared->freq = 22050; /* a reasonable default */
913  }
914  }
915 
916  if (orig->format == 0) {
917  const char *env = SDL_getenv("SDL_AUDIO_FORMAT");
918  if ((!env) || ((prepared->format = SDL_ParseAudioFormat(env)) == 0)) {
919  prepared->format = AUDIO_S16; /* a reasonable default */
920  }
921  }
922 
923  switch (orig->channels) {
924  case 0:{
925  const char *env = SDL_getenv("SDL_AUDIO_CHANNELS");
926  if ((!env) || ((prepared->channels = (Uint8) SDL_atoi(env)) == 0)) {
927  prepared->channels = 2; /* a reasonable default */
928  }
929  break;
930  }
931  case 1: /* Mono */
932  case 2: /* Stereo */
933  case 4: /* surround */
934  case 6: /* surround with center and lfe */
935  break;
936  default:
937  SDL_SetError("Unsupported number of audio channels.");
938  return 0;
939  }
940 
941  if (orig->samples == 0) {
942  const char *env = SDL_getenv("SDL_AUDIO_SAMPLES");
943  if ((!env) || ((prepared->samples = (Uint16) SDL_atoi(env)) == 0)) {
944  /* Pick a default of ~46 ms at desired frequency */
945  /* !!! FIXME: remove this when the non-Po2 resampling is in. */
946  const int samples = (prepared->freq / 1000) * 46;
947  int power2 = 1;
948  while (power2 < samples) {
949  power2 *= 2;
950  }
951  prepared->samples = power2;
952  }
953  }
954 
955  /* Calculate the silence and size of the audio specification */
956  SDL_CalculateAudioSpec(prepared);
957 
958  return 1;
959 }
960 
961 static SDL_AudioDeviceID
962 open_audio_device(const char *devname, int iscapture,
963  const SDL_AudioSpec * desired, SDL_AudioSpec * obtained,
964  int allowed_changes, int min_id)
965 {
966  SDL_AudioDeviceID id = 0;
967  SDL_AudioSpec _obtained;
968  SDL_AudioDevice *device;
969  SDL_bool build_cvt;
970  void *handle = NULL;
971  Uint32 stream_len;
972  int i = 0;
973 
974  if (!SDL_WasInit(SDL_INIT_AUDIO)) {
975  SDL_SetError("Audio subsystem is not initialized");
976  return 0;
977  }
978 
979  if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
980  SDL_SetError("No capture support");
981  return 0;
982  }
983 
984  /* Find an available device ID... */
985  for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
986  if (open_devices[id] == NULL) {
987  break;
988  }
989  }
990 
991  if (id == SDL_arraysize(open_devices)) {
992  SDL_SetError("Too many open audio devices");
993  return 0;
994  }
995 
996  if (!obtained) {
997  obtained = &_obtained;
998  }
999  if (!prepare_audiospec(desired, obtained)) {
1000  return 0;
1001  }
1002 
1003  /* If app doesn't care about a specific device, let the user override. */
1004  if (devname == NULL) {
1005  devname = SDL_getenv("SDL_AUDIO_DEVICE_NAME");
1006  }
1007 
1008  /*
1009  * Catch device names at the high level for the simple case...
1010  * This lets us have a basic "device enumeration" for systems that
1011  * don't have multiple devices, but makes sure the device name is
1012  * always NULL when it hits the low level.
1013  *
1014  * Also make sure that the simple case prevents multiple simultaneous
1015  * opens of the default system device.
1016  */
1017 
1018  if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
1019  if ((devname) && (SDL_strcmp(devname, DEFAULT_INPUT_DEVNAME) != 0)) {
1020  SDL_SetError("No such device");
1021  return 0;
1022  }
1023  devname = NULL;
1024 
1025  for (i = 0; i < SDL_arraysize(open_devices); i++) {
1026  if ((open_devices[i]) && (open_devices[i]->iscapture)) {
1027  SDL_SetError("Audio device already open");
1028  return 0;
1029  }
1030  }
1031  } else if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
1032  if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) {
1033  SDL_SetError("No such device");
1034  return 0;
1035  }
1036  devname = NULL;
1037 
1038  for (i = 0; i < SDL_arraysize(open_devices); i++) {
1039  if ((open_devices[i]) && (!open_devices[i]->iscapture)) {
1040  SDL_SetError("Audio device already open");
1041  return 0;
1042  }
1043  }
1044  } else if (devname != NULL) {
1045  /* if the app specifies an exact string, we can pass the backend
1046  an actual device handle thingey, which saves them the effort of
1047  figuring out what device this was (such as, reenumerating
1048  everything again to find the matching human-readable name).
1049  It might still need to open a device based on the string for,
1050  say, a network audio server, but this optimizes some cases. */
1051  SDL_AudioDeviceItem *item;
1052  SDL_LockMutex(current_audio.detectionLock);
1053  for (item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; item; item = item->next) {
1054  if ((item->handle != NULL) && (SDL_strcmp(item->name, devname) == 0)) {
1055  handle = item->handle;
1056  break;
1057  }
1058  }
1059  SDL_UnlockMutex(current_audio.detectionLock);
1060  }
1061 
1062  if (!current_audio.impl.AllowsArbitraryDeviceNames) {
1063  /* has to be in our device list, or the default device. */
1064  if ((handle == NULL) && (devname != NULL)) {
1065  SDL_SetError("No such device.");
1066  return 0;
1067  }
1068  }
1069 
1070  device = (SDL_AudioDevice *) SDL_AllocAudioMem(sizeof(SDL_AudioDevice));
1071  if (device == NULL) {
1072  SDL_OutOfMemory();
1073  return 0;
1074  }
1075  SDL_zerop(device);
1076  device->id = id + 1;
1077  device->spec = *obtained;
1078  device->enabled = 1;
1079  device->paused = 1;
1080  device->iscapture = iscapture;
1081 
1082  /* Create a mutex for locking the sound buffers */
1083  if (!current_audio.impl.SkipMixerLock) {
1084  device->mixer_lock = SDL_CreateMutex();
1085  if (device->mixer_lock == NULL) {
1086  close_audio_device(device);
1087  SDL_SetError("Couldn't create mixer lock");
1088  return 0;
1089  }
1090  }
1091 
1092  if (current_audio.impl.OpenDevice(device, handle, devname, iscapture) < 0) {
1093  close_audio_device(device);
1094  return 0;
1095  }
1096  device->opened = 1;
1097 
1098  /* See if we need to do any conversion */
1099  build_cvt = SDL_FALSE;
1100  if (obtained->freq != device->spec.freq) {
1101  if (allowed_changes & SDL_AUDIO_ALLOW_FREQUENCY_CHANGE) {
1102  obtained->freq = device->spec.freq;
1103  } else {
1104  build_cvt = SDL_TRUE;
1105  }
1106  }
1107  if (obtained->format != device->spec.format) {
1108  if (allowed_changes & SDL_AUDIO_ALLOW_FORMAT_CHANGE) {
1109  obtained->format = device->spec.format;
1110  } else {
1111  build_cvt = SDL_TRUE;
1112  }
1113  }
1114  if (obtained->channels != device->spec.channels) {
1115  if (allowed_changes & SDL_AUDIO_ALLOW_CHANNELS_CHANGE) {
1116  obtained->channels = device->spec.channels;
1117  } else {
1118  build_cvt = SDL_TRUE;
1119  }
1120  }
1121 
1122  /* If the audio driver changes the buffer size, accept it.
1123  This needs to be done after the format is modified above,
1124  otherwise it might not have the correct buffer size.
1125  */
1126  if (device->spec.samples != obtained->samples) {
1127  obtained->samples = device->spec.samples;
1128  SDL_CalculateAudioSpec(obtained);
1129  }
1130 
1131  if (build_cvt) {
1132  /* Build an audio conversion block */
1133  if (SDL_BuildAudioCVT(&device->convert,
1134  obtained->format, obtained->channels,
1135  obtained->freq,
1136  device->spec.format, device->spec.channels,
1137  device->spec.freq) < 0) {
1138  close_audio_device(device);
1139  return 0;
1140  }
1141  if (device->convert.needed) {
1142  device->convert.len = (int) (((double) device->spec.size) /
1143  device->convert.len_ratio);
1144 
1145  device->convert.buf =
1146  (Uint8 *) SDL_AllocAudioMem(device->convert.len *
1147  device->convert.len_mult);
1148  if (device->convert.buf == NULL) {
1149  close_audio_device(device);
1150  SDL_OutOfMemory();
1151  return 0;
1152  }
1153  }
1154  }
1155 
1156  /* Allocate a fake audio memory buffer */
1157  stream_len = (device->convert.needed) ? device->convert.len_cvt : 0;
1158  if (device->spec.size > stream_len) {
1159  stream_len = device->spec.size;
1160  }
1161  SDL_assert(stream_len > 0);
1162  device->fake_stream = (Uint8 *)SDL_AllocAudioMem(stream_len);
1163  if (device->fake_stream == NULL) {
1164  close_audio_device(device);
1165  SDL_OutOfMemory();
1166  return 0;
1167  }
1168 
1169  if (device->spec.callback == NULL) { /* use buffer queueing? */
1170  /* pool a few packets to start. Enough for two callbacks. */
1171  const int packetlen = SDL_AUDIOBUFFERQUEUE_PACKETLEN;
1172  const int wantbytes = ((device->convert.needed) ? device->convert.len : device->spec.size) * 2;
1173  const int wantpackets = (wantbytes / packetlen) + ((wantbytes % packetlen) ? packetlen : 0);
1174  for (i = 0; i < wantpackets; i++) {
1176  if (packet) { /* don't care if this fails, we'll deal later. */
1177  packet->datalen = 0;
1178  packet->startpos = 0;
1179  packet->next = device->buffer_queue_pool;
1180  device->buffer_queue_pool = packet;
1181  }
1182  }
1183 
1185  device->spec.userdata = device;
1186  }
1187 
1188  /* add it to our list of open devices. */
1189  open_devices[id] = device;
1190 
1191  /* Start the audio thread if necessary */
1192  if (!current_audio.impl.ProvidesOwnCallbackThread) {
1193  /* Start the audio thread */
1194  char name[64];
1195  SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) device->id);
1196 /* !!! FIXME: this is nasty. */
1197 #if defined(__WIN32__) && !defined(HAVE_LIBC)
1198 #undef SDL_CreateThread
1199 #if SDL_DYNAMIC_API
1200  device->thread = SDL_CreateThread_REAL(SDL_RunAudio, name, device, NULL, NULL);
1201 #else
1202  device->thread = SDL_CreateThread(SDL_RunAudio, name, device, NULL, NULL);
1203 #endif
1204 #else
1205  device->thread = SDL_CreateThread(SDL_RunAudio, name, device);
1206 #endif
1207  if (device->thread == NULL) {
1208  SDL_CloseAudioDevice(device->id);
1209  SDL_SetError("Couldn't create audio thread");
1210  return 0;
1211  }
1212  }
1213 
1214  return device->id;
1215 }
1216 
1217 
1218 int
1220 {
1221  SDL_AudioDeviceID id = 0;
1222 
1223  /* Start up the audio driver, if necessary. This is legacy behaviour! */
1224  if (!SDL_WasInit(SDL_INIT_AUDIO)) {
1225  if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
1226  return -1;
1227  }
1228  }
1229 
1230  /* SDL_OpenAudio() is legacy and can only act on Device ID #1. */
1231  if (open_devices[0] != NULL) {
1232  SDL_SetError("Audio device is already opened");
1233  return -1;
1234  }
1235 
1236  if (obtained) {
1237  id = open_audio_device(NULL, 0, desired, obtained,
1239  } else {
1240  id = open_audio_device(NULL, 0, desired, NULL, 0, 1);
1241  }
1242 
1243  SDL_assert((id == 0) || (id == 1));
1244  return (id == 0) ? -1 : 0;
1245 }
1246 
1248 SDL_OpenAudioDevice(const char *device, int iscapture,
1249  const SDL_AudioSpec * desired, SDL_AudioSpec * obtained,
1250  int allowed_changes)
1251 {
1252  return open_audio_device(device, iscapture, desired, obtained,
1253  allowed_changes, 2);
1254 }
1255 
1258 {
1259  SDL_AudioDevice *device = get_audio_device(devid);
1261  if (device && device->enabled) {
1262  if (device->paused) {
1263  status = SDL_AUDIO_PAUSED;
1264  } else {
1265  status = SDL_AUDIO_PLAYING;
1266  }
1267  }
1268  return status;
1269 }
1270 
1271 
1274 {
1275  return SDL_GetAudioDeviceStatus(1);
1276 }
1277 
1278 void
1280 {
1281  SDL_AudioDevice *device = get_audio_device(devid);
1282  if (device) {
1283  current_audio.impl.LockDevice(device);
1284  device->paused = pause_on;
1285  current_audio.impl.UnlockDevice(device);
1286  }
1287 }
1288 
1289 void
1290 SDL_PauseAudio(int pause_on)
1291 {
1292  SDL_PauseAudioDevice(1, pause_on);
1293 }
1294 
1295 
1296 void
1298 {
1299  /* Obtain a lock on the mixing buffers */
1300  SDL_AudioDevice *device = get_audio_device(devid);
1301  if (device) {
1302  current_audio.impl.LockDevice(device);
1303  }
1304 }
1305 
1306 void
1308 {
1310 }
1311 
1312 void
1314 {
1315  /* Obtain a lock on the mixing buffers */
1316  SDL_AudioDevice *device = get_audio_device(devid);
1317  if (device) {
1318  current_audio.impl.UnlockDevice(device);
1319  }
1320 }
1321 
1322 void
1324 {
1326 }
1327 
1328 void
1330 {
1331  SDL_AudioDevice *device = get_audio_device(devid);
1332  if (device) {
1333  close_audio_device(device);
1334  open_devices[devid - 1] = NULL;
1335  }
1336 }
1337 
1338 void
1340 {
1342 }
1343 
1344 void
1346 {
1348 
1349  if (!current_audio.name) { /* not initialized?! */
1350  return;
1351  }
1352 
1353  for (i = 0; i < SDL_arraysize(open_devices); i++) {
1354  if (open_devices[i] != NULL) {
1355  SDL_CloseAudioDevice(i+1);
1356  }
1357  }
1358 
1359  free_device_list(&current_audio.outputDevices, &current_audio.outputDeviceCount);
1360  free_device_list(&current_audio.inputDevices, &current_audio.inputDeviceCount);
1361 
1362  /* Free the driver data */
1363  current_audio.impl.Deinitialize();
1364 
1365  SDL_DestroyMutex(current_audio.detectionLock);
1366 
1367  SDL_zero(current_audio);
1368  SDL_zero(open_devices);
1369 }
1370 
1371 #define NUM_FORMATS 10
1372 static int format_idx;
1373 static int format_idx_sub;
1395 };
1396 
1399 {
1400  for (format_idx = 0; format_idx < NUM_FORMATS; ++format_idx) {
1401  if (format_list[format_idx][0] == format) {
1402  break;
1403  }
1404  }
1405  format_idx_sub = 0;
1406  return SDL_NextAudioFormat();
1407 }
1408 
1411 {
1412  if ((format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS)) {
1413  return 0;
1414  }
1416 }
1417 
1418 void
1420 {
1421  switch (spec->format) {
1422  case AUDIO_U8:
1423  spec->silence = 0x80;
1424  break;
1425  default:
1426  spec->silence = 0x00;
1427  break;
1428  }
1429  spec->size = SDL_AUDIO_BITSIZE(spec->format) / 8;
1430  spec->size *= spec->channels;
1431  spec->size *= spec->samples;
1432 }
1433 
1434 
1435 /*
1436  * Moved here from SDL_mixer.c, since it relies on internals of an opened
1437  * audio device (and is deprecated, by the way!).
1438  */
1439 void
1440 SDL_MixAudio(Uint8 * dst, const Uint8 * src, Uint32 len, int volume)
1441 {
1442  /* Mix the user-level audio format */
1443  SDL_AudioDevice *device = get_audio_device(1);
1444  if (device != NULL) {
1446  if (device->convert.needed) {
1447  format = device->convert.src_format;
1448  } else {
1449  format = device->spec.format;
1450  }
1451  SDL_MixAudioFormat(dst, src, format, len, volume);
1452  }
1453 }
1454 
1455 /* vi: set ts=4 sw=4 expandtab: */
static SDL_AudioDevice * open_devices[16]
Definition: SDL_audio.c:34
#define SDL_ThreadID
static int format_idx_sub
Definition: SDL_audio.c:1373
AudioBootStrap DISKAUD_bootstrap
void SDL_LockAudioDevice(SDL_AudioDeviceID devid)
Definition: SDL_audio.c:1297
#define SDL_strlcpy
GLenum GLenum dst
SDL_AudioDeviceID id
Definition: SDL_sysaudio.h:147
#define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE
Definition: SDL_audio.h:140
void SDL_UnlockAudio(void)
Definition: SDL_audio.c:1323
#define SDL_LockMutex
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1565
GLuint id
AudioBootStrap SUNAUDIO_bootstrap
static int format_idx
Definition: SDL_audio.c:1372
GLuint GLfloat GLfloat GLfloat x1
SDL_mutex * mixer_lock
Definition: SDL_sysaudio.h:171
#define SDL_min(x, y)
Definition: SDL_stdinc.h:345
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
Definition: SDL_audio.c:1398
#define AUDIO_S32MSB
Definition: SDL_audio.h:104
SDL_bool captureDevicesRemoved
Definition: SDL_sysaudio.h:124
#define S32
AudioBootStrap PULSEAUDIO_bootstrap
const char * name
Definition: SDL_sysaudio.h:114
void(* DetectDevices)(void)
Definition: SDL_sysaudio.h:71
int SDL_GetNumAudioDrivers(void)
Definition: SDL_audio.c:696
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:155
Uint8 silence
Definition: SDL_audio.h:173
int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
Definition: SDL_audio.c:1219
AudioBootStrap DUMMYAUD_bootstrap
const char * SDL_GetCurrentAudioDriver()
Definition: SDL_audio.c:772
const char * name
Definition: SDL_sysaudio.h:191
static void mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *removedFlag)
Definition: SDL_audio.c:390
#define AUDIO_U16LSB
Definition: SDL_audio.h:91
Uint8 * buf
Definition: SDL_audio.h:206
GLuint GLuint stream
const char * SDL_GetAudioDriver(int index)
Definition: SDL_audio.c:702
#define SDL_BuildAudioCVT
AudioBootStrap NDSAUD_bootstrap
struct SDL_AudioDeviceItem * next
Definition: SDL_sysaudio.h:101
static void clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *removedFlag)
Definition: SDL_audio.c:779
AudioBootStrap QSAAUDIO_bootstrap
static SDL_INLINE int add_output_device(const char *name, void *handle)
Definition: SDL_audio.c:324
#define SDL_CreateMutex
#define SDL_FreeAudioMem
Definition: SDL_audiomem.h:24
static SDL_AudioFormat format_list[NUM_FORMATS][NUM_FORMATS]
Definition: SDL_audio.c:1374
double len_ratio
Definition: SDL_audio.h:210
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1967
SDL_AudioStatus
Definition: SDL_audio.h:368
#define DEFAULT_INPUT_DEVNAME
Definition: SDL_audio.c:38
AudioBootStrap DCAUD_bootstrap
SDL_AudioDeviceID SDL_OpenAudioDevice(const char *device, int iscapture, const SDL_AudioSpec *desired, SDL_AudioSpec *obtained, int allowed_changes)
Definition: SDL_audio.c:1248
SDL_threadID threadid
Definition: SDL_sysaudio.h:175
#define SDL_ENABLE
Definition: SDL_events.h:718
void(* PlayDevice)(_THIS)
Definition: SDL_sysaudio.h:75
SDL_AudioBufferQueue * buffer_queue_pool
Definition: SDL_sysaudio.h:180
Uint16 samples
Definition: SDL_audio.h:174
void(* WaitDevice)(_THIS)
Definition: SDL_sysaudio.h:74
void SDL_ClearQueuedAudio(SDL_AudioDeviceID devid)
Definition: SDL_audio.c:573
void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device)
Definition: SDL_audio.c:364
#define SDL_InitSubSystem
#define SDL_MixAudioFormat
SDL_AudioSpec spec
Definition: SDL_sysaudio.h:150
Uint16 SDL_AudioFormat
Audio format flags.
Definition: SDL_audio.h:64
Uint32 SDL_GetQueuedAudioSize(SDL_AudioDeviceID devid)
Definition: SDL_audio.c:557
static Uint8 * SDL_AudioGetDeviceBuf_Default(_THIS)
Definition: SDL_audio.c:198
GLuint const GLchar * name
AudioBootStrap DSOUND_bootstrap
static void SDL_AudioUnlockDevice_Default(SDL_AudioDevice *device)
Definition: SDL_audio.c:253
static SDL_AudioDriver current_audio
Definition: SDL_audio.c:33
void(* UnlockDevice)(_THIS)
Definition: SDL_sysaudio.h:81
AudioBootStrap ARTS_bootstrap
int SDL_RunAudio(void *devicep)
Definition: SDL_audio.c:595
#define SDL_strncasecmp
static void finalize_audio_entry_points(void)
Definition: SDL_audio.c:262
AudioBootStrap WINMM_bootstrap
#define SDL_zerop(x)
Definition: SDL_stdinc.h:356
GLsizeiptr size
AudioBootStrap BSD_AUDIO_bootstrap
GLfixed GLfixed x2
GLenum GLsizei len
SDL_AudioFormat SDL_NextAudioFormat(void)
Definition: SDL_audio.c:1410
#define SDL_AUDIO_ALLOW_CHANNELS_CHANGE
Definition: SDL_audio.h:142
AudioBootStrap DART_bootstrap
#define FILL_STUB(x)
#define AUDIO_F32MSB
Definition: SDL_audio.h:113
SDL_mutex * detectionLock
Definition: SDL_sysaudio.h:123
SDL_AudioBufferQueue * buffer_queue_head
Definition: SDL_sysaudio.h:178
SDL_bool
Definition: SDL_stdinc.h:126
#define DEFAULT_OUTPUT_DEVNAME
Definition: SDL_audio.c:37
SDL_AudioSpec spec
Definition: loopwave.c:35
SDL_bool retval
#define AUDIO_U8
Definition: SDL_audio.h:89
void SDL_LockAudio(void)
Definition: SDL_audio.c:1307
SDL_AudioBufferQueue * buffer_queue_tail
Definition: SDL_sysaudio.h:179
#define SDL_memcpy
static void SDL_AudioDeinitialize_Default(void)
Definition: SDL_audio.c:214
struct SDL_AudioBufferQueue * next
Definition: SDL_sysaudio.h:66
void(* ThreadInit)(_THIS)
Definition: SDL_sysaudio.h:73
SDL_AudioStatus SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid)
Definition: SDL_audio.c:1257
#define SDL_GetEventState(type)
Definition: SDL_events.h:731
#define SDL_ConvertAudio
AudioBootStrap NACLAUD_bootstrap
void SDL_RemoveAudioDevice(const int iscapture, void *handle)
Definition: SDL_audio.c:405
Uint8 channels
Definition: SDL_audio.h:172
#define _THIS
Definition: SDL_audio.c:31
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
const char * desc
Definition: SDL_sysaudio.h:118
struct _cl_event * event
static void SDL_AudioWaitDevice_Default(_THIS)
Definition: SDL_audio.c:182
void SDL_free(void *mem)
#define SDL_AUDIO_BITSIZE(x)
Definition: SDL_audio.h:75
#define AUDIO_F32LSB
Definition: SDL_audio.h:112
AudioBootStrap PAUDIO_bootstrap
void SDL_AudioQuit(void)
Definition: SDL_audio.c:1345
#define SDL_AUDIO_ALLOW_ANY_CHANGE
Definition: SDL_audio.h:143
#define SDL_PushEvent
void(* Deinitialize)(void)
Definition: SDL_sysaudio.h:83
static int prepare_audiospec(const SDL_AudioSpec *orig, SDL_AudioSpec *prepared)
Definition: SDL_audio.c:905
void SDL_UnlockAudioDevice(SDL_AudioDeviceID devid)
Definition: SDL_audio.c:1313
static int SDL_AudioOpenDevice_Default(_THIS, void *handle, const char *devname, int iscapture)
Definition: SDL_audio.c:225
AudioBootStrap COREAUDIO_bootstrap
#define AUDIO_S32LSB
Definition: SDL_audio.h:103
#define SDL_zero(x)
Definition: SDL_stdinc.h:355
void SDL_PauseAudio(int pause_on)
Definition: SDL_audio.c:1290
#define NUM_FORMATS
Definition: SDL_audio.c:1371
AudioBootStrap ALSA_bootstrap
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
Definition: SDL_audio.c:1419
#define SDL_AllocAudioMem
Definition: SDL_audiomem.h:23
GLsizei samples
SDL_AudioStatus SDL_GetAudioStatus(void)
Definition: SDL_audio.c:1273
SDL_AudioCallback callback
Definition: SDL_audio.h:177
SDL_AudioFormat src_format
Definition: SDL_audio.h:203
static void SDL_AudioThreadInit_Default(_THIS)
Definition: SDL_audio.c:177
static void SDL_AudioDetectDevices_Default(void)
Definition: SDL_audio.c:164
Uint8 * fake_stream
Definition: SDL_sysaudio.h:168
#define SDL_atoi
GLuint index
static int add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
Definition: SDL_audio.c:293
AudioBootStrap NAS_bootstrap
void(* LockDevice)(_THIS)
Definition: SDL_sysaudio.h:80
#define SDL_CreateThread
const char * SDL_GetAudioDeviceName(int index, int iscapture)
Definition: SDL_audio.c:833
#define SDL_Delay
#define SDL_getenv
SDL_AudioDeviceItem * outputDevices
Definition: SDL_sysaudio.h:128
Uint32 size
Definition: SDL_audio.h:176
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:42
static int SDL_AudioGetPendingBytes_Default(_THIS)
Definition: SDL_audio.c:192
#define SDL_assert(condition)
Definition: SDL_assert.h:167
static const AudioBootStrap *const bootstrap[]
Definition: SDL_audio.c:76
AudioBootStrap SNDMGR_bootstrap
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
Definition: SDL_sysaudio.h:72
static void SDL_AudioPlayDevice_Default(_THIS)
Definition: SDL_audio.c:187
#define NULL
Definition: begin_code.h:143
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_bool outputDevicesRemoved
Definition: SDL_sysaudio.h:125
static void free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
Definition: SDL_audio.c:330
static void free_audio_queue(SDL_AudioBufferQueue *buffer)
Definition: SDL_audio.c:423
AudioBootStrap DSP_bootstrap
#define SDL_SetError
static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture, const SDL_AudioSpec *desired, SDL_AudioSpec *obtained, int allowed_changes, int min_id)
Definition: SDL_audio.c:962
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
void(* CloseDevice)(_THIS)
Definition: SDL_sysaudio.h:79
#define SDL_DestroyMutex
static SDL_INLINE int add_capture_device(const char *name, void *handle)
Definition: SDL_audio.c:317
#define SDL_INIT_AUDIO
Definition: SDL.h:76
#define AUDIO_S16MSB
Definition: SDL_audio.h:94
static void SDL_AudioLockDevice_Default(SDL_AudioDevice *device)
Definition: SDL_audio.c:245
Uint32 SDL_AudioDeviceID
Definition: SDL_audio.h:303
SDL_AudioDriverImpl impl
Definition: SDL_sysaudio.h:120
void(* FreeDeviceHandle)(void *handle)
Definition: SDL_sysaudio.h:82
#define SDL_strlen
SDL_AudioFormat format
Definition: SDL_audio.h:171
AudioBootStrap XAUDIO2_bootstrap
AudioBootStrap HAIKUAUDIO_bootstrap
GLuint buffer
#define AUDIO_S16
Definition: SDL_audio.h:96
#define AUDIO_S16LSB
Definition: SDL_audio.h:92
void SDL_CloseAudio(void)
Definition: SDL_audio.c:1339
Uint8 *(* GetDeviceBuf)(_THIS)
Definition: SDL_sysaudio.h:77
int SDL_GetNumAudioDevices(int iscapture)
Definition: SDL_audio.c:807
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:147
void * userdata
Definition: SDL_audio.h:178
#define SDL_AUDIO_ALLOW_FORMAT_CHANGE
Definition: SDL_audio.h:141
#define SDL_snprintf
static SDL_AudioFormat SDL_ParseAudioFormat(const char *string)
Definition: SDL_audio.c:670
#define SDL_UnlockMutex
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:93
Uint8 data[SDL_AUDIOBUFFERQUEUE_PACKETLEN]
Definition: SDL_sysaudio.h:63
#define SDL_INLINE
Definition: begin_code.h:120
General event structure.
Definition: SDL_events.h:521
#define SDL_malloc
int(* init)(SDL_AudioDriverImpl *impl)
Definition: SDL_sysaudio.h:193
static void SDL_AudioCloseDevice_Default(_THIS)
Definition: SDL_audio.c:209
int(* GetPendingBytes)(_THIS)
Definition: SDL_sysaudio.h:76
#define SDL_strcmp
const char * desc
Definition: SDL_sysaudio.h:192
AudioBootStrap ESD_bootstrap
SDL_Thread * thread
Definition: SDL_sysaudio.h:174
#define SDL_WasInit
void SDL_CloseAudioDevice(SDL_AudioDeviceID devid)
Definition: SDL_audio.c:1329
static void SDL_AudioWaitDone_Default(_THIS)
Definition: SDL_audio.c:204
#define SDL_AUDIOBUFFERQUEUE_PACKETLEN
Definition: SDL_sysaudio.h:58
AudioBootStrap ANDROIDAUD_bootstrap
SDL_AudioCVT convert
Definition: SDL_sysaudio.h:153
static void SDL_BufferQueueDrainCallback(void *userdata, Uint8 *stream, int _len)
Definition: SDL_audio.c:433
#define AUDIO_S8
Definition: SDL_audio.h:90
void SDL_MixAudio(Uint8 *dst, const Uint8 *src, Uint32 len, int volume)
Definition: SDL_audio.c:1440
#define CHECK_FMT_STRING(x)
GLenum src
#define SDLCALL
Definition: SDL_internal.h:31
void SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on)
Definition: SDL_audio.c:1279
static SDL_AudioDevice * get_audio_device(SDL_AudioDeviceID id)
Definition: SDL_audio.c:150
#define SDL_Unsupported()
Definition: SDL_error.h:53
AudioBootStrap PSPAUD_bootstrap
static SDL_INLINE SDL_bool is_in_audio_device_thread(SDL_AudioDevice *device)
Definition: SDL_audio.c:231
#define SDL_SetThreadPriority
AudioBootStrap EmscriptenAudio_bootstrap
SDL_AudioDeviceItem * inputDevices
Definition: SDL_sysaudio.h:129
#define SDL_memset
void(* WaitDone)(_THIS)
Definition: SDL_sysaudio.h:78
static void SDL_AudioFreeDeviceHandle_Default(void *handle)
Definition: SDL_audio.c:219
AudioBootStrap SNDIO_bootstrap
int SDL_AudioInit(const char *driver_name)
Definition: SDL_audio.c:711
#define SDL_WaitThread
#define AUDIO_U16MSB
Definition: SDL_audio.h:93
void SDL_AddAudioDevice(const int iscapture, const char *name, void *handle)
Definition: SDL_audio.c:347
static void close_audio_device(SDL_AudioDevice *device)
Definition: SDL_audio.c:873
AudioBootStrap FUSIONSOUND_bootstrap
int SDL_QueueAudio(SDL_AudioDeviceID devid, const void *_data, Uint32 len)
Definition: SDL_audio.c:475