From e1c78718d4b678111b745841757f7fe3e0e863eb Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 24 Jun 2023 14:57:12 -0400 Subject: [PATCH] test: testaudiocapture is updated for the SDL3 audio API. --- test/testaudiocapture.c | 109 +++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 46 deletions(-) diff --git a/test/testaudiocapture.c b/test/testaudiocapture.c index 01c267608..87ee24c4b 100644 --- a/test/testaudiocapture.c +++ b/test/testaudiocapture.c @@ -22,13 +22,14 @@ static SDL_Window *window = NULL; static SDL_Renderer *renderer = NULL; -static SDL_AudioSpec spec; -static SDL_AudioDeviceID devid_in = 0; -static SDL_AudioDeviceID devid_out = 0; +static SDL_AudioStream *stream_in = NULL; +static SDL_AudioStream *stream_out = NULL; static int done = 0; static void loop(void) { + const SDL_AudioDeviceID devid_in = SDL_GetAudioStreamBinding(stream_in); + const SDL_AudioDeviceID devid_out = SDL_GetAudioStreamBinding(stream_out); SDL_bool please_quit = SDL_FALSE; SDL_Event e; @@ -42,17 +43,18 @@ static void loop(void) } else if (e.type == SDL_EVENT_MOUSE_BUTTON_DOWN) { if (e.button.button == 1) { SDL_PauseAudioDevice(devid_out); - SDL_PlayAudioDevice(devid_in); + SDL_UnpauseAudioDevice(devid_in); } } else if (e.type == SDL_EVENT_MOUSE_BUTTON_UP) { if (e.button.button == 1) { SDL_PauseAudioDevice(devid_in); - SDL_PlayAudioDevice(devid_out); + SDL_FlushAudioStream(stream_in); /* so no samples are held back for resampling purposes. */ + SDL_UnpauseAudioDevice(devid_out); } } } - if (SDL_GetAudioDeviceStatus(devid_in) == SDL_AUDIO_PLAYING) { + if (!SDL_IsAudioDevicePaused(devid_in)) { SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); } else { SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); @@ -60,13 +62,26 @@ static void loop(void) SDL_RenderClear(renderer); SDL_RenderPresent(renderer); + /* Feed any new data we captured to the output stream. It'll play when we unpause the device. */ + while (!please_quit && (SDL_GetAudioStreamAvailable(stream_in) > 0)) { + Uint8 buf[1024]; + const int br = SDL_GetAudioStreamData(stream_in, buf, sizeof(buf)); + if (br < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to read from input audio stream: %s\n", SDL_GetError()); + please_quit = 1; + } else if (SDL_PutAudioStreamData(stream_out, buf, br) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to write to output audio stream: %s\n", SDL_GetError()); + please_quit = 1; + } + } + if (please_quit) { /* stop playing back, quit. */ SDL_Log("Shutting down.\n"); - SDL_PauseAudioDevice(devid_in); SDL_CloseAudioDevice(devid_in); - SDL_PauseAudioDevice(devid_out); SDL_CloseAudioDevice(devid_out); + SDL_DestroyAudioStream(stream_in); + SDL_DestroyAudioStream(stream_out); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); @@ -77,28 +92,17 @@ static void loop(void) done = 1; return; } - - /* Note that it would be easier to just have a one-line function that - calls SDL_QueueAudio() as a capture device callback, but we're - trying to test the API, so we use SDL_DequeueAudio() here. */ - while (SDL_TRUE) { - Uint8 buf[1024]; - const Uint32 br = SDL_DequeueAudio(devid_in, buf, sizeof(buf)); - SDL_QueueAudio(devid_out, buf, br); - if (br < sizeof(buf)) { - break; - } - } } int main(int argc, char **argv) { - /* (NULL means "open default device.") */ - const char *devname = NULL; - SDL_AudioSpec wanted; - int devcount; - int i; + SDL_AudioDeviceID *devices; SDLTest_CommonState *state; + SDL_AudioSpec spec; + SDL_AudioDeviceID device; + SDL_AudioDeviceID want_device = SDL_AUDIO_DEVICE_DEFAULT_CAPTURE; + const char *devname = NULL; + int i; /* Initialize test framework */ state = SDLTest_CommonCreateState(argv, 0); @@ -121,7 +125,7 @@ int main(int argc, char **argv) } } if (consumed <= 0) { - static const char *options[] = { "[driver_name]", NULL }; + static const char *options[] = { "[device_name]", NULL }; SDLTest_CommonLogUsage(state, argv[0], options); exit(1); } @@ -145,19 +149,20 @@ int main(int argc, char **argv) SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver()); - devcount = SDL_GetNumAudioDevices(SDL_TRUE); - for (i = 0; i < devcount; i++) { - SDL_Log(" Capture device #%d: '%s'\n", i, SDL_GetAudioDeviceName(i, SDL_TRUE)); + devices = SDL_GetAudioCaptureDevices(NULL); + for (i = 0; devices[i] != 0; i++) { + char *name = SDL_GetAudioDeviceName(devices[i]); + SDL_Log(" Capture device #%d: '%s'\n", i, name); + if (devname && (SDL_strcmp(devname, name) == 0)) { + want_device = devices[i]; + } + SDL_free(name); } - SDL_zero(wanted); - wanted.freq = 44100; - wanted.format = SDL_AUDIO_F32SYS; - wanted.channels = 1; - wanted.samples = 4096; - wanted.callback = NULL; - - SDL_zero(spec); + if (devname && (want_device == SDL_AUDIO_DEVICE_DEFAULT_CAPTURE)) { + SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Didn't see a capture device named '%s', using the system default instead.\n", devname); + devname = NULL; + } /* DirectSound can fail in some instances if you open the same hardware for both capture and output and didn't open the output end first, @@ -166,24 +171,40 @@ int main(int argc, char **argv) circumstances. */ SDL_Log("Opening default playback device...\n"); - devid_out = SDL_OpenAudioDevice(NULL, SDL_FALSE, &wanted, &spec, SDL_AUDIO_ALLOW_ANY_CHANGE); - if (!devid_out) { + device = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, NULL); + if (!device) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open an audio device for playback: %s!\n", SDL_GetError()); SDL_Quit(); exit(1); } + SDL_PauseAudioDevice(device); + SDL_GetAudioDeviceFormat(device, &spec); + stream_out = SDL_CreateAndBindAudioStream(device, &spec); + if (!stream_out) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create an audio stream for playback: %s!\n", SDL_GetError()); + SDL_Quit(); + exit(1); + } SDL_Log("Opening capture device %s%s%s...\n", devname ? "'" : "", devname ? devname : "[[default]]", devname ? "'" : ""); - devid_in = SDL_OpenAudioDevice(devname, SDL_TRUE, &spec, &spec, 0); - if (!devid_in) { + device = SDL_OpenAudioDevice(want_device, NULL); + if (!device) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open an audio device for capture: %s!\n", SDL_GetError()); SDL_Quit(); exit(1); } + SDL_PauseAudioDevice(device); + SDL_GetAudioDeviceFormat(device, &spec); + stream_in = SDL_CreateAndBindAudioStream(device, &spec); + if (!stream_in) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create an audio stream for capture: %s!\n", SDL_GetError()); + SDL_Quit(); + exit(1); + } SDL_Log("Ready! Hold down mouse or finger to record!\n"); @@ -198,11 +219,7 @@ int main(int argc, char **argv) } #endif - /* SDL_DestroyRenderer(renderer); */ - /* SDL_DestroyWindow(window); */ - - /* SDL_Quit(); */ - /* SDLTest_CommonDestroyState(state); */ + SDLTest_CommonDestroyState(state); return 0; }