testaudiohotplug.c
Go to the documentation of this file.
/*
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
/* Program to test hotplugging of audio devices */
#include "SDL_config.h"
#include <stdio.h>
#include <stdlib.h>
#if HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#endif
#include "SDL.h"
static SDL_AudioSpec spec;
static Uint8 *sound = NULL; /* Pointer to wave data */
static Uint32 soundlen = 0; /* Length of wave data */
static int posindex = 0;
static Uint32 positions[64];
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void
quit(int rc)
{
SDL_Quit();
exit(rc);
}
void SDLCALL
fillerup(void *_pos, Uint8 * stream, int len)
{
Uint32 pos = *((Uint32 *) _pos);
Uint8 *waveptr;
int waveleft;
/* Set up the pointers */
waveptr = sound + pos;
waveleft = soundlen - pos;
/* Go! */
while (waveleft <= len) {
SDL_memcpy(stream, waveptr, waveleft);
stream += waveleft;
len -= waveleft;
waveptr = sound;
waveleft = soundlen;
pos = 0;
}
SDL_memcpy(stream, waveptr, len);
pos += len;
*((Uint32 *) _pos) = pos;
}
static int done = 0;
void
poked(int sig)
{
done = 1;
}
static const char*
devtypestr(int iscapture)
{
return iscapture ? "capture" : "output";
}
static void
iteration()
{
SDL_Event e;
SDL_AudioDeviceID dev;
while (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT) {
done = 1;
} else if (e.type == SDL_KEYUP) {
if (e.key.keysym.sym == SDLK_ESCAPE)
done = 1;
} else if (e.type == SDL_AUDIODEVICEADDED) {
int index = e.adevice.which;
int iscapture = e.adevice.iscapture;
const char *name = SDL_GetAudioDeviceName(index, iscapture);
if (name != NULL)
SDL_Log("New %s audio device at index %u: %s\n", devtypestr(iscapture), (unsigned int) index, name);
else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Got new %s device at index %u, but failed to get the name: %s\n",
devtypestr(iscapture), (unsigned int) index, SDL_GetError());
continue;
}
if (!iscapture) {
positions[posindex] = 0;
spec.userdata = &positions[posindex++];
spec.callback = fillerup;
dev = SDL_OpenAudioDevice(name, 0, &spec, NULL, 0);
if (!dev) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open '%s': %s\n", name, SDL_GetError());
} else {
SDL_Log("Opened '%s' as %u\n", name, (unsigned int) dev);
SDL_PauseAudioDevice(dev, 0);
}
}
} else if (e.type == SDL_AUDIODEVICEREMOVED) {
dev = (SDL_AudioDeviceID) e.adevice.which;
SDL_Log("%s device %u removed.\n", devtypestr(e.adevice.iscapture), (unsigned int) dev);
SDL_CloseAudioDevice(dev);
}
}
}
#ifdef __EMSCRIPTEN__
void
loop()
{
if(done)
emscripten_cancel_main_loop();
else
iteration();
}
#endif
int
main(int argc, char *argv[])
{
int i;
char filename[4096];
/* Enable standard application logging */
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
/* Load the SDL library */
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
return (1);
}
/* Some targets (Mac CoreAudio) need an event queue for audio hotplug, so make and immediately hide a window. */
SDL_MinimizeWindow(SDL_CreateWindow("testaudiohotplug", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0));
if (argc > 1) {
SDL_strlcpy(filename, argv[1], sizeof(filename));
} else {
SDL_strlcpy(filename, "sample.wav", sizeof(filename));
}
/* Load the wave file into memory */
if (SDL_LoadWAV(filename, &spec, &sound, &soundlen) == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError());
quit(1);
}
#if HAVE_SIGNAL_H
/* Set the signals */
#ifdef SIGHUP
signal(SIGHUP, poked);
#endif
signal(SIGINT, poked);
#ifdef SIGQUIT
signal(SIGQUIT, poked);
#endif
signal(SIGTERM, poked);
#endif /* HAVE_SIGNAL_H */
/* Show the list of available drivers */
SDL_Log("Available audio drivers:");
for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) {
SDL_Log("%i: %s", i, SDL_GetAudioDriver(i));
}
SDL_Log("Select a driver with the SDL_AUDIODRIVER environment variable.\n");
SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
#ifdef __EMSCRIPTEN__
emscripten_set_main_loop(loop, 0, 1);
#else
while (!done) {
SDL_Delay(100);
iteration();
}
#endif
/* Clean up on signal */
/* Quit audio first, then free WAV. This prevents access violations in the audio threads. */
SDL_QuitSubSystem(SDL_INIT_AUDIO);
SDL_FreeWAV(sound);
SDL_Quit();
return (0);
}
/* vi: set ts=4 sw=4 expandtab: */
SDL_GetNumAudioDrivers
#define SDL_GetNumAudioDrivers
Definition: SDL_dynapi_overrides.h:73
SDL_strlcpy
#define SDL_strlcpy
Definition: SDL_dynapi_overrides.h:394
loop
void loop()
Definition: checkkeys.c:152
SDL_PollEvent
#define SDL_PollEvent
Definition: SDL_dynapi_overrides.h:122
SDL_GetError
#define SDL_GetError
Definition: SDL_dynapi_overrides.h:113
SDL_CloseAudioDevice
#define SDL_CloseAudioDevice
Definition: SDL_dynapi_overrides.h:97
SDL_OpenAudioDevice
#define SDL_OpenAudioDevice
Definition: SDL_dynapi_overrides.h:81
spec
static SDL_AudioSpec spec
Definition: testaudiohotplug.c:30
e
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 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 Uint32 * e
Definition: SDL_dynapi_procs.h:117
devtypestr
static const char * devtypestr(int iscapture)
Definition: testaudiohotplug.c:78
SDL_QuitSubSystem
#define SDL_QuitSubSystem
Definition: SDL_dynapi_overrides.h:56
SDL_QUIT
Definition: SDL_events.h:60
SDL_AudioSpec
Definition: SDL_audio.h:177
poked
void poked(int sig)
Definition: testaudiohotplug.c:72
SDL_FreeWAV
#define SDL_FreeWAV
Definition: SDL_dynapi_overrides.h:87
SDL_CreateWindow
#define SDL_CreateWindow
Definition: SDL_dynapi_overrides.h:514
SDL_WINDOWPOS_UNDEFINED
#define SDL_WINDOWPOS_UNDEFINED
Definition: SDL_video.h:130
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:181
SDL_MinimizeWindow
#define SDL_MinimizeWindow
Definition: SDL_dynapi_overrides.h:537
quit
static void quit(int rc)
Definition: testaudiohotplug.c:39
SDL_config.h
len
GLenum GLsizei len
Definition: SDL_opengl_glext.h:2926
name
GLuint const GLchar * name
Definition: SDL_opengl_glext.h:660
iteration
static void iteration()
Definition: testaudiohotplug.c:84
SDL_LogError
#define SDL_LogError
Definition: SDL_dynapi_overrides.h:36
sound
static Uint8 * sound
Definition: testaudiohotplug.c:31
SDL_GetAudioDeviceName
#define SDL_GetAudioDeviceName
Definition: SDL_dynapi_overrides.h:80
SDL_AUDIODEVICEREMOVED
Definition: SDL_events.h:145
SDL_Log
#define SDL_Log
Definition: SDL_dynapi_overrides.h:31
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:387
posindex
static int posindex
Definition: testaudiohotplug.c:34
SDL_AUDIODEVICEADDED
Definition: SDL_events.h:144
stream
GLuint GLuint stream
Definition: SDL_opengl_glext.h:1776
sort_controllers.filename
string filename
Definition: sort_controllers.py:8
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:157
SDL_KEYUP
Definition: SDL_events.h:94
SDL_Quit
#define SDL_Quit
Definition: SDL_dynapi_overrides.h:58
SDL_LoadWAV
#define SDL_LoadWAV(file, spec, audio_buf, audio_len)
Definition: SDL_audio.h:450
positions
static Uint32 positions[64]
Definition: testaudiohotplug.c:35
SDL_GetAudioDriver
#define SDL_GetAudioDriver
Definition: SDL_dynapi_overrides.h:74
SDL_LOG_PRIORITY_INFO
Definition: SDL_log.h:106
SDL_KeyboardEvent::keysym
SDL_Keysym keysym
Definition: SDL_events.h:199
soundlen
static Uint32 soundlen
Definition: testaudiohotplug.c:32
SDL_AudioSpec::callback
SDL_AudioCallback callback
Definition: SDL_audio.h:186
main
int main(int argc, char *argv[])
Definition: testaudiohotplug.c:137
index
GLuint index
Definition: SDL_opengl_glext.h:660
SDL_Delay
#define SDL_Delay
Definition: SDL_dynapi_overrides.h:486
i
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:50
SDL_LogSetPriority
#define SDL_LogSetPriority
Definition: SDL_dynapi_overrides.h:236
SDL_GetCurrentAudioDriver
#define SDL_GetCurrentAudioDriver
Definition: SDL_dynapi_overrides.h:77
NULL
#define NULL
Definition: begin_code.h:164
SDL_Event::adevice
SDL_AudioDeviceEvent adevice
Definition: SDL_events.h:544
SDL_INIT_AUDIO
#define SDL_INIT_AUDIO
Definition: SDL.h:77
SDL_Event::key
SDL_KeyboardEvent key
Definition: SDL_events.h:530
SDL_AudioDeviceID
Uint32 SDL_AudioDeviceID
Definition: SDL_audio.h:329
fillerup
void fillerup(void *_pos, Uint8 *stream, int len)
Definition: testaudiohotplug.c:46
SDL_Keysym::sym
SDL_Keycode sym
Definition: SDL_keyboard.h:50
SDL_AudioSpec::userdata
void * userdata
Definition: SDL_audio.h:187
SDL_Init
#define SDL_Init
Definition: SDL_dynapi_overrides.h:54
SDL_Event
General event structure.
Definition: SDL_events.h:525
SDL_AudioDeviceEvent::which
Uint32 which
Definition: SDL_events.h:402
SDLK_ESCAPE
Definition: SDL_keycode.h:55
SDL.h
done
static int done
Definition: testaudiohotplug.c:70
SDLCALL
#define SDLCALL
Definition: SDL_internal.h:45
SDL_AudioDeviceEvent::iscapture
Uint8 iscapture
Definition: SDL_events.h:403
SDL_LOG_CATEGORY_APPLICATION
Definition: SDL_log.h:66
SDL_INIT_VIDEO
#define SDL_INIT_VIDEO
Definition: SDL.h:78
SDL_Event::type
Uint32 type
Definition: SDL_events.h:527
SDL_PauseAudioDevice
#define SDL_PauseAudioDevice
Definition: SDL_dynapi_overrides.h:85