testmultiaudio.c
Go to the documentation of this file.
/*
Copyright (C) 1997-2016 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.
*/
#include "SDL.h"
#include <stdio.h> /* for fflush() and stdout */
#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#endif
static SDL_AudioSpec spec;
static Uint8 *sound = NULL; /* Pointer to wave data */
static Uint32 soundlen = 0; /* Length of wave data */
typedef struct
{
SDL_AudioDeviceID dev;
int soundpos;
volatile int done;
} callback_data;
callback_data cbd[64];
void SDLCALL
play_through_once(void *arg, Uint8 * stream, int len)
{
callback_data *cbd = (callback_data *) arg;
Uint8 *waveptr = sound + cbd->soundpos;
int waveleft = soundlen - cbd->soundpos;
int cpy = len;
if (cpy > waveleft)
cpy = waveleft;
SDL_memcpy(stream, waveptr, cpy);
len -= cpy;
cbd->soundpos += cpy;
if (len > 0) {
stream += cpy;
SDL_memset(stream, spec.silence, len);
cbd->done++;
}
}
void
loop()
{
if(cbd[0].done) {
#ifdef __EMSCRIPTEN__
emscripten_cancel_main_loop();
#endif
SDL_PauseAudioDevice(cbd[0].dev, 1);
SDL_CloseAudioDevice(cbd[0].dev);
SDL_FreeWAV(sound);
SDL_Quit();
}
}
static void
test_multi_audio(int devcount)
{
int keep_going = 1;
int i;
#ifdef __ANDROID__
SDL_Event event;
/* Create a Window to get fully initialized event processing for testing pause on Android. */
SDL_CreateWindow("testmultiaudio", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 320, 240, 0);
#endif
if (devcount > 64) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Too many devices (%d), clamping to 64...\n",
devcount);
devcount = 64;
}
spec.callback = play_through_once;
for (i = 0; i < devcount; i++) {
const char *devname = SDL_GetAudioDeviceName(i, 0);
SDL_Log("playing on device #%d: ('%s')...", i, devname);
fflush(stdout);
SDL_memset(&cbd[0], '\0', sizeof(callback_data));
spec.userdata = &cbd[0];
cbd[0].dev = SDL_OpenAudioDevice(devname, 0, &spec, NULL, 0);
if (cbd[0].dev == 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device failed: %s\n", SDL_GetError());
} else {
SDL_PauseAudioDevice(cbd[0].dev, 0);
#ifdef __EMSCRIPTEN__
emscripten_set_main_loop(loop, 0, 1);
#else
while (!cbd[0].done)
{
#ifdef __ANDROID__
/* Empty queue, some application events would prevent pause. */
while (SDL_PollEvent(&event)){}
#endif
SDL_Delay(100);
}
SDL_PauseAudioDevice(cbd[0].dev, 1);
#endif
SDL_Log("done.\n");
SDL_CloseAudioDevice(cbd[0].dev);
}
}
SDL_memset(cbd, '\0', sizeof(cbd));
SDL_Log("playing on all devices...\n");
for (i = 0; i < devcount; i++) {
const char *devname = SDL_GetAudioDeviceName(i, 0);
spec.userdata = &cbd[i];
cbd[i].dev = SDL_OpenAudioDevice(devname, 0, &spec, NULL, 0);
if (cbd[i].dev == 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device %d failed: %s\n", i, SDL_GetError());
}
}
for (i = 0; i < devcount; i++) {
if (cbd[i].dev) {
SDL_PauseAudioDevice(cbd[i].dev, 0);
}
}
while (keep_going) {
keep_going = 0;
for (i = 0; i < devcount; i++) {
if ((cbd[i].dev) && (!cbd[i].done)) {
keep_going = 1;
}
}
#ifdef __ANDROID__
/* Empty queue, some application events would prevent pause. */
while (SDL_PollEvent(&event)){}
#endif
SDL_Delay(100);
}
#ifndef __EMSCRIPTEN__
for (i = 0; i < devcount; i++) {
if (cbd[i].dev) {
SDL_PauseAudioDevice(cbd[i].dev, 1);
SDL_CloseAudioDevice(cbd[i].dev);
}
}
SDL_Log("All done!\n");
#endif
}
int
main(int argc, char **argv)
{
int devcount = 0;
/* Enable standard application logging */
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
/* Load the SDL library */
if (SDL_Init(SDL_INIT_AUDIO) < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
return (1);
}
SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
devcount = SDL_GetNumAudioDevices(0);
if (devcount < 1) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Don't see any specific audio devices!\n");
} else {
if (argv[1] == NULL) {
argv[1] = "sample.wav";
}
/* Load the wave file into memory */
if (SDL_LoadWAV(argv[1], &spec, &sound, &soundlen) == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", argv[1],
SDL_GetError());
} else {
test_multi_audio(devcount);
SDL_FreeWAV(sound);
}
}
SDL_Quit();
return 0;
}
SDL_GetNumAudioDevices
#define SDL_GetNumAudioDevices
Definition: SDL_dynapi_overrides.h:85
SDL_WINDOWPOS_CENTERED
#define SDL_WINDOWPOS_CENTERED
Definition: SDL_video.h:129
SDL_PollEvent
#define SDL_PollEvent
Definition: SDL_dynapi_overrides.h:128
SDL_GetError
#define SDL_GetError
Definition: SDL_dynapi_overrides.h:119
callback_data::done
volatile int done
Definition: testmultiaudio.c:28
SDL_CloseAudioDevice
#define SDL_CloseAudioDevice
Definition: SDL_dynapi_overrides.h:103
SDL_OpenAudioDevice
#define SDL_OpenAudioDevice
Definition: SDL_dynapi_overrides.h:87
Uint32
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:157
SDL_AudioSpec::silence
Uint8 silence
Definition: SDL_audio.h:173
stream
GLuint GLuint stream
Definition: SDL_opengl_glext.h:1776
callback_data::soundpos
int soundpos
Definition: testmultiaudio.c:27
SDL_AudioSpec
Definition: SDL_audio.h:168
SDL_FreeWAV
#define SDL_FreeWAV
Definition: SDL_dynapi_overrides.h:93
SDL_CreateWindow
#define SDL_CreateWindow
Definition: SDL_dynapi_overrides.h:518
play_through_once
void play_through_once(void *arg, Uint8 *stream, int len)
Definition: testmultiaudio.c:34
callback_data::dev
SDL_AudioDeviceID dev
Definition: testmultiaudio.c:26
len
GLenum GLsizei len
Definition: SDL_opengl_glext.h:2926
SDL_LogError
#define SDL_LogError
Definition: SDL_dynapi_overrides.h:42
SDL_GetAudioDeviceName
#define SDL_GetAudioDeviceName
Definition: SDL_dynapi_overrides.h:86
spec
static SDL_AudioSpec spec
Definition: testmultiaudio.c:20
sound
static Uint8 * sound
Definition: testmultiaudio.c:21
SDL_Log
#define SDL_Log
Definition: SDL_dynapi_overrides.h:37
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:393
test_multi_audio
static void test_multi_audio(int devcount)
Definition: testmultiaudio.c:68
Uint8
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2649
callback_data
Definition: testmultiaudio.c:24
SDL_Quit
#define SDL_Quit
Definition: SDL_dynapi_overrides.h:64
done
int done
Definition: checkkeys.c:28
SDL_LoadWAV
#define SDL_LoadWAV(file, spec, audio_buf, audio_len)
Definition: SDL_audio.h:424
SDL_LOG_PRIORITY_INFO
Definition: SDL_log.h:106
SDL_AudioSpec::callback
SDL_AudioCallback callback
Definition: SDL_audio.h:177
SDL_Delay
#define SDL_Delay
Definition: SDL_dynapi_overrides.h:490
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:42
SDL_LogSetPriority
#define SDL_LogSetPriority
Definition: SDL_dynapi_overrides.h:242
SDL_GetCurrentAudioDriver
#define SDL_GetCurrentAudioDriver
Definition: SDL_dynapi_overrides.h:83
NULL
#define NULL
Definition: begin_code.h:143
main
int main(int argc, char **argv)
Definition: testmultiaudio.c:165
SDL_INIT_AUDIO
#define SDL_INIT_AUDIO
Definition: SDL.h:76
SDL_AudioDeviceID
Uint32 SDL_AudioDeviceID
Definition: SDL_audio.h:303
SDL_AudioSpec::userdata
void * userdata
Definition: SDL_audio.h:178
SDL_Init
#define SDL_Init
Definition: SDL_dynapi_overrides.h:60
SDL_Event
General event structure.
Definition: SDL_events.h:521
soundlen
static Uint32 soundlen
Definition: testmultiaudio.c:22
SDL.h
cbd
callback_data cbd[64]
Definition: testmultiaudio.c:31
SDLCALL
#define SDLCALL
Definition: SDL_internal.h:31
SDL_LOG_CATEGORY_APPLICATION
Definition: SDL_log.h:66
SDL_memset
#define SDL_memset
Definition: SDL_dynapi_overrides.h:392
SDL_PauseAudioDevice
#define SDL_PauseAudioDevice
Definition: SDL_dynapi_overrides.h:91
loop
void loop()
Definition: testmultiaudio.c:54