SDL  2.0
testaudiohotplug.c
Go to the documentation of this file.
1 /*
2  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
3 
4  This software is provided 'as-is', without any express or implied
5  warranty. In no event will the authors be held liable for any damages
6  arising from the use of this software.
7 
8  Permission is granted to anyone to use this software for any purpose,
9  including commercial applications, and to alter it and redistribute it
10  freely.
11 */
12 
13 /* Program to test hotplugging of audio devices */
14 
15 #include "SDL_config.h"
16 
17 #include <stdio.h>
18 #include <stdlib.h>
19 
20 #if HAVE_SIGNAL_H
21 #include <signal.h>
22 #endif
23 
24 #ifdef __EMSCRIPTEN__
25 #include <emscripten/emscripten.h>
26 #endif
27 
28 #include "SDL.h"
29 
31 static Uint8 *sound = NULL; /* Pointer to wave data */
32 static Uint32 soundlen = 0; /* Length of wave data */
33 
34 static int posindex = 0;
35 static Uint32 positions[64];
36 
37 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
38 static void
39 quit(int rc)
40 {
41  SDL_Quit();
42  exit(rc);
43 }
44 
45 void SDLCALL
46 fillerup(void *_pos, Uint8 * stream, int len)
47 {
48  Uint32 pos = *((Uint32 *) _pos);
49  Uint8 *waveptr;
50  int waveleft;
51 
52  /* Set up the pointers */
53  waveptr = sound + pos;
54  waveleft = soundlen - pos;
55 
56  /* Go! */
57  while (waveleft <= len) {
58  SDL_memcpy(stream, waveptr, waveleft);
59  stream += waveleft;
60  len -= waveleft;
61  waveptr = sound;
62  waveleft = soundlen;
63  pos = 0;
64  }
65  SDL_memcpy(stream, waveptr, len);
66  pos += len;
67  *((Uint32 *) _pos) = pos;
68 }
69 
70 static int done = 0;
71 void
72 poked(int sig)
73 {
74  done = 1;
75 }
76 
77 static void
79 {
80  SDL_Event e;
82  while (SDL_PollEvent(&e)) {
83  if (e.type == SDL_QUIT) {
84  done = 1;
85  } else if (e.type == SDL_AUDIODEVICEADDED) {
86  const char *name = SDL_GetAudioDeviceName(e.adevice.which, 0);
87  SDL_Log("New %s audio device: %s\n", e.adevice.iscapture ? "capture" : "output", name);
88  if (!e.adevice.iscapture) {
89  positions[posindex] = 0;
90  spec.userdata = &positions[posindex++];
91  spec.callback = fillerup;
92  dev = SDL_OpenAudioDevice(name, 0, &spec, NULL, 0);
93  if (!dev) {
94  SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open '%s': %s\n", name, SDL_GetError());
95  } else {
96  SDL_Log("Opened '%s' as %u\n", name, (unsigned int) dev);
97  SDL_PauseAudioDevice(dev, 0);
98  }
99  }
100  } else if (e.type == SDL_AUDIODEVICEREMOVED) {
101  dev = (SDL_AudioDeviceID) e.adevice.which;
102  SDL_Log("%s device %u removed.\n", e.adevice.iscapture ? "capture" : "output", (unsigned int) dev);
104  }
105  }
106 }
107 
108 #ifdef __EMSCRIPTEN__
109 void
110 loop()
111 {
112  if(done)
113  emscripten_cancel_main_loop();
114  else
115  iteration();
116 }
117 #endif
118 
119 int
120 main(int argc, char *argv[])
121 {
122  int i;
123  char filename[4096];
124 
125  /* Enable standard application logging */
127 
128  /* Load the SDL library */
130  SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
131  return (1);
132  }
133 
134  /* Some targets (Mac CoreAudio) need an event queue for audio hotplug, so make and immediately hide a window. */
136 
137  if (argc > 1) {
138  SDL_strlcpy(filename, argv[1], sizeof(filename));
139  } else {
140  SDL_strlcpy(filename, "sample.wav", sizeof(filename));
141  }
142  /* Load the wave file into memory */
143  if (SDL_LoadWAV(filename, &spec, &sound, &soundlen) == NULL) {
144  SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError());
145  quit(1);
146  }
147 
148 #if HAVE_SIGNAL_H
149  /* Set the signals */
150 #ifdef SIGHUP
151  signal(SIGHUP, poked);
152 #endif
153  signal(SIGINT, poked);
154 #ifdef SIGQUIT
155  signal(SIGQUIT, poked);
156 #endif
157  signal(SIGTERM, poked);
158 #endif /* HAVE_SIGNAL_H */
159 
160  /* Show the list of available drivers */
161  SDL_Log("Available audio drivers:");
162  for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) {
163  SDL_Log("%i: %s", i, SDL_GetAudioDriver(i));
164  }
165 
166  SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
167 
168 #ifdef __EMSCRIPTEN__
169  emscripten_set_main_loop(loop, 0, 1);
170 #else
171  while (!done) {
172  SDL_Delay(100);
173  iteration();
174  }
175 #endif
176 
177  /* Clean up on signal */
179  SDL_Quit();
180  return (0);
181 }
182 
183 /* vi: set ts=4 sw=4 expandtab: */
#define SDL_GetNumAudioDrivers
#define SDL_strlcpy
void loop()
Definition: checkkeys.c:152
#define SDL_PollEvent
#define SDL_GetError
#define SDL_CloseAudioDevice
#define SDL_OpenAudioDevice
static SDL_AudioSpec spec
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:155
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
GLuint GLuint stream
void poked(int sig)
#define SDL_FreeWAV
#define SDL_CreateWindow
#define SDL_WINDOWPOS_UNDEFINED
Definition: SDL_video.h:120
GLuint const GLchar * name
#define SDL_MinimizeWindow
static void quit(int rc)
GLenum GLsizei len
static void iteration()
#define SDL_LogError
static Uint8 * sound
#define SDL_GetAudioDeviceName
#define SDL_Log
#define SDL_memcpy
static int posindex
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
#define SDL_Quit
#define SDL_LoadWAV(file, spec, audio_buf, audio_len)
Definition: SDL_audio.h:424
static Uint32 positions[64]
#define SDL_GetAudioDriver
static Uint32 soundlen
SDL_AudioCallback callback
Definition: SDL_audio.h:177
int main(int argc, char *argv[])
#define SDL_Delay
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
#define SDL_LogSetPriority
#define SDL_GetCurrentAudioDriver
#define NULL
Definition: begin_code.h:143
SDL_AudioDeviceEvent adevice
Definition: SDL_events.h:540
#define SDL_INIT_AUDIO
Definition: SDL.h:76
Uint32 SDL_AudioDeviceID
Definition: SDL_audio.h:303
void fillerup(void *_pos, Uint8 *stream, int len)
void * userdata
Definition: SDL_audio.h:178
#define SDL_Init
General event structure.
Definition: SDL_events.h:521
static int done
#define SDLCALL
Definition: SDL_internal.h:31
#define SDL_INIT_VIDEO
Definition: SDL.h:77
Uint32 type
Definition: SDL_events.h:523
#define SDL_PauseAudioDevice