forked from Green-Sky/tomato
Merge commit 'dec0d4ec4153bf9fc2b78ae6c2df45b6ea8dde7a' as 'external/sdl/SDL'
This commit is contained in:
238
external/sdl/SDL/src/audio/haiku/SDL_haikuaudio.cc
vendored
Normal file
238
external/sdl/SDL/src/audio/haiku/SDL_haikuaudio.cc
vendored
Normal file
@ -0,0 +1,238 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef SDL_AUDIO_DRIVER_HAIKU
|
||||
|
||||
/* Allow access to the audio stream on Haiku */
|
||||
|
||||
#include <SoundPlayer.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "../../core/haiku/SDL_BeApp.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
#include "../SDL_audio_c.h"
|
||||
#include "../SDL_sysaudio.h"
|
||||
#include "SDL_haikuaudio.h"
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* !!! FIXME: have the callback call the higher level to avoid code dupe. */
|
||||
/* The Haiku callback for handling the audio buffer */
|
||||
static void FillSound(void *device, void *stream, size_t len,
|
||||
const media_raw_audio_format & format)
|
||||
{
|
||||
SDL_AudioDevice *audio = (SDL_AudioDevice *) device;
|
||||
SDL_AudioCallback callback = audio->callbackspec.callback;
|
||||
|
||||
SDL_LockMutex(audio->mixer_lock);
|
||||
|
||||
/* Only do something if audio is enabled */
|
||||
if (!SDL_AtomicGet(&audio->enabled) || SDL_AtomicGet(&audio->paused)) {
|
||||
if (audio->stream) {
|
||||
SDL_ClearAudioStream(audio->stream);
|
||||
}
|
||||
SDL_memset(stream, audio->spec.silence, len);
|
||||
} else {
|
||||
SDL_assert(audio->spec.size == len);
|
||||
|
||||
if (audio->stream == NULL) { /* no conversion necessary. */
|
||||
callback(audio->callbackspec.userdata, (Uint8 *) stream, len);
|
||||
} else { /* streaming/converting */
|
||||
const int stream_len = audio->callbackspec.size;
|
||||
const int ilen = (int) len;
|
||||
while (SDL_GetAudioStreamAvailable(audio->stream) < ilen) {
|
||||
callback(audio->callbackspec.userdata, audio->work_buffer, stream_len);
|
||||
if (SDL_PutAudioStreamData(audio->stream, audio->work_buffer, stream_len) == -1) {
|
||||
SDL_ClearAudioStream(audio->stream);
|
||||
SDL_AtomicSet(&audio->enabled, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const int got = SDL_GetAudioStreamData(audio->stream, stream, ilen);
|
||||
SDL_assert((got < 0) || (got == ilen));
|
||||
if (got != ilen) {
|
||||
SDL_memset(stream, audio->spec.silence, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockMutex(audio->mixer_lock);
|
||||
}
|
||||
|
||||
static void HAIKUAUDIO_CloseDevice(SDL_AudioDevice *_this)
|
||||
{
|
||||
if (_this->hidden->audio_obj) {
|
||||
_this->hidden->audio_obj->Stop();
|
||||
delete _this->hidden->audio_obj;
|
||||
}
|
||||
delete _this->hidden;
|
||||
}
|
||||
|
||||
|
||||
static const int sig_list[] = {
|
||||
SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGWINCH, 0
|
||||
};
|
||||
|
||||
static inline void MaskSignals(sigset_t * omask)
|
||||
{
|
||||
sigset_t mask;
|
||||
int i;
|
||||
|
||||
sigemptyset(&mask);
|
||||
for (i = 0; sig_list[i]; ++i) {
|
||||
sigaddset(&mask, sig_list[i]);
|
||||
}
|
||||
sigprocmask(SIG_BLOCK, &mask, omask);
|
||||
}
|
||||
|
||||
static inline void UnmaskSignals(sigset_t * omask)
|
||||
{
|
||||
sigprocmask(SIG_SETMASK, omask, NULL);
|
||||
}
|
||||
|
||||
|
||||
static int HAIKUAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||
{
|
||||
media_raw_audio_format format;
|
||||
SDL_AudioFormat test_format;
|
||||
const SDL_AudioFormat *closefmts;
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
_this->hidden = new SDL_PrivateAudioData;
|
||||
if (_this->hidden == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(_this->hidden);
|
||||
|
||||
/* Parse the audio format and fill the Be raw audio format */
|
||||
SDL_zero(format);
|
||||
format.byte_order = B_MEDIA_LITTLE_ENDIAN;
|
||||
format.frame_rate = (float) _this->spec.freq;
|
||||
format.channel_count = _this->spec.channels; /* !!! FIXME: support > 2? */
|
||||
|
||||
closefmts = SDL_ClosestAudioFormats(_this->spec.format);
|
||||
while ((test_format = *(closefmts++)) != 0) {
|
||||
switch (test_format) {
|
||||
case SDL_AUDIO_S8:
|
||||
format.format = media_raw_audio_format::B_AUDIO_CHAR;
|
||||
break;
|
||||
|
||||
case SDL_AUDIO_U8:
|
||||
format.format = media_raw_audio_format::B_AUDIO_UCHAR;
|
||||
break;
|
||||
|
||||
case SDL_AUDIO_S16LSB:
|
||||
format.format = media_raw_audio_format::B_AUDIO_SHORT;
|
||||
break;
|
||||
|
||||
case SDL_AUDIO_S16MSB:
|
||||
format.format = media_raw_audio_format::B_AUDIO_SHORT;
|
||||
format.byte_order = B_MEDIA_BIG_ENDIAN;
|
||||
break;
|
||||
|
||||
case SDL_AUDIO_S32LSB:
|
||||
format.format = media_raw_audio_format::B_AUDIO_INT;
|
||||
break;
|
||||
|
||||
case SDL_AUDIO_S32MSB:
|
||||
format.format = media_raw_audio_format::B_AUDIO_INT;
|
||||
format.byte_order = B_MEDIA_BIG_ENDIAN;
|
||||
break;
|
||||
|
||||
case SDL_AUDIO_F32LSB:
|
||||
format.format = media_raw_audio_format::B_AUDIO_FLOAT;
|
||||
break;
|
||||
|
||||
case SDL_AUDIO_F32MSB:
|
||||
format.format = media_raw_audio_format::B_AUDIO_FLOAT;
|
||||
format.byte_order = B_MEDIA_BIG_ENDIAN;
|
||||
break;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!test_format) { /* shouldn't happen, but just in case... */
|
||||
return SDL_SetError("%s: Unsupported audio format", "haiku");
|
||||
}
|
||||
_this->spec.format = test_format;
|
||||
|
||||
/* Calculate the final parameters for this audio specification */
|
||||
SDL_CalculateAudioSpec(&_this->spec);
|
||||
|
||||
format.buffer_size = _this->spec.size;
|
||||
|
||||
/* Subscribe to the audio stream (creates a new thread) */
|
||||
sigset_t omask;
|
||||
MaskSignals(&omask);
|
||||
_this->hidden->audio_obj = new BSoundPlayer(&format, "SDL Audio",
|
||||
FillSound, NULL, _this);
|
||||
UnmaskSignals(&omask);
|
||||
|
||||
if (_this->hidden->audio_obj->Start() == B_NO_ERROR) {
|
||||
_this->hidden->audio_obj->SetHasData(true);
|
||||
} else {
|
||||
return SDL_SetError("Unable to start Be audio");
|
||||
}
|
||||
|
||||
/* We're running! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void HAIKUAUDIO_Deinitialize(void)
|
||||
{
|
||||
SDL_QuitBeApp();
|
||||
}
|
||||
|
||||
static SDL_bool HAIKUAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
/* Initialize the Be Application, if it's not already started */
|
||||
if (SDL_InitBeApp() < 0) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Set the function pointers */
|
||||
impl->OpenDevice = HAIKUAUDIO_OpenDevice;
|
||||
impl->CloseDevice = HAIKUAUDIO_CloseDevice;
|
||||
impl->Deinitialize = HAIKUAUDIO_Deinitialize;
|
||||
impl->ProvidesOwnCallbackThread = SDL_TRUE;
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
extern AudioBootStrap HAIKUAUDIO_bootstrap;
|
||||
}
|
||||
AudioBootStrap HAIKUAUDIO_bootstrap = {
|
||||
"haiku", "Haiku BSoundPlayer", HAIKUAUDIO_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_HAIKU */
|
33
external/sdl/SDL/src/audio/haiku/SDL_haikuaudio.h
vendored
Normal file
33
external/sdl/SDL/src/audio/haiku/SDL_haikuaudio.h
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifndef SDL_haikuaudio_h_
|
||||
#define SDL_haikuaudio_h_
|
||||
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
BSoundPlayer *audio_obj;
|
||||
};
|
||||
|
||||
#endif /* SDL_haikuaudio_h_ */
|
Reference in New Issue
Block a user