Atlas - SDL_haikuaudio.cc
Home / ext / SDL / src / audio / haiku Lines: 1 | Size: 6708 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 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#ifdef SDL_AUDIO_DRIVER_HAIKU 24 25// Allow access to the audio stream on Haiku 26 27#include <SoundPlayer.h> 28#include <signal.h> 29 30#include "../../core/haiku/SDL_BeApp.h" 31 32extern "C" 33{ 34 35#include "../SDL_sysaudio.h" 36#include "SDL_haikuaudio.h" 37 38} 39 40static Uint8 *HAIKUAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size) 41{ 42 SDL_assert(device->hidden->current_buffer != NULL); 43 SDL_assert(device->hidden->current_buffer_len > 0); 44 *buffer_size = device->hidden->current_buffer_len; 45 return device->hidden->current_buffer; 46} 47 48static bool HAIKUAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size) 49{ 50 // We already wrote our output right into the BSoundPlayer's callback's stream. Just clean up our stuff. 51 SDL_assert(device->hidden->current_buffer != NULL); 52 SDL_assert(device->hidden->current_buffer_len > 0); 53 device->hidden->current_buffer = NULL; 54 device->hidden->current_buffer_len = 0; 55 return true; 56} 57 58// The Haiku callback for handling the audio buffer 59static void FillSound(void *data, void *stream, size_t len, const media_raw_audio_format & format) 60{ 61 SDL_AudioDevice *device = (SDL_AudioDevice *)data; 62 SDL_assert(device->hidden->current_buffer == NULL); 63 SDL_assert(device->hidden->current_buffer_len == 0); 64 device->hidden->current_buffer = (Uint8 *) stream; 65 device->hidden->current_buffer_len = (int) len; 66 SDL_PlaybackAudioThreadIterate(device); 67} 68 69static void HAIKUAUDIO_CloseDevice(SDL_AudioDevice *device) 70{ 71 if (device->hidden) { 72 if (device->hidden->audio_obj) { 73 device->hidden->audio_obj->Stop(); 74 delete device->hidden->audio_obj; 75 } 76 delete device->hidden; 77 device->hidden = NULL; 78 SDL_AudioThreadFinalize(device); 79 } 80} 81 82 83static const int sig_list[] = { 84 SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGWINCH, 0 85}; 86 87static inline void MaskSignals(sigset_t * omask) 88{ 89 sigset_t mask; 90 int i; 91 92 sigemptyset(&mask); 93 for (i = 0; sig_list[i]; ++i) { 94 sigaddset(&mask, sig_list[i]); 95 } 96 sigprocmask(SIG_BLOCK, &mask, omask); 97} 98 99static inline void UnmaskSignals(sigset_t * omask) 100{ 101 sigprocmask(SIG_SETMASK, omask, NULL); 102} 103 104 105static bool HAIKUAUDIO_OpenDevice(SDL_AudioDevice *device) 106{ 107 // Initialize all variables that we clean on shutdown 108 device->hidden = new SDL_PrivateAudioData; 109 if (!device->hidden) { 110 return false; 111 } 112 SDL_zerop(device->hidden); 113 114 // Parse the audio format and fill the Be raw audio format 115 media_raw_audio_format format; 116 SDL_zero(format); 117 format.byte_order = B_MEDIA_LITTLE_ENDIAN; 118 format.frame_rate = (float) device->spec.freq; 119 format.channel_count = device->spec.channels; // !!! FIXME: support > 2? 120 121 SDL_AudioFormat test_format; 122 const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format); 123 while ((test_format = *(closefmts++)) != 0) { 124 switch (test_format) { 125 case SDL_AUDIO_S8: 126 format.format = media_raw_audio_format::B_AUDIO_CHAR; 127 break; 128 129 case SDL_AUDIO_U8: 130 format.format = media_raw_audio_format::B_AUDIO_UCHAR; 131 break; 132 133 case SDL_AUDIO_S16LE: 134 format.format = media_raw_audio_format::B_AUDIO_SHORT; 135 break; 136 137 case SDL_AUDIO_S16BE: 138 format.format = media_raw_audio_format::B_AUDIO_SHORT; 139 format.byte_order = B_MEDIA_BIG_ENDIAN; 140 break; 141 142 case SDL_AUDIO_S32LE: 143 format.format = media_raw_audio_format::B_AUDIO_INT; 144 break; 145 146 case SDL_AUDIO_S32BE: 147 format.format = media_raw_audio_format::B_AUDIO_INT; 148 format.byte_order = B_MEDIA_BIG_ENDIAN; 149 break; 150 151 case SDL_AUDIO_F32LE: 152 format.format = media_raw_audio_format::B_AUDIO_FLOAT; 153 break; 154 155 case SDL_AUDIO_F32BE: 156 format.format = media_raw_audio_format::B_AUDIO_FLOAT; 157 format.byte_order = B_MEDIA_BIG_ENDIAN; 158 break; 159 160 default: 161 continue; 162 } 163 break; 164 } 165 166 if (!test_format) { // shouldn't happen, but just in case... 167 return SDL_SetError("HAIKU: Unsupported audio format"); 168 } 169 device->spec.format = test_format; 170 171 // Calculate the final parameters for this audio specification 172 SDL_UpdatedAudioDeviceFormat(device); 173 174 format.buffer_size = device->buffer_size; 175 176 // Subscribe to the audio stream (creates a new thread) 177 sigset_t omask; 178 MaskSignals(&omask); 179 device->hidden->audio_obj = new BSoundPlayer(&format, "SDL Audio", 180 FillSound, NULL, device); 181 UnmaskSignals(&omask); 182 183 if (device->hidden->audio_obj->Start() == B_NO_ERROR) { 184 device->hidden->audio_obj->SetHasData(true); 185 } else { 186 return SDL_SetError("Unable to start Haiku audio"); 187 } 188 189 return true; // We're running! 190} 191 192static void HAIKUAUDIO_Deinitialize(void) 193{ 194 SDL_QuitBeApp(); 195} 196 197static bool HAIKUAUDIO_Init(SDL_AudioDriverImpl *impl) 198{ 199 if (!SDL_InitBeApp()) { 200 return false; 201 } 202 203 // Set the function pointers 204 impl->OpenDevice = HAIKUAUDIO_OpenDevice; 205 impl->GetDeviceBuf = HAIKUAUDIO_GetDeviceBuf; 206 impl->PlayDevice = HAIKUAUDIO_PlayDevice; 207 impl->CloseDevice = HAIKUAUDIO_CloseDevice; 208 impl->Deinitialize = HAIKUAUDIO_Deinitialize; 209 impl->ProvidesOwnCallbackThread = true; 210 impl->OnlyHasDefaultPlaybackDevice = true; 211 212 return true; 213} 214 215 216extern "C" { extern AudioBootStrap HAIKUAUDIO_bootstrap; } 217 218AudioBootStrap HAIKUAUDIO_bootstrap = { 219 "haiku", "Haiku BSoundPlayer", HAIKUAUDIO_Init, false, false 220}; 221 222#endif // SDL_AUDIO_DRIVER_HAIKU 223[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.