2 Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
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.
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
14 #include <stdio.h> /* for fflush() and stdout */
17 #include <emscripten/emscripten.h>
20 static SDL_AudioSpec spec;
21 static Uint8 *sound = NULL; /* Pointer to wave data */
22 static Uint32 soundlen = 0; /* Length of wave data */
26 SDL_AudioDeviceID dev;
31 callback_data cbd[64];
34 play_through_once(void *arg, Uint8 * stream, int len)
36 callback_data *cbd = (callback_data *) arg;
37 Uint8 *waveptr = sound + cbd->soundpos;
38 int waveleft = soundlen - cbd->soundpos;
43 SDL_memcpy(stream, waveptr, cpy);
48 SDL_memset(stream, spec.silence, len);
49 SDL_AtomicSet(&cbd->done, 1);
56 if (SDL_AtomicGet(&cbd[0].done)) {
58 emscripten_cancel_main_loop();
60 SDL_PauseAudioDevice(cbd[0].dev, 1);
61 SDL_CloseAudioDevice(cbd[0].dev);
68 test_multi_audio(int devcount)
76 /* Create a Window to get fully initialized event processing for testing pause on Android. */
77 SDL_CreateWindow("testmultiaudio", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 320, 240, 0);
81 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Too many devices (%d), clamping to 64...\n",
86 spec.callback = play_through_once;
88 for (i = 0; i < devcount; i++) {
89 const char *devname = SDL_GetAudioDeviceName(i, 0);
90 SDL_Log("playing on device #%d: ('%s')...", i, devname);
93 SDL_memset(&cbd[0], '\0', sizeof(callback_data));
94 spec.userdata = &cbd[0];
95 cbd[0].dev = SDL_OpenAudioDevice(devname, 0, &spec, NULL, 0);
96 if (cbd[0].dev == 0) {
97 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device failed: %s\n", SDL_GetError());
99 SDL_PauseAudioDevice(cbd[0].dev, 0);
100 #ifdef __EMSCRIPTEN__
101 emscripten_set_main_loop(loop, 0, 1);
103 while (!SDL_AtomicGet(&cbd[0].done)) {
105 /* Empty queue, some application events would prevent pause. */
106 while (SDL_PollEvent(&event)){}
110 SDL_PauseAudioDevice(cbd[0].dev, 1);
113 SDL_CloseAudioDevice(cbd[0].dev);
117 SDL_memset(cbd, '\0', sizeof(cbd));
119 SDL_Log("playing on all devices...\n");
120 for (i = 0; i < devcount; i++) {
121 const char *devname = SDL_GetAudioDeviceName(i, 0);
122 spec.userdata = &cbd[i];
123 cbd[i].dev = SDL_OpenAudioDevice(devname, 0, &spec, NULL, 0);
124 if (cbd[i].dev == 0) {
125 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device %d failed: %s\n", i, SDL_GetError());
129 for (i = 0; i < devcount; i++) {
131 SDL_PauseAudioDevice(cbd[i].dev, 0);
137 for (i = 0; i < devcount; i++) {
138 if ((cbd[i].dev) && (!SDL_AtomicGet(&cbd[i].done))) {
143 /* Empty queue, some application events would prevent pause. */
144 while (SDL_PollEvent(&event)){}
150 #ifndef __EMSCRIPTEN__
151 for (i = 0; i < devcount; i++) {
153 SDL_PauseAudioDevice(cbd[i].dev, 1);
154 SDL_CloseAudioDevice(cbd[i].dev);
158 SDL_Log("All done!\n");
164 main(int argc, char **argv)
168 /* Enable standard application logging */
169 SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
171 /* Load the SDL library */
172 if (SDL_Init(SDL_INIT_AUDIO) < 0) {
173 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
177 SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
179 devcount = SDL_GetNumAudioDevices(0);
181 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Don't see any specific audio devices!\n");
183 if (argv[1] == NULL) {
184 argv[1] = "sample.wav";
187 /* Load the wave file into memory */
188 if (SDL_LoadWAV(argv[1], &spec, &sound, &soundlen) == NULL) {
189 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", argv[1],
192 test_multi_audio(devcount);