Atlas - SDL_fsaudio.c

Home / ext / SDL2 / src / audio / fusionsound Lines: 3 | Size: 8730 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_FUSIONSOUND 24 25/* !!! FIXME: why is this is SDL_FS_* instead of FUSIONSOUND_*? */ 26 27/* Allow access to a raw mixing buffer */ 28 29#ifdef HAVE_SIGNAL_H 30#include <signal.h> 31#endif 32#include <unistd.h> 33 34#include "SDL_timer.h" 35#include "SDL_audio.h" 36#include "../SDL_audio_c.h" 37#include "SDL_fsaudio.h" 38 39#include <fusionsound/fusionsound_version.h> 40 41/* #define SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC "libfusionsound.so" */ 42 43#ifdef SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC 44#include "SDL_name.h" 45#include "SDL_loadso.h" 46#else 47#define SDL_NAME(X) X 48#endif 49 50#if (FUSIONSOUND_MAJOR_VERSION == 1) && (FUSIONSOUND_MINOR_VERSION < 1) 51typedef DFBResult DirectResult; 52#endif 53 54/* Buffers to use - more than 2 gives a lot of latency */ 55#define FUSION_BUFFERS (2) 56 57#ifdef SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC 58 59static const char *fs_library = SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC; 60static void *fs_handle = NULL; 61 62static DirectResult (*SDL_NAME(FusionSoundInit)) (int *argc, char *(*argv[])); 63static DirectResult (*SDL_NAME(FusionSoundCreate)) (IFusionSound ** 64 ret_interface); 65 66#define SDL_FS_SYM(x) { #x, (void **) (char *) &SDL_NAME(x) } 67static struct 68{ 69 const char *name; 70 void **func; 71} fs_functions[] = { 72/* *INDENT-OFF* */ 73 SDL_FS_SYM(FusionSoundInit), 74 SDL_FS_SYM(FusionSoundCreate), 75/* *INDENT-ON* */ 76}; 77 78#undef SDL_FS_SYM 79 80static void 81UnloadFusionSoundLibrary() 82{ 83 if (fs_handle != NULL) { 84 SDL_UnloadObject(fs_handle); 85 fs_handle = NULL; 86 } 87} 88 89static int 90LoadFusionSoundLibrary(void) 91{ 92 int i, retval = -1; 93 94 if (fs_handle == NULL) { 95 fs_handle = SDL_LoadObject(fs_library); 96 if (fs_handle != NULL) { 97 retval = 0; 98 for (i = 0; i < SDL_arraysize(fs_functions); ++i) { 99 *fs_functions[i].func = 100 SDL_LoadFunction(fs_handle, fs_functions[i].name); 101 if (!*fs_functions[i].func) { 102 retval = -1; 103 UnloadFusionSoundLibrary(); 104 break; 105 } 106 } 107 } 108 } 109 110 return retval; 111} 112 113#else 114 115static void 116UnloadFusionSoundLibrary() 117{ 118 return; 119} 120 121static int 122LoadFusionSoundLibrary(void) 123{ 124 return 0; 125} 126 127#endif /* SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC */ 128 129/* This function waits until it is possible to write a full sound buffer */ 130static void 131SDL_FS_WaitDevice(_THIS) 132{ 133 this->hidden->stream->Wait(this->hidden->stream, 134 this->hidden->mixsamples); 135} 136 137static void 138SDL_FS_PlayDevice(_THIS) 139{ 140 DirectResult ret; 141 142 ret = this->hidden->stream->Write(this->hidden->stream, 143 this->hidden->mixbuf, 144 this->hidden->mixsamples); 145 /* If we couldn't write, assume fatal error for now */ 146 if (ret) { 147 SDL_OpenedAudioDeviceDisconnected(this); 148 } 149#ifdef DEBUG_AUDIO 150 fprintf(stderr, "Wrote %d bytes of audio data\n", this->hidden->mixlen); 151#endif 152} 153 154 155static Uint8 * 156SDL_FS_GetDeviceBuf(_THIS) 157{ 158 return (this->hidden->mixbuf); 159} 160 161 162static void 163SDL_FS_CloseDevice(_THIS) 164{ 165 if (this->hidden->stream) { 166 this->hidden->stream->Release(this->hidden->stream); 167 } 168 if (this->hidden->fs) { 169 this->hidden->fs->Release(this->hidden->fs); 170 } 171 SDL_free(this->hidden->mixbuf); 172 SDL_free(this->hidden); 173} 174 175 176static int 177SDL_FS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) 178{ 179 int bytes; 180 SDL_AudioFormat test_format = 0, format = 0; 181 FSSampleFormat fs_format; 182 FSStreamDescription desc; 183 DirectResult ret; 184 185 /* Initialize all variables that we clean on shutdown */ 186 this->hidden = (struct SDL_PrivateAudioData *) 187 SDL_malloc((sizeof *this->hidden)); 188 if (this->hidden == NULL) { 189 return SDL_OutOfMemory(); 190 } 191 SDL_zerop(this->hidden); 192 193 /* Try for a closest match on audio format */ 194 for (test_format = SDL_FirstAudioFormat(this->spec.format); 195 !format && test_format;) { 196#ifdef DEBUG_AUDIO 197 fprintf(stderr, "Trying format 0x%4.4x\n", test_format); 198#endif 199 switch (test_format) { 200 case AUDIO_U8: 201 fs_format = FSSF_U8; 202 bytes = 1; 203 format = 1; 204 break; 205 case AUDIO_S16SYS: 206 fs_format = FSSF_S16; 207 bytes = 2; 208 format = 1; 209 break; 210 case AUDIO_S32SYS: 211 fs_format = FSSF_S32; 212 bytes = 4; 213 format = 1; 214 break; 215 case AUDIO_F32SYS: 216 fs_format = FSSF_FLOAT; 217 bytes = 4; 218 format = 1; 219 break; 220 default: 221 format = 0; 222 break; 223 } 224 if (!format) { 225 test_format = SDL_NextAudioFormat(); 226 } 227 } 228 229 if (format == 0) { 230 return SDL_SetError("Couldn't find any hardware audio formats"); 231 } 232 this->spec.format = test_format; 233 234 /* Retrieve the main sound interface. */ 235 ret = SDL_NAME(FusionSoundCreate) (&this->hidden->fs); 236 if (ret) { 237 return SDL_SetError("Unable to initialize FusionSound: %d", ret); 238 } 239 240 this->hidden->mixsamples = this->spec.size / bytes / this->spec.channels; 241 242 /* Fill stream description. */ 243 desc.flags = FSSDF_SAMPLERATE | FSSDF_BUFFERSIZE | 244 FSSDF_CHANNELS | FSSDF_SAMPLEFORMAT | FSSDF_PREBUFFER; 245 desc.samplerate = this->spec.freq; 246 desc.buffersize = this->spec.size * FUSION_BUFFERS; 247 desc.channels = this->spec.channels; 248 desc.prebuffer = 10; 249 desc.sampleformat = fs_format; 250 251 ret = 252 this->hidden->fs->CreateStream(this->hidden->fs, &desc, 253 &this->hidden->stream); 254 if (ret) { 255 return SDL_SetError("Unable to create FusionSoundStream: %d", ret); 256 } 257 258 /* See what we got */ 259 desc.flags = FSSDF_SAMPLERATE | FSSDF_BUFFERSIZE | 260 FSSDF_CHANNELS | FSSDF_SAMPLEFORMAT; 261 ret = this->hidden->stream->GetDescription(this->hidden->stream, &desc); 262 263 this->spec.freq = desc.samplerate; 264 this->spec.size = 265 desc.buffersize / FUSION_BUFFERS * bytes * desc.channels; 266 this->spec.channels = desc.channels; 267 268 /* Calculate the final parameters for this audio specification */ 269 SDL_CalculateAudioSpec(&this->spec); 270 271 /* Allocate mixing buffer */ 272 this->hidden->mixlen = this->spec.size; 273 this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); 274 if (this->hidden->mixbuf == NULL) { 275 return SDL_OutOfMemory(); 276 } 277 SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); 278 279 /* We're ready to rock and roll. :-) */ 280 return 0; 281} 282 283 284static void 285SDL_FS_Deinitialize(void) 286{ 287 UnloadFusionSoundLibrary(); 288} 289 290 291static int 292SDL_FS_Init(SDL_AudioDriverImpl * impl) 293{ 294 if (LoadFusionSoundLibrary() < 0) { 295 return 0; 296 } else { 297 DirectResult ret; 298 299 ret = SDL_NAME(FusionSoundInit) (NULL, NULL); 300 if (ret) { 301 UnloadFusionSoundLibrary(); 302 SDL_SetError 303 ("FusionSound: SDL_FS_init failed (FusionSoundInit: %d)", 304 ret); 305 return 0; 306 } 307 } 308 309 /* Set the function pointers */ 310 impl->OpenDevice = SDL_FS_OpenDevice; 311 impl->PlayDevice = SDL_FS_PlayDevice; 312 impl->WaitDevice = SDL_FS_WaitDevice; 313 impl->GetDeviceBuf = SDL_FS_GetDeviceBuf; 314 impl->CloseDevice = SDL_FS_CloseDevice; 315 impl->Deinitialize = SDL_FS_Deinitialize; 316 impl->OnlyHasDefaultOutputDevice = 1; 317 318 return 1; /* this audio target is available. */ 319} 320 321 322AudioBootStrap FUSIONSOUND_bootstrap = { 323 "fusionsound", "FusionSound", SDL_FS_Init, 0 324}; 325 326#endif /* SDL_AUDIO_DRIVER_FUSIONSOUND */ 327 328/* vi: set ts=4 sw=4 expandtab: */ 329
[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.