Atlas - testaudiorecording.c

Home / ext / SDL / test Lines: 1 | Size: 8028 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 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#define SDL_MAIN_USE_CALLBACKS 1 14#include <SDL3/SDL.h> 15#include <SDL3/SDL_main.h> 16#include <SDL3/SDL_test.h> 17 18static SDL_Window *window = NULL; 19static SDL_Renderer *renderer = NULL; 20static SDL_AudioStream *stream_in = NULL; 21static SDL_AudioStream *stream_out = NULL; 22static SDLTest_CommonState *state = NULL; 23 24SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) 25{ 26 SDL_AudioDeviceID *devices; 27 SDL_AudioSpec outspec; 28 SDL_AudioSpec inspec; 29 SDL_AudioDeviceID device; 30 SDL_AudioDeviceID want_device = SDL_AUDIO_DEVICE_DEFAULT_RECORDING; 31 const char *devname = NULL; 32 int i; 33 34 /* this doesn't have to run very much, so give up tons of CPU time between iterations. */ 35 SDL_SetHint(SDL_HINT_MAIN_CALLBACK_RATE, "15"); 36 37 /* Initialize test framework */ 38 state = SDLTest_CommonCreateState(argv, 0); 39 if (!state) { 40 return SDL_APP_SUCCESS; 41 } 42 43 /* Parse commandline */ 44 for (i = 1; i < argc;) { 45 int consumed; 46 47 consumed = SDLTest_CommonArg(state, i); 48 if (!consumed) { 49 if (!devname) { 50 devname = argv[i]; 51 consumed = 1; 52 } 53 } 54 if (consumed <= 0) { 55 static const char *options[] = { "[device_name]", NULL }; 56 SDLTest_CommonLogUsage(state, argv[0], options); 57 return SDL_APP_FAILURE; 58 } 59 60 i += consumed; 61 } 62 63 /* Load the SDL library */ 64 if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) { 65 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError()); 66 return SDL_APP_SUCCESS; 67 } 68 69 if (!SDL_CreateWindowAndRenderer("testaudiorecording", 320, 240, 0, &window, &renderer)) { 70 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create SDL window and renderer: %s", SDL_GetError()); 71 return SDL_APP_SUCCESS; 72 } 73 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); 74 SDL_RenderClear(renderer); 75 SDL_RenderPresent(renderer); 76 77 SDL_Log("Using audio driver: %s", SDL_GetCurrentAudioDriver()); 78 79 devices = SDL_GetAudioRecordingDevices(NULL); 80 for (i = 0; devices[i] != 0; i++) { 81 const char *name = SDL_GetAudioDeviceName(devices[i]); 82 SDL_Log(" Recording device #%d: '%s'", i, name); 83 if (devname && (SDL_strcmp(devname, name) == 0)) { 84 want_device = devices[i]; 85 } 86 } 87 88 if (devname && (want_device == SDL_AUDIO_DEVICE_DEFAULT_RECORDING)) { 89 SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Didn't see a recording device named '%s', using the system default instead.", devname); 90 devname = NULL; 91 } 92 93 /* DirectSound can fail in some instances if you open the same hardware 94 for both recording and output and didn't open the output end first, 95 according to the docs, so if you're doing something like this, always 96 open your recording devices second in case you land in those bizarre 97 circumstances. */ 98 99 SDL_Log("Opening default playback device..."); 100 device = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, NULL); 101 if (!device) { 102 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open an audio device for playback: %s!", SDL_GetError()); 103 SDL_free(devices); 104 return SDL_APP_FAILURE; 105 } 106 SDL_PauseAudioDevice(device); 107 SDL_GetAudioDeviceFormat(device, &outspec, NULL); 108 stream_out = SDL_CreateAudioStream(&outspec, &outspec); 109 if (!stream_out) { 110 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create an audio stream for playback: %s!", SDL_GetError()); 111 SDL_free(devices); 112 return SDL_APP_FAILURE; 113 } else if (!SDL_BindAudioStream(device, stream_out)) { 114 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't bind an audio stream for playback: %s!", SDL_GetError()); 115 SDL_free(devices); 116 return SDL_APP_FAILURE; 117 } 118 119 SDL_Log("Opening recording device %s%s%s...", 120 devname ? "'" : "", 121 devname ? devname : "[[default]]", 122 devname ? "'" : ""); 123 124 device = SDL_OpenAudioDevice(want_device, NULL); 125 if (!device) { 126 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open an audio device for recording: %s!", SDL_GetError()); 127 SDL_free(devices); 128 return SDL_APP_FAILURE; 129 } 130 SDL_free(devices); 131 SDL_PauseAudioDevice(device); 132 SDL_GetAudioDeviceFormat(device, &inspec, NULL); 133 stream_in = SDL_CreateAudioStream(&inspec, &inspec); 134 if (!stream_in) { 135 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create an audio stream for recording: %s!", SDL_GetError()); 136 return SDL_APP_FAILURE; 137 } else if (!SDL_BindAudioStream(device, stream_in)) { 138 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't bind an audio stream for recording: %s!", SDL_GetError()); 139 return SDL_APP_FAILURE; 140 } 141 142 SDL_SetAudioStreamFormat(stream_in, NULL, &outspec); /* make sure we output at the playback format. */ 143 144 SDL_Log("Ready! Hold down mouse or finger to record!"); 145 146 return SDL_APP_CONTINUE; 147} 148 149SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) 150{ 151 if (event->type == SDL_EVENT_QUIT) { 152 return SDL_APP_SUCCESS; 153 } else if (event->type == SDL_EVENT_KEY_DOWN) { 154 if (event->key.key == SDLK_ESCAPE) { 155 return SDL_APP_SUCCESS; 156 } 157 } else if (event->type == SDL_EVENT_MOUSE_BUTTON_DOWN) { 158 if (event->button.button == 1) { 159 SDL_PauseAudioStreamDevice(stream_out); 160 SDL_FlushAudioStream(stream_out); /* so no samples are held back for resampling purposes. */ 161 SDL_ResumeAudioStreamDevice(stream_in); 162 } 163 } else if (event->type == SDL_EVENT_MOUSE_BUTTON_UP) { 164 if (event->button.button == 1) { 165 SDL_PauseAudioStreamDevice(stream_in); 166 SDL_FlushAudioStream(stream_in); /* so no samples are held back for resampling purposes. */ 167 SDL_ResumeAudioStreamDevice(stream_out); 168 } 169 } 170 return SDL_APP_CONTINUE; 171} 172 173SDL_AppResult SDL_AppIterate(void *appstate) 174{ 175 if (!SDL_AudioStreamDevicePaused(stream_in)) { 176 SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); 177 } else { 178 SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); 179 } 180 SDL_RenderClear(renderer); 181 SDL_RenderPresent(renderer); 182 183 /* Feed any new data we recorded to the output stream. It'll play when we unpause the device. */ 184 while (SDL_GetAudioStreamAvailable(stream_in) > 0) { 185 Uint8 buf[1024]; 186 const int br = SDL_GetAudioStreamData(stream_in, buf, sizeof(buf)); 187 if (br < 0) { 188 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to read from input audio stream: %s", SDL_GetError()); 189 return SDL_APP_FAILURE; 190 } else if (!SDL_PutAudioStreamData(stream_out, buf, br)) { 191 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to write to output audio stream: %s", SDL_GetError()); 192 return SDL_APP_FAILURE; 193 } 194 } 195 196 return SDL_APP_CONTINUE; 197} 198 199void SDL_AppQuit(void *appstate, SDL_AppResult result) 200{ 201 SDL_Log("Shutting down."); 202 const SDL_AudioDeviceID devid_in = SDL_GetAudioStreamDevice(stream_in); 203 const SDL_AudioDeviceID devid_out = SDL_GetAudioStreamDevice(stream_out); 204 SDL_CloseAudioDevice(devid_in); /* !!! FIXME: use SDL_OpenAudioDeviceStream instead so we can dump this. */ 205 SDL_CloseAudioDevice(devid_out); 206 SDL_DestroyAudioStream(stream_in); 207 SDL_DestroyAudioStream(stream_out); 208 SDL_DestroyRenderer(renderer); 209 SDL_DestroyWindow(window); 210 SDL_Quit(); 211 SDLTest_CommonDestroyState(state); 212} 213 214 215
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.