From 570e286fd6fc5cf1a7fed67de2105cdf85977bb3 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 15 Mar 2017 11:39:54 -0700 Subject: [PATCH] Added an audio recording test program --- test/Makefile.in | 4 ++ test/README | 1 + test/loopbackaudio.c | 166 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 test/loopbackaudio.c diff --git a/test/Makefile.in b/test/Makefile.in index 68f0d3dab..f92c93619 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -9,6 +9,7 @@ LIBS = @LIBS@ TARGETS = \ checkkeys$(EXE) \ + loopbackaudio$(EXE) \ loopwave$(EXE) \ loopwavequeue$(EXE) \ testatomic$(EXE) \ @@ -75,6 +76,9 @@ Makefile: $(srcdir)/Makefile.in checkkeys$(EXE): $(srcdir)/checkkeys.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) +loopbackaudio$(EXE): $(srcdir)/loopbackaudio.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + loopwave$(EXE): $(srcdir)/loopwave.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) diff --git a/test/README b/test/README index f6282be34..84642199f 100644 --- a/test/README +++ b/test/README @@ -2,6 +2,7 @@ These are test programs for the SDL library: checkkeys Watch the key events to check the keyboard + loopbackaudio Audio test -- record from the microphone and play it back immediately loopwave Audio test -- loop playing a WAV file loopwavequeue Audio test -- loop playing a WAV file with SDL_QueueAudio testaudioinfo Lists audio device capabilities diff --git a/test/loopbackaudio.c b/test/loopbackaudio.c new file mode 100644 index 000000000..11ba1a346 --- /dev/null +++ b/test/loopbackaudio.c @@ -0,0 +1,166 @@ +/* + Copyright (C) 1997-2017 Sam Lantinga + + 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 record audio from the microphone and play it back immediately */ + +#include "SDL_config.h" + +#include +#include + +#if HAVE_SIGNAL_H +#include +#endif + +#ifdef __EMSCRIPTEN__ +#include +#endif + +#include "SDL.h" + +static SDL_AudioDeviceID device; +static SDL_AudioDeviceID capture; + +static void SDLCALL +fillerup(void *unused, Uint8 * stream, int len) +{ + SDL_QueueAudio(device, stream, len); +} + +/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ +static void +quit(int rc) +{ + SDL_Quit(); + exit(rc); +} + +static void +close_audio() +{ + if (capture != 0) { + SDL_CloseAudioDevice(capture); + capture = 0; + } + if (device != 0) { + SDL_CloseAudioDevice(device); + device = 0; + } +} + +static void +open_audio() +{ + SDL_AudioSpec spec; + + SDL_zero(spec); + spec.freq = 44100; + spec.format = AUDIO_S16; + spec.channels = 1; + spec.samples = 1024; + spec.callback = fillerup; + + capture = SDL_OpenAudioDevice(NULL, SDL_TRUE, &spec, &spec, SDL_AUDIO_ALLOW_ANY_CHANGE); + if (!capture) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open microphone: %s\n", SDL_GetError()); + quit(2); + } + + spec.callback = NULL; + + device = SDL_OpenAudioDevice(NULL, SDL_FALSE, &spec, NULL, 0); + if (!device) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError()); + quit(2); + } + + /* Let the audio run */ + SDL_PauseAudioDevice(capture, SDL_FALSE); + SDL_PauseAudioDevice(device, SDL_FALSE); +} + +static void reopen_audio() +{ + close_audio(); + open_audio(); +} + + +static int done = 0; +void +poked(int sig) +{ + done = 1; +} + +#ifdef __EMSCRIPTEN__ +void +loop() +{ + if(done || (SDL_GetAudioDeviceStatus(capture) != SDL_AUDIO_PLAYING) || (SDL_GetAudioDeviceStatus(device) != SDL_AUDIO_PLAYING)) + emscripten_cancel_main_loop(); +} +#endif + +int +main(int argc, char *argv[]) +{ + int i; + + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + /* Load the SDL library */ + if (SDL_Init(SDL_INIT_AUDIO|SDL_INIT_EVENTS) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); + return (1); + } + + /* 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("Using audio driver: %s\n", SDL_GetCurrentAudioDriver()); + + open_audio(); + + SDL_FlushEvents(SDL_AUDIODEVICEADDED, SDL_AUDIODEVICEREMOVED); + +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(loop, 0, 1); +#else + while (!done) { + SDL_Event event; + + while (SDL_PollEvent(&event) > 0) { + if (event.type == SDL_QUIT) { + done = 1; + } + if (event.type == SDL_AUDIODEVICEADDED || + (event.type == SDL_AUDIODEVICEREMOVED && event.adevice.iscapture && event.adevice.which == capture) || + (event.type == SDL_AUDIODEVICEREMOVED && !event.adevice.iscapture && event.adevice.which == device)) { + reopen_audio(); + } + } + SDL_Delay(100); + } +#endif + + /* Clean up on signal */ + close_audio(); + SDL_Quit(); + return (0); +} + +/* vi: set ts=4 sw=4 expandtab: */