Atlas - SDL_diskaudio.c

Home / ext / SDL2 / src / audio / disk Lines: 4 | Size: 6017 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2018 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "../../SDL_internal.h" 22 23#if SDL_AUDIO_DRIVER_DISK 24 25/* Output raw audio data to a file. */ 26 27#if HAVE_STDIO_H 28#include <stdio.h> 29#endif 30 31#include "SDL_rwops.h" 32#include "SDL_timer.h" 33#include "SDL_audio.h" 34#include "../SDL_audio_c.h" 35#include "SDL_diskaudio.h" 36#include "SDL_log.h" 37 38/* !!! FIXME: these should be SDL hints, not environment variables. */ 39/* environment variables and defaults. */ 40#define DISKENVR_OUTFILE "SDL_DISKAUDIOFILE" 41#define DISKDEFAULT_OUTFILE "sdlaudio.raw" 42#define DISKENVR_INFILE "SDL_DISKAUDIOFILEIN" 43#define DISKDEFAULT_INFILE "sdlaudio-in.raw" 44#define DISKENVR_IODELAY "SDL_DISKAUDIODELAY" 45 46/* This function waits until it is possible to write a full sound buffer */ 47static void 48DISKAUDIO_WaitDevice(_THIS) 49{ 50 SDL_Delay(this->hidden->io_delay); 51} 52 53static void 54DISKAUDIO_PlayDevice(_THIS) 55{ 56 const size_t written = SDL_RWwrite(this->hidden->io, 57 this->hidden->mixbuf, 58 1, this->spec.size); 59 60 /* If we couldn't write, assume fatal error for now */ 61 if (written != this->spec.size) { 62 SDL_OpenedAudioDeviceDisconnected(this); 63 } 64#ifdef DEBUG_AUDIO 65 fprintf(stderr, "Wrote %d bytes of audio data\n", written); 66#endif 67} 68 69static Uint8 * 70DISKAUDIO_GetDeviceBuf(_THIS) 71{ 72 return (this->hidden->mixbuf); 73} 74 75static int 76DISKAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) 77{ 78 struct SDL_PrivateAudioData *h = this->hidden; 79 const int origbuflen = buflen; 80 81 SDL_Delay(h->io_delay); 82 83 if (h->io) { 84 const size_t br = SDL_RWread(h->io, buffer, 1, buflen); 85 buflen -= (int) br; 86 buffer = ((Uint8 *) buffer) + br; 87 if (buflen > 0) { /* EOF (or error, but whatever). */ 88 SDL_RWclose(h->io); 89 h->io = NULL; 90 } 91 } 92 93 /* if we ran out of file, just write silence. */ 94 SDL_memset(buffer, this->spec.silence, buflen); 95 96 return origbuflen; 97} 98 99static void 100DISKAUDIO_FlushCapture(_THIS) 101{ 102 /* no op...we don't advance the file pointer or anything. */ 103} 104 105 106static void 107DISKAUDIO_CloseDevice(_THIS) 108{ 109 if (this->hidden->io != NULL) { 110 SDL_RWclose(this->hidden->io); 111 } 112 SDL_free(this->hidden->mixbuf); 113 SDL_free(this->hidden); 114} 115 116 117static const char * 118get_filename(const int iscapture, const char *devname) 119{ 120 if (devname == NULL) { 121 devname = SDL_getenv(iscapture ? DISKENVR_INFILE : DISKENVR_OUTFILE); 122 if (devname == NULL) { 123 devname = iscapture ? DISKDEFAULT_INFILE : DISKDEFAULT_OUTFILE; 124 } 125 } 126 return devname; 127} 128 129static int 130DISKAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) 131{ 132 /* handle != NULL means "user specified the placeholder name on the fake detected device list" */ 133 const char *fname = get_filename(iscapture, handle ? NULL : devname); 134 const char *envr = SDL_getenv(DISKENVR_IODELAY); 135 136 this->hidden = (struct SDL_PrivateAudioData *) 137 SDL_malloc(sizeof(*this->hidden)); 138 if (this->hidden == NULL) { 139 return SDL_OutOfMemory(); 140 } 141 SDL_zerop(this->hidden); 142 143 if (envr != NULL) { 144 this->hidden->io_delay = SDL_atoi(envr); 145 } else { 146 this->hidden->io_delay = ((this->spec.samples * 1000) / this->spec.freq); 147 } 148 149 /* Open the audio device */ 150 this->hidden->io = SDL_RWFromFile(fname, iscapture ? "rb" : "wb"); 151 if (this->hidden->io == NULL) { 152 return -1; 153 } 154 155 /* Allocate mixing buffer */ 156 if (!iscapture) { 157 this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->spec.size); 158 if (this->hidden->mixbuf == NULL) { 159 return SDL_OutOfMemory(); 160 } 161 SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); 162 } 163 164 SDL_LogCritical(SDL_LOG_CATEGORY_AUDIO, 165 "You are using the SDL disk i/o audio driver!\n"); 166 SDL_LogCritical(SDL_LOG_CATEGORY_AUDIO, 167 " %s file [%s].\n", iscapture ? "Reading from" : "Writing to", 168 fname); 169 170 /* We're ready to rock and roll. :-) */ 171 return 0; 172} 173 174static void 175DISKAUDIO_DetectDevices(void) 176{ 177 SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) 0x1); 178 SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, (void *) 0x2); 179} 180 181static int 182DISKAUDIO_Init(SDL_AudioDriverImpl * impl) 183{ 184 /* Set the function pointers */ 185 impl->OpenDevice = DISKAUDIO_OpenDevice; 186 impl->WaitDevice = DISKAUDIO_WaitDevice; 187 impl->PlayDevice = DISKAUDIO_PlayDevice; 188 impl->GetDeviceBuf = DISKAUDIO_GetDeviceBuf; 189 impl->CaptureFromDevice = DISKAUDIO_CaptureFromDevice; 190 impl->FlushCapture = DISKAUDIO_FlushCapture; 191 192 impl->CloseDevice = DISKAUDIO_CloseDevice; 193 impl->DetectDevices = DISKAUDIO_DetectDevices; 194 195 impl->AllowsArbitraryDeviceNames = 1; 196 impl->HasCaptureSupport = SDL_TRUE; 197 198 return 1; /* this audio target is available. */ 199} 200 201AudioBootStrap DISKAUDIO_bootstrap = { 202 "disk", "direct-to-disk audio", DISKAUDIO_Init, 1 203}; 204 205#endif /* SDL_AUDIO_DRIVER_DISK */ 206 207/* vi: set ts=4 sw=4 expandtab: */ 208
[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.