mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 15:44:36 +00:00
update sdl to 2.32.6
This commit is contained in:
parent
e557f5962b
commit
ddc1f8c1e2
1339 changed files with 53966 additions and 19207 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -29,9 +29,6 @@
|
|||
#endif
|
||||
#if defined(__OS2__)
|
||||
#include "core/os2/SDL_os2.h"
|
||||
#if SDL_THREAD_OS2
|
||||
#include "thread/os2/SDL_systls_c.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* this checks for HAVE_DBUS_DBUS_H internally. */
|
||||
|
|
@ -52,12 +49,13 @@
|
|||
#include "haptic/SDL_haptic_c.h"
|
||||
#include "joystick/SDL_joystick_c.h"
|
||||
#include "sensor/SDL_sensor_c.h"
|
||||
#include "thread/SDL_thread_c.h"
|
||||
|
||||
/* Initialization/Cleanup routines */
|
||||
#if !SDL_TIMERS_DISABLED
|
||||
#ifndef SDL_TIMERS_DISABLED
|
||||
#include "timer/SDL_timer_c.h"
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_WINDOWS
|
||||
#ifdef SDL_VIDEO_DRIVER_WINDOWS
|
||||
extern int SDL_HelperWindowCreate(void);
|
||||
extern int SDL_HelperWindowDestroy(void);
|
||||
#endif
|
||||
|
|
@ -116,6 +114,7 @@ static SDL_bool SDL_MainIsReady = SDL_FALSE;
|
|||
#else
|
||||
static SDL_bool SDL_MainIsReady = SDL_TRUE;
|
||||
#endif
|
||||
static SDL_bool SDL_main_thread_initialized = SDL_FALSE;
|
||||
static SDL_bool SDL_bInMainQuit = SDL_FALSE;
|
||||
static Uint8 SDL_SubsystemRefCount[32];
|
||||
|
||||
|
|
@ -160,11 +159,57 @@ static SDL_bool SDL_PrivateShouldQuitSubsystem(Uint32 subsystem)
|
|||
return (((subsystem_index >= 0) && (SDL_SubsystemRefCount[subsystem_index] == 1)) || SDL_bInMainQuit) ? SDL_TRUE : SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Private helper to either increment's existing ref counter,
|
||||
* or fully init a new subsystem. */
|
||||
static SDL_bool SDL_PrivateInitOrIncrSubsystem(Uint32 subsystem)
|
||||
{
|
||||
int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
|
||||
SDL_assert((subsystem_index < 0) || (SDL_SubsystemRefCount[subsystem_index] < 255));
|
||||
if (subsystem_index < 0) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
if (SDL_SubsystemRefCount[subsystem_index] > 0) {
|
||||
++SDL_SubsystemRefCount[subsystem_index];
|
||||
return SDL_TRUE;
|
||||
}
|
||||
return SDL_InitSubSystem(subsystem) == 0;
|
||||
}
|
||||
|
||||
void SDL_SetMainReady(void)
|
||||
{
|
||||
SDL_MainIsReady = SDL_TRUE;
|
||||
}
|
||||
|
||||
void SDL_InitMainThread(void)
|
||||
{
|
||||
if (SDL_main_thread_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_InitTLSData();
|
||||
#ifndef SDL_TIMERS_DISABLED
|
||||
SDL_TicksInit();
|
||||
#endif
|
||||
SDL_LogInit();
|
||||
|
||||
SDL_main_thread_initialized = SDL_TRUE;
|
||||
}
|
||||
|
||||
static void SDL_QuitMainThread(void)
|
||||
{
|
||||
if (!SDL_main_thread_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_LogQuit();
|
||||
#ifndef SDL_TIMERS_DISABLED
|
||||
SDL_TicksQuit();
|
||||
#endif
|
||||
SDL_QuitTLSData();
|
||||
|
||||
SDL_main_thread_initialized = SDL_FALSE;
|
||||
}
|
||||
|
||||
int SDL_InitSubSystem(Uint32 flags)
|
||||
{
|
||||
Uint32 flags_initialized = 0;
|
||||
|
|
@ -173,30 +218,14 @@ int SDL_InitSubSystem(Uint32 flags)
|
|||
return SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
|
||||
}
|
||||
|
||||
SDL_LogInit();
|
||||
|
||||
/* Clear the error message */
|
||||
SDL_ClearError();
|
||||
|
||||
#if SDL_USE_LIBDBUS
|
||||
#ifdef SDL_USE_LIBDBUS
|
||||
SDL_DBus_Init();
|
||||
#endif
|
||||
|
||||
if (flags & SDL_INIT_GAMECONTROLLER) {
|
||||
/* game controller implies joystick */
|
||||
flags |= SDL_INIT_JOYSTICK;
|
||||
}
|
||||
|
||||
if (flags & (SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO)) {
|
||||
/* video or joystick or audio implies events */
|
||||
flags |= SDL_INIT_EVENTS;
|
||||
}
|
||||
|
||||
#if SDL_THREAD_OS2
|
||||
SDL_OS2TLSAlloc(); /* thread/os2/SDL_systls.c */
|
||||
#endif
|
||||
|
||||
#if SDL_VIDEO_DRIVER_WINDOWS
|
||||
#ifdef SDL_VIDEO_DRIVER_WINDOWS
|
||||
if (flags & (SDL_INIT_HAPTIC | SDL_INIT_JOYSTICK)) {
|
||||
if (SDL_HelperWindowCreate() < 0) {
|
||||
goto quit_and_error;
|
||||
|
|
@ -204,13 +233,9 @@ int SDL_InitSubSystem(Uint32 flags)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if !SDL_TIMERS_DISABLED
|
||||
SDL_TicksInit();
|
||||
#endif
|
||||
|
||||
/* Initialize the event subsystem */
|
||||
if (flags & SDL_INIT_EVENTS) {
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
#ifndef SDL_EVENTS_DISABLED
|
||||
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_EVENTS)) {
|
||||
if (SDL_EventsInit() < 0) {
|
||||
goto quit_and_error;
|
||||
|
|
@ -226,7 +251,7 @@ int SDL_InitSubSystem(Uint32 flags)
|
|||
|
||||
/* Initialize the timer subsystem */
|
||||
if (flags & SDL_INIT_TIMER) {
|
||||
#if !SDL_TIMERS_DISABLED && !SDL_TIMER_DUMMY
|
||||
#if !defined(SDL_TIMERS_DISABLED) && !defined(SDL_TIMER_DUMMY)
|
||||
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_TIMER)) {
|
||||
if (SDL_TimerInit() < 0) {
|
||||
goto quit_and_error;
|
||||
|
|
@ -242,8 +267,13 @@ int SDL_InitSubSystem(Uint32 flags)
|
|||
|
||||
/* Initialize the video subsystem */
|
||||
if (flags & SDL_INIT_VIDEO) {
|
||||
#if !SDL_VIDEO_DISABLED
|
||||
#ifndef SDL_VIDEO_DISABLED
|
||||
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_VIDEO)) {
|
||||
/* video implies events */
|
||||
if (!SDL_PrivateInitOrIncrSubsystem(SDL_INIT_EVENTS)) {
|
||||
goto quit_and_error;
|
||||
}
|
||||
|
||||
if (SDL_VideoInit(NULL) < 0) {
|
||||
goto quit_and_error;
|
||||
}
|
||||
|
|
@ -258,8 +288,13 @@ int SDL_InitSubSystem(Uint32 flags)
|
|||
|
||||
/* Initialize the audio subsystem */
|
||||
if (flags & SDL_INIT_AUDIO) {
|
||||
#if !SDL_AUDIO_DISABLED
|
||||
#ifndef SDL_AUDIO_DISABLED
|
||||
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_AUDIO)) {
|
||||
/* audio implies events */
|
||||
if (!SDL_PrivateInitOrIncrSubsystem(SDL_INIT_EVENTS)) {
|
||||
goto quit_and_error;
|
||||
}
|
||||
|
||||
if (SDL_AudioInit(NULL) < 0) {
|
||||
goto quit_and_error;
|
||||
}
|
||||
|
|
@ -274,8 +309,13 @@ int SDL_InitSubSystem(Uint32 flags)
|
|||
|
||||
/* Initialize the joystick subsystem */
|
||||
if (flags & SDL_INIT_JOYSTICK) {
|
||||
#if !SDL_JOYSTICK_DISABLED
|
||||
#ifndef SDL_JOYSTICK_DISABLED
|
||||
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_JOYSTICK)) {
|
||||
/* joystick implies events */
|
||||
if (!SDL_PrivateInitOrIncrSubsystem(SDL_INIT_EVENTS)) {
|
||||
goto quit_and_error;
|
||||
}
|
||||
|
||||
if (SDL_JoystickInit() < 0) {
|
||||
goto quit_and_error;
|
||||
}
|
||||
|
|
@ -289,8 +329,13 @@ int SDL_InitSubSystem(Uint32 flags)
|
|||
}
|
||||
|
||||
if (flags & SDL_INIT_GAMECONTROLLER) {
|
||||
#if !SDL_JOYSTICK_DISABLED
|
||||
#ifndef SDL_JOYSTICK_DISABLED
|
||||
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_GAMECONTROLLER)) {
|
||||
/* game controller implies joystick */
|
||||
if (!SDL_PrivateInitOrIncrSubsystem(SDL_INIT_JOYSTICK)) {
|
||||
goto quit_and_error;
|
||||
}
|
||||
|
||||
if (SDL_GameControllerInit() < 0) {
|
||||
goto quit_and_error;
|
||||
}
|
||||
|
|
@ -305,7 +350,7 @@ int SDL_InitSubSystem(Uint32 flags)
|
|||
|
||||
/* Initialize the haptic subsystem */
|
||||
if (flags & SDL_INIT_HAPTIC) {
|
||||
#if !SDL_HAPTIC_DISABLED
|
||||
#ifndef SDL_HAPTIC_DISABLED
|
||||
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_HAPTIC)) {
|
||||
if (SDL_HapticInit() < 0) {
|
||||
goto quit_and_error;
|
||||
|
|
@ -321,7 +366,7 @@ int SDL_InitSubSystem(Uint32 flags)
|
|||
|
||||
/* Initialize the sensor subsystem */
|
||||
if (flags & SDL_INIT_SENSOR) {
|
||||
#if !SDL_SENSOR_DISABLED
|
||||
#ifndef SDL_SENSOR_DISABLED
|
||||
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_SENSOR)) {
|
||||
if (SDL_SensorInit() < 0) {
|
||||
goto quit_and_error;
|
||||
|
|
@ -352,14 +397,11 @@ int SDL_Init(Uint32 flags)
|
|||
void SDL_QuitSubSystem(Uint32 flags)
|
||||
{
|
||||
#if defined(__OS2__)
|
||||
#if SDL_THREAD_OS2
|
||||
SDL_OS2TLSFree(); /* thread/os2/SDL_systls.c */
|
||||
#endif
|
||||
SDL_OS2Quit();
|
||||
#endif
|
||||
|
||||
/* Shut down requested initialized subsystems */
|
||||
#if !SDL_SENSOR_DISABLED
|
||||
#ifndef SDL_SENSOR_DISABLED
|
||||
if (flags & SDL_INIT_SENSOR) {
|
||||
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_SENSOR)) {
|
||||
SDL_SensorQuit();
|
||||
|
|
@ -368,29 +410,27 @@ void SDL_QuitSubSystem(Uint32 flags)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if !SDL_JOYSTICK_DISABLED
|
||||
#ifndef SDL_JOYSTICK_DISABLED
|
||||
if (flags & SDL_INIT_GAMECONTROLLER) {
|
||||
/* game controller implies joystick */
|
||||
flags |= SDL_INIT_JOYSTICK;
|
||||
|
||||
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_GAMECONTROLLER)) {
|
||||
SDL_GameControllerQuit();
|
||||
/* game controller implies joystick */
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
}
|
||||
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_GAMECONTROLLER);
|
||||
}
|
||||
|
||||
if (flags & SDL_INIT_JOYSTICK) {
|
||||
/* joystick implies events */
|
||||
flags |= SDL_INIT_EVENTS;
|
||||
|
||||
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_JOYSTICK)) {
|
||||
SDL_JoystickQuit();
|
||||
/* joystick implies events */
|
||||
SDL_QuitSubSystem(SDL_INIT_EVENTS);
|
||||
}
|
||||
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_JOYSTICK);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !SDL_HAPTIC_DISABLED
|
||||
#ifndef SDL_HAPTIC_DISABLED
|
||||
if (flags & SDL_INIT_HAPTIC) {
|
||||
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_HAPTIC)) {
|
||||
SDL_HapticQuit();
|
||||
|
|
@ -399,31 +439,29 @@ void SDL_QuitSubSystem(Uint32 flags)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if !SDL_AUDIO_DISABLED
|
||||
#ifndef SDL_AUDIO_DISABLED
|
||||
if (flags & SDL_INIT_AUDIO) {
|
||||
/* audio implies events */
|
||||
flags |= SDL_INIT_EVENTS;
|
||||
|
||||
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_AUDIO)) {
|
||||
SDL_AudioQuit();
|
||||
/* audio implies events */
|
||||
SDL_QuitSubSystem(SDL_INIT_EVENTS);
|
||||
}
|
||||
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_AUDIO);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !SDL_VIDEO_DISABLED
|
||||
#ifndef SDL_VIDEO_DISABLED
|
||||
if (flags & SDL_INIT_VIDEO) {
|
||||
/* video implies events */
|
||||
flags |= SDL_INIT_EVENTS;
|
||||
|
||||
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_VIDEO)) {
|
||||
SDL_VideoQuit();
|
||||
/* video implies events */
|
||||
SDL_QuitSubSystem(SDL_INIT_EVENTS);
|
||||
}
|
||||
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_VIDEO);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !SDL_TIMERS_DISABLED && !SDL_TIMER_DUMMY
|
||||
#if !defined(SDL_TIMERS_DISABLED) && !defined(SDL_TIMER_DUMMY)
|
||||
if (flags & SDL_INIT_TIMER) {
|
||||
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_TIMER)) {
|
||||
SDL_TimerQuit();
|
||||
|
|
@ -432,7 +470,7 @@ void SDL_QuitSubSystem(Uint32 flags)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
#ifndef SDL_EVENTS_DISABLED
|
||||
if (flags & SDL_INIT_EVENTS) {
|
||||
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_EVENTS)) {
|
||||
SDL_EventsQuit();
|
||||
|
|
@ -477,30 +515,24 @@ void SDL_Quit(void)
|
|||
SDL_bInMainQuit = SDL_TRUE;
|
||||
|
||||
/* Quit all subsystems */
|
||||
#if SDL_VIDEO_DRIVER_WINDOWS
|
||||
#ifdef SDL_VIDEO_DRIVER_WINDOWS
|
||||
SDL_HelperWindowDestroy();
|
||||
#endif
|
||||
SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
|
||||
|
||||
#if !SDL_TIMERS_DISABLED
|
||||
SDL_TicksQuit();
|
||||
#ifdef SDL_USE_LIBDBUS
|
||||
SDL_DBus_Quit();
|
||||
#endif
|
||||
|
||||
SDL_ClearHints();
|
||||
SDL_AssertionsQuit();
|
||||
|
||||
#if SDL_USE_LIBDBUS
|
||||
SDL_DBus_Quit();
|
||||
#endif
|
||||
|
||||
SDL_LogQuit();
|
||||
|
||||
/* Now that every subsystem has been quit, we reset the subsystem refcount
|
||||
* and the list of initialized subsystems.
|
||||
*/
|
||||
SDL_memset(SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount));
|
||||
|
||||
SDL_TLSCleanup();
|
||||
SDL_QuitMainThread();
|
||||
|
||||
SDL_bInMainQuit = SDL_FALSE;
|
||||
}
|
||||
|
|
@ -511,7 +543,7 @@ void SDL_GetVersion(SDL_version *ver)
|
|||
static SDL_bool check_hint = SDL_TRUE;
|
||||
static SDL_bool legacy_version = SDL_FALSE;
|
||||
|
||||
if (ver == NULL) {
|
||||
if (!ver) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -544,71 +576,71 @@ int SDL_GetRevisionNumber(void)
|
|||
/* Get the name of the platform */
|
||||
const char *SDL_GetPlatform(void)
|
||||
{
|
||||
#if __AIX__
|
||||
#if defined(__AIX__)
|
||||
return "AIX";
|
||||
#elif __ANDROID__
|
||||
#elif defined(__ANDROID__)
|
||||
return "Android";
|
||||
#elif __BSDI__
|
||||
#elif defined(__BSDI__)
|
||||
return "BSDI";
|
||||
#elif __DREAMCAST__
|
||||
#elif defined(__DREAMCAST__)
|
||||
return "Dreamcast";
|
||||
#elif __EMSCRIPTEN__
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
return "Emscripten";
|
||||
#elif __FREEBSD__
|
||||
#elif defined(__FREEBSD__)
|
||||
return "FreeBSD";
|
||||
#elif __HAIKU__
|
||||
#elif defined(__HAIKU__)
|
||||
return "Haiku";
|
||||
#elif __HPUX__
|
||||
#elif defined(__HPUX__)
|
||||
return "HP-UX";
|
||||
#elif __IRIX__
|
||||
#elif defined(__IRIX__)
|
||||
return "Irix";
|
||||
#elif __LINUX__
|
||||
#elif defined(__LINUX__)
|
||||
return "Linux";
|
||||
#elif __MINT__
|
||||
#elif defined(__MINT__)
|
||||
return "Atari MiNT";
|
||||
#elif __MACOS__
|
||||
#elif defined(__MACOS__)
|
||||
return "MacOS Classic";
|
||||
#elif __MACOSX__
|
||||
#elif defined(__MACOSX__)
|
||||
return "Mac OS X";
|
||||
#elif __NACL__
|
||||
#elif defined(__NACL__)
|
||||
return "NaCl";
|
||||
#elif __NETBSD__
|
||||
#elif defined(__NETBSD__)
|
||||
return "NetBSD";
|
||||
#elif __OPENBSD__
|
||||
#elif defined(__OPENBSD__)
|
||||
return "OpenBSD";
|
||||
#elif __OS2__
|
||||
#elif defined(__OS2__)
|
||||
return "OS/2";
|
||||
#elif __OSF__
|
||||
#elif defined(__OSF__)
|
||||
return "OSF/1";
|
||||
#elif __QNXNTO__
|
||||
#elif defined(__QNXNTO__)
|
||||
return "QNX Neutrino";
|
||||
#elif __RISCOS__
|
||||
#elif defined(__RISCOS__)
|
||||
return "RISC OS";
|
||||
#elif __SOLARIS__
|
||||
#elif defined(__SOLARIS__)
|
||||
return "Solaris";
|
||||
#elif __WIN32__
|
||||
#elif defined(__WIN32__)
|
||||
return "Windows";
|
||||
#elif __WINRT__
|
||||
#elif defined(__WINRT__)
|
||||
return "WinRT";
|
||||
#elif __WINGDK__
|
||||
#elif defined(__WINGDK__)
|
||||
return "WinGDK";
|
||||
#elif __XBOXONE__
|
||||
#elif defined(__XBOXONE__)
|
||||
return "Xbox One";
|
||||
#elif __XBOXSERIES__
|
||||
#elif defined(__XBOXSERIES__)
|
||||
return "Xbox Series X|S";
|
||||
#elif __TVOS__
|
||||
#elif defined(__TVOS__)
|
||||
return "tvOS";
|
||||
#elif __IPHONEOS__
|
||||
#elif defined(__IPHONEOS__)
|
||||
return "iOS";
|
||||
#elif __PS2__
|
||||
#elif defined(__PS2__)
|
||||
return "PlayStation 2";
|
||||
#elif __PSP__
|
||||
#elif defined(__PSP__)
|
||||
return "PlayStation Portable";
|
||||
#elif __VITA__
|
||||
#elif defined(__VITA__)
|
||||
return "PlayStation Vita";
|
||||
#elif __NGAGE__
|
||||
#elif defined(__NGAGE__)
|
||||
return "Nokia N-Gage";
|
||||
#elif __3DS__
|
||||
#elif defined(__3DS__)
|
||||
return "Nintendo 3DS";
|
||||
#else
|
||||
return "Unknown (see SDL_platform.h)";
|
||||
|
|
@ -617,10 +649,10 @@ const char *SDL_GetPlatform(void)
|
|||
|
||||
SDL_bool SDL_IsTablet(void)
|
||||
{
|
||||
#if __ANDROID__
|
||||
#if defined(__ANDROID__)
|
||||
extern SDL_bool SDL_IsAndroidTablet(void);
|
||||
return SDL_IsAndroidTablet();
|
||||
#elif __IPHONEOS__
|
||||
#elif defined(__IPHONEOS__)
|
||||
extern SDL_bool SDL_IsIPad(void);
|
||||
return SDL_IsIPad();
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -42,15 +42,7 @@
|
|||
#endif
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#include <emscripten.h>
|
||||
/* older Emscriptens don't have this, but we need to for wasm64 compatibility. */
|
||||
#ifndef MAIN_THREAD_EM_ASM_PTR
|
||||
#ifdef __wasm64__
|
||||
#error You need to upgrade your Emscripten compiler to support wasm64
|
||||
#else
|
||||
#define MAIN_THREAD_EM_ASM_PTR MAIN_THREAD_EM_ASM_INT
|
||||
#endif
|
||||
#endif
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
/* The size of the stack buffer to use for rendering assert messages. */
|
||||
|
|
@ -114,11 +106,11 @@ static void SDL_GenerateAssertionReport(void)
|
|||
const SDL_assert_data *item = triggered_assertions;
|
||||
|
||||
/* only do this if the app hasn't assigned an assertion handler. */
|
||||
if ((item != NULL) && (assertion_handler != SDL_PromptAssertion)) {
|
||||
if ((item) && (assertion_handler != SDL_PromptAssertion)) {
|
||||
debug_print("\n\nSDL assertion report.\n");
|
||||
debug_print("All SDL assertions between last init/quit:\n\n");
|
||||
|
||||
while (item != NULL) {
|
||||
while (item) {
|
||||
debug_print(
|
||||
"'%s'\n"
|
||||
" * %s (%s:%d)\n"
|
||||
|
|
@ -206,7 +198,7 @@ static SDL_assert_state SDLCALL SDL_PromptAssertion(const SDL_assert_data *data,
|
|||
|
||||
/* let env. variable override, so unit tests won't block in a GUI. */
|
||||
envr = SDL_getenv("SDL_ASSERT");
|
||||
if (envr != NULL) {
|
||||
if (envr) {
|
||||
if (message != stack_buf) {
|
||||
SDL_free(message);
|
||||
}
|
||||
|
|
@ -259,7 +251,7 @@ static SDL_assert_state SDLCALL SDL_PromptAssertion(const SDL_assert_data *data,
|
|||
for (;;) {
|
||||
SDL_bool okay = SDL_TRUE;
|
||||
/* *INDENT-OFF* */ /* clang-format off */
|
||||
char *buf = (char *) MAIN_THREAD_EM_ASM_PTR({
|
||||
int reply = MAIN_THREAD_EM_ASM_INT({
|
||||
var str =
|
||||
UTF8ToString($0) + '\n\n' +
|
||||
'Abort/Retry/Ignore/AlwaysIgnore? [ariA] :';
|
||||
|
|
@ -267,32 +259,37 @@ static SDL_assert_state SDLCALL SDL_PromptAssertion(const SDL_assert_data *data,
|
|||
if (reply === null) {
|
||||
reply = "i";
|
||||
}
|
||||
return allocate(intArrayFromString(reply), 'i8', ALLOC_NORMAL);
|
||||
return reply.length === 1 ? reply.charCodeAt(0) : -1;
|
||||
}, message);
|
||||
/* *INDENT-ON* */ /* clang-format on */
|
||||
|
||||
if (SDL_strcmp(buf, "a") == 0) {
|
||||
switch (reply) {
|
||||
case 'a':
|
||||
state = SDL_ASSERTION_ABORT;
|
||||
#if 0 /* (currently) no break functionality on Emscripten */
|
||||
} else if (SDL_strcmp(buf, "b") == 0) {
|
||||
case 'b':
|
||||
state = SDL_ASSERTION_BREAK;
|
||||
break;
|
||||
#endif
|
||||
} else if (SDL_strcmp(buf, "r") == 0) {
|
||||
case 'r':
|
||||
state = SDL_ASSERTION_RETRY;
|
||||
} else if (SDL_strcmp(buf, "i") == 0) {
|
||||
break;
|
||||
case 'i':
|
||||
state = SDL_ASSERTION_IGNORE;
|
||||
} else if (SDL_strcmp(buf, "A") == 0) {
|
||||
break;
|
||||
case 'A':
|
||||
state = SDL_ASSERTION_ALWAYS_IGNORE;
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
okay = SDL_FALSE;
|
||||
break;
|
||||
}
|
||||
free(buf);
|
||||
|
||||
if (okay) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#elif defined(HAVE_STDIO_H)
|
||||
#elif defined(HAVE_STDIO_H) && !defined(__3DS__)
|
||||
/* this is a little hacky. */
|
||||
for (;;) {
|
||||
char buf[32];
|
||||
|
|
@ -319,6 +316,8 @@ static SDL_assert_state SDLCALL SDL_PromptAssertion(const SDL_assert_data *data,
|
|||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "Assertion Failed", message, window);
|
||||
#endif /* HAVE_STDIO_H */
|
||||
}
|
||||
|
||||
|
|
@ -342,9 +341,9 @@ SDL_assert_state SDL_ReportAssertion(SDL_assert_data *data, const char *func, co
|
|||
#ifndef SDL_THREADS_DISABLED
|
||||
static SDL_SpinLock spinlock = 0;
|
||||
SDL_AtomicLock(&spinlock);
|
||||
if (assertion_mutex == NULL) { /* never called SDL_Init()? */
|
||||
if (!assertion_mutex) { /* never called SDL_Init()? */
|
||||
assertion_mutex = SDL_CreateMutex();
|
||||
if (assertion_mutex == NULL) {
|
||||
if (!assertion_mutex) {
|
||||
SDL_AtomicUnlock(&spinlock);
|
||||
return SDL_ASSERTION_IGNORE; /* oh well, I guess. */
|
||||
}
|
||||
|
|
@ -409,7 +408,7 @@ void SDL_AssertionsQuit(void)
|
|||
#if SDL_ASSERT_LEVEL > 0
|
||||
SDL_GenerateAssertionReport();
|
||||
#ifndef SDL_THREADS_DISABLED
|
||||
if (assertion_mutex != NULL) {
|
||||
if (assertion_mutex) {
|
||||
SDL_DestroyMutex(assertion_mutex);
|
||||
assertion_mutex = NULL;
|
||||
}
|
||||
|
|
@ -437,7 +436,7 @@ void SDL_ResetAssertionReport(void)
|
|||
{
|
||||
SDL_assert_data *next = NULL;
|
||||
SDL_assert_data *item;
|
||||
for (item = triggered_assertions; item != NULL; item = next) {
|
||||
for (item = triggered_assertions; item; item = next) {
|
||||
next = (SDL_assert_data *)item->next;
|
||||
item->always_ignore = SDL_FALSE;
|
||||
item->trigger_count = 0;
|
||||
|
|
@ -454,7 +453,7 @@ SDL_AssertionHandler SDL_GetDefaultAssertionHandler(void)
|
|||
|
||||
SDL_AssertionHandler SDL_GetAssertionHandler(void **userdata)
|
||||
{
|
||||
if (userdata != NULL) {
|
||||
if (userdata) {
|
||||
*userdata = assertion_userdata;
|
||||
}
|
||||
return assertion_handler;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -54,7 +54,7 @@ SDL_DataQueue *SDL_NewDataQueue(const size_t _packetlen, const size_t initialsla
|
|||
{
|
||||
SDL_DataQueue *queue = (SDL_DataQueue *)SDL_calloc(1, sizeof(SDL_DataQueue));
|
||||
|
||||
if (queue == NULL) {
|
||||
if (!queue) {
|
||||
SDL_OutOfMemory();
|
||||
} else {
|
||||
const size_t packetlen = _packetlen ? _packetlen : 1024;
|
||||
|
|
@ -101,7 +101,7 @@ void SDL_ClearDataQueue(SDL_DataQueue *queue, const size_t slack)
|
|||
SDL_DataQueuePacket *prev = NULL;
|
||||
size_t i;
|
||||
|
||||
if (queue == NULL) {
|
||||
if (!queue) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -147,13 +147,13 @@ static SDL_DataQueuePacket *AllocateDataQueuePacket(SDL_DataQueue *queue)
|
|||
SDL_assert(queue != NULL);
|
||||
|
||||
packet = queue->pool;
|
||||
if (packet != NULL) {
|
||||
if (packet) {
|
||||
/* we have one available in the pool. */
|
||||
queue->pool = packet->next;
|
||||
} else {
|
||||
/* Have to allocate a new one! */
|
||||
packet = (SDL_DataQueuePacket *)SDL_malloc(sizeof(SDL_DataQueuePacket) + queue->packet_size);
|
||||
if (packet == NULL) {
|
||||
if (!packet) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -163,7 +163,7 @@ static SDL_DataQueuePacket *AllocateDataQueuePacket(SDL_DataQueue *queue)
|
|||
packet->next = NULL;
|
||||
|
||||
SDL_assert((queue->head != NULL) == (queue->queued_bytes != 0));
|
||||
if (queue->tail == NULL) {
|
||||
if (!queue->tail) {
|
||||
queue->head = packet;
|
||||
} else {
|
||||
queue->tail->next = packet;
|
||||
|
|
@ -182,7 +182,7 @@ int SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *_data, const size_t _
|
|||
size_t origlen;
|
||||
size_t datalen;
|
||||
|
||||
if (queue == NULL) {
|
||||
if (!queue) {
|
||||
return SDL_InvalidParamError("queue");
|
||||
}
|
||||
|
||||
|
|
@ -195,12 +195,12 @@ int SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *_data, const size_t _
|
|||
while (len > 0) {
|
||||
SDL_DataQueuePacket *packet = queue->tail;
|
||||
SDL_assert(packet == NULL || (packet->datalen <= packet_size));
|
||||
if (packet == NULL || (packet->datalen >= packet_size)) {
|
||||
if (!packet || (packet->datalen >= packet_size)) {
|
||||
/* tail packet missing or completely full; we need a new packet. */
|
||||
packet = AllocateDataQueuePacket(queue);
|
||||
if (packet == NULL) {
|
||||
if (!packet) {
|
||||
/* uhoh, reset so we've queued nothing new, free what we can. */
|
||||
if (origtail == NULL) {
|
||||
if (!origtail) {
|
||||
packet = queue->head; /* whole queue. */
|
||||
} else {
|
||||
packet = origtail->next; /* what we added to existing queue. */
|
||||
|
|
@ -238,7 +238,7 @@ SDL_PeekIntoDataQueue(SDL_DataQueue *queue, void *_buf, const size_t _len)
|
|||
Uint8 *ptr = buf;
|
||||
SDL_DataQueuePacket *packet;
|
||||
|
||||
if (queue == NULL) {
|
||||
if (!queue) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -267,7 +267,7 @@ SDL_ReadFromDataQueue(SDL_DataQueue *queue, void *_buf, const size_t _len)
|
|||
Uint8 *ptr = buf;
|
||||
SDL_DataQueuePacket *packet;
|
||||
|
||||
if (queue == NULL) {
|
||||
if (!queue) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -294,7 +294,7 @@ SDL_ReadFromDataQueue(SDL_DataQueue *queue, void *_buf, const size_t _len)
|
|||
|
||||
SDL_assert((queue->head != NULL) == (queue->queued_bytes != 0));
|
||||
|
||||
if (queue->head == NULL) {
|
||||
if (!queue->head) {
|
||||
queue->tail = NULL; /* in case we drained the queue entirely. */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
int SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
|
||||
{
|
||||
/* Ignore call if invalid format pointer was passed */
|
||||
if (fmt != NULL) {
|
||||
if (fmt) {
|
||||
va_list ap;
|
||||
int result;
|
||||
SDL_error *error = SDL_GetErrBuf();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -29,7 +29,7 @@ void SDL_GUIDToString(SDL_GUID guid, char *pszGUID, int cbGUID)
|
|||
static const char k_rgchHexToASCII[] = "0123456789abcdef";
|
||||
int i;
|
||||
|
||||
if ((pszGUID == NULL) || (cbGUID <= 0)) {
|
||||
if ((!pszGUID) || (cbGUID <= 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -51,7 +51,7 @@ SDL_bool SDL_SetHintWithPriority(const char *name, const char *value, SDL_HintPr
|
|||
SDL_Hint *hint;
|
||||
SDL_HintWatch *entry;
|
||||
|
||||
if (name == NULL) {
|
||||
if (!name) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ SDL_bool SDL_SetHintWithPriority(const char *name, const char *value, SDL_HintPr
|
|||
return SDL_FALSE;
|
||||
}
|
||||
if (hint->value != value &&
|
||||
(value == NULL || !hint->value || SDL_strcmp(hint->value, value) != 0)) {
|
||||
(!value || !hint->value || SDL_strcmp(hint->value, value) != 0)) {
|
||||
for (entry = hint->callbacks; entry;) {
|
||||
/* Save the next entry in case this one is deleted */
|
||||
SDL_HintWatch *next = entry->next;
|
||||
|
|
@ -83,7 +83,7 @@ SDL_bool SDL_SetHintWithPriority(const char *name, const char *value, SDL_HintPr
|
|||
|
||||
/* Couldn't find the hint, add a new one */
|
||||
hint = (SDL_Hint *)SDL_malloc(sizeof(*hint));
|
||||
if (hint == NULL) {
|
||||
if (!hint) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
hint->name = SDL_strdup(name);
|
||||
|
|
@ -101,16 +101,16 @@ SDL_bool SDL_ResetHint(const char *name)
|
|||
SDL_Hint *hint;
|
||||
SDL_HintWatch *entry;
|
||||
|
||||
if (name == NULL) {
|
||||
if (!name) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
env = SDL_getenv(name);
|
||||
for (hint = SDL_hints; hint; hint = hint->next) {
|
||||
if (SDL_strcmp(name, hint->name) == 0) {
|
||||
if ((env == NULL && hint->value != NULL) ||
|
||||
(env != NULL && hint->value == NULL) ||
|
||||
(env != NULL && SDL_strcmp(env, hint->value) != 0)) {
|
||||
if ((!env && hint->value) ||
|
||||
(env && !hint->value) ||
|
||||
(env && SDL_strcmp(env, hint->value) != 0)) {
|
||||
for (entry = hint->callbacks; entry;) {
|
||||
/* Save the next entry in case this one is deleted */
|
||||
SDL_HintWatch *next = entry->next;
|
||||
|
|
@ -135,9 +135,9 @@ void SDL_ResetHints(void)
|
|||
|
||||
for (hint = SDL_hints; hint; hint = hint->next) {
|
||||
env = SDL_getenv(hint->name);
|
||||
if ((env == NULL && hint->value != NULL) ||
|
||||
(env != NULL && hint->value == NULL) ||
|
||||
(env != NULL && SDL_strcmp(env, hint->value) != 0)) {
|
||||
if ((!env && hint->value) ||
|
||||
(env && !hint->value) ||
|
||||
(env && SDL_strcmp(env, hint->value) != 0)) {
|
||||
for (entry = hint->callbacks; entry;) {
|
||||
/* Save the next entry in case this one is deleted */
|
||||
SDL_HintWatch *next = entry->next;
|
||||
|
|
@ -161,10 +161,14 @@ const char *SDL_GetHint(const char *name)
|
|||
const char *env;
|
||||
SDL_Hint *hint;
|
||||
|
||||
if (!name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
env = SDL_getenv(name);
|
||||
for (hint = SDL_hints; hint; hint = hint->next) {
|
||||
if (SDL_strcmp(name, hint->name) == 0) {
|
||||
if (env == NULL || hint->priority == SDL_HINT_OVERRIDE) {
|
||||
if (!env || hint->priority == SDL_HINT_OVERRIDE) {
|
||||
return hint->value;
|
||||
}
|
||||
break;
|
||||
|
|
@ -175,7 +179,7 @@ const char *SDL_GetHint(const char *name)
|
|||
|
||||
SDL_bool SDL_GetStringBoolean(const char *value, SDL_bool default_value)
|
||||
{
|
||||
if (value == NULL || !*value) {
|
||||
if (!value || !*value) {
|
||||
return default_value;
|
||||
}
|
||||
if (*value == '0' || SDL_strcasecmp(value, "false") == 0) {
|
||||
|
|
@ -196,7 +200,7 @@ void SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *user
|
|||
SDL_HintWatch *entry;
|
||||
const char *value;
|
||||
|
||||
if (name == NULL || !*name) {
|
||||
if (!name || !*name) {
|
||||
SDL_InvalidParamError("name");
|
||||
return;
|
||||
}
|
||||
|
|
@ -208,7 +212,7 @@ void SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *user
|
|||
SDL_DelHintCallback(name, callback, userdata);
|
||||
|
||||
entry = (SDL_HintWatch *)SDL_malloc(sizeof(*entry));
|
||||
if (entry == NULL) {
|
||||
if (!entry) {
|
||||
SDL_OutOfMemory();
|
||||
return;
|
||||
}
|
||||
|
|
@ -220,10 +224,10 @@ void SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *user
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (hint == NULL) {
|
||||
if (!hint) {
|
||||
/* Need to add a hint entry for this watcher */
|
||||
hint = (SDL_Hint *)SDL_malloc(sizeof(*hint));
|
||||
if (hint == NULL) {
|
||||
if (!hint) {
|
||||
SDL_OutOfMemory();
|
||||
SDL_free(entry);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -125,9 +125,91 @@
|
|||
#define SDL_HAVE_YUV !SDL_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#ifndef SDL_RENDER_DISABLED
|
||||
/* define the not defined ones as 0 */
|
||||
#ifndef SDL_VIDEO_RENDER_D3D
|
||||
#define SDL_VIDEO_RENDER_D3D 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_D3D11
|
||||
#define SDL_VIDEO_RENDER_D3D11 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_D3D12
|
||||
#define SDL_VIDEO_RENDER_D3D12 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_METAL
|
||||
#define SDL_VIDEO_RENDER_METAL 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_OGL
|
||||
#define SDL_VIDEO_RENDER_OGL 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_OGL_ES
|
||||
#define SDL_VIDEO_RENDER_OGL_ES 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_OGL_ES2
|
||||
#define SDL_VIDEO_RENDER_OGL_ES2 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_DIRECTFB
|
||||
#define SDL_VIDEO_RENDER_DIRECTFB 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_PS2
|
||||
#define SDL_VIDEO_RENDER_PS2 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_PSP
|
||||
#define SDL_VIDEO_RENDER_PSP 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_VITA_GXM
|
||||
#define SDL_VIDEO_RENDER_VITA_GXM 0
|
||||
#endif
|
||||
#else /* define all as 0 */
|
||||
#undef SDL_VIDEO_RENDER_SW
|
||||
#define SDL_VIDEO_RENDER_SW 0
|
||||
#undef SDL_VIDEO_RENDER_D3D
|
||||
#define SDL_VIDEO_RENDER_D3D 0
|
||||
#undef SDL_VIDEO_RENDER_D3D11
|
||||
#define SDL_VIDEO_RENDER_D3D11 0
|
||||
#undef SDL_VIDEO_RENDER_D3D12
|
||||
#define SDL_VIDEO_RENDER_D3D12 0
|
||||
#undef SDL_VIDEO_RENDER_METAL
|
||||
#define SDL_VIDEO_RENDER_METAL 0
|
||||
#undef SDL_VIDEO_RENDER_OGL
|
||||
#define SDL_VIDEO_RENDER_OGL 0
|
||||
#undef SDL_VIDEO_RENDER_OGL_ES
|
||||
#define SDL_VIDEO_RENDER_OGL_ES 0
|
||||
#undef SDL_VIDEO_RENDER_OGL_ES2
|
||||
#define SDL_VIDEO_RENDER_OGL_ES2 0
|
||||
#undef SDL_VIDEO_RENDER_DIRECTFB
|
||||
#define SDL_VIDEO_RENDER_DIRECTFB 0
|
||||
#undef SDL_VIDEO_RENDER_PS2
|
||||
#define SDL_VIDEO_RENDER_PS2 0
|
||||
#undef SDL_VIDEO_RENDER_PSP
|
||||
#define SDL_VIDEO_RENDER_PSP 0
|
||||
#undef SDL_VIDEO_RENDER_VITA_GXM
|
||||
#define SDL_VIDEO_RENDER_VITA_GXM 0
|
||||
#endif /* SDL_RENDER_DISABLED */
|
||||
|
||||
#define SDL_HAS_RENDER_DRIVER \
|
||||
(SDL_VIDEO_RENDER_SW | \
|
||||
SDL_VIDEO_RENDER_D3D | \
|
||||
SDL_VIDEO_RENDER_D3D11 | \
|
||||
SDL_VIDEO_RENDER_D3D12 | \
|
||||
SDL_VIDEO_RENDER_METAL | \
|
||||
SDL_VIDEO_RENDER_OGL | \
|
||||
SDL_VIDEO_RENDER_OGL_ES | \
|
||||
SDL_VIDEO_RENDER_OGL_ES2 | \
|
||||
SDL_VIDEO_RENDER_DIRECTFB | \
|
||||
SDL_VIDEO_RENDER_PS2 | \
|
||||
SDL_VIDEO_RENDER_PSP | \
|
||||
SDL_VIDEO_RENDER_VITA_GXM)
|
||||
|
||||
#if !defined(SDL_RENDER_DISABLED) && !SDL_HAS_RENDER_DRIVER
|
||||
#error SDL_RENDER enabled without any backend drivers.
|
||||
#endif
|
||||
|
||||
#include "SDL_assert.h"
|
||||
#include "SDL_log.h"
|
||||
|
||||
extern void SDL_InitMainThread(void);
|
||||
|
||||
#endif /* SDL_internal_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -28,7 +28,7 @@ int SDL_ListAdd(SDL_ListNode **head, void *ent)
|
|||
{
|
||||
SDL_ListNode *node = SDL_malloc(sizeof(*node));
|
||||
|
||||
if (node == NULL) {
|
||||
if (!node) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ void SDL_ListPop(SDL_ListNode **head, void **ent)
|
|||
SDL_ListNode **ptr = head;
|
||||
|
||||
/* Invalid or empty */
|
||||
if (head == NULL || *head == NULL) {
|
||||
if (!head || !*head) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -28,10 +28,11 @@
|
|||
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_log.h"
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_mutex.h"
|
||||
#include "SDL_log_c.h"
|
||||
|
||||
#if HAVE_STDIO_H
|
||||
#ifdef HAVE_STDIO_H
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
|
|
@ -44,10 +45,7 @@
|
|||
/* The size of the stack buffer to use for rendering log messages. */
|
||||
#define SDL_MAX_LOG_MESSAGE_STACK 256
|
||||
|
||||
#define DEFAULT_PRIORITY SDL_LOG_PRIORITY_CRITICAL
|
||||
#define DEFAULT_ASSERT_PRIORITY SDL_LOG_PRIORITY_WARN
|
||||
#define DEFAULT_APPLICATION_PRIORITY SDL_LOG_PRIORITY_INFO
|
||||
#define DEFAULT_TEST_PRIORITY SDL_LOG_PRIORITY_VERBOSE
|
||||
#define DEFAULT_CATEGORY -1
|
||||
|
||||
typedef struct SDL_LogLevel
|
||||
{
|
||||
|
|
@ -60,15 +58,14 @@ typedef struct SDL_LogLevel
|
|||
static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority, const char *message);
|
||||
|
||||
static SDL_LogLevel *SDL_loglevels;
|
||||
static SDL_LogPriority SDL_default_priority = DEFAULT_PRIORITY;
|
||||
static SDL_LogPriority SDL_assert_priority = DEFAULT_ASSERT_PRIORITY;
|
||||
static SDL_LogPriority SDL_application_priority = DEFAULT_APPLICATION_PRIORITY;
|
||||
static SDL_LogPriority SDL_test_priority = DEFAULT_TEST_PRIORITY;
|
||||
static SDL_bool SDL_forced_priority = SDL_FALSE;
|
||||
static SDL_LogPriority SDL_forced_priority_level;
|
||||
static SDL_LogOutputFunction SDL_log_function = SDL_LogOutput;
|
||||
static void *SDL_log_userdata = NULL;
|
||||
static SDL_mutex *log_function_mutex = NULL;
|
||||
|
||||
static const char *SDL_priority_prefixes[SDL_NUM_LOG_PRIORITIES] = {
|
||||
/* If this list changes, update the documentation for SDL_HINT_LOGGING */
|
||||
static const char *SDL_priority_prefixes[] = {
|
||||
NULL,
|
||||
"VERBOSE",
|
||||
"DEBUG",
|
||||
|
|
@ -77,8 +74,9 @@ static const char *SDL_priority_prefixes[SDL_NUM_LOG_PRIORITIES] = {
|
|||
"ERROR",
|
||||
"CRITICAL"
|
||||
};
|
||||
SDL_COMPILE_TIME_ASSERT(priority_prefixes, SDL_arraysize(SDL_priority_prefixes) == SDL_NUM_LOG_PRIORITIES);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
/* If this list changes, update the documentation for SDL_HINT_LOGGING */
|
||||
static const char *SDL_category_prefixes[] = {
|
||||
"APP",
|
||||
"ERROR",
|
||||
|
|
@ -90,9 +88,9 @@ static const char *SDL_category_prefixes[] = {
|
|||
"INPUT",
|
||||
"TEST"
|
||||
};
|
||||
SDL_COMPILE_TIME_ASSERT(category_prefixes, SDL_arraysize(SDL_category_prefixes) == SDL_LOG_CATEGORY_RESERVED1);
|
||||
|
||||
SDL_COMPILE_TIME_ASSERT(category_prefixes_enum, SDL_TABLESIZE(SDL_category_prefixes) == SDL_LOG_CATEGORY_RESERVED1);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
static int SDL_android_priority[SDL_NUM_LOG_PRIORITIES] = {
|
||||
ANDROID_LOG_UNKNOWN,
|
||||
ANDROID_LOG_VERBOSE,
|
||||
|
|
@ -106,7 +104,7 @@ static int SDL_android_priority[SDL_NUM_LOG_PRIORITIES] = {
|
|||
|
||||
void SDL_LogInit(void)
|
||||
{
|
||||
if (log_function_mutex == NULL) {
|
||||
if (!log_function_mutex) {
|
||||
/* if this fails we'll try to continue without it. */
|
||||
log_function_mutex = SDL_CreateMutex();
|
||||
}
|
||||
|
|
@ -128,9 +126,9 @@ void SDL_LogSetAllPriority(SDL_LogPriority priority)
|
|||
for (entry = SDL_loglevels; entry; entry = entry->next) {
|
||||
entry->priority = priority;
|
||||
}
|
||||
SDL_default_priority = priority;
|
||||
SDL_assert_priority = priority;
|
||||
SDL_application_priority = priority;
|
||||
|
||||
SDL_forced_priority = SDL_TRUE;
|
||||
SDL_forced_priority_level = priority;
|
||||
}
|
||||
|
||||
void SDL_LogSetPriority(int category, SDL_LogPriority priority)
|
||||
|
|
@ -154,6 +152,122 @@ void SDL_LogSetPriority(int category, SDL_LogPriority priority)
|
|||
}
|
||||
}
|
||||
|
||||
static SDL_bool SDL_ParseLogCategory(const char *string, size_t length, int *category)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (SDL_isdigit(*string)) {
|
||||
*category = SDL_atoi(string);
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
if (*string == '*') {
|
||||
*category = DEFAULT_CATEGORY;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < SDL_arraysize(SDL_category_prefixes); ++i) {
|
||||
if (SDL_strncasecmp(string, SDL_category_prefixes[i], length) == 0) {
|
||||
*category = i;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static SDL_bool SDL_ParseLogPriority(const char *string, size_t length, SDL_LogPriority *priority)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (SDL_isdigit(*string)) {
|
||||
i = SDL_atoi(string);
|
||||
if (i == 0) {
|
||||
/* 0 has a special meaning of "disable this category" */
|
||||
*priority = SDL_NUM_LOG_PRIORITIES;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
if (i >= SDL_LOG_PRIORITY_VERBOSE && i < SDL_NUM_LOG_PRIORITIES) {
|
||||
*priority = (SDL_LogPriority)i;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (SDL_strncasecmp(string, "quiet", length) == 0) {
|
||||
*priority = SDL_NUM_LOG_PRIORITIES;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
for (i = SDL_LOG_PRIORITY_VERBOSE; i < SDL_NUM_LOG_PRIORITIES; ++i) {
|
||||
if (SDL_strncasecmp(string, SDL_priority_prefixes[i], length) == 0) {
|
||||
*priority = (SDL_LogPriority)i;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static SDL_bool SDL_ParseLogCategoryPriority(const char *hint, int category, SDL_LogPriority *priority)
|
||||
{
|
||||
const char *name, *next;
|
||||
int current_category;
|
||||
|
||||
if (category == DEFAULT_CATEGORY && SDL_strchr(hint, '=') == NULL) {
|
||||
return SDL_ParseLogPriority(hint, SDL_strlen(hint), priority);
|
||||
}
|
||||
|
||||
for (name = hint; name; name = next) {
|
||||
const char *sep = SDL_strchr(name, '=');
|
||||
if (!sep) {
|
||||
break;
|
||||
}
|
||||
next = SDL_strchr(sep, ',');
|
||||
if (next) {
|
||||
++next;
|
||||
}
|
||||
|
||||
if (SDL_ParseLogCategory(name, (sep - name), ¤t_category)) {
|
||||
if (current_category == category) {
|
||||
const char *value = sep + 1;
|
||||
size_t len;
|
||||
if (next) {
|
||||
len = (next - value - 1);
|
||||
} else {
|
||||
len = SDL_strlen(value);
|
||||
}
|
||||
return SDL_ParseLogPriority(value, len, priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static SDL_LogPriority SDL_GetDefaultLogPriority(int category)
|
||||
{
|
||||
const char *hint = SDL_GetHint(SDL_HINT_LOGGING);
|
||||
if (hint) {
|
||||
SDL_LogPriority priority;
|
||||
|
||||
if (SDL_ParseLogCategoryPriority(hint, category, &priority)) {
|
||||
return priority;
|
||||
}
|
||||
if (SDL_ParseLogCategoryPriority(hint, DEFAULT_CATEGORY, &priority)) {
|
||||
return priority;
|
||||
}
|
||||
}
|
||||
|
||||
switch (category) {
|
||||
case SDL_LOG_CATEGORY_APPLICATION:
|
||||
return SDL_LOG_PRIORITY_INFO;
|
||||
case SDL_LOG_CATEGORY_ASSERT:
|
||||
return SDL_LOG_PRIORITY_WARN;
|
||||
case SDL_LOG_CATEGORY_TEST:
|
||||
return SDL_LOG_PRIORITY_VERBOSE;
|
||||
default:
|
||||
return SDL_LOG_PRIORITY_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_LogPriority SDL_LogGetPriority(int category)
|
||||
{
|
||||
SDL_LogLevel *entry;
|
||||
|
|
@ -164,15 +278,11 @@ SDL_LogPriority SDL_LogGetPriority(int category)
|
|||
}
|
||||
}
|
||||
|
||||
if (category == SDL_LOG_CATEGORY_TEST) {
|
||||
return SDL_test_priority;
|
||||
} else if (category == SDL_LOG_CATEGORY_APPLICATION) {
|
||||
return SDL_application_priority;
|
||||
} else if (category == SDL_LOG_CATEGORY_ASSERT) {
|
||||
return SDL_assert_priority;
|
||||
} else {
|
||||
return SDL_default_priority;
|
||||
if (SDL_forced_priority) {
|
||||
return SDL_forced_priority_level;
|
||||
}
|
||||
|
||||
return SDL_GetDefaultLogPriority(category);
|
||||
}
|
||||
|
||||
void SDL_LogResetPriorities(void)
|
||||
|
|
@ -184,11 +294,7 @@ void SDL_LogResetPriorities(void)
|
|||
SDL_loglevels = entry->next;
|
||||
SDL_free(entry);
|
||||
}
|
||||
|
||||
SDL_default_priority = DEFAULT_PRIORITY;
|
||||
SDL_assert_priority = DEFAULT_ASSERT_PRIORITY;
|
||||
SDL_application_priority = DEFAULT_APPLICATION_PRIORITY;
|
||||
SDL_test_priority = DEFAULT_TEST_PRIORITY;
|
||||
SDL_forced_priority = SDL_FALSE;
|
||||
}
|
||||
|
||||
void SDL_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
|
||||
|
|
@ -299,7 +405,7 @@ void SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va
|
|||
return;
|
||||
}
|
||||
|
||||
if (log_function_mutex == NULL) {
|
||||
if (!log_function_mutex) {
|
||||
/* this mutex creation can race if you log from two threads at startup. You should have called SDL_Init first! */
|
||||
log_function_mutex = SDL_CreateMutex();
|
||||
}
|
||||
|
|
@ -317,7 +423,7 @@ void SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va
|
|||
if (len >= sizeof(stack_buf) && SDL_size_add_overflow(len, 1, &len_plus_term) == 0) {
|
||||
/* Allocate exactly what we need, including the zero-terminator */
|
||||
message = (char *)SDL_malloc(len_plus_term);
|
||||
if (message == NULL) {
|
||||
if (!message) {
|
||||
return;
|
||||
}
|
||||
va_copy(aq, ap);
|
||||
|
|
@ -453,7 +559,7 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
|
|||
{
|
||||
FILE *pFile;
|
||||
pFile = fopen("SDL_Log.txt", "a");
|
||||
if (pFile != NULL) {
|
||||
if (pFile) {
|
||||
(void)fprintf(pFile, "%s: %s\n", SDL_priority_prefixes[priority], message);
|
||||
(void)fclose(pFile);
|
||||
}
|
||||
|
|
@ -462,7 +568,7 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
|
|||
{
|
||||
FILE *pFile;
|
||||
pFile = fopen("ux0:/data/SDL_Log.txt", "a");
|
||||
if (pFile != NULL) {
|
||||
if (pFile) {
|
||||
(void)fprintf(pFile, "%s: %s\n", SDL_priority_prefixes[priority], message);
|
||||
(void)fclose(pFile);
|
||||
}
|
||||
|
|
@ -471,16 +577,16 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
|
|||
{
|
||||
FILE *pFile;
|
||||
pFile = fopen("sdmc:/3ds/SDL_Log.txt", "a");
|
||||
if (pFile != NULL) {
|
||||
if (pFile) {
|
||||
(void)fprintf(pFile, "%s: %s\n", SDL_priority_prefixes[priority], message);
|
||||
(void)fclose(pFile);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if HAVE_STDIO_H && \
|
||||
#if defined(HAVE_STDIO_H) && \
|
||||
!(defined(__APPLE__) && (defined(SDL_VIDEO_DRIVER_COCOA) || defined(SDL_VIDEO_DRIVER_UIKIT)))
|
||||
fprintf(stderr, "%s: %s\n", SDL_priority_prefixes[priority], message);
|
||||
#if __NACL__
|
||||
#ifdef __NACL__
|
||||
fflush(stderr);
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -103,10 +103,10 @@ extern __inline int _SDL_xadd_watcom(volatile int *a, int v);
|
|||
*/
|
||||
|
||||
#if !defined(HAVE_MSC_ATOMICS) && !defined(HAVE_GCC_ATOMICS) && !defined(__MACOSX__) && !defined(__SOLARIS__) && !defined(HAVE_WATCOM_ATOMICS)
|
||||
#define EMULATE_CAS 1
|
||||
#define EMULATE_CAS
|
||||
#endif
|
||||
|
||||
#if EMULATE_CAS
|
||||
#ifdef EMULATE_CAS
|
||||
static SDL_SpinLock locks[32];
|
||||
|
||||
static SDL_INLINE void enterLock(void *a)
|
||||
|
|
@ -137,7 +137,7 @@ SDL_bool SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval)
|
|||
return (SDL_bool) OSAtomicCompareAndSwap32Barrier(oldval, newval, &a->value);
|
||||
#elif defined(__SOLARIS__)
|
||||
return (SDL_bool)((int)atomic_cas_uint((volatile uint_t *)&a->value, (uint_t)oldval, (uint_t)newval) == oldval);
|
||||
#elif EMULATE_CAS
|
||||
#elif defined(EMULATE_CAS)
|
||||
SDL_bool retval = SDL_FALSE;
|
||||
|
||||
enterLock(a);
|
||||
|
|
@ -167,7 +167,7 @@ SDL_bool SDL_AtomicCASPtr(void **a, void *oldval, void *newval)
|
|||
return (SDL_bool) OSAtomicCompareAndSwap32Barrier((int32_t)oldval, (int32_t)newval, (int32_t*) a);
|
||||
#elif defined(__SOLARIS__)
|
||||
return (SDL_bool)(atomic_cas_ptr(a, oldval, newval) == oldval);
|
||||
#elif EMULATE_CAS
|
||||
#elif defined(EMULATE_CAS)
|
||||
SDL_bool retval = SDL_FALSE;
|
||||
|
||||
enterLock(a);
|
||||
|
|
@ -259,7 +259,7 @@ int SDL_AtomicGet(SDL_atomic_t *a)
|
|||
#elif defined(__MACOSX__) /* this is deprecated in 10.12 sdk; favor gcc atomics. */
|
||||
return sizeof(a->value) == sizeof(uint32_t) ? OSAtomicOr32Barrier(0, (volatile uint32_t *)&a->value) : OSAtomicAdd64Barrier(0, (volatile int64_t *)&a->value);
|
||||
#elif defined(__SOLARIS__)
|
||||
return atomic_or_uint((volatile uint_t *)&a->value, 0);
|
||||
return atomic_or_uint_nv((volatile uint_t *)&a->value, 0);
|
||||
#else
|
||||
int value;
|
||||
do {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -63,11 +63,11 @@ extern __inline int _SDL_xchg_watcom(volatile int *a, int v);
|
|||
/* This function is where all the magic happens... */
|
||||
SDL_bool SDL_AtomicTryLock(SDL_SpinLock *lock)
|
||||
{
|
||||
#if SDL_ATOMIC_DISABLED
|
||||
#ifdef SDL_ATOMIC_DISABLED
|
||||
/* Terrible terrible damage */
|
||||
static SDL_mutex *_spinlock_mutex;
|
||||
|
||||
if (_spinlock_mutex == NULL) {
|
||||
if (!_spinlock_mutex) {
|
||||
/* Race condition on first lock... */
|
||||
_spinlock_mutex = SDL_CreateMutex();
|
||||
}
|
||||
|
|
@ -81,7 +81,7 @@ SDL_bool SDL_AtomicTryLock(SDL_SpinLock *lock)
|
|||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
|
||||
#elif defined(HAVE_GCC_ATOMICS) || defined(HAVE_GCC_SYNC_LOCK_TEST_AND_SET)
|
||||
return __sync_lock_test_and_set(lock, 1) == 0;
|
||||
|
||||
#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
|
||||
|
|
@ -186,7 +186,7 @@ void SDL_AtomicLock(SDL_SpinLock *lock)
|
|||
|
||||
void SDL_AtomicUnlock(SDL_SpinLock *lock)
|
||||
{
|
||||
#if HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
|
||||
#if defined(HAVE_GCC_ATOMICS) || defined(HAVE_GCC_SYNC_LOCK_TEST_AND_SET)
|
||||
__sync_lock_release(lock);
|
||||
|
||||
#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -31,102 +31,108 @@
|
|||
|
||||
#define _THIS SDL_AudioDevice *_this
|
||||
|
||||
typedef struct AudioThreadStartupData
|
||||
{
|
||||
SDL_AudioDevice *device;
|
||||
SDL_sem *startup_semaphore;
|
||||
} AudioThreadStartupData;
|
||||
|
||||
static SDL_AudioDriver current_audio;
|
||||
static SDL_AudioDevice *open_devices[16];
|
||||
|
||||
/* Available audio drivers */
|
||||
static const AudioBootStrap *const bootstrap[] = {
|
||||
#if SDL_AUDIO_DRIVER_PULSEAUDIO
|
||||
#ifdef SDL_AUDIO_DRIVER_PULSEAUDIO
|
||||
&PULSEAUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_ALSA
|
||||
#ifdef SDL_AUDIO_DRIVER_ALSA
|
||||
&ALSA_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_SNDIO
|
||||
#ifdef SDL_AUDIO_DRIVER_SNDIO
|
||||
&SNDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_NETBSD
|
||||
#ifdef SDL_AUDIO_DRIVER_NETBSD
|
||||
&NETBSDAUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_QSA
|
||||
#ifdef SDL_AUDIO_DRIVER_QSA
|
||||
&QSAAUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_SUNAUDIO
|
||||
#ifdef SDL_AUDIO_DRIVER_SUNAUDIO
|
||||
&SUNAUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_ARTS
|
||||
#ifdef SDL_AUDIO_DRIVER_ARTS
|
||||
&ARTS_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_ESD
|
||||
#ifdef SDL_AUDIO_DRIVER_ESD
|
||||
&ESD_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_NACL
|
||||
#ifdef SDL_AUDIO_DRIVER_NACL
|
||||
&NACLAUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_NAS
|
||||
#ifdef SDL_AUDIO_DRIVER_NAS
|
||||
&NAS_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_WASAPI
|
||||
#ifdef SDL_AUDIO_DRIVER_WASAPI
|
||||
&WASAPI_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_DSOUND
|
||||
#ifdef SDL_AUDIO_DRIVER_DSOUND
|
||||
&DSOUND_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_WINMM
|
||||
#ifdef SDL_AUDIO_DRIVER_WINMM
|
||||
&WINMM_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_PAUDIO
|
||||
#ifdef SDL_AUDIO_DRIVER_PAUDIO
|
||||
&PAUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_HAIKU
|
||||
#ifdef SDL_AUDIO_DRIVER_HAIKU
|
||||
&HAIKUAUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_COREAUDIO
|
||||
#ifdef SDL_AUDIO_DRIVER_COREAUDIO
|
||||
&COREAUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_FUSIONSOUND
|
||||
#ifdef SDL_AUDIO_DRIVER_FUSIONSOUND
|
||||
&FUSIONSOUND_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_AAUDIO
|
||||
&aaudio_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_OPENSLES
|
||||
#ifdef SDL_AUDIO_DRIVER_OPENSLES
|
||||
&openslES_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_ANDROID
|
||||
#ifdef SDL_AUDIO_DRIVER_AAUDIO
|
||||
&aaudio_bootstrap,
|
||||
#endif
|
||||
#ifdef SDL_AUDIO_DRIVER_ANDROID
|
||||
&ANDROIDAUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_PS2
|
||||
#ifdef SDL_AUDIO_DRIVER_PS2
|
||||
&PS2AUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_PSP
|
||||
#ifdef SDL_AUDIO_DRIVER_PSP
|
||||
&PSPAUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_VITA
|
||||
#ifdef SDL_AUDIO_DRIVER_VITA
|
||||
&VITAAUD_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_N3DS
|
||||
#ifdef SDL_AUDIO_DRIVER_N3DS
|
||||
&N3DSAUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_EMSCRIPTEN
|
||||
#ifdef SDL_AUDIO_DRIVER_EMSCRIPTEN
|
||||
&EMSCRIPTENAUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_JACK
|
||||
#ifdef SDL_AUDIO_DRIVER_JACK
|
||||
&JACK_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_PIPEWIRE
|
||||
#ifdef SDL_AUDIO_DRIVER_PIPEWIRE
|
||||
&PIPEWIRE_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_OSS
|
||||
#ifdef SDL_AUDIO_DRIVER_OSS
|
||||
&DSP_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_OS2
|
||||
#ifdef SDL_AUDIO_DRIVER_OS2
|
||||
&OS2AUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_DISK
|
||||
#ifdef SDL_AUDIO_DRIVER_DISK
|
||||
&DISKAUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_DUMMY
|
||||
#ifdef SDL_AUDIO_DRIVER_DUMMY
|
||||
&DUMMYAUDIO_bootstrap,
|
||||
#endif
|
||||
NULL
|
||||
|
|
@ -658,22 +664,24 @@ void SDL_ClearQueuedAudio(SDL_AudioDeviceID devid)
|
|||
current_audio.impl.UnlockDevice(device);
|
||||
}
|
||||
|
||||
#if SDL_AUDIO_DRIVER_ANDROID
|
||||
#ifdef SDL_AUDIO_DRIVER_ANDROID
|
||||
extern void Android_JNI_AudioSetThreadPriority(int, int);
|
||||
#endif
|
||||
|
||||
/* The general mixing thread function */
|
||||
static int SDLCALL SDL_RunAudio(void *devicep)
|
||||
static int SDLCALL SDL_RunAudio(void *userdata)
|
||||
{
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *)devicep;
|
||||
const AudioThreadStartupData *startup_data = (const AudioThreadStartupData *) userdata;
|
||||
SDL_AudioDevice *device = startup_data->device;
|
||||
void *udata = device->callbackspec.userdata;
|
||||
SDL_AudioCallback callback = device->callbackspec.callback;
|
||||
int data_len = 0;
|
||||
Uint8 *data;
|
||||
Uint8 *device_buf_keepsafe = NULL;
|
||||
|
||||
SDL_assert(!device->iscapture);
|
||||
|
||||
#if SDL_AUDIO_DRIVER_ANDROID
|
||||
#ifdef SDL_AUDIO_DRIVER_ANDROID
|
||||
{
|
||||
/* Set thread priority to THREAD_PRIORITY_AUDIO */
|
||||
Android_JNI_AudioSetThreadPriority(device->iscapture, device->id);
|
||||
|
|
@ -685,16 +693,25 @@ static int SDLCALL SDL_RunAudio(void *devicep)
|
|||
|
||||
/* Perform any thread setup */
|
||||
device->threadid = SDL_ThreadID();
|
||||
|
||||
SDL_SemPost(startup_data->startup_semaphore); /* SDL_OpenAudioDevice may now continue. */
|
||||
|
||||
current_audio.impl.ThreadInit(device);
|
||||
|
||||
/* Loop, filling the audio buffers */
|
||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||
data_len = device->callbackspec.size;
|
||||
|
||||
/* Fill the current buffer with sound */
|
||||
if (!device->stream && SDL_AtomicGet(&device->enabled)) {
|
||||
SDL_assert(data_len == device->spec.size);
|
||||
data = current_audio.impl.GetDeviceBuf(device);
|
||||
|
||||
if (device->stream && SDL_AtomicGet(&device->enabled)) {
|
||||
/* Oops. Audio device reset and now we suddenly use a stream, */
|
||||
/* so save this devicebuf for later, to prevent de-sync */
|
||||
if (data != NULL) {
|
||||
device_buf_keepsafe = data;
|
||||
}
|
||||
data = NULL;
|
||||
}
|
||||
} else {
|
||||
/* if the device isn't enabled, we still write to the
|
||||
work_buffer, so the app's callback will fire with
|
||||
|
|
@ -709,6 +726,8 @@ static int SDLCALL SDL_RunAudio(void *devicep)
|
|||
data = device->work_buffer;
|
||||
}
|
||||
|
||||
data_len = device->callbackspec.size;
|
||||
|
||||
/* !!! FIXME: this should be LockDevice. */
|
||||
SDL_LockMutex(device->mixer_lock);
|
||||
if (SDL_AtomicGet(&device->paused)) {
|
||||
|
|
@ -725,7 +744,19 @@ static int SDLCALL SDL_RunAudio(void *devicep)
|
|||
|
||||
while (SDL_AudioStreamAvailable(device->stream) >= ((int)device->spec.size)) {
|
||||
int got;
|
||||
data = SDL_AtomicGet(&device->enabled) ? current_audio.impl.GetDeviceBuf(device) : NULL;
|
||||
if (SDL_AtomicGet(&device->enabled)) {
|
||||
/* if device reset occured - a switch from direct output to streaming */
|
||||
/* use the already aquired device buffer */
|
||||
if (device_buf_keepsafe) {
|
||||
data = device_buf_keepsafe;
|
||||
device_buf_keepsafe = NULL;
|
||||
} else {
|
||||
/* else - normal flow, just acquire the device buffer here */
|
||||
data = current_audio.impl.GetDeviceBuf(device);
|
||||
}
|
||||
} else {
|
||||
data = NULL;
|
||||
}
|
||||
got = SDL_AudioStreamGet(device->stream, data ? data : device->work_buffer, device->spec.size);
|
||||
SDL_assert((got <= 0) || (got == device->spec.size));
|
||||
|
||||
|
|
@ -740,6 +771,14 @@ static int SDLCALL SDL_RunAudio(void *devicep)
|
|||
current_audio.impl.WaitDevice(device);
|
||||
}
|
||||
}
|
||||
|
||||
/* it seems resampling was not fast enough, device_buf_keepsafe was not released yet, so play silence here */
|
||||
if (device_buf_keepsafe) {
|
||||
SDL_memset(device_buf_keepsafe, device->spec.silence, device->spec.size);
|
||||
current_audio.impl.PlayDevice(device);
|
||||
current_audio.impl.WaitDevice(device);
|
||||
device_buf_keepsafe = NULL;
|
||||
}
|
||||
} else if (data == device->work_buffer) {
|
||||
/* nothing to do; pause like we queued a buffer to play. */
|
||||
const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
|
||||
|
|
@ -761,9 +800,10 @@ static int SDLCALL SDL_RunAudio(void *devicep)
|
|||
|
||||
/* !!! FIXME: this needs to deal with device spec changes. */
|
||||
/* The general capture thread function */
|
||||
static int SDLCALL SDL_CaptureAudio(void *devicep)
|
||||
static int SDLCALL SDL_CaptureAudio(void *userdata)
|
||||
{
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *)devicep;
|
||||
const AudioThreadStartupData *startup_data = (const AudioThreadStartupData *) userdata;
|
||||
SDL_AudioDevice *device = startup_data->device;
|
||||
const int silence = (int)device->spec.silence;
|
||||
const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
|
||||
const int data_len = device->spec.size;
|
||||
|
|
@ -773,7 +813,7 @@ static int SDLCALL SDL_CaptureAudio(void *devicep)
|
|||
|
||||
SDL_assert(device->iscapture);
|
||||
|
||||
#if SDL_AUDIO_DRIVER_ANDROID
|
||||
#ifdef SDL_AUDIO_DRIVER_ANDROID
|
||||
{
|
||||
/* Set thread priority to THREAD_PRIORITY_AUDIO */
|
||||
Android_JNI_AudioSetThreadPriority(device->iscapture, device->id);
|
||||
|
|
@ -785,6 +825,9 @@ static int SDLCALL SDL_CaptureAudio(void *devicep)
|
|||
|
||||
/* Perform any thread setup */
|
||||
device->threadid = SDL_ThreadID();
|
||||
|
||||
SDL_SemPost(startup_data->startup_semaphore); /* SDL_OpenAudioDevice may now continue. */
|
||||
|
||||
current_audio.impl.ThreadInit(device);
|
||||
|
||||
/* Loop, filling the audio buffers */
|
||||
|
|
@ -932,7 +975,7 @@ int SDL_AudioInit(const char *driver_name)
|
|||
const char *driver_attempt_end = SDL_strchr(driver_attempt, ',');
|
||||
size_t driver_attempt_len = (driver_attempt_end != NULL) ? (driver_attempt_end - driver_attempt)
|
||||
: SDL_strlen(driver_attempt);
|
||||
#if SDL_AUDIO_DRIVER_DSOUND
|
||||
#ifdef SDL_AUDIO_DRIVER_DSOUND
|
||||
/* SDL 1.2 uses the name "dsound", so we'll support both. */
|
||||
if (driver_attempt_len == SDL_strlen("dsound") &&
|
||||
(SDL_strncasecmp(driver_attempt, "dsound", driver_attempt_len) == 0)) {
|
||||
|
|
@ -941,7 +984,7 @@ int SDL_AudioInit(const char *driver_name)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if SDL_AUDIO_DRIVER_PULSEAUDIO
|
||||
#ifdef SDL_AUDIO_DRIVER_PULSEAUDIO
|
||||
/* SDL 1.2 uses the name "pulse", so we'll support both. */
|
||||
if (driver_attempt_len == SDL_strlen("pulse") &&
|
||||
(SDL_strncasecmp(driver_attempt, "pulse", driver_attempt_len) == 0)) {
|
||||
|
|
@ -962,7 +1005,7 @@ int SDL_AudioInit(const char *driver_name)
|
|||
}
|
||||
}
|
||||
|
||||
driver_attempt = (driver_attempt_end != NULL) ? (driver_attempt_end + 1) : NULL;
|
||||
driver_attempt = (driver_attempt_end) ? (driver_attempt_end + 1) : NULL;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; (!initialized) && (bootstrap[i]); ++i) {
|
||||
|
|
@ -1009,7 +1052,7 @@ int SDL_AudioInit(const char *driver_name)
|
|||
/*
|
||||
* Get the current audio driver name
|
||||
*/
|
||||
const char *SDL_GetCurrentAudioDriver()
|
||||
const char *SDL_GetCurrentAudioDriver(void)
|
||||
{
|
||||
return current_audio.name;
|
||||
}
|
||||
|
|
@ -1261,7 +1304,6 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
|||
const SDL_AudioSpec *desired, SDL_AudioSpec *obtained,
|
||||
int allowed_changes, int min_id)
|
||||
{
|
||||
const SDL_bool is_internal_thread = (desired->callback == NULL);
|
||||
SDL_AudioDeviceID id = 0;
|
||||
SDL_AudioSpec _obtained;
|
||||
SDL_AudioDevice *device;
|
||||
|
|
@ -1279,25 +1321,10 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
|||
return 0;
|
||||
}
|
||||
|
||||
SDL_LockMutex(current_audio.detectionLock);
|
||||
/* Find an available device ID... */
|
||||
for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
|
||||
if (open_devices[id] == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (id == SDL_arraysize(open_devices)) {
|
||||
SDL_SetError("Too many open audio devices");
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!obtained) {
|
||||
obtained = &_obtained;
|
||||
}
|
||||
if (!prepare_audiospec(desired, obtained)) {
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1319,11 +1346,11 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
|||
if ((iscapture) && (current_audio.impl.OnlyHasDefaultCaptureDevice)) {
|
||||
if ((devname) && (SDL_strcmp(devname, DEFAULT_INPUT_DEVNAME) != 0)) {
|
||||
SDL_SetError("No such device");
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
return 0;
|
||||
}
|
||||
devname = NULL;
|
||||
|
||||
SDL_LockMutex(current_audio.detectionLock);
|
||||
for (i = 0; i < SDL_arraysize(open_devices); i++) {
|
||||
if ((open_devices[i]) && (open_devices[i]->iscapture)) {
|
||||
SDL_SetError("Audio device already open");
|
||||
|
|
@ -1331,14 +1358,15 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
} else if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
|
||||
if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) {
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
SDL_SetError("No such device");
|
||||
return 0;
|
||||
}
|
||||
devname = NULL;
|
||||
|
||||
SDL_LockMutex(current_audio.detectionLock);
|
||||
for (i = 0; i < SDL_arraysize(open_devices); i++) {
|
||||
if ((open_devices[i]) && (!open_devices[i]->iscapture)) {
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
|
|
@ -1346,6 +1374,7 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
} else if (devname != NULL) {
|
||||
/* if the app specifies an exact string, we can pass the backend
|
||||
an actual device handle thingey, which saves them the effort of
|
||||
|
|
@ -1354,19 +1383,20 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
|||
It might still need to open a device based on the string for,
|
||||
say, a network audio server, but this optimizes some cases. */
|
||||
SDL_AudioDeviceItem *item;
|
||||
SDL_LockMutex(current_audio.detectionLock);
|
||||
for (item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; item; item = item->next) {
|
||||
if ((item->handle != NULL) && (SDL_strcmp(item->name, devname) == 0)) {
|
||||
handle = item->handle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
}
|
||||
|
||||
if (!current_audio.impl.AllowsArbitraryDeviceNames) {
|
||||
/* has to be in our device list, or the default device. */
|
||||
if ((handle == NULL) && (devname != NULL)) {
|
||||
SDL_SetError("No such device.");
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1374,10 +1404,8 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
|||
device = (SDL_AudioDevice *)SDL_calloc(1, sizeof(SDL_AudioDevice));
|
||||
if (device == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
return 0;
|
||||
}
|
||||
device->id = id + 1;
|
||||
device->spec = *obtained;
|
||||
device->iscapture = iscapture ? SDL_TRUE : SDL_FALSE;
|
||||
device->handle = handle;
|
||||
|
|
@ -1391,7 +1419,6 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
|||
device->mixer_lock = SDL_CreateMutex();
|
||||
if (device->mixer_lock == NULL) {
|
||||
close_audio_device(device);
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
SDL_SetError("Couldn't create mixer lock");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1406,7 +1433,6 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
|||
|
||||
if (current_audio.impl.OpenDevice(device, devname) < 0) {
|
||||
close_audio_device(device);
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1462,7 +1488,6 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
|||
|
||||
if (!device->stream) {
|
||||
close_audio_device(device);
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1472,7 +1497,6 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
|||
device->buffer_queue = SDL_NewDataQueue(SDL_AUDIOBUFFERQUEUE_PACKETLEN, obtained->size * 2);
|
||||
if (!device->buffer_queue) {
|
||||
close_audio_device(device);
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
SDL_SetError("Couldn't create audio buffer queue");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1490,32 +1514,56 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
|||
device->work_buffer = (Uint8 *)SDL_malloc(device->work_buffer_len);
|
||||
if (device->work_buffer == NULL) {
|
||||
close_audio_device(device);
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
SDL_OutOfMemory();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find an available device ID... */
|
||||
SDL_LockMutex(current_audio.detectionLock);
|
||||
for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
|
||||
if (open_devices[id] == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (id == SDL_arraysize(open_devices)) {
|
||||
close_audio_device(device);
|
||||
SDL_SetError("Too many open audio devices");
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
device->id = id + 1;
|
||||
open_devices[id] = device; /* add it to our list of open devices. */
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
|
||||
/* Start the audio thread if necessary */
|
||||
if (!current_audio.impl.ProvidesOwnCallbackThread) {
|
||||
/* Start the audio thread */
|
||||
/* !!! FIXME: we don't force the audio thread stack size here if it calls into user code, but maybe we should? */
|
||||
/* buffer queueing callback only needs a few bytes, so make the stack tiny. */
|
||||
const size_t stacksize = is_internal_thread ? 64 * 1024 : 0;
|
||||
char threadname[64];
|
||||
AudioThreadStartupData startup_data;
|
||||
|
||||
(void)SDL_snprintf(threadname, sizeof(threadname), "SDLAudio%c%" SDL_PRIu32, (iscapture) ? 'C' : 'P', device->id);
|
||||
device->thread = SDL_CreateThreadInternal(iscapture ? SDL_CaptureAudio : SDL_RunAudio, threadname, stacksize, device);
|
||||
|
||||
if (device->thread == NULL) {
|
||||
startup_data.device = device;
|
||||
startup_data.startup_semaphore = SDL_CreateSemaphore(0);
|
||||
if (!startup_data.startup_semaphore) {
|
||||
close_audio_device(device);
|
||||
SDL_SetError("Couldn't create audio thread");
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
SDL_SetError("Couldn't create audio thread startup semaphore");
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void)SDL_snprintf(threadname, sizeof(threadname), "SDLAudio%c%" SDL_PRIu32, (iscapture) ? 'C' : 'P', device->id);
|
||||
|
||||
device->thread = SDL_CreateThreadInternal(iscapture ? SDL_CaptureAudio : SDL_RunAudio, threadname, 0, &startup_data);
|
||||
if (device->thread == NULL) {
|
||||
SDL_DestroySemaphore(startup_data.startup_semaphore);
|
||||
close_audio_device(device);
|
||||
SDL_SetError("Couldn't create audio thread");
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_SemWait(startup_data.startup_semaphore);
|
||||
SDL_DestroySemaphore(startup_data.startup_semaphore);
|
||||
}
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
|
||||
return device->id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -93,7 +93,7 @@
|
|||
* 8 channels (7.1) layout: FL+FR+FC+LFE+BL+BR+SL+SR
|
||||
*/
|
||||
|
||||
#if HAVE_SSE3_INTRINSICS
|
||||
#ifdef HAVE_SSE3_INTRINSICS
|
||||
/* Convert from stereo to mono. Average left and right. */
|
||||
static void SDLCALL SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT *cvt, SDL_AudioFormat format)
|
||||
{
|
||||
|
|
@ -130,7 +130,7 @@ static void SDLCALL SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT *cvt, SDL_AudioFor
|
|||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_SSE_INTRINSICS
|
||||
#ifdef HAVE_SSE_INTRINSICS
|
||||
/* Convert from mono to stereo. Duplicate to stereo left and right. */
|
||||
static void SDLCALL SDL_ConvertMonoToStereo_SSE(SDL_AudioCVT *cvt, SDL_AudioFormat format)
|
||||
{
|
||||
|
|
@ -266,7 +266,7 @@ int SDL_ConvertAudio(SDL_AudioCVT *cvt)
|
|||
/* !!! FIXME: (actually, we can't...len_cvt needs to be updated. Grr.) */
|
||||
|
||||
/* Make sure there's data to convert */
|
||||
if (cvt->buf == NULL) {
|
||||
if (!cvt->buf) {
|
||||
return SDL_SetError("No buffer allocated for conversion");
|
||||
}
|
||||
|
||||
|
|
@ -473,10 +473,12 @@ static void SDL_ResampleCVT_SRC(SDL_AudioCVT *cvt, const int chans, const SDL_Au
|
|||
|
||||
result = SRC_src_simple(&data, SRC_converter, chans); /* Simple API converts the whole buffer at once. No need for initialization. */
|
||||
/* !!! FIXME: Handle library failures? */
|
||||
#ifdef DEBUG_CONVERT
|
||||
#if DEBUG_CONVERT
|
||||
if (result != 0) {
|
||||
SDL_Log("src_simple() failed: %s", SRC_src_strerror(result));
|
||||
}
|
||||
#else
|
||||
(void)result;
|
||||
#endif
|
||||
|
||||
cvt->len_cvt = data.output_frames_gen * framelen;
|
||||
|
|
@ -517,7 +519,7 @@ static void SDL_ResampleCVT(SDL_AudioCVT *cvt, const int chans, const SDL_AudioF
|
|||
|
||||
/* we keep no streaming state here, so pad with silence on both ends. */
|
||||
padding = (float *)SDL_calloc(paddingsamples ? paddingsamples : 1, sizeof(float));
|
||||
if (padding == NULL) {
|
||||
if (!padding) {
|
||||
SDL_OutOfMemory();
|
||||
return;
|
||||
}
|
||||
|
|
@ -614,7 +616,7 @@ static int SDL_BuildAudioResampleCVT(SDL_AudioCVT *cvt, const int dst_channels,
|
|||
}
|
||||
|
||||
filter = ChooseCVTResampler(dst_channels);
|
||||
if (filter == NULL) {
|
||||
if (!filter) {
|
||||
return SDL_SetError("No conversion available for these rates");
|
||||
}
|
||||
|
||||
|
|
@ -687,7 +689,7 @@ int SDL_BuildAudioCVT(SDL_AudioCVT *cvt,
|
|||
SDL_AudioFilter channel_converter = NULL;
|
||||
|
||||
/* Sanity check target pointer */
|
||||
if (cvt == NULL) {
|
||||
if (!cvt) {
|
||||
return SDL_InvalidParamError("cvt");
|
||||
}
|
||||
|
||||
|
|
@ -782,14 +784,14 @@ int SDL_BuildAudioCVT(SDL_AudioCVT *cvt,
|
|||
SDL_assert(dst_channels <= SDL_arraysize(channel_converters[0]));
|
||||
|
||||
channel_converter = channel_converters[src_channels - 1][dst_channels - 1];
|
||||
if ((channel_converter == NULL) != (src_channels == dst_channels)) {
|
||||
if ((!channel_converter) != (src_channels == dst_channels)) {
|
||||
/* All combinations of supported channel counts should have been handled by now, but let's be defensive */
|
||||
return SDL_SetError("Invalid channel combination");
|
||||
} else if (channel_converter != NULL) {
|
||||
/* swap in some SIMD versions for a few of these. */
|
||||
if (channel_converter == SDL_ConvertStereoToMono) {
|
||||
SDL_AudioFilter filter = NULL;
|
||||
#if HAVE_SSE3_INTRINSICS
|
||||
#ifdef HAVE_SSE3_INTRINSICS
|
||||
if (!filter && SDL_HasSSE3()) {
|
||||
filter = SDL_ConvertStereoToMono_SSE3;
|
||||
}
|
||||
|
|
@ -799,7 +801,7 @@ int SDL_BuildAudioCVT(SDL_AudioCVT *cvt,
|
|||
}
|
||||
} else if (channel_converter == SDL_ConvertMonoToStereo) {
|
||||
SDL_AudioFilter filter = NULL;
|
||||
#if HAVE_SSE_INTRINSICS
|
||||
#ifdef HAVE_SSE_INTRINSICS
|
||||
if (!filter && SDL_HasSSE()) {
|
||||
filter = SDL_ConvertMonoToStereo_SSE;
|
||||
}
|
||||
|
|
@ -878,7 +880,7 @@ static Uint8 *EnsureStreamBufferSize(SDL_AudioStream *stream, int newlen)
|
|||
ptr = stream->work_buffer_base;
|
||||
} else {
|
||||
ptr = (Uint8 *)SDL_realloc(stream->work_buffer_base, (size_t)newlen + 32);
|
||||
if (ptr == NULL) {
|
||||
if (!ptr) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -950,12 +952,12 @@ static SDL_bool SetupLibSampleRateResampling(SDL_AudioStream *stream)
|
|||
|
||||
if (SRC_available) {
|
||||
state = SRC_src_new(SRC_converter, stream->pre_resample_channels, &result);
|
||||
if (state == NULL) {
|
||||
if (!state) {
|
||||
SDL_SetError("src_new() failed: %s", SRC_src_strerror(result));
|
||||
}
|
||||
}
|
||||
|
||||
if (state == NULL) {
|
||||
if (!state) {
|
||||
SDL_CleanupAudioStreamResampler_SRC(stream);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
|
@ -1027,7 +1029,7 @@ SDL_AudioStream *SDL_NewAudioStream(const SDL_AudioFormat src_format,
|
|||
}
|
||||
|
||||
retval = (SDL_AudioStream *)SDL_calloc(1, sizeof(SDL_AudioStream));
|
||||
if (retval == NULL) {
|
||||
if (!retval) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1053,7 +1055,7 @@ SDL_AudioStream *SDL_NewAudioStream(const SDL_AudioFormat src_format,
|
|||
retval->resampler_padding_samples = ResamplerPadding(retval->src_rate, retval->dst_rate) * pre_resample_channels;
|
||||
retval->resampler_padding = (float *)SDL_calloc(retval->resampler_padding_samples ? retval->resampler_padding_samples : 1, sizeof(float));
|
||||
|
||||
if (retval->resampler_padding == NULL) {
|
||||
if (!retval->resampler_padding) {
|
||||
SDL_FreeAudioStream(retval);
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
|
|
@ -1062,7 +1064,7 @@ SDL_AudioStream *SDL_NewAudioStream(const SDL_AudioFormat src_format,
|
|||
retval->staging_buffer_size = ((retval->resampler_padding_samples / retval->pre_resample_channels) * retval->src_sample_frame_size);
|
||||
if (retval->staging_buffer_size > 0) {
|
||||
retval->staging_buffer = (Uint8 *)SDL_malloc(retval->staging_buffer_size);
|
||||
if (retval->staging_buffer == NULL) {
|
||||
if (!retval->staging_buffer) {
|
||||
SDL_FreeAudioStream(retval);
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
|
|
@ -1169,7 +1171,7 @@ static int SDL_AudioStreamPutInternal(SDL_AudioStream *stream, const void *buf,
|
|||
#endif
|
||||
|
||||
workbuf = EnsureStreamBufferSize(stream, workbuflen);
|
||||
if (workbuf == NULL) {
|
||||
if (!workbuf) {
|
||||
return -1; /* probably out of memory. */
|
||||
}
|
||||
|
||||
|
|
@ -1260,10 +1262,10 @@ int SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len)
|
|||
SDL_Log("AUDIOSTREAM: wants to put %d preconverted bytes\n", buflen);
|
||||
#endif
|
||||
|
||||
if (stream == NULL) {
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
}
|
||||
if (buf == NULL) {
|
||||
if (!buf) {
|
||||
return SDL_InvalidParamError("buf");
|
||||
}
|
||||
if (len == 0) {
|
||||
|
|
@ -1315,7 +1317,7 @@ int SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len)
|
|||
|
||||
int SDL_AudioStreamFlush(SDL_AudioStream *stream)
|
||||
{
|
||||
if (stream == NULL) {
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
}
|
||||
|
||||
|
|
@ -1373,10 +1375,10 @@ int SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, int len)
|
|||
SDL_Log("AUDIOSTREAM: want to get %d converted bytes\n", len);
|
||||
#endif
|
||||
|
||||
if (stream == NULL) {
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
}
|
||||
if (buf == NULL) {
|
||||
if (!buf) {
|
||||
return SDL_InvalidParamError("buf");
|
||||
}
|
||||
if (len <= 0) {
|
||||
|
|
@ -1397,7 +1399,7 @@ int SDL_AudioStreamAvailable(SDL_AudioStream *stream)
|
|||
|
||||
void SDL_AudioStreamClear(SDL_AudioStream *stream)
|
||||
{
|
||||
if (stream == NULL) {
|
||||
if (!stream) {
|
||||
SDL_InvalidParamError("stream");
|
||||
} else {
|
||||
SDL_ClearDataQueue(stream->queue, (size_t)stream->packetlen * 2);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
/* Get the name of the audio device we use for output */
|
||||
|
||||
#if SDL_AUDIO_DRIVER_NETBSD || SDL_AUDIO_DRIVER_OSS || SDL_AUDIO_DRIVER_SUNAUDIO
|
||||
#if defined(SDL_AUDIO_DRIVER_NETBSD) || defined(SDL_AUDIO_DRIVER_OSS) || defined(SDL_AUDIO_DRIVER_SUNAUDIO)
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
|
|
@ -81,16 +81,16 @@ static void SDL_EnumUnixAudioDevices_Internal(const int iscapture, const int cla
|
|||
const char *audiodev;
|
||||
char audiopath[1024];
|
||||
|
||||
if (test == NULL) {
|
||||
if (!test) {
|
||||
test = test_stub;
|
||||
}
|
||||
|
||||
/* Figure out what our audio device is */
|
||||
audiodev = SDL_getenv("SDL_PATH_DSP");
|
||||
if (audiodev == NULL) {
|
||||
if (!audiodev) {
|
||||
audiodev = SDL_getenv("AUDIODEV");
|
||||
}
|
||||
if (audiodev == NULL) {
|
||||
if (!audiodev) {
|
||||
if (classic) {
|
||||
audiodev = _PATH_DEV_AUDIO;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -29,16 +29,16 @@
|
|||
#endif
|
||||
|
||||
#ifdef __SSE2__
|
||||
#define HAVE_SSE2_INTRINSICS 1
|
||||
#define HAVE_SSE2_INTRINSICS
|
||||
#endif
|
||||
|
||||
#if defined(__x86_64__) && HAVE_SSE2_INTRINSICS
|
||||
#if defined(__x86_64__) && defined(HAVE_SSE2_INTRINSICS)
|
||||
#define NEED_SCALAR_CONVERTER_FALLBACKS 0 /* x86_64 guarantees SSE2. */
|
||||
#elif __MACOSX__ && HAVE_SSE2_INTRINSICS
|
||||
#elif defined(__MACOSX__) && defined(HAVE_SSE2_INTRINSICS)
|
||||
#define NEED_SCALAR_CONVERTER_FALLBACKS 0 /* Mac OS X/Intel guarantees SSE2. */
|
||||
#elif defined(__ARM_ARCH) && (__ARM_ARCH >= 8) && HAVE_NEON_INTRINSICS
|
||||
#elif defined(__ARM_ARCH) && (__ARM_ARCH >= 8) && defined(HAVE_NEON_INTRINSICS)
|
||||
#define NEED_SCALAR_CONVERTER_FALLBACKS 0 /* ARMv8+ promise NEON. */
|
||||
#elif defined(__APPLE__) && defined(__ARM_ARCH) && (__ARM_ARCH >= 7) && HAVE_NEON_INTRINSICS
|
||||
#elif defined(__APPLE__) && defined(__ARM_ARCH) && (__ARM_ARCH >= 7) && defined(HAVE_NEON_INTRINSICS)
|
||||
#define NEED_SCALAR_CONVERTER_FALLBACKS 0 /* All Apple ARMv7 chips promise NEON support. */
|
||||
#endif
|
||||
|
||||
|
|
@ -62,18 +62,36 @@ SDL_AudioFilter SDL_Convert_F32_to_S32 = NULL;
|
|||
#define DIVBY128 0.0078125f
|
||||
#define DIVBY32768 0.000030517578125f
|
||||
#define DIVBY8388607 0.00000011920930376163766f
|
||||
#define DIVBY2147483648 0.0000000004656612873077392578125f /* 0x1p-31f */
|
||||
|
||||
#if NEED_SCALAR_CONVERTER_FALLBACKS
|
||||
|
||||
/* This code requires that floats are in the IEEE-754 binary32 format */
|
||||
SDL_COMPILE_TIME_ASSERT(float_bits, sizeof(float) == sizeof(Uint32));
|
||||
|
||||
union float_bits {
|
||||
Uint32 u32;
|
||||
float f32;
|
||||
};
|
||||
|
||||
/* Create a bit-mask based on the sign-bit. Should optimize to a single arithmetic-shift-right */
|
||||
#define SIGNMASK(x) (Uint32)(0u - ((Uint32)(x) >> 31))
|
||||
|
||||
static void SDLCALL SDL_Convert_S8_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format)
|
||||
{
|
||||
const Sint8 *src = ((const Sint8 *)(cvt->buf + cvt->len_cvt)) - 1;
|
||||
float *dst = ((float *)(cvt->buf + cvt->len_cvt * 4)) - 1;
|
||||
const int num_samples = cvt->len_cvt;
|
||||
const Sint8 *src = (const Sint8 *)cvt->buf;
|
||||
float *dst = (float *)cvt->buf;
|
||||
int i;
|
||||
|
||||
LOG_DEBUG_CONVERT("AUDIO_S8", "AUDIO_F32");
|
||||
|
||||
for (i = cvt->len_cvt; i; --i, --src, --dst) {
|
||||
*dst = ((float)*src) * DIVBY128;
|
||||
for (i = num_samples - 1; i >= 0; --i) {
|
||||
/* 1) Construct a float in the range [65536.0, 65538.0)
|
||||
* 2) Shift the float range to [-1.0, 1.0) */
|
||||
union float_bits x;
|
||||
x.u32 = (Uint8)src[i] ^ 0x47800080u;
|
||||
dst[i] = x.f32 - 65537.0f;
|
||||
}
|
||||
|
||||
cvt->len_cvt *= 4;
|
||||
|
|
@ -84,14 +102,19 @@ static void SDLCALL SDL_Convert_S8_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFor
|
|||
|
||||
static void SDLCALL SDL_Convert_U8_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format)
|
||||
{
|
||||
const Uint8 *src = ((const Uint8 *)(cvt->buf + cvt->len_cvt)) - 1;
|
||||
float *dst = ((float *)(cvt->buf + cvt->len_cvt * 4)) - 1;
|
||||
const int num_samples = cvt->len_cvt;
|
||||
const Uint8 *src = (const Uint8 *)cvt->buf;
|
||||
float *dst = (float *)cvt->buf;
|
||||
int i;
|
||||
|
||||
LOG_DEBUG_CONVERT("AUDIO_U8", "AUDIO_F32");
|
||||
|
||||
for (i = cvt->len_cvt; i; --i, --src, --dst) {
|
||||
*dst = (((float)*src) * DIVBY128) - 1.0f;
|
||||
for (i = num_samples - 1; i >= 0; --i) {
|
||||
/* 1) Construct a float in the range [65536.0, 65538.0)
|
||||
* 2) Shift the float range to [-1.0, 1.0) */
|
||||
union float_bits x;
|
||||
x.u32 = src[i] ^ 0x47800000u;
|
||||
dst[i] = x.f32 - 65537.0f;
|
||||
}
|
||||
|
||||
cvt->len_cvt *= 4;
|
||||
|
|
@ -102,14 +125,19 @@ static void SDLCALL SDL_Convert_U8_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFor
|
|||
|
||||
static void SDLCALL SDL_Convert_S16_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format)
|
||||
{
|
||||
const Sint16 *src = ((const Sint16 *)(cvt->buf + cvt->len_cvt)) - 1;
|
||||
float *dst = ((float *)(cvt->buf + cvt->len_cvt * 2)) - 1;
|
||||
const int num_samples = cvt->len_cvt / sizeof(Sint16);
|
||||
const Sint16 *src = (const Sint16 *)cvt->buf;
|
||||
float *dst = (float *)cvt->buf;
|
||||
int i;
|
||||
|
||||
LOG_DEBUG_CONVERT("AUDIO_S16", "AUDIO_F32");
|
||||
|
||||
for (i = cvt->len_cvt / sizeof(Sint16); i; --i, --src, --dst) {
|
||||
*dst = ((float)*src) * DIVBY32768;
|
||||
for (i = num_samples - 1; i >= 0; --i) {
|
||||
/* 1) Construct a float in the range [256.0, 258.0)
|
||||
* 2) Shift the float range to [-1.0, 1.0) */
|
||||
union float_bits x;
|
||||
x.u32 = (Uint16)src[i] ^ 0x43808000u;
|
||||
dst[i] = x.f32 - 257.0f;
|
||||
}
|
||||
|
||||
cvt->len_cvt *= 2;
|
||||
|
|
@ -155,21 +183,26 @@ static void SDLCALL SDL_Convert_S32_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFo
|
|||
|
||||
static void SDLCALL SDL_Convert_F32_to_S8_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format)
|
||||
{
|
||||
const int num_samples = cvt->len_cvt / sizeof (float);
|
||||
const float *src = (const float *)cvt->buf;
|
||||
Sint8 *dst = (Sint8 *)cvt->buf;
|
||||
int i;
|
||||
|
||||
LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S8");
|
||||
|
||||
for (i = cvt->len_cvt / sizeof(float); i; --i, ++src, ++dst) {
|
||||
const float sample = *src;
|
||||
if (sample >= 1.0f) {
|
||||
*dst = 127;
|
||||
} else if (sample <= -1.0f) {
|
||||
*dst = -128;
|
||||
} else {
|
||||
*dst = (Sint8)(sample * 127.0f);
|
||||
}
|
||||
for (i = 0; i < num_samples; ++i) {
|
||||
/* 1) Shift the float range from [-1.0, 1.0] to [98303.0, 98305.0]
|
||||
* 2) Shift the integer range from [0x47BFFF80, 0x47C00080] to [-128, 128]
|
||||
* 3) Clamp the value to [-128, 127] */
|
||||
union float_bits x;
|
||||
Uint32 y, z;
|
||||
x.f32 = src[i] + 98304.0f;
|
||||
|
||||
y = x.u32 - 0x47C00000u;
|
||||
z = 0x7Fu - (y ^ SIGNMASK(y));
|
||||
y = y ^ (z & SIGNMASK(z));
|
||||
|
||||
dst[i] = (Sint8)(y & 0xFF);
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 4;
|
||||
|
|
@ -180,21 +213,27 @@ static void SDLCALL SDL_Convert_F32_to_S8_Scalar(SDL_AudioCVT *cvt, SDL_AudioFor
|
|||
|
||||
static void SDLCALL SDL_Convert_F32_to_U8_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format)
|
||||
{
|
||||
const int num_samples = cvt->len_cvt / sizeof (float);
|
||||
const float *src = (const float *)cvt->buf;
|
||||
Uint8 *dst = (Uint8 *)cvt->buf;
|
||||
int i;
|
||||
|
||||
LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U8");
|
||||
|
||||
for (i = cvt->len_cvt / sizeof(float); i; --i, ++src, ++dst) {
|
||||
const float sample = *src;
|
||||
if (sample >= 1.0f) {
|
||||
*dst = 255;
|
||||
} else if (sample <= -1.0f) {
|
||||
*dst = 0;
|
||||
} else {
|
||||
*dst = (Uint8)((sample + 1.0f) * 127.0f);
|
||||
}
|
||||
for (i = 0; i < num_samples; ++i) {
|
||||
/* 1) Shift the float range from [-1.0, 1.0] to [98303.0, 98305.0]
|
||||
* 2) Shift the integer range from [0x47BFFF80, 0x47C00080] to [-128, 128]
|
||||
* 3) Clamp the value to [-128, 127]
|
||||
* 4) Shift the integer range from [-128, 127] to [0, 255] */
|
||||
union float_bits x;
|
||||
Uint32 y, z;
|
||||
x.f32 = src[i] + 98304.0f;
|
||||
|
||||
y = x.u32 - 0x47C00000u;
|
||||
z = 0x7Fu - (y ^ SIGNMASK(y));
|
||||
y = (y ^ 0x80u) ^ (z & SIGNMASK(z));
|
||||
|
||||
dst[i] = (Uint8)(y & 0xFF);
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 4;
|
||||
|
|
@ -205,21 +244,26 @@ static void SDLCALL SDL_Convert_F32_to_U8_Scalar(SDL_AudioCVT *cvt, SDL_AudioFor
|
|||
|
||||
static void SDLCALL SDL_Convert_F32_to_S16_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format)
|
||||
{
|
||||
const int num_samples = cvt->len_cvt / sizeof (float);
|
||||
const float *src = (const float *)cvt->buf;
|
||||
Sint16 *dst = (Sint16 *)cvt->buf;
|
||||
int i;
|
||||
|
||||
LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S16");
|
||||
|
||||
for (i = cvt->len_cvt / sizeof(float); i; --i, ++src, ++dst) {
|
||||
const float sample = *src;
|
||||
if (sample >= 1.0f) {
|
||||
*dst = 32767;
|
||||
} else if (sample <= -1.0f) {
|
||||
*dst = -32768;
|
||||
} else {
|
||||
*dst = (Sint16)(sample * 32767.0f);
|
||||
}
|
||||
for (i = 0; i < num_samples; ++i) {
|
||||
/* 1) Shift the float range from [-1.0, 1.0] to [383.0, 385.0]
|
||||
* 2) Shift the integer range from [0x43BF8000, 0x43C08000] to [-32768, 32768]
|
||||
* 3) Clamp values outside the [-32768, 32767] range */
|
||||
union float_bits x;
|
||||
Uint32 y, z;
|
||||
x.f32 = src[i] + 384.0f;
|
||||
|
||||
y = x.u32 - 0x43C00000u;
|
||||
z = 0x7FFFu - (y ^ SIGNMASK(y));
|
||||
y = y ^ (z & SIGNMASK(z));
|
||||
|
||||
dst[i] = (Sint16)(y & 0xFFFF);
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 2;
|
||||
|
|
@ -255,21 +299,27 @@ static void SDLCALL SDL_Convert_F32_to_U16_Scalar(SDL_AudioCVT *cvt, SDL_AudioFo
|
|||
|
||||
static void SDLCALL SDL_Convert_F32_to_S32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format)
|
||||
{
|
||||
const int num_samples = cvt->len_cvt / sizeof (float);
|
||||
const float *src = (const float *)cvt->buf;
|
||||
Sint32 *dst = (Sint32 *)cvt->buf;
|
||||
int i;
|
||||
|
||||
LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S32");
|
||||
|
||||
for (i = cvt->len_cvt / sizeof(float); i; --i, ++src, ++dst) {
|
||||
const float sample = *src;
|
||||
if (sample >= 1.0f) {
|
||||
*dst = 2147483647;
|
||||
} else if (sample <= -1.0f) {
|
||||
*dst = (Sint32)-2147483648LL;
|
||||
} else {
|
||||
*dst = ((Sint32)(sample * 8388607.0f)) << 8;
|
||||
}
|
||||
for (i = 0; i < num_samples; ++i) {
|
||||
/* 1) Shift the float range from [-1.0, 1.0] to [-2147483648.0, 2147483648.0]
|
||||
* 2) Set values outside the [-2147483648.0, 2147483647.0] range to -2147483648.0
|
||||
* 3) Convert the float to an integer, and fixup values outside the valid range */
|
||||
union float_bits x;
|
||||
Uint32 y, z;
|
||||
x.f32 = src[i];
|
||||
|
||||
y = x.u32 + 0x0F800000u;
|
||||
z = y - 0xCF000000u;
|
||||
z &= SIGNMASK(y ^ z);
|
||||
x.u32 = y - z;
|
||||
|
||||
dst[i] = (Sint32)x.f32 ^ (Sint32)SIGNMASK(z);
|
||||
}
|
||||
|
||||
if (cvt->filters[++cvt->filter_index]) {
|
||||
|
|
@ -278,63 +328,48 @@ static void SDLCALL SDL_Convert_F32_to_S32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFo
|
|||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_SSE2_INTRINSICS
|
||||
#ifdef HAVE_SSE2_INTRINSICS
|
||||
static void SDLCALL SDL_Convert_S8_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format)
|
||||
{
|
||||
const Sint8 *src = ((const Sint8 *)(cvt->buf + cvt->len_cvt)) - 1;
|
||||
float *dst = ((float *)(cvt->buf + cvt->len_cvt * 4)) - 1;
|
||||
int i;
|
||||
const Sint8 *src = (const Sint8 *)cvt->buf;
|
||||
float *dst = (float *)cvt->buf;
|
||||
int i = cvt->len_cvt;
|
||||
|
||||
/* 1) Flip the sign bit to convert from S8 to U8 format
|
||||
* 2) Construct a float in the range [65536.0, 65538.0)
|
||||
* 3) Shift the float range to [-1.0, 1.0)
|
||||
* dst[i] = i2f((src[i] ^ 0x80) | 0x47800000) - 65537.0 */
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
const __m128i flipper = _mm_set1_epi8(-0x80);
|
||||
const __m128i caster = _mm_set1_epi16(0x4780 /* 0x47800000 = f2i(65536.0) */);
|
||||
const __m128 offset = _mm_set1_ps(-65537.0);
|
||||
|
||||
LOG_DEBUG_CONVERT("AUDIO_S8", "AUDIO_F32 (using SSE2)");
|
||||
|
||||
/* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */
|
||||
for (i = cvt->len_cvt; i && (((size_t)(dst - 15)) & 15); --i, --src, --dst) {
|
||||
*dst = ((float)*src) * DIVBY128;
|
||||
}
|
||||
while (i >= 16) {
|
||||
i -= 16;
|
||||
|
||||
src -= 15;
|
||||
dst -= 15; /* adjust to read SSE blocks from the start. */
|
||||
SDL_assert(!i || !(((size_t)dst) & 15));
|
||||
{
|
||||
const __m128i bytes = _mm_xor_si128(_mm_loadu_si128((const __m128i *)&src[i]), flipper);
|
||||
|
||||
/* Make sure src is aligned too. */
|
||||
if (!(((size_t)src) & 15)) {
|
||||
/* Aligned! Do SSE blocks as long as we have 16 bytes available. */
|
||||
const __m128i *mmsrc = (const __m128i *)src;
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
const __m128 divby128 = _mm_set1_ps(DIVBY128);
|
||||
while (i >= 16) { /* 16 * 8-bit */
|
||||
const __m128i bytes = _mm_load_si128(mmsrc); /* get 16 sint8 into an XMM register. */
|
||||
/* treat as int16, shift left to clear every other sint16, then back right with sign-extend. Now sint16. */
|
||||
const __m128i shorts1 = _mm_srai_epi16(_mm_slli_epi16(bytes, 8), 8);
|
||||
/* right-shift-sign-extend gets us sint16 with the other set of values. */
|
||||
const __m128i shorts2 = _mm_srai_epi16(bytes, 8);
|
||||
/* unpack against zero to make these int32, shift to make them sign-extend, convert to float, multiply. Whew! */
|
||||
const __m128 floats1 = _mm_mul_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_slli_epi32(_mm_unpacklo_epi16(shorts1, zero), 16), 16)), divby128);
|
||||
const __m128 floats2 = _mm_mul_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_slli_epi32(_mm_unpacklo_epi16(shorts2, zero), 16), 16)), divby128);
|
||||
const __m128 floats3 = _mm_mul_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_slli_epi32(_mm_unpackhi_epi16(shorts1, zero), 16), 16)), divby128);
|
||||
const __m128 floats4 = _mm_mul_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_slli_epi32(_mm_unpackhi_epi16(shorts2, zero), 16), 16)), divby128);
|
||||
/* Interleave back into correct order, store. */
|
||||
_mm_store_ps(dst, _mm_unpacklo_ps(floats1, floats2));
|
||||
_mm_store_ps(dst + 4, _mm_unpackhi_ps(floats1, floats2));
|
||||
_mm_store_ps(dst + 8, _mm_unpacklo_ps(floats3, floats4));
|
||||
_mm_store_ps(dst + 12, _mm_unpackhi_ps(floats3, floats4));
|
||||
i -= 16;
|
||||
mmsrc--;
|
||||
dst -= 16;
|
||||
const __m128i shorts1 = _mm_unpacklo_epi8(bytes, zero);
|
||||
const __m128i shorts2 = _mm_unpackhi_epi8(bytes, zero);
|
||||
|
||||
const __m128 floats1 = _mm_add_ps(_mm_castsi128_ps(_mm_unpacklo_epi16(shorts1, caster)), offset);
|
||||
const __m128 floats2 = _mm_add_ps(_mm_castsi128_ps(_mm_unpackhi_epi16(shorts1, caster)), offset);
|
||||
const __m128 floats3 = _mm_add_ps(_mm_castsi128_ps(_mm_unpacklo_epi16(shorts2, caster)), offset);
|
||||
const __m128 floats4 = _mm_add_ps(_mm_castsi128_ps(_mm_unpackhi_epi16(shorts2, caster)), offset);
|
||||
|
||||
_mm_storeu_ps(&dst[i], floats1);
|
||||
_mm_storeu_ps(&dst[i + 4], floats2);
|
||||
_mm_storeu_ps(&dst[i + 8], floats3);
|
||||
_mm_storeu_ps(&dst[i + 12], floats4);
|
||||
}
|
||||
|
||||
src = (const Sint8 *)mmsrc;
|
||||
}
|
||||
|
||||
src += 15;
|
||||
dst += 15; /* adjust for any scalar finishing. */
|
||||
|
||||
/* Finish off any leftovers with scalar operations. */
|
||||
while (i) {
|
||||
*dst = ((float)*src) * DIVBY128;
|
||||
i--;
|
||||
src--;
|
||||
dst--;
|
||||
--i;
|
||||
_mm_store_ss(&dst[i], _mm_add_ss(_mm_castsi128_ps(_mm_cvtsi32_si128((Uint8)src[i] ^ 0x47800080u)), offset));
|
||||
}
|
||||
|
||||
cvt->len_cvt *= 4;
|
||||
|
|
@ -345,62 +380,43 @@ static void SDLCALL SDL_Convert_S8_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioForma
|
|||
|
||||
static void SDLCALL SDL_Convert_U8_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format)
|
||||
{
|
||||
const Uint8 *src = ((const Uint8 *)(cvt->buf + cvt->len_cvt)) - 1;
|
||||
float *dst = ((float *)(cvt->buf + cvt->len_cvt * 4)) - 1;
|
||||
int i;
|
||||
const Sint8 *src = (const Sint8 *)cvt->buf;
|
||||
float *dst = (float *)cvt->buf;
|
||||
int i = cvt->len_cvt;
|
||||
|
||||
/* 1) Construct a float in the range [65536.0, 65538.0)
|
||||
* 2) Shift the float range to [-1.0, 1.0)
|
||||
* dst[i] = i2f(src[i] | 0x47800000) - 65537.0 */
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
const __m128i caster = _mm_set1_epi16(0x4780 /* 0x47800000 = f2i(65536.0) */);
|
||||
const __m128 offset = _mm_set1_ps(-65537.0);
|
||||
|
||||
LOG_DEBUG_CONVERT("AUDIO_U8", "AUDIO_F32 (using SSE2)");
|
||||
|
||||
/* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */
|
||||
for (i = cvt->len_cvt; i && (((size_t)(dst - 15)) & 15); --i, --src, --dst) {
|
||||
*dst = (((float)*src) * DIVBY128) - 1.0f;
|
||||
}
|
||||
while (i >= 16) {
|
||||
i -= 16;
|
||||
|
||||
src -= 15;
|
||||
dst -= 15; /* adjust to read SSE blocks from the start. */
|
||||
SDL_assert(!i || !(((size_t)dst) & 15));
|
||||
{
|
||||
const __m128i bytes = _mm_loadu_si128((const __m128i *)&src[i]);
|
||||
|
||||
/* Make sure src is aligned too. */
|
||||
if (!(((size_t)src) & 15)) {
|
||||
/* Aligned! Do SSE blocks as long as we have 16 bytes available. */
|
||||
const __m128i *mmsrc = (const __m128i *)src;
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
const __m128 divby128 = _mm_set1_ps(DIVBY128);
|
||||
const __m128 minus1 = _mm_set1_ps(-1.0f);
|
||||
while (i >= 16) { /* 16 * 8-bit */
|
||||
const __m128i bytes = _mm_load_si128(mmsrc); /* get 16 uint8 into an XMM register. */
|
||||
/* treat as int16, shift left to clear every other sint16, then back right with zero-extend. Now uint16. */
|
||||
const __m128i shorts1 = _mm_srli_epi16(_mm_slli_epi16(bytes, 8), 8);
|
||||
/* right-shift-zero-extend gets us uint16 with the other set of values. */
|
||||
const __m128i shorts2 = _mm_srli_epi16(bytes, 8);
|
||||
/* unpack against zero to make these int32, convert to float, multiply, add. Whew! */
|
||||
/* Note that AVX2 can do floating point multiply+add in one instruction, fwiw. SSE2 cannot. */
|
||||
const __m128 floats1 = _mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(_mm_unpacklo_epi16(shorts1, zero)), divby128), minus1);
|
||||
const __m128 floats2 = _mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(_mm_unpacklo_epi16(shorts2, zero)), divby128), minus1);
|
||||
const __m128 floats3 = _mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(_mm_unpackhi_epi16(shorts1, zero)), divby128), minus1);
|
||||
const __m128 floats4 = _mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(_mm_unpackhi_epi16(shorts2, zero)), divby128), minus1);
|
||||
/* Interleave back into correct order, store. */
|
||||
_mm_store_ps(dst, _mm_unpacklo_ps(floats1, floats2));
|
||||
_mm_store_ps(dst + 4, _mm_unpackhi_ps(floats1, floats2));
|
||||
_mm_store_ps(dst + 8, _mm_unpacklo_ps(floats3, floats4));
|
||||
_mm_store_ps(dst + 12, _mm_unpackhi_ps(floats3, floats4));
|
||||
i -= 16;
|
||||
mmsrc--;
|
||||
dst -= 16;
|
||||
const __m128i shorts1 = _mm_unpacklo_epi8(bytes, zero);
|
||||
const __m128i shorts2 = _mm_unpackhi_epi8(bytes, zero);
|
||||
|
||||
const __m128 floats1 = _mm_add_ps(_mm_castsi128_ps(_mm_unpacklo_epi16(shorts1, caster)), offset);
|
||||
const __m128 floats2 = _mm_add_ps(_mm_castsi128_ps(_mm_unpackhi_epi16(shorts1, caster)), offset);
|
||||
const __m128 floats3 = _mm_add_ps(_mm_castsi128_ps(_mm_unpacklo_epi16(shorts2, caster)), offset);
|
||||
const __m128 floats4 = _mm_add_ps(_mm_castsi128_ps(_mm_unpackhi_epi16(shorts2, caster)), offset);
|
||||
|
||||
_mm_storeu_ps(&dst[i], floats1);
|
||||
_mm_storeu_ps(&dst[i + 4], floats2);
|
||||
_mm_storeu_ps(&dst[i + 8], floats3);
|
||||
_mm_storeu_ps(&dst[i + 12], floats4);
|
||||
}
|
||||
|
||||
src = (const Uint8 *)mmsrc;
|
||||
}
|
||||
|
||||
src += 15;
|
||||
dst += 15; /* adjust for any scalar finishing. */
|
||||
|
||||
/* Finish off any leftovers with scalar operations. */
|
||||
while (i) {
|
||||
*dst = (((float)*src) * DIVBY128) - 1.0f;
|
||||
i--;
|
||||
src--;
|
||||
dst--;
|
||||
--i;
|
||||
_mm_store_ss(&dst[i], _mm_add_ss(_mm_castsi128_ps(_mm_cvtsi32_si128((Uint8)src[i] ^ 0x47800000u)), offset));
|
||||
}
|
||||
|
||||
cvt->len_cvt *= 4;
|
||||
|
|
@ -411,49 +427,42 @@ static void SDLCALL SDL_Convert_U8_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioForma
|
|||
|
||||
static void SDLCALL SDL_Convert_S16_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format)
|
||||
{
|
||||
const Sint16 *src = ((const Sint16 *)(cvt->buf + cvt->len_cvt)) - 1;
|
||||
float *dst = ((float *)(cvt->buf + cvt->len_cvt * 2)) - 1;
|
||||
int i;
|
||||
const Sint16 *src = (const Sint16 *)cvt->buf;
|
||||
float *dst = (float *)cvt->buf;
|
||||
int i = cvt->len_cvt / 2;
|
||||
|
||||
/* 1) Flip the sign bit to convert from S16 to U16 format
|
||||
* 2) Construct a float in the range [256.0, 258.0)
|
||||
* 3) Shift the float range to [-1.0, 1.0)
|
||||
* dst[i] = i2f((src[i] ^ 0x8000) | 0x43800000) - 257.0 */
|
||||
const __m128i flipper = _mm_set1_epi16(-0x8000);
|
||||
const __m128i caster = _mm_set1_epi16(0x4380 /* 0x43800000 = f2i(256.0) */);
|
||||
const __m128 offset = _mm_set1_ps(-257.0f);
|
||||
|
||||
LOG_DEBUG_CONVERT("AUDIO_S16", "AUDIO_F32 (using SSE2)");
|
||||
|
||||
/* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */
|
||||
for (i = cvt->len_cvt / sizeof(Sint16); i && (((size_t)(dst - 7)) & 15); --i, --src, --dst) {
|
||||
*dst = ((float)*src) * DIVBY32768;
|
||||
}
|
||||
while (i >= 16) {
|
||||
i -= 16;
|
||||
|
||||
src -= 7;
|
||||
dst -= 7; /* adjust to read SSE blocks from the start. */
|
||||
SDL_assert(!i || !(((size_t)dst) & 15));
|
||||
{
|
||||
const __m128i shorts1 = _mm_xor_si128(_mm_loadu_si128((const __m128i *)&src[i]), flipper);
|
||||
const __m128i shorts2 = _mm_xor_si128(_mm_loadu_si128((const __m128i *)&src[i + 8]), flipper);
|
||||
|
||||
/* Make sure src is aligned too. */
|
||||
if (!(((size_t)src) & 15)) {
|
||||
/* Aligned! Do SSE blocks as long as we have 16 bytes available. */
|
||||
const __m128 divby32768 = _mm_set1_ps(DIVBY32768);
|
||||
while (i >= 8) { /* 8 * 16-bit */
|
||||
const __m128i ints = _mm_load_si128((__m128i const *)src); /* get 8 sint16 into an XMM register. */
|
||||
/* treat as int32, shift left to clear every other sint16, then back right with sign-extend. Now sint32. */
|
||||
const __m128i a = _mm_srai_epi32(_mm_slli_epi32(ints, 16), 16);
|
||||
/* right-shift-sign-extend gets us sint32 with the other set of values. */
|
||||
const __m128i b = _mm_srai_epi32(ints, 16);
|
||||
/* Interleave these back into the right order, convert to float, multiply, store. */
|
||||
_mm_store_ps(dst, _mm_mul_ps(_mm_cvtepi32_ps(_mm_unpacklo_epi32(a, b)), divby32768));
|
||||
_mm_store_ps(dst + 4, _mm_mul_ps(_mm_cvtepi32_ps(_mm_unpackhi_epi32(a, b)), divby32768));
|
||||
i -= 8;
|
||||
src -= 8;
|
||||
dst -= 8;
|
||||
const __m128 floats1 = _mm_add_ps(_mm_castsi128_ps(_mm_unpacklo_epi16(shorts1, caster)), offset);
|
||||
const __m128 floats2 = _mm_add_ps(_mm_castsi128_ps(_mm_unpackhi_epi16(shorts1, caster)), offset);
|
||||
const __m128 floats3 = _mm_add_ps(_mm_castsi128_ps(_mm_unpacklo_epi16(shorts2, caster)), offset);
|
||||
const __m128 floats4 = _mm_add_ps(_mm_castsi128_ps(_mm_unpackhi_epi16(shorts2, caster)), offset);
|
||||
|
||||
_mm_storeu_ps(&dst[i], floats1);
|
||||
_mm_storeu_ps(&dst[i + 4], floats2);
|
||||
_mm_storeu_ps(&dst[i + 8], floats3);
|
||||
_mm_storeu_ps(&dst[i + 12], floats4);
|
||||
}
|
||||
}
|
||||
|
||||
src += 7;
|
||||
dst += 7; /* adjust for any scalar finishing. */
|
||||
|
||||
/* Finish off any leftovers with scalar operations. */
|
||||
while (i) {
|
||||
*dst = ((float)*src) * DIVBY32768;
|
||||
i--;
|
||||
src--;
|
||||
dst--;
|
||||
--i;
|
||||
_mm_store_ss(&dst[i], _mm_add_ss(_mm_castsi128_ps(_mm_cvtsi32_si128((Uint16)src[i] ^ 0x43808000u)), offset));
|
||||
}
|
||||
|
||||
cvt->len_cvt *= 2;
|
||||
|
|
@ -520,38 +529,37 @@ static void SDLCALL SDL_Convert_S32_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioForm
|
|||
{
|
||||
const Sint32 *src = (const Sint32 *)cvt->buf;
|
||||
float *dst = (float *)cvt->buf;
|
||||
int i;
|
||||
int i = cvt->len_cvt / 4;
|
||||
|
||||
/* dst[i] = f32(src[i]) / f32(0x80000000) */
|
||||
const __m128 scaler = _mm_set1_ps(DIVBY2147483648);
|
||||
|
||||
LOG_DEBUG_CONVERT("AUDIO_S32", "AUDIO_F32 (using SSE2)");
|
||||
|
||||
/* Get dst aligned to 16 bytes */
|
||||
for (i = cvt->len_cvt / sizeof(Sint32); i && (((size_t)dst) & 15); --i, ++src, ++dst) {
|
||||
*dst = ((float)(*src >> 8)) * DIVBY8388607;
|
||||
}
|
||||
while (i >= 16) {
|
||||
i -= 16;
|
||||
|
||||
SDL_assert(!i || !(((size_t)dst) & 15));
|
||||
{
|
||||
const __m128i ints1 = _mm_loadu_si128((const __m128i *)&src[i]);
|
||||
const __m128i ints2 = _mm_loadu_si128((const __m128i *)&src[i + 4]);
|
||||
const __m128i ints3 = _mm_loadu_si128((const __m128i *)&src[i + 8]);
|
||||
const __m128i ints4 = _mm_loadu_si128((const __m128i *)&src[i + 12]);
|
||||
|
||||
/* Make sure src is aligned too. */
|
||||
if (!(((size_t)src) & 15)) {
|
||||
/* Aligned! Do SSE blocks as long as we have 16 bytes available. */
|
||||
const __m128 divby8388607 = _mm_set1_ps(DIVBY8388607);
|
||||
const __m128i *mmsrc = (const __m128i *)src;
|
||||
while (i >= 4) { /* 4 * sint32 */
|
||||
/* shift out lowest bits so int fits in a float32. Small precision loss, but much faster. */
|
||||
_mm_store_ps(dst, _mm_mul_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_load_si128(mmsrc), 8)), divby8388607));
|
||||
i -= 4;
|
||||
mmsrc++;
|
||||
dst += 4;
|
||||
const __m128 floats1 = _mm_mul_ps(_mm_cvtepi32_ps(ints1), scaler);
|
||||
const __m128 floats2 = _mm_mul_ps(_mm_cvtepi32_ps(ints2), scaler);
|
||||
const __m128 floats3 = _mm_mul_ps(_mm_cvtepi32_ps(ints3), scaler);
|
||||
const __m128 floats4 = _mm_mul_ps(_mm_cvtepi32_ps(ints4), scaler);
|
||||
|
||||
_mm_storeu_ps(&dst[i], floats1);
|
||||
_mm_storeu_ps(&dst[i + 4], floats2);
|
||||
_mm_storeu_ps(&dst[i + 8], floats3);
|
||||
_mm_storeu_ps(&dst[i + 12], floats4);
|
||||
}
|
||||
src = (const Sint32 *)mmsrc;
|
||||
}
|
||||
|
||||
/* Finish off any leftovers with scalar operations. */
|
||||
while (i) {
|
||||
*dst = ((float)(*src >> 8)) * DIVBY8388607;
|
||||
i--;
|
||||
src++;
|
||||
dst++;
|
||||
--i;
|
||||
_mm_store_ss(&dst[i], _mm_mul_ss(_mm_cvt_si2ss(_mm_setzero_ps(), src[i]), scaler));
|
||||
}
|
||||
|
||||
if (cvt->filters[++cvt->filter_index]) {
|
||||
|
|
@ -563,57 +571,47 @@ static void SDLCALL SDL_Convert_F32_to_S8_SSE2(SDL_AudioCVT *cvt, SDL_AudioForma
|
|||
{
|
||||
const float *src = (const float *)cvt->buf;
|
||||
Sint8 *dst = (Sint8 *)cvt->buf;
|
||||
int i;
|
||||
int i = cvt->len_cvt / 4;
|
||||
|
||||
/* 1) Shift the float range from [-1.0, 1.0] to [98303.0, 98305.0]
|
||||
* 2) Extract the lowest 16 bits and clamp to [-128, 127]
|
||||
* Overflow is correctly handled for inputs between roughly [-255.0, 255.0]
|
||||
* dst[i] = clamp(i16(f2i(src[i] + 98304.0) & 0xFFFF), -128, 127) */
|
||||
const __m128 offset = _mm_set1_ps(98304.0f);
|
||||
const __m128i mask = _mm_set1_epi16(0xFF);
|
||||
|
||||
LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S8 (using SSE2)");
|
||||
|
||||
/* Get dst aligned to 16 bytes */
|
||||
for (i = cvt->len_cvt / sizeof(float); i && (((size_t)dst) & 15); --i, ++src, ++dst) {
|
||||
const float sample = *src;
|
||||
if (sample >= 1.0f) {
|
||||
*dst = 127;
|
||||
} else if (sample <= -1.0f) {
|
||||
*dst = -128;
|
||||
} else {
|
||||
*dst = (Sint8)(sample * 127.0f);
|
||||
}
|
||||
while (i >= 16) {
|
||||
const __m128 floats1 = _mm_loadu_ps(&src[0]);
|
||||
const __m128 floats2 = _mm_loadu_ps(&src[4]);
|
||||
const __m128 floats3 = _mm_loadu_ps(&src[8]);
|
||||
const __m128 floats4 = _mm_loadu_ps(&src[12]);
|
||||
|
||||
const __m128i ints1 = _mm_castps_si128(_mm_add_ps(floats1, offset));
|
||||
const __m128i ints2 = _mm_castps_si128(_mm_add_ps(floats2, offset));
|
||||
const __m128i ints3 = _mm_castps_si128(_mm_add_ps(floats3, offset));
|
||||
const __m128i ints4 = _mm_castps_si128(_mm_add_ps(floats4, offset));
|
||||
|
||||
const __m128i shorts1 = _mm_and_si128(_mm_packs_epi16(ints1, ints2), mask);
|
||||
const __m128i shorts2 = _mm_and_si128(_mm_packs_epi16(ints3, ints4), mask);
|
||||
|
||||
const __m128i bytes = _mm_packus_epi16(shorts1, shorts2);
|
||||
|
||||
_mm_storeu_si128((__m128i*)dst, bytes);
|
||||
|
||||
i -= 16;
|
||||
src += 16;
|
||||
dst += 16;
|
||||
}
|
||||
|
||||
SDL_assert(!i || !(((size_t)dst) & 15));
|
||||
|
||||
/* Make sure src is aligned too. */
|
||||
if (!(((size_t)src) & 15)) {
|
||||
/* Aligned! Do SSE blocks as long as we have 16 bytes available. */
|
||||
const __m128 one = _mm_set1_ps(1.0f);
|
||||
const __m128 negone = _mm_set1_ps(-1.0f);
|
||||
const __m128 mulby127 = _mm_set1_ps(127.0f);
|
||||
__m128i *mmdst = (__m128i *)dst;
|
||||
while (i >= 16) { /* 16 * float32 */
|
||||
const __m128i ints1 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src)), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */
|
||||
const __m128i ints2 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src + 4)), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */
|
||||
const __m128i ints3 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src + 8)), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */
|
||||
const __m128i ints4 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src + 12)), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */
|
||||
_mm_store_si128(mmdst, _mm_packs_epi16(_mm_packs_epi32(ints1, ints2), _mm_packs_epi32(ints3, ints4))); /* pack down, store out. */
|
||||
i -= 16;
|
||||
src += 16;
|
||||
mmdst++;
|
||||
}
|
||||
dst = (Sint8 *)mmdst;
|
||||
}
|
||||
|
||||
/* Finish off any leftovers with scalar operations. */
|
||||
while (i) {
|
||||
const float sample = *src;
|
||||
if (sample >= 1.0f) {
|
||||
*dst = 127;
|
||||
} else if (sample <= -1.0f) {
|
||||
*dst = -128;
|
||||
} else {
|
||||
*dst = (Sint8)(sample * 127.0f);
|
||||
}
|
||||
i--;
|
||||
src++;
|
||||
dst++;
|
||||
const __m128i ints = _mm_castps_si128(_mm_add_ss(_mm_load_ss(src), offset));
|
||||
*dst = (Sint8)(_mm_cvtsi128_si32(_mm_packs_epi16(ints, ints)) & 0xFF);
|
||||
|
||||
--i;
|
||||
++src;
|
||||
++dst;
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 4;
|
||||
|
|
@ -626,57 +624,47 @@ static void SDLCALL SDL_Convert_F32_to_U8_SSE2(SDL_AudioCVT *cvt, SDL_AudioForma
|
|||
{
|
||||
const float *src = (const float *)cvt->buf;
|
||||
Uint8 *dst = cvt->buf;
|
||||
int i;
|
||||
int i = cvt->len_cvt / 4;
|
||||
|
||||
/* 1) Shift the float range from [-1.0, 1.0] to [98304.0, 98306.0]
|
||||
* 2) Extract the lowest 16 bits and clamp to [0, 255]
|
||||
* Overflow is correctly handled for inputs between roughly [-254.0, 254.0]
|
||||
* dst[i] = clamp(i16(f2i(src[i] + 98305.0) & 0xFFFF), 0, 255) */
|
||||
const __m128 offset = _mm_set1_ps(98305.0f);
|
||||
const __m128i mask = _mm_set1_epi16(0xFF);
|
||||
|
||||
LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U8 (using SSE2)");
|
||||
|
||||
/* Get dst aligned to 16 bytes */
|
||||
for (i = cvt->len_cvt / sizeof(float); i && (((size_t)dst) & 15); --i, ++src, ++dst) {
|
||||
const float sample = *src;
|
||||
if (sample >= 1.0f) {
|
||||
*dst = 255;
|
||||
} else if (sample <= -1.0f) {
|
||||
*dst = 0;
|
||||
} else {
|
||||
*dst = (Uint8)((sample + 1.0f) * 127.0f);
|
||||
}
|
||||
while (i >= 16) {
|
||||
const __m128 floats1 = _mm_loadu_ps(&src[0]);
|
||||
const __m128 floats2 = _mm_loadu_ps(&src[4]);
|
||||
const __m128 floats3 = _mm_loadu_ps(&src[8]);
|
||||
const __m128 floats4 = _mm_loadu_ps(&src[12]);
|
||||
|
||||
const __m128i ints1 = _mm_castps_si128(_mm_add_ps(floats1, offset));
|
||||
const __m128i ints2 = _mm_castps_si128(_mm_add_ps(floats2, offset));
|
||||
const __m128i ints3 = _mm_castps_si128(_mm_add_ps(floats3, offset));
|
||||
const __m128i ints4 = _mm_castps_si128(_mm_add_ps(floats4, offset));
|
||||
|
||||
const __m128i shorts1 = _mm_and_si128(_mm_packus_epi16(ints1, ints2), mask);
|
||||
const __m128i shorts2 = _mm_and_si128(_mm_packus_epi16(ints3, ints4), mask);
|
||||
|
||||
const __m128i bytes = _mm_packus_epi16(shorts1, shorts2);
|
||||
|
||||
_mm_storeu_si128((__m128i*)dst, bytes);
|
||||
|
||||
i -= 16;
|
||||
src += 16;
|
||||
dst += 16;
|
||||
}
|
||||
|
||||
SDL_assert(!i || !(((size_t)dst) & 15));
|
||||
|
||||
/* Make sure src is aligned too. */
|
||||
if (!(((size_t)src) & 15)) {
|
||||
/* Aligned! Do SSE blocks as long as we have 16 bytes available. */
|
||||
const __m128 one = _mm_set1_ps(1.0f);
|
||||
const __m128 negone = _mm_set1_ps(-1.0f);
|
||||
const __m128 mulby127 = _mm_set1_ps(127.0f);
|
||||
__m128i *mmdst = (__m128i *)dst;
|
||||
while (i >= 16) { /* 16 * float32 */
|
||||
const __m128i ints1 = _mm_cvtps_epi32(_mm_mul_ps(_mm_add_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src)), one), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */
|
||||
const __m128i ints2 = _mm_cvtps_epi32(_mm_mul_ps(_mm_add_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src + 4)), one), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */
|
||||
const __m128i ints3 = _mm_cvtps_epi32(_mm_mul_ps(_mm_add_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src + 8)), one), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */
|
||||
const __m128i ints4 = _mm_cvtps_epi32(_mm_mul_ps(_mm_add_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src + 12)), one), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */
|
||||
_mm_store_si128(mmdst, _mm_packus_epi16(_mm_packs_epi32(ints1, ints2), _mm_packs_epi32(ints3, ints4))); /* pack down, store out. */
|
||||
i -= 16;
|
||||
src += 16;
|
||||
mmdst++;
|
||||
}
|
||||
dst = (Uint8 *)mmdst;
|
||||
}
|
||||
|
||||
/* Finish off any leftovers with scalar operations. */
|
||||
while (i) {
|
||||
const float sample = *src;
|
||||
if (sample >= 1.0f) {
|
||||
*dst = 255;
|
||||
} else if (sample <= -1.0f) {
|
||||
*dst = 0;
|
||||
} else {
|
||||
*dst = (Uint8)((sample + 1.0f) * 127.0f);
|
||||
}
|
||||
i--;
|
||||
src++;
|
||||
dst++;
|
||||
const __m128i ints = _mm_castps_si128(_mm_add_ss(_mm_load_ss(src), offset));
|
||||
*dst = (Uint8)(_mm_cvtsi128_si32(_mm_packus_epi16(ints, ints)) & 0xFF);
|
||||
|
||||
--i;
|
||||
++src;
|
||||
++dst;
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 4;
|
||||
|
|
@ -689,55 +677,46 @@ static void SDLCALL SDL_Convert_F32_to_S16_SSE2(SDL_AudioCVT *cvt, SDL_AudioForm
|
|||
{
|
||||
const float *src = (const float *)cvt->buf;
|
||||
Sint16 *dst = (Sint16 *)cvt->buf;
|
||||
int i;
|
||||
int i = cvt->len_cvt / 4;
|
||||
|
||||
/* 1) Shift the float range from [-1.0, 1.0] to [256.0, 258.0]
|
||||
* 2) Shift the int range from [0x43800000, 0x43810000] to [-32768,32768]
|
||||
* 3) Clamp to range [-32768,32767]
|
||||
* Overflow is correctly handled for inputs between roughly [-257.0, +inf)
|
||||
* dst[i] = clamp(f2i(src[i] + 257.0) - 0x43808000, -32768, 32767) */
|
||||
const __m128 offset = _mm_set1_ps(257.0f);
|
||||
|
||||
LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S16 (using SSE2)");
|
||||
|
||||
/* Get dst aligned to 16 bytes */
|
||||
for (i = cvt->len_cvt / sizeof(float); i && (((size_t)dst) & 15); --i, ++src, ++dst) {
|
||||
const float sample = *src;
|
||||
if (sample >= 1.0f) {
|
||||
*dst = 32767;
|
||||
} else if (sample <= -1.0f) {
|
||||
*dst = -32768;
|
||||
} else {
|
||||
*dst = (Sint16)(sample * 32767.0f);
|
||||
}
|
||||
while (i >= 16) {
|
||||
const __m128 floats1 = _mm_loadu_ps(&src[0]);
|
||||
const __m128 floats2 = _mm_loadu_ps(&src[4]);
|
||||
const __m128 floats3 = _mm_loadu_ps(&src[8]);
|
||||
const __m128 floats4 = _mm_loadu_ps(&src[12]);
|
||||
|
||||
const __m128i ints1 = _mm_sub_epi32(_mm_castps_si128(_mm_add_ps(floats1, offset)), _mm_castps_si128(offset));
|
||||
const __m128i ints2 = _mm_sub_epi32(_mm_castps_si128(_mm_add_ps(floats2, offset)), _mm_castps_si128(offset));
|
||||
const __m128i ints3 = _mm_sub_epi32(_mm_castps_si128(_mm_add_ps(floats3, offset)), _mm_castps_si128(offset));
|
||||
const __m128i ints4 = _mm_sub_epi32(_mm_castps_si128(_mm_add_ps(floats4, offset)), _mm_castps_si128(offset));
|
||||
|
||||
const __m128i shorts1 = _mm_packs_epi32(ints1, ints2);
|
||||
const __m128i shorts2 = _mm_packs_epi32(ints3, ints4);
|
||||
|
||||
_mm_storeu_si128((__m128i*)&dst[0], shorts1);
|
||||
_mm_storeu_si128((__m128i*)&dst[8], shorts2);
|
||||
|
||||
i -= 16;
|
||||
src += 16;
|
||||
dst += 16;
|
||||
}
|
||||
|
||||
SDL_assert(!i || !(((size_t)dst) & 15));
|
||||
|
||||
/* Make sure src is aligned too. */
|
||||
if (!(((size_t)src) & 15)) {
|
||||
/* Aligned! Do SSE blocks as long as we have 16 bytes available. */
|
||||
const __m128 one = _mm_set1_ps(1.0f);
|
||||
const __m128 negone = _mm_set1_ps(-1.0f);
|
||||
const __m128 mulby32767 = _mm_set1_ps(32767.0f);
|
||||
__m128i *mmdst = (__m128i *)dst;
|
||||
while (i >= 8) { /* 8 * float32 */
|
||||
const __m128i ints1 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src)), one), mulby32767)); /* load 4 floats, clamp, convert to sint32 */
|
||||
const __m128i ints2 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src + 4)), one), mulby32767)); /* load 4 floats, clamp, convert to sint32 */
|
||||
_mm_store_si128(mmdst, _mm_packs_epi32(ints1, ints2)); /* pack to sint16, store out. */
|
||||
i -= 8;
|
||||
src += 8;
|
||||
mmdst++;
|
||||
}
|
||||
dst = (Sint16 *)mmdst;
|
||||
}
|
||||
|
||||
/* Finish off any leftovers with scalar operations. */
|
||||
while (i) {
|
||||
const float sample = *src;
|
||||
if (sample >= 1.0f) {
|
||||
*dst = 32767;
|
||||
} else if (sample <= -1.0f) {
|
||||
*dst = -32768;
|
||||
} else {
|
||||
*dst = (Sint16)(sample * 32767.0f);
|
||||
}
|
||||
i--;
|
||||
src++;
|
||||
dst++;
|
||||
const __m128i ints = _mm_sub_epi32(_mm_castps_si128(_mm_add_ss(_mm_load_ss(src), offset)), _mm_castps_si128(offset));
|
||||
*dst = (Sint16)(_mm_cvtsi128_si32(_mm_packs_epi32(ints, ints)) & 0xFFFF);
|
||||
|
||||
--i;
|
||||
++src;
|
||||
++dst;
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 2;
|
||||
|
|
@ -819,53 +798,51 @@ static void SDLCALL SDL_Convert_F32_to_S32_SSE2(SDL_AudioCVT *cvt, SDL_AudioForm
|
|||
{
|
||||
const float *src = (const float *)cvt->buf;
|
||||
Sint32 *dst = (Sint32 *)cvt->buf;
|
||||
int i;
|
||||
int i = cvt->len_cvt / 4;
|
||||
|
||||
/* 1) Scale the float range from [-1.0, 1.0] to [-2147483648.0, 2147483648.0]
|
||||
* 2) Convert to integer (values too small/large become 0x80000000 = -2147483648)
|
||||
* 3) Fixup values which were too large (0x80000000 ^ 0xFFFFFFFF = 2147483647)
|
||||
* dst[i] = i32(src[i] * 2147483648.0) ^ ((src[i] >= 2147483648.0) ? 0xFFFFFFFF : 0x00000000) */
|
||||
const __m128 limit = _mm_set1_ps(2147483648.0f);
|
||||
|
||||
LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S32 (using SSE2)");
|
||||
|
||||
/* Get dst aligned to 16 bytes */
|
||||
for (i = cvt->len_cvt / sizeof(float); i && (((size_t)dst) & 15); --i, ++src, ++dst) {
|
||||
const float sample = *src;
|
||||
if (sample >= 1.0f) {
|
||||
*dst = 2147483647;
|
||||
} else if (sample <= -1.0f) {
|
||||
*dst = (Sint32)-2147483648LL;
|
||||
} else {
|
||||
*dst = ((Sint32)(sample * 8388607.0f)) << 8;
|
||||
}
|
||||
while (i >= 16) {
|
||||
const __m128 floats1 = _mm_loadu_ps(&src[0]);
|
||||
const __m128 floats2 = _mm_loadu_ps(&src[4]);
|
||||
const __m128 floats3 = _mm_loadu_ps(&src[8]);
|
||||
const __m128 floats4 = _mm_loadu_ps(&src[12]);
|
||||
|
||||
const __m128 values1 = _mm_mul_ps(floats1, limit);
|
||||
const __m128 values2 = _mm_mul_ps(floats2, limit);
|
||||
const __m128 values3 = _mm_mul_ps(floats3, limit);
|
||||
const __m128 values4 = _mm_mul_ps(floats4, limit);
|
||||
|
||||
const __m128i ints1 = _mm_xor_si128(_mm_cvttps_epi32(values1), _mm_castps_si128(_mm_cmpge_ps(values1, limit)));
|
||||
const __m128i ints2 = _mm_xor_si128(_mm_cvttps_epi32(values2), _mm_castps_si128(_mm_cmpge_ps(values2, limit)));
|
||||
const __m128i ints3 = _mm_xor_si128(_mm_cvttps_epi32(values3), _mm_castps_si128(_mm_cmpge_ps(values3, limit)));
|
||||
const __m128i ints4 = _mm_xor_si128(_mm_cvttps_epi32(values4), _mm_castps_si128(_mm_cmpge_ps(values4, limit)));
|
||||
|
||||
_mm_storeu_si128((__m128i*)&dst[0], ints1);
|
||||
_mm_storeu_si128((__m128i*)&dst[4], ints2);
|
||||
_mm_storeu_si128((__m128i*)&dst[8], ints3);
|
||||
_mm_storeu_si128((__m128i*)&dst[12], ints4);
|
||||
|
||||
i -= 16;
|
||||
src += 16;
|
||||
dst += 16;
|
||||
}
|
||||
|
||||
SDL_assert(!i || !(((size_t)dst) & 15));
|
||||
SDL_assert(!i || !(((size_t)src) & 15));
|
||||
|
||||
{
|
||||
/* Aligned! Do SSE blocks as long as we have 16 bytes available. */
|
||||
const __m128 one = _mm_set1_ps(1.0f);
|
||||
const __m128 negone = _mm_set1_ps(-1.0f);
|
||||
const __m128 mulby8388607 = _mm_set1_ps(8388607.0f);
|
||||
__m128i *mmdst = (__m128i *)dst;
|
||||
while (i >= 4) { /* 4 * float32 */
|
||||
_mm_store_si128(mmdst, _mm_slli_epi32(_mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src)), one), mulby8388607)), 8)); /* load 4 floats, clamp, convert to sint32 */
|
||||
i -= 4;
|
||||
src += 4;
|
||||
mmdst++;
|
||||
}
|
||||
dst = (Sint32 *)mmdst;
|
||||
}
|
||||
|
||||
/* Finish off any leftovers with scalar operations. */
|
||||
while (i) {
|
||||
const float sample = *src;
|
||||
if (sample >= 1.0f) {
|
||||
*dst = 2147483647;
|
||||
} else if (sample <= -1.0f) {
|
||||
*dst = (Sint32)-2147483648LL;
|
||||
} else {
|
||||
*dst = ((Sint32)(sample * 8388607.0f)) << 8;
|
||||
}
|
||||
i--;
|
||||
src++;
|
||||
dst++;
|
||||
const __m128 floats = _mm_load_ss(src);
|
||||
const __m128 values = _mm_mul_ss(floats, limit);
|
||||
const __m128i ints = _mm_xor_si128(_mm_cvttps_epi32(values), _mm_castps_si128(_mm_cmpge_ss(values, limit)));
|
||||
*dst = (Sint32)_mm_cvtsi128_si32(ints);
|
||||
|
||||
--i;
|
||||
++src;
|
||||
++dst;
|
||||
}
|
||||
|
||||
if (cvt->filters[++cvt->filter_index]) {
|
||||
|
|
@ -874,7 +851,7 @@ static void SDLCALL SDL_Convert_F32_to_S32_SSE2(SDL_AudioCVT *cvt, SDL_AudioForm
|
|||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_NEON_INTRINSICS
|
||||
#ifdef HAVE_NEON_INTRINSICS
|
||||
static void SDLCALL SDL_Convert_S8_to_F32_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format)
|
||||
{
|
||||
const Sint8 *src = ((const Sint8 *)(cvt->buf + cvt->len_cvt)) - 1;
|
||||
|
|
@ -1463,14 +1440,14 @@ void SDL_ChooseAudioConverters(void)
|
|||
SDL_Convert_F32_to_S32 = SDL_Convert_F32_to_S32_##fntype; \
|
||||
converters_chosen = SDL_TRUE
|
||||
|
||||
#if HAVE_SSE2_INTRINSICS
|
||||
#ifdef HAVE_SSE2_INTRINSICS
|
||||
if (SDL_HasSSE2()) {
|
||||
SET_CONVERTER_FUNCS(SSE2);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_NEON_INTRINSICS
|
||||
#ifdef HAVE_NEON_INTRINSICS
|
||||
if (SDL_HasNEON()) {
|
||||
SET_CONVERTER_FUNCS(NEON);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -264,7 +264,7 @@ static void WaveDebugDumpFormat(WaveFile *file, Uint32 rifflen, Uint32 fmtlen, U
|
|||
int res;
|
||||
|
||||
dumpstr = SDL_malloc(bufsize);
|
||||
if (dumpstr == NULL) {
|
||||
if (!dumpstr) {
|
||||
return;
|
||||
}
|
||||
dumpstr[0] = 0;
|
||||
|
|
@ -441,7 +441,7 @@ static int MS_ADPCM_Init(WaveFile *file, size_t datalength)
|
|||
|
||||
coeffdata = (MS_ADPCM_CoeffData *)SDL_malloc(sizeof(MS_ADPCM_CoeffData) + coeffcount * 4);
|
||||
file->decoderdata = coeffdata; /* Freed in cleanup. */
|
||||
if (coeffdata == NULL) {
|
||||
if (!coeffdata) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
coeffdata->coeff = &coeffdata->aligndummy;
|
||||
|
|
@ -684,7 +684,7 @@ static int MS_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
|||
state.output.pos = 0;
|
||||
state.output.size = outputsize / sizeof(Sint16);
|
||||
state.output.data = (Sint16 *)SDL_calloc(1, outputsize);
|
||||
if (state.output.data == NULL) {
|
||||
if (!state.output.data) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
|
|
@ -1075,12 +1075,12 @@ static int IMA_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len
|
|||
state.output.pos = 0;
|
||||
state.output.size = outputsize / sizeof(Sint16);
|
||||
state.output.data = (Sint16 *)SDL_malloc(outputsize);
|
||||
if (state.output.data == NULL) {
|
||||
if (!state.output.data) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
cstate = (Sint8 *)SDL_calloc(state.channels, sizeof(Sint8));
|
||||
if (cstate == NULL) {
|
||||
if (!cstate) {
|
||||
SDL_free(state.output.data);
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
|
@ -1235,7 +1235,7 @@ static int LAW_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
|||
|
||||
/* 1 to avoid allocating zero bytes, to keep static analysis happy. */
|
||||
src = (Uint8 *)SDL_realloc(chunk->data, expanded_len ? expanded_len : 1);
|
||||
if (src == NULL) {
|
||||
if (!src) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
chunk->data = NULL;
|
||||
|
|
@ -1366,7 +1366,7 @@ static int PCM_ConvertSint24ToSint32(WaveFile *file, Uint8 **audio_buf, Uint32 *
|
|||
|
||||
/* 1 to avoid allocating zero bytes, to keep static analysis happy. */
|
||||
ptr = (Uint8 *)SDL_realloc(chunk->data, expanded_len ? expanded_len : 1);
|
||||
if (ptr == NULL) {
|
||||
if (!ptr) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
|
|
@ -1438,11 +1438,11 @@ static int PCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static WaveRiffSizeHint WaveGetRiffSizeHint()
|
||||
static WaveRiffSizeHint WaveGetRiffSizeHint(void)
|
||||
{
|
||||
const char *hint = SDL_GetHint(SDL_HINT_WAVE_RIFF_CHUNK_SIZE);
|
||||
|
||||
if (hint != NULL) {
|
||||
if (hint) {
|
||||
if (SDL_strcmp(hint, "force") == 0) {
|
||||
return RiffSizeForce;
|
||||
} else if (SDL_strcmp(hint, "ignore") == 0) {
|
||||
|
|
@ -1457,11 +1457,11 @@ static WaveRiffSizeHint WaveGetRiffSizeHint()
|
|||
return RiffSizeNoHint;
|
||||
}
|
||||
|
||||
static WaveTruncationHint WaveGetTruncationHint()
|
||||
static WaveTruncationHint WaveGetTruncationHint(void)
|
||||
{
|
||||
const char *hint = SDL_GetHint(SDL_HINT_WAVE_TRUNCATION);
|
||||
|
||||
if (hint != NULL) {
|
||||
if (hint) {
|
||||
if (SDL_strcmp(hint, "verystrict") == 0) {
|
||||
return TruncVeryStrict;
|
||||
} else if (SDL_strcmp(hint, "strict") == 0) {
|
||||
|
|
@ -1476,11 +1476,11 @@ static WaveTruncationHint WaveGetTruncationHint()
|
|||
return TruncNoHint;
|
||||
}
|
||||
|
||||
static WaveFactChunkHint WaveGetFactChunkHint()
|
||||
static WaveFactChunkHint WaveGetFactChunkHint(void)
|
||||
{
|
||||
const char *hint = SDL_GetHint(SDL_HINT_WAVE_FACT_CHUNK);
|
||||
|
||||
if (hint != NULL) {
|
||||
if (hint) {
|
||||
if (SDL_strcmp(hint, "truncate") == 0) {
|
||||
return FactTruncate;
|
||||
} else if (SDL_strcmp(hint, "strict") == 0) {
|
||||
|
|
@ -1497,7 +1497,7 @@ static WaveFactChunkHint WaveGetFactChunkHint()
|
|||
|
||||
static void WaveFreeChunkData(WaveChunk *chunk)
|
||||
{
|
||||
if (chunk->data != NULL) {
|
||||
if (chunk->data) {
|
||||
SDL_free(chunk->data);
|
||||
chunk->data = NULL;
|
||||
}
|
||||
|
|
@ -1546,7 +1546,7 @@ static int WaveReadPartialChunkData(SDL_RWops *src, WaveChunk *chunk, size_t len
|
|||
|
||||
if (length > 0) {
|
||||
chunk->data = (Uint8 *)SDL_malloc(length);
|
||||
if (chunk->data == NULL) {
|
||||
if (!chunk->data) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
|
|
@ -1612,7 +1612,7 @@ static int WaveReadFormat(WaveFile *file)
|
|||
return SDL_SetError("Data of WAVE fmt chunk too big");
|
||||
}
|
||||
fmtsrc = SDL_RWFromConstMem(chunk->data, (int)chunk->size);
|
||||
if (fmtsrc == NULL) {
|
||||
if (!fmtsrc) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
|
|
@ -1787,7 +1787,7 @@ static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 *
|
|||
SDL_zero(datachunk);
|
||||
|
||||
envchunkcountlimit = SDL_getenv("SDL_WAVE_CHUNK_LIMIT");
|
||||
if (envchunkcountlimit != NULL) {
|
||||
if (envchunkcountlimit) {
|
||||
unsigned int count;
|
||||
if (SDL_sscanf(envchunkcountlimit, "%u", &count) == 1) {
|
||||
chunkcountlimit = count <= SDL_MAX_UINT32 ? count : SDL_MAX_UINT32;
|
||||
|
|
@ -2085,16 +2085,16 @@ SDL_AudioSpec *SDL_LoadWAV_RW(SDL_RWops *src, int freesrc, SDL_AudioSpec *spec,
|
|||
SDL_zero(file);
|
||||
|
||||
/* Make sure we are passed a valid data source */
|
||||
if (src == NULL) {
|
||||
if (!src) {
|
||||
/* Error may come from RWops. */
|
||||
return NULL;
|
||||
} else if (spec == NULL) {
|
||||
} else if (!spec) {
|
||||
SDL_InvalidParamError("spec");
|
||||
return NULL;
|
||||
} else if (audio_buf == NULL) {
|
||||
} else if (!audio_buf) {
|
||||
SDL_InvalidParamError("audio_buf");
|
||||
return NULL;
|
||||
} else if (audio_len == NULL) {
|
||||
} else if (!audio_len) {
|
||||
SDL_InvalidParamError("audio_len");
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_AAUDIO
|
||||
#ifdef SDL_AUDIO_DRIVER_AAUDIO
|
||||
|
||||
#include "SDL_audio.h"
|
||||
#include "SDL_loadso.h"
|
||||
|
|
@ -94,29 +94,24 @@ static int aaudio_OpenDevice(_THIS, const char *devname)
|
|||
}
|
||||
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
private = this->hidden;
|
||||
|
||||
ctx.AAudioStreamBuilder_setSampleRate(ctx.builder, this->spec.freq);
|
||||
ctx.AAudioStreamBuilder_setChannelCount(ctx.builder, this->spec.channels);
|
||||
if(devname != NULL) {
|
||||
int aaudio_device_id = SDL_atoi(devname);
|
||||
LOGI("Opening device id %d", aaudio_device_id);
|
||||
ctx.AAudioStreamBuilder_setDeviceId(ctx.builder, aaudio_device_id);
|
||||
if(devname) {
|
||||
private->devid = SDL_atoi(devname);
|
||||
LOGI("Opening device id %d", private->devid);
|
||||
ctx.AAudioStreamBuilder_setDeviceId(ctx.builder, private->devid);
|
||||
}
|
||||
{
|
||||
aaudio_direction_t direction = (iscapture ? AAUDIO_DIRECTION_INPUT : AAUDIO_DIRECTION_OUTPUT);
|
||||
const aaudio_direction_t direction = (iscapture ? AAUDIO_DIRECTION_INPUT : AAUDIO_DIRECTION_OUTPUT);
|
||||
ctx.AAudioStreamBuilder_setDirection(ctx.builder, direction);
|
||||
}
|
||||
{
|
||||
aaudio_format_t format = AAUDIO_FORMAT_PCM_FLOAT;
|
||||
if (this->spec.format == AUDIO_S16SYS) {
|
||||
format = AAUDIO_FORMAT_PCM_I16;
|
||||
} else if (this->spec.format == AUDIO_S16SYS) {
|
||||
format = AAUDIO_FORMAT_PCM_FLOAT;
|
||||
}
|
||||
const aaudio_format_t format = (this->spec.format == AUDIO_S16SYS) ? AAUDIO_FORMAT_PCM_I16 : AAUDIO_FORMAT_PCM_FLOAT;
|
||||
ctx.AAudioStreamBuilder_setFormat(ctx.builder, format);
|
||||
}
|
||||
|
||||
|
|
@ -153,7 +148,7 @@ static int aaudio_OpenDevice(_THIS, const char *devname)
|
|||
if (!iscapture) {
|
||||
private->mixlen = this->spec.size;
|
||||
private->mixbuf = (Uint8 *)SDL_malloc(private->mixlen);
|
||||
if (private->mixbuf == NULL) {
|
||||
if (!private->mixbuf) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(private->mixbuf, this->spec.silence, this->spec.size);
|
||||
|
|
@ -211,6 +206,96 @@ static Uint8 *aaudio_GetDeviceBuf(_THIS)
|
|||
return private->mixbuf;
|
||||
}
|
||||
|
||||
/* Try to reestablish an AAudioStream.
|
||||
|
||||
This needs to get a stream with the same format as the previous one,
|
||||
even if this means AAudio needs to handle a conversion it didn't when
|
||||
we initially opened the device. If we can't get that, we are forced
|
||||
to give up here.
|
||||
|
||||
(This is more robust in SDL3, which is designed to handle
|
||||
abrupt format changes.)
|
||||
*/
|
||||
static int RebuildAAudioStream(SDL_AudioDevice *device)
|
||||
{
|
||||
struct SDL_PrivateAudioData *hidden = device->hidden;
|
||||
const SDL_bool iscapture = device->iscapture;
|
||||
aaudio_result_t res;
|
||||
|
||||
ctx.AAudioStreamBuilder_setSampleRate(ctx.builder, device->spec.freq);
|
||||
ctx.AAudioStreamBuilder_setChannelCount(ctx.builder, device->spec.channels);
|
||||
if(hidden->devid) {
|
||||
LOGI("Reopening device id %d", hidden->devid);
|
||||
ctx.AAudioStreamBuilder_setDeviceId(ctx.builder, hidden->devid);
|
||||
}
|
||||
{
|
||||
const aaudio_direction_t direction = (iscapture ? AAUDIO_DIRECTION_INPUT : AAUDIO_DIRECTION_OUTPUT);
|
||||
ctx.AAudioStreamBuilder_setDirection(ctx.builder, direction);
|
||||
}
|
||||
{
|
||||
const aaudio_format_t format = (device->spec.format == AUDIO_S16SYS) ? AAUDIO_FORMAT_PCM_I16 : AAUDIO_FORMAT_PCM_FLOAT;
|
||||
ctx.AAudioStreamBuilder_setFormat(ctx.builder, format);
|
||||
}
|
||||
|
||||
ctx.AAudioStreamBuilder_setErrorCallback(ctx.builder, aaudio_errorCallback, hidden);
|
||||
|
||||
LOGI("AAudio Try to reopen %u hz %u bit chan %u %s samples %u",
|
||||
device->spec.freq, SDL_AUDIO_BITSIZE(device->spec.format),
|
||||
device->spec.channels, (device->spec.format & 0x1000) ? "BE" : "LE", device->spec.samples);
|
||||
|
||||
res = ctx.AAudioStreamBuilder_openStream(ctx.builder, &hidden->stream);
|
||||
if (res != AAUDIO_OK) {
|
||||
LOGI("SDL Failed AAudioStreamBuilder_openStream %d", res);
|
||||
return SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||
}
|
||||
|
||||
{
|
||||
const aaudio_format_t fmt = ctx.AAudioStream_getFormat(hidden->stream);
|
||||
SDL_AudioFormat sdlfmt = (SDL_AudioFormat) 0;
|
||||
if (fmt == AAUDIO_FORMAT_PCM_I16) {
|
||||
sdlfmt = AUDIO_S16SYS;
|
||||
} else if (fmt == AAUDIO_FORMAT_PCM_FLOAT) {
|
||||
sdlfmt = AUDIO_F32SYS;
|
||||
}
|
||||
|
||||
/* We handle this better in SDL3, but this _needs_ to match the previous stream for SDL2. */
|
||||
if ( (device->spec.freq != ctx.AAudioStream_getSampleRate(hidden->stream)) ||
|
||||
(device->spec.channels != ctx.AAudioStream_getChannelCount(hidden->stream)) ||
|
||||
(device->spec.format != sdlfmt) ) {
|
||||
LOGI("Didn't get an identical spec from AAudioStream during reopen!");
|
||||
ctx.AAudioStream_close(hidden->stream);
|
||||
hidden->stream = NULL;
|
||||
return SDL_SetError("Didn't get an identical spec from AAudioStream during reopen!");
|
||||
}
|
||||
}
|
||||
|
||||
res = ctx.AAudioStream_requestStart(hidden->stream);
|
||||
if (res != AAUDIO_OK) {
|
||||
LOGI("SDL Failed AAudioStream_requestStart %d iscapture:%d", res, iscapture);
|
||||
return SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int RecoverAAudioDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
struct SDL_PrivateAudioData *hidden = device->hidden;
|
||||
AAudioStream *stream = hidden->stream;
|
||||
|
||||
/* attempt to build a new stream, in case there's a new default device. */
|
||||
hidden->stream = NULL;
|
||||
ctx.AAudioStream_requestStop(stream);
|
||||
ctx.AAudioStream_close(stream);
|
||||
|
||||
if (RebuildAAudioStream(device) < 0) {
|
||||
return -1; // oh well, we tried.
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void aaudio_PlayDevice(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *private = this->hidden;
|
||||
|
|
@ -219,6 +304,9 @@ static void aaudio_PlayDevice(_THIS)
|
|||
res = ctx.AAudioStream_write(private->stream, private->mixbuf, private->mixlen / private->frame_size, timeoutNanoseconds);
|
||||
if (res < 0) {
|
||||
LOGI("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||
if (RecoverAAudioDevice(this) < 0) {
|
||||
return; /* oh well, we went down hard. */
|
||||
}
|
||||
} else {
|
||||
LOGI("SDL AAudio play: %d frames, wanted:%d frames", (int)res, private->mixlen / private->frame_size);
|
||||
}
|
||||
|
|
@ -285,7 +373,7 @@ static SDL_bool aaudio_Init(SDL_AudioDriverImpl *impl)
|
|||
SDL_zero(ctx);
|
||||
|
||||
ctx.handle = SDL_LoadObject(LIB_AAUDIO_SO);
|
||||
if (ctx.handle == NULL) {
|
||||
if (!ctx.handle) {
|
||||
LOGI("SDL couldn't find " LIB_AAUDIO_SO);
|
||||
goto failure;
|
||||
}
|
||||
|
|
@ -300,7 +388,7 @@ static SDL_bool aaudio_Init(SDL_AudioDriverImpl *impl)
|
|||
goto failure;
|
||||
}
|
||||
|
||||
if (ctx.builder == NULL) {
|
||||
if (!ctx.builder) {
|
||||
LOGI("SDL Failed AAudio_createStreamBuilder - builder NULL");
|
||||
goto failure;
|
||||
}
|
||||
|
|
@ -344,9 +432,9 @@ void aaudio_PauseDevices(void)
|
|||
{
|
||||
/* TODO: Handle multiple devices? */
|
||||
struct SDL_PrivateAudioData *private;
|
||||
if (audioDevice != NULL && audioDevice->hidden != NULL) {
|
||||
if (audioDevice && audioDevice->hidden) {
|
||||
SDL_LockMutex(audioDevice->mixer_lock);
|
||||
private = (struct SDL_PrivateAudioData *)audioDevice->hidden;
|
||||
|
||||
if (private->stream) {
|
||||
aaudio_result_t res = ctx.AAudioStream_requestPause(private->stream);
|
||||
if (res != AAUDIO_OK) {
|
||||
|
|
@ -354,20 +442,11 @@ void aaudio_PauseDevices(void)
|
|||
SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_AtomicGet(&audioDevice->paused)) {
|
||||
/* The device is already paused, leave it alone */
|
||||
private->resume = SDL_FALSE;
|
||||
} else {
|
||||
SDL_LockMutex(audioDevice->mixer_lock);
|
||||
SDL_AtomicSet(&audioDevice->paused, 1);
|
||||
private->resume = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (captureDevice != NULL && captureDevice->hidden != NULL) {
|
||||
if (captureDevice && captureDevice->hidden) {
|
||||
SDL_LockMutex(captureDevice->mixer_lock);
|
||||
private = (struct SDL_PrivateAudioData *)captureDevice->hidden;
|
||||
|
||||
if (private->stream) {
|
||||
/* Pause() isn't implemented for 'capture', use Stop() */
|
||||
aaudio_result_t res = ctx.AAudioStream_requestStop(private->stream);
|
||||
|
|
@ -376,15 +455,6 @@ void aaudio_PauseDevices(void)
|
|||
SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_AtomicGet(&captureDevice->paused)) {
|
||||
/* The device is already paused, leave it alone */
|
||||
private->resume = SDL_FALSE;
|
||||
} else {
|
||||
SDL_LockMutex(captureDevice->mixer_lock);
|
||||
SDL_AtomicSet(&captureDevice->paused, 1);
|
||||
private->resume = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -393,15 +463,8 @@ void aaudio_ResumeDevices(void)
|
|||
{
|
||||
/* TODO: Handle multiple devices? */
|
||||
struct SDL_PrivateAudioData *private;
|
||||
if (audioDevice != NULL && audioDevice->hidden != NULL) {
|
||||
if (audioDevice && audioDevice->hidden) {
|
||||
private = (struct SDL_PrivateAudioData *)audioDevice->hidden;
|
||||
|
||||
if (private->resume) {
|
||||
SDL_AtomicSet(&audioDevice->paused, 0);
|
||||
private->resume = SDL_FALSE;
|
||||
SDL_UnlockMutex(audioDevice->mixer_lock);
|
||||
}
|
||||
|
||||
if (private->stream) {
|
||||
aaudio_result_t res = ctx.AAudioStream_requestStart(private->stream);
|
||||
if (res != AAUDIO_OK) {
|
||||
|
|
@ -409,17 +472,11 @@ void aaudio_ResumeDevices(void)
|
|||
SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(audioDevice->mixer_lock);
|
||||
}
|
||||
|
||||
if (captureDevice != NULL && captureDevice->hidden != NULL) {
|
||||
if (captureDevice && captureDevice->hidden) {
|
||||
private = (struct SDL_PrivateAudioData *)captureDevice->hidden;
|
||||
|
||||
if (private->resume) {
|
||||
SDL_AtomicSet(&captureDevice->paused, 0);
|
||||
private->resume = SDL_FALSE;
|
||||
SDL_UnlockMutex(captureDevice->mixer_lock);
|
||||
}
|
||||
|
||||
if (private->stream) {
|
||||
aaudio_result_t res = ctx.AAudioStream_requestStart(private->stream);
|
||||
if (res != AAUDIO_OK) {
|
||||
|
|
@ -427,6 +484,7 @@ void aaudio_ResumeDevices(void)
|
|||
SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(captureDevice->mixer_lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -437,19 +495,24 @@ void aaudio_ResumeDevices(void)
|
|||
*/
|
||||
SDL_bool aaudio_DetectBrokenPlayState(void)
|
||||
{
|
||||
AAudioStream *stream;
|
||||
struct SDL_PrivateAudioData *private;
|
||||
int64_t framePosition, timeNanoseconds;
|
||||
aaudio_result_t res;
|
||||
|
||||
if (audioDevice == NULL || !audioDevice->hidden) {
|
||||
if (!audioDevice || !audioDevice->hidden) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
private = audioDevice->hidden;
|
||||
stream = private->stream;
|
||||
if (!stream) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
res = ctx.AAudioStream_getTimestamp(private->stream, CLOCK_MONOTONIC, &framePosition, &timeNanoseconds);
|
||||
res = ctx.AAudioStream_getTimestamp(stream, CLOCK_MONOTONIC, &framePosition, &timeNanoseconds);
|
||||
if (res == AAUDIO_ERROR_INVALID_STATE) {
|
||||
aaudio_stream_state_t currentState = ctx.AAudioStream_getState(private->stream);
|
||||
aaudio_stream_state_t currentState = ctx.AAudioStream_getState(stream);
|
||||
/* AAudioStream_getTimestamp() will also return AAUDIO_ERROR_INVALID_STATE while the stream is still initially starting. But we only care if it silently went invalid while playing. */
|
||||
if (currentState == AAUDIO_STREAM_STATE_STARTED) {
|
||||
LOGI("SDL aaudio_DetectBrokenPlayState: detected invalid audio device state: AAudioStream_getTimestamp result=%d, framePosition=%lld, timeNanoseconds=%lld, getState=%d", (int)res, (long long)framePosition, (long long)timeNanoseconds, (int)currentState);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -38,9 +38,7 @@ struct SDL_PrivateAudioData
|
|||
Uint8 *mixbuf;
|
||||
int mixlen;
|
||||
int frame_size;
|
||||
|
||||
/* Resume device if it was paused automatically */
|
||||
int resume;
|
||||
int devid;
|
||||
};
|
||||
|
||||
void aaudio_ResumeDevices(void);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright , (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright , (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_ALSA
|
||||
#ifdef SDL_AUDIO_DRIVER_ALSA
|
||||
|
||||
#ifndef SDL_ALSA_NON_BLOCKING
|
||||
#define SDL_ALSA_NON_BLOCKING 0
|
||||
|
|
@ -98,7 +98,7 @@ static void *alsa_handle = NULL;
|
|||
static int load_alsa_sym(const char *fn, void **addr)
|
||||
{
|
||||
*addr = SDL_LoadFunction(alsa_handle, fn);
|
||||
if (*addr == NULL) {
|
||||
if (!*addr) {
|
||||
/* Don't call SDL_SetError(): SDL_LoadFunction already did. */
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -166,7 +166,7 @@ static int load_alsa_syms(void)
|
|||
|
||||
static void UnloadALSALibrary(void)
|
||||
{
|
||||
if (alsa_handle != NULL) {
|
||||
if (alsa_handle) {
|
||||
SDL_UnloadObject(alsa_handle);
|
||||
alsa_handle = NULL;
|
||||
}
|
||||
|
|
@ -175,9 +175,9 @@ static void UnloadALSALibrary(void)
|
|||
static int LoadALSALibrary(void)
|
||||
{
|
||||
int retval = 0;
|
||||
if (alsa_handle == NULL) {
|
||||
if (!alsa_handle) {
|
||||
alsa_handle = SDL_LoadObject(alsa_library);
|
||||
if (alsa_handle == NULL) {
|
||||
if (!alsa_handle) {
|
||||
retval = -1;
|
||||
/* Don't call SDL_SetError(): SDL_LoadObject already did. */
|
||||
} else {
|
||||
|
|
@ -208,13 +208,13 @@ static const char *get_audio_device(void *handle, const int channels)
|
|||
{
|
||||
const char *device;
|
||||
|
||||
if (handle != NULL) {
|
||||
if (handle) {
|
||||
return (const char *)handle;
|
||||
}
|
||||
|
||||
/* !!! FIXME: we also check "SDL_AUDIO_DEVICE_NAME" at the higher level. */
|
||||
device = SDL_getenv("AUDIODEV"); /* Is there a standard variable name? */
|
||||
if (device != NULL) {
|
||||
if (device) {
|
||||
return device;
|
||||
}
|
||||
|
||||
|
|
@ -539,7 +539,7 @@ static int ALSA_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
|
@ -687,7 +687,7 @@ static int ALSA_OpenDevice(_THIS, const char *devname)
|
|||
if (!iscapture) {
|
||||
this->hidden->mixlen = this->spec.size;
|
||||
this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->hidden->mixlen);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
if (!this->hidden->mixbuf) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen);
|
||||
|
|
@ -717,7 +717,7 @@ static void add_device(const int iscapture, const char *name, void *hint, ALSA_D
|
|||
char *handle = NULL;
|
||||
char *ptr;
|
||||
|
||||
if (dev == NULL) {
|
||||
if (!dev) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -727,7 +727,7 @@ static void add_device(const int iscapture, const char *name, void *hint, ALSA_D
|
|||
Make sure not to free the storage associated with desc in this case */
|
||||
if (hint) {
|
||||
desc = ALSA_snd_device_name_get_hint(hint, "DESC");
|
||||
if (desc == NULL) {
|
||||
if (!desc) {
|
||||
SDL_free(dev);
|
||||
return;
|
||||
}
|
||||
|
|
@ -741,14 +741,14 @@ static void add_device(const int iscapture, const char *name, void *hint, ALSA_D
|
|||
just chop the extra lines off, this seems to get a reasonable device
|
||||
name without extra details. */
|
||||
ptr = SDL_strchr(desc, '\n');
|
||||
if (ptr != NULL) {
|
||||
if (ptr) {
|
||||
*ptr = '\0';
|
||||
}
|
||||
|
||||
/*printf("ALSA: adding %s device '%s' (%s)\n", iscapture ? "capture" : "output", name, desc);*/
|
||||
|
||||
handle = SDL_strdup(name);
|
||||
if (handle == NULL) {
|
||||
if (!handle) {
|
||||
if (hint) {
|
||||
free(desc);
|
||||
}
|
||||
|
|
@ -800,7 +800,7 @@ static void ALSA_HotplugIteration(void)
|
|||
if we can find a preferred prefix for the system. */
|
||||
for (i = 0; hints[i]; i++) {
|
||||
char *name = ALSA_snd_device_name_get_hint(hints[i], "NAME");
|
||||
if (name == NULL) {
|
||||
if (!name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -829,20 +829,20 @@ static void ALSA_HotplugIteration(void)
|
|||
char *name;
|
||||
|
||||
/* if we didn't find a device name prefix we like at all... */
|
||||
if ((match == NULL) && (defaultdev != i)) {
|
||||
if ((!match) && (defaultdev != i)) {
|
||||
continue; /* ...skip anything that isn't the default device. */
|
||||
}
|
||||
|
||||
name = ALSA_snd_device_name_get_hint(hints[i], "NAME");
|
||||
if (name == NULL) {
|
||||
if (!name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* only want physical hardware interfaces */
|
||||
if (match == NULL || (SDL_strncmp(name, match, match_len) == 0)) {
|
||||
if (!match || (SDL_strncmp(name, match, match_len) == 0)) {
|
||||
char *ioid = ALSA_snd_device_name_get_hint(hints[i], "IOID");
|
||||
const SDL_bool isoutput = (ioid == NULL) || (SDL_strcmp(ioid, "Output") == 0);
|
||||
const SDL_bool isinput = (ioid == NULL) || (SDL_strcmp(ioid, "Input") == 0);
|
||||
const SDL_bool isoutput = (!ioid) || (SDL_strcmp(ioid, "Output") == 0);
|
||||
const SDL_bool isinput = (!ioid) || (SDL_strcmp(ioid, "Input") == 0);
|
||||
SDL_bool have_output = SDL_FALSE;
|
||||
SDL_bool have_input = SDL_FALSE;
|
||||
|
||||
|
|
@ -940,7 +940,7 @@ static void ALSA_Deinitialize(void)
|
|||
ALSA_Device *next;
|
||||
|
||||
#if SDL_ALSA_HOTPLUG_THREAD
|
||||
if (ALSA_hotplug_thread != NULL) {
|
||||
if (ALSA_hotplug_thread) {
|
||||
SDL_AtomicSet(&ALSA_hotplug_shutdown, 1);
|
||||
SDL_WaitThread(ALSA_hotplug_thread, NULL);
|
||||
ALSA_hotplug_thread = NULL;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_ANDROID
|
||||
#ifdef SDL_AUDIO_DRIVER_ANDROID
|
||||
|
||||
/* Output audio to Android */
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ static int ANDROIDAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
}
|
||||
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ static int ANDROIDAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
{
|
||||
int audio_device_id = 0;
|
||||
if (devname != NULL) {
|
||||
if (devname) {
|
||||
audio_device_id = SDL_atoi(devname);
|
||||
}
|
||||
if (Android_JNI_OpenAudioDevice(iscapture, audio_device_id, &this->spec) < 0) {
|
||||
|
|
@ -148,29 +148,12 @@ AudioBootStrap ANDROIDAUDIO_bootstrap = {
|
|||
void ANDROIDAUDIO_PauseDevices(void)
|
||||
{
|
||||
/* TODO: Handle multiple devices? */
|
||||
struct SDL_PrivateAudioData *private;
|
||||
if (audioDevice != NULL && audioDevice->hidden != NULL) {
|
||||
private = (struct SDL_PrivateAudioData *)audioDevice->hidden;
|
||||
if (SDL_AtomicGet(&audioDevice->paused)) {
|
||||
/* The device is already paused, leave it alone */
|
||||
private->resume = SDL_FALSE;
|
||||
} else {
|
||||
SDL_LockMutex(audioDevice->mixer_lock);
|
||||
SDL_AtomicSet(&audioDevice->paused, 1);
|
||||
private->resume = SDL_TRUE;
|
||||
}
|
||||
if (audioDevice && audioDevice->hidden) {
|
||||
SDL_LockMutex(audioDevice->mixer_lock);
|
||||
}
|
||||
|
||||
if (captureDevice != NULL && captureDevice->hidden != NULL) {
|
||||
private = (struct SDL_PrivateAudioData *)captureDevice->hidden;
|
||||
if (SDL_AtomicGet(&captureDevice->paused)) {
|
||||
/* The device is already paused, leave it alone */
|
||||
private->resume = SDL_FALSE;
|
||||
} else {
|
||||
SDL_LockMutex(captureDevice->mixer_lock);
|
||||
SDL_AtomicSet(&captureDevice->paused, 1);
|
||||
private->resume = SDL_TRUE;
|
||||
}
|
||||
if (captureDevice && captureDevice->hidden) {
|
||||
SDL_LockMutex(captureDevice->mixer_lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -178,23 +161,12 @@ void ANDROIDAUDIO_PauseDevices(void)
|
|||
void ANDROIDAUDIO_ResumeDevices(void)
|
||||
{
|
||||
/* TODO: Handle multiple devices? */
|
||||
struct SDL_PrivateAudioData *private;
|
||||
if (audioDevice != NULL && audioDevice->hidden != NULL) {
|
||||
private = (struct SDL_PrivateAudioData *)audioDevice->hidden;
|
||||
if (private->resume) {
|
||||
SDL_AtomicSet(&audioDevice->paused, 0);
|
||||
private->resume = SDL_FALSE;
|
||||
SDL_UnlockMutex(audioDevice->mixer_lock);
|
||||
}
|
||||
if (audioDevice && audioDevice->hidden) {
|
||||
SDL_UnlockMutex(audioDevice->mixer_lock);
|
||||
}
|
||||
|
||||
if (captureDevice != NULL && captureDevice->hidden != NULL) {
|
||||
private = (struct SDL_PrivateAudioData *)captureDevice->hidden;
|
||||
if (private->resume) {
|
||||
SDL_AtomicSet(&captureDevice->paused, 0);
|
||||
private->resume = SDL_FALSE;
|
||||
SDL_UnlockMutex(captureDevice->mixer_lock);
|
||||
}
|
||||
if (captureDevice && captureDevice->hidden) {
|
||||
SDL_UnlockMutex(captureDevice->mixer_lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -30,8 +30,7 @@
|
|||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
/* Resume device if it was paused automatically */
|
||||
int resume;
|
||||
int unused;
|
||||
};
|
||||
|
||||
void ANDROIDAUDIO_ResumeDevices(void);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_ARTS
|
||||
#ifdef SDL_AUDIO_DRIVER_ARTS
|
||||
|
||||
/* Allow access to a raw mixing buffer */
|
||||
|
||||
|
|
@ -86,9 +86,9 @@ static struct
|
|||
|
||||
#undef SDL_ARTS_SYM
|
||||
|
||||
static void UnloadARTSLibrary()
|
||||
static void UnloadARTSLibrary(void)
|
||||
{
|
||||
if (arts_handle != NULL) {
|
||||
if (arts_handle) {
|
||||
SDL_UnloadObject(arts_handle);
|
||||
arts_handle = NULL;
|
||||
}
|
||||
|
|
@ -98,9 +98,9 @@ static int LoadARTSLibrary(void)
|
|||
{
|
||||
int i, retval = -1;
|
||||
|
||||
if (arts_handle == NULL) {
|
||||
if (!arts_handle) {
|
||||
arts_handle = SDL_LoadObject(arts_library);
|
||||
if (arts_handle != NULL) {
|
||||
if (arts_handle) {
|
||||
retval = 0;
|
||||
for (i = 0; i < SDL_arraysize(arts_functions); ++i) {
|
||||
*arts_functions[i].func =
|
||||
|
|
@ -119,7 +119,7 @@ static int LoadARTSLibrary(void)
|
|||
|
||||
#else
|
||||
|
||||
static void UnloadARTSLibrary()
|
||||
static void UnloadARTSLibrary(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -214,7 +214,7 @@ static int ARTS_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
|
@ -281,7 +281,7 @@ static int ARTS_OpenDevice(_THIS, const char *devname)
|
|||
/* Allocate mixing buffer */
|
||||
this->hidden->mixlen = this->spec.size;
|
||||
this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
if (!this->hidden->mixbuf) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
|
||||
|
|
@ -300,12 +300,12 @@ static void ARTS_Deinitialize(void)
|
|||
}
|
||||
|
||||
|
||||
static SDL_bool ARTS_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool ARTS_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
if (LoadARTSLibrary() < 0) {
|
||||
return SDL_FALSE;
|
||||
} else {
|
||||
if (SDL_NAME(arts_init) () != NULL) {
|
||||
if (SDL_NAME(arts_init) () != 0) {
|
||||
UnloadARTSLibrary();
|
||||
SDL_SetError("ARTS: arts_init failed (no audio server?)");
|
||||
return SDL_FALSE;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -26,10 +26,10 @@
|
|||
#include "../SDL_sysaudio.h"
|
||||
|
||||
#if !defined(__IPHONEOS__)
|
||||
#define MACOSX_COREAUDIO 1
|
||||
#define MACOSX_COREAUDIO
|
||||
#endif
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
#ifdef MACOSX_COREAUDIO
|
||||
#include <CoreAudio/CoreAudio.h>
|
||||
#else
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
#include <AudioUnit/AudioUnit.h>
|
||||
|
||||
/* Things named "Master" were renamed to "Main" in macOS 12.0's SDK. */
|
||||
#if MACOSX_COREAUDIO
|
||||
#ifdef MACOSX_COREAUDIO
|
||||
#include <AvailabilityMacros.h>
|
||||
#ifndef MAC_OS_VERSION_12_0
|
||||
#define kAudioObjectPropertyElementMain kAudioObjectPropertyElementMaster
|
||||
|
|
@ -62,7 +62,7 @@ struct SDL_PrivateAudioData
|
|||
AudioStreamBasicDescription strdesc;
|
||||
SDL_sem *ready_semaphore;
|
||||
char *thread_error;
|
||||
#if MACOSX_COREAUDIO
|
||||
#ifdef MACOSX_COREAUDIO
|
||||
AudioDeviceID deviceID;
|
||||
SDL_atomic_t device_change_flag;
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_COREAUDIO
|
||||
#ifdef SDL_AUDIO_DRIVER_COREAUDIO
|
||||
|
||||
/* !!! FIXME: clean out some of the macro salsa in here. */
|
||||
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
#ifdef MACOSX_COREAUDIO
|
||||
static const AudioObjectPropertyAddress devlist_address = {
|
||||
kAudioHardwarePropertyDevices,
|
||||
kAudioObjectPropertyScopeGlobal,
|
||||
|
|
@ -289,11 +289,11 @@ static int open_capture_devices;
|
|||
static int num_open_devices;
|
||||
static SDL_AudioDevice **open_devices;
|
||||
|
||||
#if !MACOSX_COREAUDIO
|
||||
#ifndef MACOSX_COREAUDIO
|
||||
|
||||
static BOOL session_active = NO;
|
||||
|
||||
static void pause_audio_devices()
|
||||
static void pause_audio_devices(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -309,7 +309,7 @@ static void pause_audio_devices()
|
|||
}
|
||||
}
|
||||
|
||||
static void resume_audio_devices()
|
||||
static void resume_audio_devices(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -455,12 +455,13 @@ static BOOL update_audio_session(_THIS, SDL_bool open, SDL_bool allow_playandrec
|
|||
|
||||
if ((open_playback_devices || open_capture_devices) && !session_active) {
|
||||
if (![session setActive:YES error:&err]) {
|
||||
NSString *desc;
|
||||
if ([err code] == AVAudioSessionErrorCodeResourceNotAvailable &&
|
||||
category == AVAudioSessionCategoryPlayAndRecord) {
|
||||
return update_audio_session(this, open, SDL_FALSE);
|
||||
}
|
||||
|
||||
NSString *desc = err.description;
|
||||
desc = err.description;
|
||||
SDL_SetError("Could not activate Audio Session: %s", desc.UTF8String);
|
||||
return NO;
|
||||
}
|
||||
|
|
@ -532,6 +533,9 @@ static void outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBuffe
|
|||
if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) {
|
||||
/* Supply silence if audio is not enabled or paused */
|
||||
SDL_memset(inBuffer->mAudioData, this->spec.silence, inBuffer->mAudioDataBytesCapacity);
|
||||
if (this->stream) {
|
||||
SDL_AudioStreamClear(this->stream);
|
||||
}
|
||||
} else if (this->stream) {
|
||||
UInt32 remaining = inBuffer->mAudioDataBytesCapacity;
|
||||
Uint8 *ptr = (Uint8 *)inBuffer->mAudioData;
|
||||
|
|
@ -627,7 +631,7 @@ static void inputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBuffer
|
|||
AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL);
|
||||
}
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
#ifdef MACOSX_COREAUDIO
|
||||
static const AudioObjectPropertyAddress alive_address = {
|
||||
kAudioDevicePropertyDeviceIsAlive,
|
||||
kAudioObjectPropertyScopeGlobal,
|
||||
|
|
@ -669,7 +673,21 @@ static OSStatus default_device_changed(AudioObjectID inObjectID, UInt32 inNumber
|
|||
#if DEBUG_COREAUDIO
|
||||
printf("COREAUDIO: default device changed for SDL audio device %p!\n", this);
|
||||
#endif
|
||||
SDL_AtomicSet(&this->hidden->device_change_flag, 1); /* let the audioqueue thread pick up on this when safe to do so. */
|
||||
|
||||
/* due to a bug (?) in CoreAudio, this seems able to fire for a device pointer that's already closed, so check our list to make sure
|
||||
the pointer is still valid before touching it. https://github.com/libsdl-org/SDL/issues/10432 */
|
||||
if (open_devices) {
|
||||
int i;
|
||||
for (i = 0; i < num_open_devices; i++) {
|
||||
SDL_AudioDevice *device = open_devices[i];
|
||||
if (device == this) {
|
||||
if (this->hidden) {
|
||||
SDL_AtomicSet(&this->hidden->device_change_flag, 1); /* let the audioqueue thread pick up on this when safe to do so. */
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -681,7 +699,7 @@ static void COREAUDIO_CloseDevice(_THIS)
|
|||
|
||||
/* !!! FIXME: what does iOS do when a bluetooth audio device vanishes? Headphones unplugged? */
|
||||
/* !!! FIXME: (we only do a "default" device on iOS right now...can we do more?) */
|
||||
#if MACOSX_COREAUDIO
|
||||
#ifdef MACOSX_COREAUDIO
|
||||
if (this->handle != NULL) { /* we don't register this listener for default devices. */
|
||||
AudioObjectRemovePropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this);
|
||||
}
|
||||
|
|
@ -708,7 +726,7 @@ static void COREAUDIO_CloseDevice(_THIS)
|
|||
open_playback_devices--;
|
||||
}
|
||||
|
||||
#if !MACOSX_COREAUDIO
|
||||
#ifndef MACOSX_COREAUDIO
|
||||
update_audio_session(this, SDL_FALSE, SDL_TRUE);
|
||||
#endif
|
||||
|
||||
|
|
@ -737,7 +755,7 @@ static void COREAUDIO_CloseDevice(_THIS)
|
|||
SDL_free(this->hidden);
|
||||
}
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
#ifdef MACOSX_COREAUDIO
|
||||
static int prepare_device(_THIS)
|
||||
{
|
||||
void *handle = this->handle;
|
||||
|
|
@ -803,8 +821,8 @@ static int assign_device_to_audioqueue(_THIS)
|
|||
result = AudioObjectGetPropertyData(this->hidden->deviceID, &prop, 0, NULL, &devuidsize, &devuid);
|
||||
CHECK_RESULT("AudioObjectGetPropertyData (kAudioDevicePropertyDeviceUID)");
|
||||
result = AudioQueueSetProperty(this->hidden->audioQueue, kAudioQueueProperty_CurrentDevice, &devuid, devuidsize);
|
||||
CFRelease(devuid); /* Release devuid; we're done with it and AudioQueueSetProperty should have retained if it wants to keep it. */
|
||||
CHECK_RESULT("AudioQueueSetProperty (kAudioQueueProperty_CurrentDevice)");
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -830,7 +848,7 @@ static int prepare_audioqueue(_THIS)
|
|||
CHECK_RESULT("AudioQueueNewOutput");
|
||||
}
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
#ifdef MACOSX_COREAUDIO
|
||||
if (!assign_device_to_audioqueue(this)) {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -853,30 +871,50 @@ static int prepare_audioqueue(_THIS)
|
|||
SDL_zero(layout);
|
||||
switch (this->spec.channels) {
|
||||
case 1:
|
||||
// a standard mono stream
|
||||
layout.mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
|
||||
break;
|
||||
case 2:
|
||||
// a standard stereo stream (L R) - implied playback
|
||||
layout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
|
||||
break;
|
||||
case 3:
|
||||
// L R LFE
|
||||
layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_4;
|
||||
break;
|
||||
case 4:
|
||||
// front left, front right, back left, back right
|
||||
layout.mChannelLayoutTag = kAudioChannelLayoutTag_Quadraphonic;
|
||||
break;
|
||||
case 5:
|
||||
layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_5_0_A;
|
||||
// L R LFE Ls Rs
|
||||
layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_6;
|
||||
break;
|
||||
case 6:
|
||||
layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_5_1_A;
|
||||
// L R C LFE Ls Rs
|
||||
layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_12;
|
||||
break;
|
||||
#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000) || \
|
||||
(defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED >= 101500)
|
||||
case 7:
|
||||
/* FIXME: Need to move channel[4] (BC) to channel[6] */
|
||||
layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_6_1_A;
|
||||
// L R C LFE Cs Ls Rs
|
||||
if (@available(macOS 10.15, iOS 13, *)) {
|
||||
layout.mChannelLayoutTag = kAudioChannelLayoutTag_WAVE_6_1;
|
||||
} else {
|
||||
return SDL_SetError("Unsupported audio channels");
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_7_1_A;
|
||||
// L R C LFE Rls Rrs Ls Rs
|
||||
if (@available(macOS 10.15, iOS 13, *)) {
|
||||
layout.mChannelLayoutTag = kAudioChannelLayoutTag_WAVE_7_1;
|
||||
} else {
|
||||
return SDL_SetError("Unsupported audio channels");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return SDL_SetError("Unsupported audio channels");
|
||||
}
|
||||
if (layout.mChannelLayoutTag != 0) {
|
||||
result = AudioQueueSetProperty(this->hidden->audioQueue, kAudioQueueProperty_ChannelLayout, &layout, sizeof(layout));
|
||||
|
|
@ -938,7 +976,7 @@ static int audioqueue_thread(void *arg)
|
|||
SDL_AudioDevice *this = (SDL_AudioDevice *)arg;
|
||||
int rc;
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
#ifdef MACOSX_COREAUDIO
|
||||
const AudioObjectPropertyAddress default_device_address = {
|
||||
this->iscapture ? kAudioHardwarePropertyDefaultInputDevice : kAudioHardwarePropertyDefaultOutputDevice,
|
||||
kAudioObjectPropertyScopeGlobal,
|
||||
|
|
@ -966,7 +1004,7 @@ static int audioqueue_thread(void *arg)
|
|||
while (!SDL_AtomicGet(&this->shutdown)) {
|
||||
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.10, 1);
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
#ifdef MACOSX_COREAUDIO
|
||||
if ((this->handle == NULL) && SDL_AtomicGet(&this->hidden->device_change_flag)) {
|
||||
const AudioDeviceID prev_devid = this->hidden->deviceID;
|
||||
SDL_AtomicSet(&this->hidden->device_change_flag, 0);
|
||||
|
|
@ -999,7 +1037,7 @@ static int audioqueue_thread(void *arg)
|
|||
CFRunLoopRunInMode(kCFRunLoopDefaultMode, secs, 0);
|
||||
}
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
#ifdef MACOSX_COREAUDIO
|
||||
if (this->handle == NULL) {
|
||||
/* we don't care if this fails; we just won't change to new default devices, but we still otherwise function in this case. */
|
||||
AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &default_device_address, default_device_changed, this);
|
||||
|
|
@ -1037,7 +1075,7 @@ static int COREAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
open_devices[num_open_devices++] = this;
|
||||
}
|
||||
|
||||
#if !MACOSX_COREAUDIO
|
||||
#ifndef MACOSX_COREAUDIO
|
||||
if (!update_audio_session(this, SDL_TRUE, SDL_TRUE)) {
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1106,7 +1144,7 @@ static int COREAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
strdesc->mBytesPerFrame = strdesc->mChannelsPerFrame * strdesc->mBitsPerChannel / 8;
|
||||
strdesc->mBytesPerPacket = strdesc->mBytesPerFrame * strdesc->mFramesPerPacket;
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
#ifdef MACOSX_COREAUDIO
|
||||
if (!prepare_device(this)) {
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1134,7 +1172,7 @@ static int COREAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
return (this->hidden->thread != NULL) ? 0 : -1;
|
||||
}
|
||||
|
||||
#if !MACOSX_COREAUDIO
|
||||
#ifndef MACOSX_COREAUDIO
|
||||
static int COREAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
{
|
||||
AVAudioSession *session = [AVAudioSession sharedInstance];
|
||||
|
|
@ -1272,7 +1310,7 @@ static int COREAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int i
|
|||
|
||||
static void COREAUDIO_Deinitialize(void)
|
||||
{
|
||||
#if MACOSX_COREAUDIO
|
||||
#ifdef MACOSX_COREAUDIO
|
||||
AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL);
|
||||
free_audio_device_list(&capture_devs);
|
||||
free_audio_device_list(&output_devs);
|
||||
|
|
@ -1287,7 +1325,7 @@ static SDL_bool COREAUDIO_Init(SDL_AudioDriverImpl *impl)
|
|||
impl->Deinitialize = COREAUDIO_Deinitialize;
|
||||
impl->GetDefaultAudioInfo = COREAUDIO_GetDefaultAudioInfo;
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
#ifdef MACOSX_COREAUDIO
|
||||
impl->DetectDevices = COREAUDIO_DetectDevices;
|
||||
AudioObjectAddPropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_DSOUND
|
||||
#ifdef SDL_AUDIO_DRIVER_DSOUND
|
||||
|
||||
/* Allow access to a raw mixing buffer */
|
||||
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
#include "../SDL_audio_c.h"
|
||||
#include "SDL_directsound.h"
|
||||
#include <mmreg.h>
|
||||
#if HAVE_MMDEVICEAPI_H
|
||||
#ifdef HAVE_MMDEVICEAPI_H
|
||||
#include "../../core/windows/SDL_immdevice.h"
|
||||
#endif /* HAVE_MMDEVICEAPI_H */
|
||||
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
#endif
|
||||
|
||||
/* For Vista+, we can enumerate DSound devices with IMMDevice */
|
||||
#if HAVE_MMDEVICEAPI_H
|
||||
#ifdef HAVE_MMDEVICEAPI_H
|
||||
static SDL_bool SupportsIMMDevice = SDL_FALSE;
|
||||
#endif /* HAVE_MMDEVICEAPI_H */
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ static void DSOUND_Unload(void)
|
|||
pDirectSoundCaptureCreate8 = NULL;
|
||||
pDirectSoundCaptureEnumerateW = NULL;
|
||||
|
||||
if (DSoundDLL != NULL) {
|
||||
if (DSoundDLL) {
|
||||
SDL_UnloadObject(DSoundDLL);
|
||||
DSoundDLL = NULL;
|
||||
}
|
||||
|
|
@ -77,7 +77,7 @@ static int DSOUND_Load(void)
|
|||
DSOUND_Unload();
|
||||
|
||||
DSoundDLL = SDL_LoadObject("DSOUND.DLL");
|
||||
if (DSoundDLL == NULL) {
|
||||
if (!DSoundDLL) {
|
||||
SDL_SetError("DirectSound: failed to load DSOUND.DLL");
|
||||
} else {
|
||||
/* Now make sure we have DirectX 8 or better... */
|
||||
|
|
@ -159,7 +159,7 @@ static void DSOUND_FreeDeviceHandle(void *handle)
|
|||
|
||||
static int DSOUND_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
{
|
||||
#if HAVE_MMDEVICEAPI_H
|
||||
#ifdef HAVE_MMDEVICEAPI_H
|
||||
if (SupportsIMMDevice) {
|
||||
return SDL_IMMDevice_GetDefaultAudioInfo(name, spec, iscapture);
|
||||
}
|
||||
|
|
@ -172,7 +172,7 @@ static BOOL CALLBACK FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVO
|
|||
const int iscapture = (int)((size_t)data);
|
||||
if (guid != NULL) { /* skip default device */
|
||||
char *str = WIN_LookupAudioDeviceName(desc, guid);
|
||||
if (str != NULL) {
|
||||
if (str) {
|
||||
LPGUID cpyguid = (LPGUID)SDL_malloc(sizeof(GUID));
|
||||
SDL_memcpy(cpyguid, guid, sizeof(GUID));
|
||||
|
||||
|
|
@ -189,14 +189,14 @@ static BOOL CALLBACK FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVO
|
|||
|
||||
static void DSOUND_DetectDevices(void)
|
||||
{
|
||||
#if HAVE_MMDEVICEAPI_H
|
||||
#ifdef HAVE_MMDEVICEAPI_H
|
||||
if (SupportsIMMDevice) {
|
||||
SDL_IMMDevice_EnumerateEndpoints(SDL_TRUE);
|
||||
} else {
|
||||
#endif /* HAVE_MMDEVICEAPI_H */
|
||||
pDirectSoundCaptureEnumerateW(FindAllDevs, (void *)((size_t)1));
|
||||
pDirectSoundEnumerateW(FindAllDevs, (void *)((size_t)0));
|
||||
#if HAVE_MMDEVICEAPI_H
|
||||
#ifdef HAVE_MMDEVICEAPI_H
|
||||
}
|
||||
#endif /* HAVE_MMDEVICEAPI_H*/
|
||||
}
|
||||
|
|
@ -379,18 +379,18 @@ static void DSOUND_FlushCapture(_THIS)
|
|||
|
||||
static void DSOUND_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->mixbuf != NULL) {
|
||||
if (this->hidden->mixbuf) {
|
||||
IDirectSoundBuffer_Stop(this->hidden->mixbuf);
|
||||
IDirectSoundBuffer_Release(this->hidden->mixbuf);
|
||||
}
|
||||
if (this->hidden->sound != NULL) {
|
||||
if (this->hidden->sound) {
|
||||
IDirectSound_Release(this->hidden->sound);
|
||||
}
|
||||
if (this->hidden->capturebuf != NULL) {
|
||||
if (this->hidden->capturebuf) {
|
||||
IDirectSoundCaptureBuffer_Stop(this->hidden->capturebuf);
|
||||
IDirectSoundCaptureBuffer_Release(this->hidden->capturebuf);
|
||||
}
|
||||
if (this->hidden->capture != NULL) {
|
||||
if (this->hidden->capture) {
|
||||
IDirectSoundCapture_Release(this->hidden->capture);
|
||||
}
|
||||
SDL_free(this->hidden);
|
||||
|
|
@ -493,7 +493,7 @@ static int DSOUND_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
|
@ -612,7 +612,7 @@ static int DSOUND_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
static void DSOUND_Deinitialize(void)
|
||||
{
|
||||
#if HAVE_MMDEVICEAPI_H
|
||||
#ifdef HAVE_MMDEVICEAPI_H
|
||||
if (SupportsIMMDevice) {
|
||||
SDL_IMMDevice_Quit();
|
||||
SupportsIMMDevice = SDL_FALSE;
|
||||
|
|
@ -627,7 +627,7 @@ static SDL_bool DSOUND_Init(SDL_AudioDriverImpl *impl)
|
|||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
#if HAVE_MMDEVICEAPI_H
|
||||
#ifdef HAVE_MMDEVICEAPI_H
|
||||
SupportsIMMDevice = !(SDL_IMMDevice_Init() < 0);
|
||||
#endif /* HAVE_MMDEVICEAPI_H */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,11 +20,11 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_DISK
|
||||
#ifdef SDL_AUDIO_DRIVER_DISK
|
||||
|
||||
/* Output raw audio data to a file. */
|
||||
|
||||
#if HAVE_STDIO_H
|
||||
#ifdef HAVE_STDIO_H
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ static void DISKAUDIO_FlushCapture(_THIS)
|
|||
|
||||
static void DISKAUDIO_CloseDevice(_THIS)
|
||||
{
|
||||
if (_this->hidden->io != NULL) {
|
||||
if (_this->hidden->io) {
|
||||
SDL_RWclose(_this->hidden->io);
|
||||
}
|
||||
SDL_free(_this->hidden->mixbuf);
|
||||
|
|
@ -107,9 +107,9 @@ static void DISKAUDIO_CloseDevice(_THIS)
|
|||
|
||||
static const char *get_filename(const SDL_bool iscapture, const char *devname)
|
||||
{
|
||||
if (devname == NULL) {
|
||||
if (!devname) {
|
||||
devname = SDL_getenv(iscapture ? DISKENVR_INFILE : DISKENVR_OUTFILE);
|
||||
if (devname == NULL) {
|
||||
if (!devname) {
|
||||
devname = iscapture ? DISKDEFAULT_INFILE : DISKDEFAULT_OUTFILE;
|
||||
}
|
||||
}
|
||||
|
|
@ -126,12 +126,12 @@ static int DISKAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
_this->hidden = (struct SDL_PrivateAudioData *)
|
||||
SDL_malloc(sizeof(*_this->hidden));
|
||||
if (_this->hidden == NULL) {
|
||||
if (!_this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(_this->hidden);
|
||||
|
||||
if (envr != NULL) {
|
||||
if (envr) {
|
||||
_this->hidden->io_delay = SDL_atoi(envr);
|
||||
} else {
|
||||
_this->hidden->io_delay = ((_this->spec.samples * 1000) / _this->spec.freq);
|
||||
|
|
@ -139,14 +139,14 @@ static int DISKAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* Open the audio device */
|
||||
_this->hidden->io = SDL_RWFromFile(fname, iscapture ? "rb" : "wb");
|
||||
if (_this->hidden->io == NULL) {
|
||||
if (!_this->hidden->io) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Allocate mixing buffer */
|
||||
if (!iscapture) {
|
||||
_this->hidden->mixbuf = (Uint8 *)SDL_malloc(_this->spec.size);
|
||||
if (_this->hidden->mixbuf == NULL) {
|
||||
if (!_this->hidden->mixbuf) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(_this->hidden->mixbuf, _this->spec.silence, _this->spec.size);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_OSS
|
||||
#ifdef SDL_AUDIO_DRIVER_OSS
|
||||
|
||||
/* Allow access to a raw mixing buffer */
|
||||
|
||||
|
|
@ -67,9 +67,9 @@ static int DSP_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* We don't care what the devname is...we'll try to open anything. */
|
||||
/* ...but default to first name in the list... */
|
||||
if (devname == NULL) {
|
||||
if (!devname) {
|
||||
devname = SDL_GetAudioDeviceName(0, iscapture);
|
||||
if (devname == NULL) {
|
||||
if (!devname) {
|
||||
return SDL_SetError("No such audio device");
|
||||
}
|
||||
}
|
||||
|
|
@ -86,7 +86,7 @@ static int DSP_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
|
@ -228,7 +228,7 @@ static int DSP_OpenDevice(_THIS, const char *devname)
|
|||
if (!iscapture) {
|
||||
this->hidden->mixlen = this->spec.size;
|
||||
this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->hidden->mixlen);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
if (!this->hidden->mixbuf) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,6 +20,8 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifdef SDL_AUDIO_DRIVER_DUMMY
|
||||
|
||||
/* Output audio to nowhere... */
|
||||
|
||||
#include "SDL_timer.h"
|
||||
|
|
@ -61,4 +63,6 @@ AudioBootStrap DUMMYAUDIO_bootstrap = {
|
|||
"dummy", "SDL dummy audio driver", DUMMYAUDIO_Init, SDL_TRUE
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_EMSCRIPTEN
|
||||
#ifdef SDL_AUDIO_DRIVER_EMSCRIPTEN
|
||||
|
||||
#include "SDL_audio.h"
|
||||
#include "../SDL_audio_c.h"
|
||||
|
|
@ -39,6 +39,12 @@ static void FeedAudioDevice(_THIS, const void *buf, const int buflen)
|
|||
/* *INDENT-OFF* */ /* clang-format off */
|
||||
MAIN_THREAD_EM_ASM({
|
||||
var SDL2 = Module['SDL2'];
|
||||
/* Convert incoming buf pointer to a HEAPF32 offset. */
|
||||
#ifdef __wasm64__
|
||||
var buf = $0 / 4;
|
||||
#else
|
||||
var buf = $0 >>> 2;
|
||||
#endif
|
||||
var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels'];
|
||||
for (var c = 0; c < numChannels; ++c) {
|
||||
var channelData = SDL2.audio.currentOutputBuffer['getChannelData'](c);
|
||||
|
|
@ -47,7 +53,7 @@ static void FeedAudioDevice(_THIS, const void *buf, const int buflen)
|
|||
}
|
||||
|
||||
for (var j = 0; j < $1; ++j) {
|
||||
channelData[j] = HEAPF32[$0 + ((j*numChannels + c) << 2) >> 2]; /* !!! FIXME: why are these shifts here? */
|
||||
channelData[j] = HEAPF32[buf + (j*numChannels + c)];
|
||||
}
|
||||
}
|
||||
}, buf, buflen / framelen);
|
||||
|
|
@ -70,7 +76,7 @@ static void HandleAudioProcess(_THIS)
|
|||
return;
|
||||
}
|
||||
|
||||
if (this->stream == NULL) { /* no conversion necessary. */
|
||||
if (!this->stream) { /* no conversion necessary. */
|
||||
SDL_assert(this->spec.size == stream_len);
|
||||
callback(this->callbackspec.userdata, this->work_buffer, stream_len);
|
||||
} else { /* streaming/converting */
|
||||
|
|
@ -130,7 +136,7 @@ static void HandleCaptureProcess(_THIS)
|
|||
|
||||
/* okay, we've got an interleaved float32 array in C now. */
|
||||
|
||||
if (this->stream == NULL) { /* no conversion necessary. */
|
||||
if (!this->stream) { /* no conversion necessary. */
|
||||
SDL_assert(this->spec.size == stream_len);
|
||||
callback(this->callbackspec.userdata, this->work_buffer, stream_len);
|
||||
} else { /* streaming/converting */
|
||||
|
|
@ -156,32 +162,28 @@ static void EMSCRIPTENAUDIO_CloseDevice(_THIS)
|
|||
var SDL2 = Module['SDL2'];
|
||||
if ($0) {
|
||||
if (SDL2.capture.silenceTimer !== undefined) {
|
||||
clearTimeout(SDL2.capture.silenceTimer);
|
||||
clearInterval(SDL2.capture.silenceTimer);
|
||||
}
|
||||
if (SDL2.capture.stream !== undefined) {
|
||||
var tracks = SDL2.capture.stream.getAudioTracks();
|
||||
for (var i = 0; i < tracks.length; i++) {
|
||||
SDL2.capture.stream.removeTrack(tracks[i]);
|
||||
}
|
||||
SDL2.capture.stream = undefined;
|
||||
}
|
||||
if (SDL2.capture.scriptProcessorNode !== undefined) {
|
||||
SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {};
|
||||
SDL2.capture.scriptProcessorNode.disconnect();
|
||||
SDL2.capture.scriptProcessorNode = undefined;
|
||||
}
|
||||
if (SDL2.capture.mediaStreamNode !== undefined) {
|
||||
SDL2.capture.mediaStreamNode.disconnect();
|
||||
SDL2.capture.mediaStreamNode = undefined;
|
||||
}
|
||||
if (SDL2.capture.silenceBuffer !== undefined) {
|
||||
SDL2.capture.silenceBuffer = undefined
|
||||
}
|
||||
SDL2.capture = undefined;
|
||||
} else {
|
||||
if (SDL2.audio.scriptProcessorNode != undefined) {
|
||||
SDL2.audio.scriptProcessorNode.disconnect();
|
||||
SDL2.audio.scriptProcessorNode = undefined;
|
||||
}
|
||||
if (SDL2.audio.silenceTimer !== undefined) {
|
||||
clearInterval(SDL2.audio.silenceTimer);
|
||||
}
|
||||
SDL2.audio = undefined;
|
||||
}
|
||||
|
|
@ -227,7 +229,9 @@ static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
SDL2.audioContext = new webkitAudioContext();
|
||||
}
|
||||
if (SDL2.audioContext) {
|
||||
autoResumeAudioContext(SDL2.audioContext);
|
||||
if ((typeof navigator.userActivation) === 'undefined') {
|
||||
autoResumeAudioContext(SDL2.audioContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
return SDL2.audioContext === undefined ? -1 : 0;
|
||||
|
|
@ -296,8 +300,9 @@ static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
var have_microphone = function(stream) {
|
||||
//console.log('SDL audio capture: we have a microphone! Replacing silence callback.');
|
||||
if (SDL2.capture.silenceTimer !== undefined) {
|
||||
clearTimeout(SDL2.capture.silenceTimer);
|
||||
clearInterval(SDL2.capture.silenceTimer);
|
||||
SDL2.capture.silenceTimer = undefined;
|
||||
SDL2.capture.silenceBuffer = undefined
|
||||
}
|
||||
SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(stream);
|
||||
SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1);
|
||||
|
|
@ -305,7 +310,7 @@ static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
if ((SDL2 === undefined) || (SDL2.capture === undefined)) { return; }
|
||||
audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0);
|
||||
SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer;
|
||||
dynCall('vi', $2, [$3]);
|
||||
dynCall('vp', $2, [$3]);
|
||||
};
|
||||
SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode);
|
||||
SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination);
|
||||
|
|
@ -321,10 +326,10 @@ static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0);
|
||||
var silence_callback = function() {
|
||||
SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer;
|
||||
dynCall('vi', $2, [$3]);
|
||||
dynCall('vp', $2, [$3]);
|
||||
};
|
||||
|
||||
SDL2.capture.silenceTimer = setTimeout(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000);
|
||||
SDL2.capture.silenceTimer = setInterval(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000);
|
||||
|
||||
if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) {
|
||||
navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(have_microphone).catch(no_microphone);
|
||||
|
|
@ -339,10 +344,37 @@ static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0);
|
||||
SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) {
|
||||
if ((SDL2 === undefined) || (SDL2.audio === undefined)) { return; }
|
||||
// if we're actually running the node, we don't need the fake callback anymore, so kill it.
|
||||
if (SDL2.audio.silenceTimer !== undefined) {
|
||||
clearInterval(SDL2.audio.silenceTimer);
|
||||
SDL2.audio.silenceTimer = undefined;
|
||||
SDL2.audio.silenceBuffer = undefined;
|
||||
}
|
||||
SDL2.audio.currentOutputBuffer = e['outputBuffer'];
|
||||
dynCall('vi', $2, [$3]);
|
||||
dynCall('vp', $2, [$3]);
|
||||
};
|
||||
|
||||
SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']);
|
||||
|
||||
if (SDL2.audioContext.state === 'suspended') { // uhoh, autoplay is blocked.
|
||||
SDL2.audio.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate);
|
||||
SDL2.audio.silenceBuffer.getChannelData(0).fill(0.0);
|
||||
var silence_callback = function() {
|
||||
if ((typeof navigator.userActivation) !== 'undefined') {
|
||||
if (navigator.userActivation.hasBeenActive) {
|
||||
SDL2.audioContext.resume();
|
||||
}
|
||||
}
|
||||
|
||||
// the buffer that gets filled here just gets ignored, so the app can make progress
|
||||
// and/or avoid flooding audio queues until we can actually play audio.
|
||||
SDL2.audio.currentOutputBuffer = SDL2.audio.silenceBuffer;
|
||||
dynCall('vp', $2, [$3]);
|
||||
SDL2.audio.currentOutputBuffer = undefined;
|
||||
};
|
||||
|
||||
SDL2.audio.silenceTimer = setInterval(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000);
|
||||
}
|
||||
}, this->spec.channels, this->spec.samples, HandleAudioProcess, this);
|
||||
}
|
||||
/* *INDENT-ON* */ /* clang-format on */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_ESD
|
||||
#ifdef SDL_AUDIO_DRIVER_ESD
|
||||
|
||||
/* Allow access to an ESD network stream mixing buffer */
|
||||
|
||||
|
|
@ -64,9 +64,9 @@ static struct
|
|||
|
||||
#undef SDL_ESD_SYM
|
||||
|
||||
static void UnloadESDLibrary()
|
||||
static void UnloadESDLibrary(void)
|
||||
{
|
||||
if (esd_handle != NULL) {
|
||||
if (esd_handle) {
|
||||
SDL_UnloadObject(esd_handle);
|
||||
esd_handle = NULL;
|
||||
}
|
||||
|
|
@ -76,7 +76,7 @@ static int LoadESDLibrary(void)
|
|||
{
|
||||
int i, retval = -1;
|
||||
|
||||
if (esd_handle == NULL) {
|
||||
if (!esd_handle) {
|
||||
esd_handle = SDL_LoadObject(esd_library);
|
||||
if (esd_handle) {
|
||||
retval = 0;
|
||||
|
|
@ -96,7 +96,7 @@ static int LoadESDLibrary(void)
|
|||
|
||||
#else
|
||||
|
||||
static void UnloadESDLibrary()
|
||||
static void UnloadESDLibrary(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -185,7 +185,7 @@ static char *get_progname(void)
|
|||
if (fp != NULL) {
|
||||
if (fgets(temp, sizeof(temp) - 1, fp)) {
|
||||
progname = SDL_strrchr(temp, '/');
|
||||
if (progname == NULL) {
|
||||
if (!progname) {
|
||||
progname = temp;
|
||||
} else {
|
||||
progname = progname + 1;
|
||||
|
|
@ -206,7 +206,7 @@ static int ESD_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
|
@ -264,7 +264,7 @@ static int ESD_OpenDevice(_THIS, const char *devname)
|
|||
/* Allocate mixing buffer */
|
||||
this->hidden->mixlen = this->spec.size;
|
||||
this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
if (!this->hidden->mixbuf) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_FUSIONSOUND
|
||||
#ifdef SDL_AUDIO_DRIVER_FUSIONSOUND
|
||||
|
||||
/* !!! FIXME: why is this is SDL_FS_* instead of FUSIONSOUND_*? */
|
||||
|
||||
|
|
@ -77,9 +77,9 @@ static struct
|
|||
|
||||
#undef SDL_FS_SYM
|
||||
|
||||
static void UnloadFusionSoundLibrary()
|
||||
static void UnloadFusionSoundLibrary(void)
|
||||
{
|
||||
if (fs_handle != NULL) {
|
||||
if (fs_handle) {
|
||||
SDL_UnloadObject(fs_handle);
|
||||
fs_handle = NULL;
|
||||
}
|
||||
|
|
@ -89,9 +89,9 @@ static int LoadFusionSoundLibrary(void)
|
|||
{
|
||||
int i, retval = -1;
|
||||
|
||||
if (fs_handle == NULL) {
|
||||
if (!fs_handle) {
|
||||
fs_handle = SDL_LoadObject(fs_library);
|
||||
if (fs_handle != NULL) {
|
||||
if (fs_handle) {
|
||||
retval = 0;
|
||||
for (i = 0; i < SDL_arraysize(fs_functions); ++i) {
|
||||
*fs_functions[i].func =
|
||||
|
|
@ -110,7 +110,7 @@ static int LoadFusionSoundLibrary(void)
|
|||
|
||||
#else
|
||||
|
||||
static void UnloadFusionSoundLibrary()
|
||||
static void UnloadFusionSoundLibrary(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -175,7 +175,7 @@ static int SDL_FS_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
|
@ -250,7 +250,7 @@ static int SDL_FS_OpenDevice(_THIS, const char *devname)
|
|||
/* Allocate mixing buffer */
|
||||
this->hidden->mixlen = this->spec.size;
|
||||
this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
if (!this->hidden->mixbuf) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_HAIKU
|
||||
#ifdef SDL_AUDIO_DRIVER_HAIKU
|
||||
|
||||
/* Allow access to the audio stream on Haiku */
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ static void FillSound(void *device, void *stream, size_t len,
|
|||
} else {
|
||||
SDL_assert(audio->spec.size == len);
|
||||
|
||||
if (audio->stream == NULL) { /* no conversion necessary. */
|
||||
if (!audio->stream) { /* no conversion necessary. */
|
||||
callback(audio->callbackspec.userdata, (Uint8 *) stream, len);
|
||||
} else { /* streaming/converting */
|
||||
const int stream_len = audio->callbackspec.size;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_JACK
|
||||
#ifdef SDL_AUDIO_DRIVER_JACK
|
||||
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_audio.h"
|
||||
|
|
@ -58,7 +58,7 @@ static void *jack_handle = NULL;
|
|||
static int load_jack_sym(const char *fn, void **addr)
|
||||
{
|
||||
*addr = SDL_LoadFunction(jack_handle, fn);
|
||||
if (*addr == NULL) {
|
||||
if (!*addr) {
|
||||
/* Don't call SDL_SetError(): SDL_LoadFunction already did. */
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ static int load_jack_sym(const char *fn, void **addr)
|
|||
|
||||
static void UnloadJackLibrary(void)
|
||||
{
|
||||
if (jack_handle != NULL) {
|
||||
if (jack_handle) {
|
||||
SDL_UnloadObject(jack_handle);
|
||||
jack_handle = NULL;
|
||||
}
|
||||
|
|
@ -82,9 +82,9 @@ static void UnloadJackLibrary(void)
|
|||
static int LoadJackLibrary(void)
|
||||
{
|
||||
int retval = 0;
|
||||
if (jack_handle == NULL) {
|
||||
if (!jack_handle) {
|
||||
jack_handle = SDL_LoadObject(jack_library);
|
||||
if (jack_handle == NULL) {
|
||||
if (!jack_handle) {
|
||||
retval = -1;
|
||||
/* Don't call SDL_SetError(): SDL_LoadObject already did. */
|
||||
} else {
|
||||
|
|
@ -341,7 +341,7 @@ static int JACK_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* Build SDL's ports, which we will connect to the device ports. */
|
||||
this->hidden->sdlports = (jack_port_t **)SDL_calloc(channels, sizeof(jack_port_t *));
|
||||
if (this->hidden->sdlports == NULL) {
|
||||
if (!this->hidden->sdlports) {
|
||||
SDL_free(audio_ports);
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
|
@ -400,7 +400,7 @@ static SDL_bool JACK_Init(SDL_AudioDriverImpl *impl)
|
|||
/* Make sure a JACK server is running and available. */
|
||||
jack_status_t status;
|
||||
jack_client_t *client = JACK_jack_client_open("SDL", JackNoStartServer, &status, NULL);
|
||||
if (client == NULL) {
|
||||
if (!client) {
|
||||
UnloadJackLibrary();
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -38,6 +38,7 @@ static SDL_AudioDevice *audio_device;
|
|||
static void FreePrivateData(_THIS);
|
||||
static int FindAudioFormat(_THIS);
|
||||
|
||||
/* fully local functions related to the wavebufs / DSP, not the same as the SDL-wide mixer lock */
|
||||
static SDL_INLINE void contextLock(_THIS)
|
||||
{
|
||||
LightLock_Lock(&this->hidden->lock);
|
||||
|
|
@ -48,16 +49,6 @@ static SDL_INLINE void contextUnlock(_THIS)
|
|||
LightLock_Unlock(&this->hidden->lock);
|
||||
}
|
||||
|
||||
static void N3DSAUD_LockAudio(_THIS)
|
||||
{
|
||||
contextLock(this);
|
||||
}
|
||||
|
||||
static void N3DSAUD_UnlockAudio(_THIS)
|
||||
{
|
||||
contextUnlock(this);
|
||||
}
|
||||
|
||||
static void N3DSAUD_DspHook(DSP_HookType hook)
|
||||
{
|
||||
if (hook == DSPHOOK_ONCANCEL) {
|
||||
|
|
@ -98,7 +89,7 @@ static int N3DSAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
float mix[12];
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*this->hidden));
|
||||
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
|
|
@ -136,14 +127,14 @@ static int N3DSAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
this->hidden->mixlen = this->spec.size;
|
||||
this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->spec.size);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
if (!this->hidden->mixbuf) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
|
||||
|
||||
data_vaddr = (Uint8 *)linearAlloc(this->hidden->mixlen * NUM_BUFFERS);
|
||||
if (data_vaddr == NULL) {
|
||||
if (!data_vaddr) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
|
|
@ -195,6 +186,7 @@ static void N3DSAUDIO_PlayDevice(_THIS)
|
|||
{
|
||||
size_t nextbuf;
|
||||
size_t sampleLen;
|
||||
|
||||
contextLock(this);
|
||||
|
||||
nextbuf = this->hidden->nextbuf;
|
||||
|
|
@ -254,7 +246,7 @@ static void N3DSAUDIO_CloseDevice(_THIS)
|
|||
|
||||
static void N3DSAUDIO_ThreadInit(_THIS)
|
||||
{
|
||||
s32 current_priority;
|
||||
s32 current_priority = 0x30;
|
||||
svcGetThreadPriority(¤t_priority, CUR_THREAD_HANDLE);
|
||||
current_priority--;
|
||||
/* 0x18 is reserved for video, 0x30 is the default for main thread */
|
||||
|
|
@ -271,8 +263,6 @@ static SDL_bool N3DSAUDIO_Init(SDL_AudioDriverImpl *impl)
|
|||
impl->GetDeviceBuf = N3DSAUDIO_GetDeviceBuf;
|
||||
impl->CloseDevice = N3DSAUDIO_CloseDevice;
|
||||
impl->ThreadInit = N3DSAUDIO_ThreadInit;
|
||||
impl->LockDevice = N3DSAUD_LockAudio;
|
||||
impl->UnlockDevice = N3DSAUD_UnlockAudio;
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
|
||||
/* Should be possible, but micInit would fail */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
#define NUM_BUFFERS 2 /* -- Don't lower this! */
|
||||
#define NUM_BUFFERS 3 /* -- Minimum 2! */
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_NACL
|
||||
#ifdef SDL_AUDIO_DRIVER_NACL
|
||||
|
||||
#include "SDL_naclaudio.h"
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ static void nacl_audio_callback(void* stream, uint32_t buffer_size, PP_TimeDelta
|
|||
} else {
|
||||
SDL_assert(_this->spec.size == len);
|
||||
|
||||
if (_this->stream == NULL) { /* no conversion necessary. */
|
||||
if (!_this->stream) { /* no conversion necessary. */
|
||||
callback(_this->callbackspec.userdata, stream, len);
|
||||
} else { /* streaming/converting */
|
||||
const int stream_len = _this->callbackspec.size;
|
||||
|
|
@ -103,7 +103,7 @@ static int NACLAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
const PPB_AudioConfig *ppb_audiocfg = PSInterfaceAudioConfig();
|
||||
|
||||
private = (SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*private));
|
||||
if (private == NULL) {
|
||||
if (!private) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_NAS
|
||||
#ifdef SDL_AUDIO_DRIVER_NAS
|
||||
|
||||
/* Allow access to a raw mixing buffer */
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ static void *nas_handle = NULL;
|
|||
static int load_nas_sym(const char *fn, void **addr)
|
||||
{
|
||||
*addr = SDL_LoadFunction(nas_handle, fn);
|
||||
if (*addr == NULL) {
|
||||
if (!*addr) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
|
@ -94,7 +94,7 @@ static int load_nas_syms(void)
|
|||
|
||||
static void UnloadNASLibrary(void)
|
||||
{
|
||||
if (nas_handle != NULL) {
|
||||
if (nas_handle) {
|
||||
SDL_UnloadObject(nas_handle);
|
||||
nas_handle = NULL;
|
||||
}
|
||||
|
|
@ -103,9 +103,9 @@ static void UnloadNASLibrary(void)
|
|||
static int LoadNASLibrary(void)
|
||||
{
|
||||
int retval = 0;
|
||||
if (nas_handle == NULL) {
|
||||
if (!nas_handle) {
|
||||
nas_handle = SDL_LoadObject(nas_library);
|
||||
if (nas_handle == NULL) {
|
||||
if (!nas_handle) {
|
||||
/* Copy error string so we can use it in a new SDL_SetError(). */
|
||||
const char *origerr = SDL_GetError();
|
||||
const size_t len = SDL_strlen(origerr) + 1;
|
||||
|
|
@ -305,7 +305,7 @@ static int NAS_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
|
@ -389,7 +389,7 @@ static int NAS_OpenDevice(_THIS, const char *devname)
|
|||
if (!iscapture) {
|
||||
this->hidden->mixlen = this->spec.size;
|
||||
this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
if (!this->hidden->mixbuf) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
|
||||
|
|
@ -410,7 +410,7 @@ static SDL_bool NAS_Init(SDL_AudioDriverImpl * impl)
|
|||
return SDL_FALSE;
|
||||
} else {
|
||||
AuServer *aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL);
|
||||
if (aud == NULL) {
|
||||
if (!aud) {
|
||||
SDL_SetError("NAS: AuOpenServer() failed (no audio server?)");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_NETBSD
|
||||
#ifdef SDL_AUDIO_DRIVER_NETBSD
|
||||
|
||||
/*
|
||||
* Driver for native NetBSD audio(4).
|
||||
|
|
@ -202,16 +202,16 @@ static int NETBSDAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* We don't care what the devname is...we'll try to open anything. */
|
||||
/* ...but default to first name in the list... */
|
||||
if (devname == NULL) {
|
||||
if (!devname) {
|
||||
devname = SDL_GetAudioDeviceName(0, iscapture);
|
||||
if (devname == NULL) {
|
||||
if (!devname) {
|
||||
return SDL_SetError("No such audio device");
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
|
@ -296,7 +296,7 @@ static int NETBSDAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
/* Allocate mixing buffer */
|
||||
this->hidden->mixlen = this->spec.size;
|
||||
this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->hidden->mixlen);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
if (!this->hidden->mixbuf) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_OPENSLES
|
||||
#ifdef SDL_AUDIO_DRIVER_OPENSLES
|
||||
|
||||
/* For more discussion of low latency audio on Android, see this:
|
||||
https://googlesamples.github.io/android-audio-high-performance/guides/opensl_es.html
|
||||
|
|
@ -320,7 +320,7 @@ static int openslES_CreatePCMRecorder(_THIS)
|
|||
|
||||
/* Create the sound buffers */
|
||||
audiodata->mixbuff = (Uint8 *)SDL_malloc(NUM_BUFFERS * this->spec.size);
|
||||
if (audiodata->mixbuff == NULL) {
|
||||
if (!audiodata->mixbuff) {
|
||||
LOGE("mixbuffer allocate - out of memory");
|
||||
goto failed;
|
||||
}
|
||||
|
|
@ -566,7 +566,7 @@ static int openslES_CreatePCMPlayer(_THIS)
|
|||
|
||||
/* Create the sound buffers */
|
||||
audiodata->mixbuff = (Uint8 *)SDL_malloc(NUM_BUFFERS * this->spec.size);
|
||||
if (audiodata->mixbuff == NULL) {
|
||||
if (!audiodata->mixbuff) {
|
||||
LOGE("mixbuffer allocate - out of memory");
|
||||
goto failed;
|
||||
}
|
||||
|
|
@ -591,7 +591,7 @@ failed:
|
|||
static int openslES_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_OS2
|
||||
#ifdef SDL_AUDIO_DRIVER_OS2
|
||||
|
||||
/* Allow access to a raw mixing buffer */
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ static ULONG _getEnvULong(const char *name, ULONG ulMax, ULONG ulDefault)
|
|||
char* end;
|
||||
char* envval = SDL_getenv(name);
|
||||
|
||||
if (envval == NULL)
|
||||
if (!envval)
|
||||
return ulDefault;
|
||||
|
||||
ulValue = SDL_strtoul(envval, &end, 10);
|
||||
|
|
@ -351,7 +351,7 @@ static void OS2_CloseDevice(_THIS)
|
|||
|
||||
debug_os2("Enter");
|
||||
|
||||
if (pAData == NULL)
|
||||
if (!pAData)
|
||||
return;
|
||||
|
||||
pAData->ulState = 2;
|
||||
|
|
@ -429,7 +429,7 @@ static int OS2_OpenDevice(_THIS, const char *devname)
|
|||
}
|
||||
|
||||
pAData = (SDL_PrivateAudioData *) SDL_calloc(1, sizeof(struct SDL_PrivateAudioData));
|
||||
if (pAData == NULL)
|
||||
if (!pAData)
|
||||
return SDL_OutOfMemory();
|
||||
_this->hidden = pAData;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_PAUDIO
|
||||
#ifdef SDL_AUDIO_DRIVER_PAUDIO
|
||||
|
||||
/* Allow access to a raw mixing buffer */
|
||||
|
||||
|
|
@ -78,11 +78,11 @@ static int OpenUserDefinedDevice(char *path, int maxlen, int flags)
|
|||
if ((audiodev = SDL_getenv("SDL_PATH_DSP")) == NULL) {
|
||||
audiodev = SDL_getenv("AUDIODEV");
|
||||
}
|
||||
if (audiodev == NULL) {
|
||||
if (!audiodev) {
|
||||
return -1;
|
||||
}
|
||||
fd = open(audiodev, flags, 0);
|
||||
if (path != NULL) {
|
||||
if (path) {
|
||||
SDL_strlcpy(path, audiodev, maxlen);
|
||||
path[maxlen - 1] = '\0';
|
||||
}
|
||||
|
|
@ -110,7 +110,7 @@ static int OpenAudioPath(char *path, int maxlen, int flags, int classic)
|
|||
if (stat(audiopath, &sb) == 0) {
|
||||
fd = open(audiopath, flags, 0);
|
||||
if (fd >= 0) {
|
||||
if (path != NULL) {
|
||||
if (path) {
|
||||
SDL_strlcpy(path, audiopath, maxlen);
|
||||
}
|
||||
return fd;
|
||||
|
|
@ -232,7 +232,7 @@ static int PAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
|
@ -403,7 +403,7 @@ static int PAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
/* Allocate mixing buffer */
|
||||
this->hidden->mixlen = this->spec.size;
|
||||
this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
if (!this->hidden->mixbuf) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
|
||||
|
|
@ -445,7 +445,7 @@ static int PAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
}
|
||||
|
||||
/* Check to see if we need to use SDL_IOReady() workaround */
|
||||
if (workaround != NULL) {
|
||||
if (workaround) {
|
||||
this->hidden->frame_ticks = (float) (this->spec.samples * 1000) /
|
||||
this->spec.freq;
|
||||
this->hidden->next_frame = SDL_GetTicks() + this->hidden->frame_ticks;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
#include "../../SDL_internal.h"
|
||||
#include "SDL_hints.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_PIPEWIRE
|
||||
#ifdef SDL_AUDIO_DRIVER_PIPEWIRE
|
||||
|
||||
#include "SDL_audio.h"
|
||||
#include "SDL_loadso.h"
|
||||
|
|
@ -129,7 +129,7 @@ static void *pipewire_handle = NULL;
|
|||
static int pipewire_dlsym(const char *fn, void **addr)
|
||||
{
|
||||
*addr = SDL_LoadFunction(pipewire_handle, fn);
|
||||
if (*addr == NULL) {
|
||||
if (!*addr) {
|
||||
/* Don't call SDL_SetError(): SDL_LoadFunction already did. */
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -142,13 +142,13 @@ static int pipewire_dlsym(const char *fn, void **addr)
|
|||
return -1; \
|
||||
}
|
||||
|
||||
static int load_pipewire_library()
|
||||
static int load_pipewire_library(void)
|
||||
{
|
||||
pipewire_handle = SDL_LoadObject(pipewire_library);
|
||||
return pipewire_handle != NULL ? 0 : -1;
|
||||
return pipewire_handle ? 0 : -1;
|
||||
}
|
||||
|
||||
static void unload_pipewire_library()
|
||||
static void unload_pipewire_library(void)
|
||||
{
|
||||
if (pipewire_handle) {
|
||||
SDL_UnloadObject(pipewire_handle);
|
||||
|
|
@ -160,18 +160,18 @@ static void unload_pipewire_library()
|
|||
|
||||
#define SDL_PIPEWIRE_SYM(x) PIPEWIRE_##x = x
|
||||
|
||||
static int load_pipewire_library()
|
||||
static int load_pipewire_library(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void unload_pipewire_library()
|
||||
static void unload_pipewire_library(void)
|
||||
{ /* Nothing to do */
|
||||
}
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC */
|
||||
|
||||
static int load_pipewire_syms()
|
||||
static int load_pipewire_syms(void)
|
||||
{
|
||||
SDL_PIPEWIRE_SYM(pw_get_library_version);
|
||||
SDL_PIPEWIRE_SYM(pw_init);
|
||||
|
|
@ -212,7 +212,7 @@ SDL_FORCE_INLINE SDL_bool pipewire_version_at_least(int major, int minor, int pa
|
|||
(pipewire_version_major > major || pipewire_version_minor > minor || pipewire_version_patch >= patch);
|
||||
}
|
||||
|
||||
static int init_pipewire_library()
|
||||
static int init_pipewire_library(void)
|
||||
{
|
||||
if (!load_pipewire_library()) {
|
||||
if (!load_pipewire_syms()) {
|
||||
|
|
@ -234,7 +234,7 @@ static int init_pipewire_library()
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void deinit_pipewire_library()
|
||||
static void deinit_pipewire_library(void)
|
||||
{
|
||||
PIPEWIRE_pw_deinit();
|
||||
unload_pipewire_library();
|
||||
|
|
@ -340,17 +340,17 @@ static void io_list_remove(Uint32 id)
|
|||
}
|
||||
}
|
||||
|
||||
static void io_list_sort()
|
||||
static void io_list_sort(void)
|
||||
{
|
||||
struct io_node *default_sink = NULL, *default_source = NULL;
|
||||
struct io_node *n, *temp;
|
||||
|
||||
/* Find and move the default nodes to the beginning of the list */
|
||||
spa_list_for_each_safe (n, temp, &hotplug_io_list, link) {
|
||||
if (pipewire_default_sink_id != NULL && SDL_strcmp(n->path, pipewire_default_sink_id) == 0) {
|
||||
if (pipewire_default_sink_id && SDL_strcmp(n->path, pipewire_default_sink_id) == 0) {
|
||||
default_sink = n;
|
||||
spa_list_remove(&n->link);
|
||||
} else if (pipewire_default_source_id != NULL && SDL_strcmp(n->path, pipewire_default_source_id) == 0) {
|
||||
} else if (pipewire_default_source_id && SDL_strcmp(n->path, pipewire_default_source_id) == 0) {
|
||||
default_source = n;
|
||||
spa_list_remove(&n->link);
|
||||
}
|
||||
|
|
@ -365,7 +365,7 @@ static void io_list_sort()
|
|||
}
|
||||
}
|
||||
|
||||
static void io_list_clear()
|
||||
static void io_list_clear(void)
|
||||
{
|
||||
struct io_node *n, *temp;
|
||||
|
||||
|
|
@ -399,7 +399,7 @@ static struct io_node *io_list_get_by_path(char *path)
|
|||
|
||||
static void node_object_destroy(struct node_object *node)
|
||||
{
|
||||
SDL_assert(node);
|
||||
SDL_assert(node != NULL);
|
||||
|
||||
spa_list_remove(&node->link);
|
||||
spa_hook_remove(&node->node_listener);
|
||||
|
|
@ -411,7 +411,7 @@ static void node_object_destroy(struct node_object *node)
|
|||
/* The pending node list */
|
||||
static void pending_list_add(struct node_object *node)
|
||||
{
|
||||
SDL_assert(node);
|
||||
SDL_assert(node != NULL);
|
||||
spa_list_append(&hotplug_pending_list, &node->link);
|
||||
}
|
||||
|
||||
|
|
@ -426,7 +426,7 @@ static void pending_list_remove(Uint32 id)
|
|||
}
|
||||
}
|
||||
|
||||
static void pending_list_clear()
|
||||
static void pending_list_clear(void)
|
||||
{
|
||||
struct node_object *node, *temp;
|
||||
|
||||
|
|
@ -442,7 +442,7 @@ static void *node_object_new(Uint32 id, const char *type, Uint32 version, const
|
|||
|
||||
/* Create the proxy object */
|
||||
proxy = pw_registry_bind(hotplug_registry, id, type, version, sizeof(struct node_object));
|
||||
if (proxy == NULL) {
|
||||
if (!proxy) {
|
||||
SDL_SetError("Pipewire: Failed to create proxy object (%i)", errno);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -590,7 +590,7 @@ static void node_event_info(void *object, const struct pw_node_info *info)
|
|||
|
||||
/* Need to parse the parameters to get the sample rate */
|
||||
for (i = 0; i < info->n_params; ++i) {
|
||||
pw_node_enum_params(node->proxy, 0, info->params[i].id, 0, 0, NULL);
|
||||
pw_node_enum_params((struct pw_node*)node->proxy, 0, info->params[i].id, 0, 0, NULL);
|
||||
}
|
||||
|
||||
hotplug_core_sync(node);
|
||||
|
|
@ -648,15 +648,15 @@ static int metadata_property(void *object, Uint32 subject, const char *key, cons
|
|||
{
|
||||
struct node_object *node = object;
|
||||
|
||||
if (subject == PW_ID_CORE && key != NULL && value != NULL) {
|
||||
if (subject == PW_ID_CORE && key && value) {
|
||||
if (!SDL_strcmp(key, "default.audio.sink")) {
|
||||
if (pipewire_default_sink_id != NULL) {
|
||||
if (pipewire_default_sink_id) {
|
||||
SDL_free(pipewire_default_sink_id);
|
||||
}
|
||||
pipewire_default_sink_id = get_name_from_json(value);
|
||||
node->persist = SDL_TRUE;
|
||||
} else if (!SDL_strcmp(key, "default.audio.source")) {
|
||||
if (pipewire_default_source_id != NULL) {
|
||||
if (pipewire_default_source_id) {
|
||||
SDL_free(pipewire_default_source_id);
|
||||
}
|
||||
pipewire_default_source_id = get_name_from_json(value);
|
||||
|
|
@ -701,7 +701,7 @@ static void registry_event_global_callback(void *object, uint32_t id, uint32_t p
|
|||
|
||||
if (node_desc && node_path) {
|
||||
node = node_object_new(id, type, version, &interface_node_events, &interface_core_events);
|
||||
if (node == NULL) {
|
||||
if (!node) {
|
||||
SDL_SetError("Pipewire: Failed to allocate interface node");
|
||||
return;
|
||||
}
|
||||
|
|
@ -710,7 +710,7 @@ static void registry_event_global_callback(void *object, uint32_t id, uint32_t p
|
|||
desc_buffer_len = SDL_strlen(node_desc) + 1;
|
||||
path_buffer_len = SDL_strlen(node_path) + 1;
|
||||
node->userdata = io = SDL_calloc(1, sizeof(struct io_node) + desc_buffer_len + path_buffer_len);
|
||||
if (io == NULL) {
|
||||
if (!io) {
|
||||
node_object_destroy(node);
|
||||
SDL_OutOfMemory();
|
||||
return;
|
||||
|
|
@ -731,7 +731,7 @@ static void registry_event_global_callback(void *object, uint32_t id, uint32_t p
|
|||
}
|
||||
} else if (!SDL_strcmp(type, PW_TYPE_INTERFACE_Metadata)) {
|
||||
node = node_object_new(id, type, version, &metadata_node_events, &metadata_core_events);
|
||||
if (node == NULL) {
|
||||
if (!node) {
|
||||
SDL_SetError("Pipewire: Failed to allocate metadata node");
|
||||
return;
|
||||
}
|
||||
|
|
@ -751,7 +751,7 @@ static const struct pw_registry_events registry_events = { PW_VERSION_REGISTRY_E
|
|||
.global_remove = registry_event_remove_callback };
|
||||
|
||||
/* The hotplug thread */
|
||||
static int hotplug_loop_init()
|
||||
static int hotplug_loop_init(void)
|
||||
{
|
||||
int res;
|
||||
|
||||
|
|
@ -759,22 +759,22 @@ static int hotplug_loop_init()
|
|||
spa_list_init(&hotplug_io_list);
|
||||
|
||||
hotplug_loop = PIPEWIRE_pw_thread_loop_new("SDLAudioHotplug", NULL);
|
||||
if (hotplug_loop == NULL) {
|
||||
if (!hotplug_loop) {
|
||||
return SDL_SetError("Pipewire: Failed to create hotplug detection loop (%i)", errno);
|
||||
}
|
||||
|
||||
hotplug_context = PIPEWIRE_pw_context_new(PIPEWIRE_pw_thread_loop_get_loop(hotplug_loop), NULL, 0);
|
||||
if (hotplug_context == NULL) {
|
||||
if (!hotplug_context) {
|
||||
return SDL_SetError("Pipewire: Failed to create hotplug detection context (%i)", errno);
|
||||
}
|
||||
|
||||
hotplug_core = PIPEWIRE_pw_context_connect(hotplug_context, NULL, 0);
|
||||
if (hotplug_core == NULL) {
|
||||
if (!hotplug_core) {
|
||||
return SDL_SetError("Pipewire: Failed to connect hotplug detection context (%i)", errno);
|
||||
}
|
||||
|
||||
hotplug_registry = pw_core_get_registry(hotplug_core, PW_VERSION_REGISTRY, 0);
|
||||
if (hotplug_registry == NULL) {
|
||||
if (!hotplug_registry) {
|
||||
return SDL_SetError("Pipewire: Failed to acquire hotplug detection registry (%i)", errno);
|
||||
}
|
||||
|
||||
|
|
@ -794,7 +794,7 @@ static int hotplug_loop_init()
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void hotplug_loop_destroy()
|
||||
static void hotplug_loop_destroy(void)
|
||||
{
|
||||
if (hotplug_loop) {
|
||||
PIPEWIRE_pw_thread_loop_stop(hotplug_loop);
|
||||
|
|
@ -806,11 +806,11 @@ static void hotplug_loop_destroy()
|
|||
hotplug_init_complete = SDL_FALSE;
|
||||
hotplug_events_enabled = SDL_FALSE;
|
||||
|
||||
if (pipewire_default_sink_id != NULL) {
|
||||
if (pipewire_default_sink_id) {
|
||||
SDL_free(pipewire_default_sink_id);
|
||||
pipewire_default_sink_id = NULL;
|
||||
}
|
||||
if (pipewire_default_source_id != NULL) {
|
||||
if (pipewire_default_source_id) {
|
||||
SDL_free(pipewire_default_source_id);
|
||||
pipewire_default_source_id = NULL;
|
||||
}
|
||||
|
|
@ -836,7 +836,7 @@ static void hotplug_loop_destroy()
|
|||
}
|
||||
}
|
||||
|
||||
static void PIPEWIRE_DetectDevices()
|
||||
static void PIPEWIRE_DetectDevices(void)
|
||||
{
|
||||
struct io_node *io;
|
||||
|
||||
|
|
@ -961,7 +961,7 @@ static void output_callback(void *data)
|
|||
|
||||
/* See if a buffer is available */
|
||||
pw_buf = PIPEWIRE_pw_stream_dequeue_buffer(stream);
|
||||
if (pw_buf == NULL) {
|
||||
if (!pw_buf) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1025,13 +1025,13 @@ static void input_callback(void *data)
|
|||
}
|
||||
|
||||
pw_buf = PIPEWIRE_pw_stream_dequeue_buffer(stream);
|
||||
if (pw_buf == NULL) {
|
||||
if (!pw_buf) {
|
||||
return;
|
||||
}
|
||||
|
||||
spa_buf = pw_buf->buffer;
|
||||
(src = (Uint8 *)spa_buf->datas[0].data);
|
||||
if (src == NULL) {
|
||||
if (!src) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1079,7 +1079,7 @@ static void stream_add_buffer_callback(void *data, struct pw_buffer *buffer)
|
|||
this->spec.samples = buffer->buffer->datas[0].maxsize / this->hidden->stride;
|
||||
this->spec.size = buffer->buffer->datas[0].maxsize;
|
||||
}
|
||||
} else if (this->hidden->buffer == NULL) {
|
||||
} else if (!this->hidden->buffer) {
|
||||
/*
|
||||
* The latency of source nodes can change, so buffering is always required.
|
||||
*
|
||||
|
|
@ -1137,7 +1137,7 @@ static int PIPEWIRE_OpenDevice(_THIS, const char *devname)
|
|||
struct SDL_PrivateAudioData *priv;
|
||||
struct pw_properties *props;
|
||||
const char *app_name, *stream_name, *stream_role, *error;
|
||||
Uint32 node_id = this->handle == NULL ? PW_ID_ANY : PW_HANDLE_TO_ID(this->handle);
|
||||
Uint32 node_id = !this->handle ? PW_ID_ANY : PW_HANDLE_TO_ID(this->handle);
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
int res;
|
||||
|
||||
|
|
@ -1146,15 +1146,15 @@ static int PIPEWIRE_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* Get the hints for the application name, stream name and role */
|
||||
app_name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME);
|
||||
if (app_name == NULL || *app_name == '\0') {
|
||||
if (!app_name || *app_name == '\0') {
|
||||
app_name = SDL_GetHint(SDL_HINT_APP_NAME);
|
||||
if (app_name == NULL || *app_name == '\0') {
|
||||
if (!app_name || *app_name == '\0') {
|
||||
app_name = "SDL Application";
|
||||
}
|
||||
}
|
||||
|
||||
stream_name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_NAME);
|
||||
if (stream_name == NULL || *stream_name == '\0') {
|
||||
if (!stream_name || *stream_name == '\0') {
|
||||
stream_name = "Audio Stream";
|
||||
}
|
||||
|
||||
|
|
@ -1163,20 +1163,20 @@ static int PIPEWIRE_OpenDevice(_THIS, const char *devname)
|
|||
* but 'Game' seems more appropriate for the majority of SDL applications.
|
||||
*/
|
||||
stream_role = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_ROLE);
|
||||
if (stream_role == NULL || *stream_role == '\0') {
|
||||
if (!stream_role || *stream_role == '\0') {
|
||||
stream_role = "Game";
|
||||
}
|
||||
|
||||
/* Initialize the Pipewire stream info from the SDL audio spec */
|
||||
initialize_spa_info(&this->spec, &spa_info);
|
||||
params = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &spa_info);
|
||||
if (params == NULL) {
|
||||
if (!params) {
|
||||
return SDL_SetError("Pipewire: Failed to set audio format parameters");
|
||||
}
|
||||
|
||||
priv = SDL_calloc(1, sizeof(struct SDL_PrivateAudioData));
|
||||
this->hidden = priv;
|
||||
if (priv == NULL) {
|
||||
if (!priv) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
|
|
@ -1190,23 +1190,23 @@ static int PIPEWIRE_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
(void)SDL_snprintf(thread_name, sizeof(thread_name), "SDLAudio%c%ld", (iscapture) ? 'C' : 'P', (long)this->handle);
|
||||
priv->loop = PIPEWIRE_pw_thread_loop_new(thread_name, NULL);
|
||||
if (priv->loop == NULL) {
|
||||
if (!priv->loop) {
|
||||
return SDL_SetError("Pipewire: Failed to create stream loop (%i)", errno);
|
||||
}
|
||||
|
||||
/* Load the realtime module so Pipewire can set the loop thread to the appropriate priority. */
|
||||
props = PIPEWIRE_pw_properties_new(PW_KEY_CONFIG_NAME, "client-rt.conf", NULL);
|
||||
if (props == NULL) {
|
||||
if (!props) {
|
||||
return SDL_SetError("Pipewire: Failed to create stream context properties (%i)", errno);
|
||||
}
|
||||
|
||||
priv->context = PIPEWIRE_pw_context_new(PIPEWIRE_pw_thread_loop_get_loop(priv->loop), props, 0);
|
||||
if (priv->context == NULL) {
|
||||
if (!priv->context) {
|
||||
return SDL_SetError("Pipewire: Failed to create stream context (%i)", errno);
|
||||
}
|
||||
|
||||
props = PIPEWIRE_pw_properties_new(NULL, NULL);
|
||||
if (props == NULL) {
|
||||
if (!props) {
|
||||
return SDL_SetError("Pipewire: Failed to create stream properties (%i)", errno);
|
||||
}
|
||||
|
||||
|
|
@ -1232,7 +1232,7 @@ static int PIPEWIRE_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
PIPEWIRE_pw_thread_loop_lock(hotplug_loop);
|
||||
node = io_list_get_by_id(node_id);
|
||||
if (node != NULL) {
|
||||
if (node) {
|
||||
PIPEWIRE_pw_properties_set(props, PW_KEY_TARGET_OBJECT, node->path);
|
||||
}
|
||||
PIPEWIRE_pw_thread_loop_unlock(hotplug_loop);
|
||||
|
|
@ -1244,7 +1244,7 @@ static int PIPEWIRE_OpenDevice(_THIS, const char *devname)
|
|||
/* Create the new stream */
|
||||
priv->stream = PIPEWIRE_pw_stream_new_simple(PIPEWIRE_pw_thread_loop_get_loop(priv->loop), stream_name, props,
|
||||
iscapture ? &stream_input_events : &stream_output_events, this);
|
||||
if (priv->stream == NULL) {
|
||||
if (!priv->stream) {
|
||||
return SDL_SetError("Pipewire: Failed to create stream (%i)", errno);
|
||||
}
|
||||
|
||||
|
|
@ -1272,7 +1272,7 @@ static int PIPEWIRE_OpenDevice(_THIS, const char *devname)
|
|||
}
|
||||
|
||||
/* If this is a capture stream, make sure the intermediate buffer was successfully allocated. */
|
||||
if (iscapture && priv->buffer == NULL) {
|
||||
if (iscapture && !priv->buffer) {
|
||||
return SDL_SetError("Pipewire: Failed to allocate source buffer");
|
||||
}
|
||||
|
||||
|
|
@ -1313,13 +1313,13 @@ static int PIPEWIRE_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int is
|
|||
PIPEWIRE_pw_thread_loop_lock(hotplug_loop);
|
||||
|
||||
if (iscapture) {
|
||||
if (pipewire_default_source_id == NULL) {
|
||||
if (!pipewire_default_source_id) {
|
||||
ret = SDL_SetError("PipeWire could not find a default source");
|
||||
goto failed;
|
||||
}
|
||||
target = pipewire_default_source_id;
|
||||
} else {
|
||||
if (pipewire_default_sink_id == NULL) {
|
||||
if (!pipewire_default_sink_id) {
|
||||
ret = SDL_SetError("PipeWire could not find a default sink");
|
||||
goto failed;
|
||||
}
|
||||
|
|
@ -1327,12 +1327,12 @@ static int PIPEWIRE_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int is
|
|||
}
|
||||
|
||||
node = io_list_get_by_path(target);
|
||||
if (node == NULL) {
|
||||
if (!node) {
|
||||
ret = SDL_SetError("PipeWire device list is out of sync with defaults");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (name != NULL) {
|
||||
if (name) {
|
||||
*name = SDL_strdup(node->name);
|
||||
}
|
||||
SDL_copyp(spec, &node->spec);
|
||||
|
|
@ -1342,7 +1342,7 @@ failed:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void PIPEWIRE_Deinitialize()
|
||||
static void PIPEWIRE_Deinitialize(void)
|
||||
{
|
||||
if (pipewire_initialized) {
|
||||
hotplug_loop_destroy();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -42,7 +42,7 @@ static int PS2AUDIO_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
|
@ -90,7 +90,7 @@ static int PS2AUDIO_OpenDevice(_THIS, const char *devname)
|
|||
64, so spec->size should be a multiple of 64 as well. */
|
||||
mixlen = this->spec.size * NUM_BUFFERS;
|
||||
this->hidden->rawbuf = (Uint8 *)memalign(64, mixlen);
|
||||
if (this->hidden->rawbuf == NULL) {
|
||||
if (!this->hidden->rawbuf) {
|
||||
return SDL_SetError("Couldn't allocate mixing buffer");
|
||||
}
|
||||
|
||||
|
|
@ -129,7 +129,7 @@ static void PS2AUDIO_CloseDevice(_THIS)
|
|||
this->hidden->channel = -1;
|
||||
}
|
||||
|
||||
if (this->hidden->rawbuf != NULL) {
|
||||
if (this->hidden->rawbuf) {
|
||||
free(this->hidden->rawbuf);
|
||||
this->hidden->rawbuf = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_PSP
|
||||
#ifdef SDL_AUDIO_DRIVER_PSP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
|
@ -52,7 +52,7 @@ static int PSPAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
|
@ -108,7 +108,7 @@ static int PSPAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
64, so spec->size should be a multiple of 64 as well. */
|
||||
mixlen = this->spec.size * NUM_BUFFERS;
|
||||
this->hidden->rawbuf = (Uint8 *)memalign(64, mixlen);
|
||||
if (this->hidden->rawbuf == NULL) {
|
||||
if (!this->hidden->rawbuf) {
|
||||
return SDL_SetError("Couldn't allocate mixing buffer");
|
||||
}
|
||||
|
||||
|
|
@ -156,7 +156,7 @@ static void PSPAUDIO_CloseDevice(_THIS)
|
|||
this->hidden->channel = -1;
|
||||
}
|
||||
|
||||
if (this->hidden->rawbuf != NULL) {
|
||||
if (this->hidden->rawbuf) {
|
||||
free(this->hidden->rawbuf);
|
||||
this->hidden->rawbuf = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -19,16 +19,10 @@
|
|||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/*
|
||||
The PulseAudio target for SDL 1.3 is based on the 1.3 arts target, with
|
||||
the appropriate parts replaced with the 1.2 PulseAudio target code. This
|
||||
was the cleanest way to move it to 1.3. The 1.2 target was written by
|
||||
Stéphan Kochen: stephan .a.t. kochen.nl
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
#include "SDL_hints.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_PULSEAUDIO
|
||||
#ifdef SDL_AUDIO_DRIVER_PULSEAUDIO
|
||||
|
||||
/* Allow access to a raw mixing buffer */
|
||||
|
||||
|
|
@ -37,7 +31,6 @@
|
|||
#endif
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_audio.h"
|
||||
|
|
@ -49,29 +42,34 @@
|
|||
/* should we include monitors in the device list? Set at SDL_Init time */
|
||||
static SDL_bool include_monitors = SDL_FALSE;
|
||||
|
||||
#if (PA_API_VERSION < 12)
|
||||
/** Return non-zero if the passed state is one of the connected states */
|
||||
static SDL_INLINE int PA_CONTEXT_IS_GOOD(pa_context_state_t x)
|
||||
{
|
||||
return x == PA_CONTEXT_CONNECTING || x == PA_CONTEXT_AUTHORIZING || x == PA_CONTEXT_SETTING_NAME || x == PA_CONTEXT_READY;
|
||||
}
|
||||
/** Return non-zero if the passed state is one of the connected states */
|
||||
static SDL_INLINE int PA_STREAM_IS_GOOD(pa_stream_state_t x)
|
||||
{
|
||||
return x == PA_STREAM_CREATING || x == PA_STREAM_READY;
|
||||
}
|
||||
#endif /* pulseaudio <= 0.9.10 */
|
||||
static pa_threaded_mainloop *pulseaudio_threaded_mainloop = NULL;
|
||||
static pa_context *pulseaudio_context = NULL;
|
||||
static SDL_Thread *pulseaudio_hotplug_thread = NULL;
|
||||
static SDL_atomic_t pulseaudio_hotplug_thread_active;
|
||||
|
||||
/* These are the OS identifiers (i.e. ALSA strings)... */
|
||||
static char *default_sink_path = NULL;
|
||||
static char *default_source_path = NULL;
|
||||
/* ... and these are the descriptions we use in GetDefaultAudioInfo. */
|
||||
static char *default_sink_name = NULL;
|
||||
static char *default_source_name = NULL;
|
||||
|
||||
|
||||
static const char *(*PULSEAUDIO_pa_get_library_version)(void);
|
||||
static pa_channel_map *(*PULSEAUDIO_pa_channel_map_init_auto)(
|
||||
pa_channel_map *, unsigned, pa_channel_map_def_t);
|
||||
static const char *(*PULSEAUDIO_pa_strerror)(int);
|
||||
static pa_mainloop *(*PULSEAUDIO_pa_mainloop_new)(void);
|
||||
static pa_mainloop_api *(*PULSEAUDIO_pa_mainloop_get_api)(pa_mainloop *);
|
||||
static int (*PULSEAUDIO_pa_mainloop_iterate)(pa_mainloop *, int, int *);
|
||||
static int (*PULSEAUDIO_pa_mainloop_run)(pa_mainloop *, int *);
|
||||
static void (*PULSEAUDIO_pa_mainloop_quit)(pa_mainloop *, int);
|
||||
static void (*PULSEAUDIO_pa_mainloop_free)(pa_mainloop *);
|
||||
|
||||
static pa_threaded_mainloop *(*PULSEAUDIO_pa_threaded_mainloop_new)(void);
|
||||
static void (*PULSEAUDIO_pa_threaded_mainloop_set_name)(pa_threaded_mainloop *, const char *);
|
||||
static pa_mainloop_api *(*PULSEAUDIO_pa_threaded_mainloop_get_api)(pa_threaded_mainloop *);
|
||||
static int (*PULSEAUDIO_pa_threaded_mainloop_start)(pa_threaded_mainloop *);
|
||||
static void (*PULSEAUDIO_pa_threaded_mainloop_stop)(pa_threaded_mainloop *);
|
||||
static void (*PULSEAUDIO_pa_threaded_mainloop_lock)(pa_threaded_mainloop *);
|
||||
static void (*PULSEAUDIO_pa_threaded_mainloop_unlock)(pa_threaded_mainloop *);
|
||||
static void (*PULSEAUDIO_pa_threaded_mainloop_wait)(pa_threaded_mainloop *);
|
||||
static void (*PULSEAUDIO_pa_threaded_mainloop_signal)(pa_threaded_mainloop *, int);
|
||||
static void (*PULSEAUDIO_pa_threaded_mainloop_free)(pa_threaded_mainloop *);
|
||||
|
||||
static pa_operation_state_t (*PULSEAUDIO_pa_operation_get_state)(
|
||||
const pa_operation *);
|
||||
|
|
@ -80,6 +78,7 @@ static void (*PULSEAUDIO_pa_operation_unref)(pa_operation *);
|
|||
|
||||
static pa_context *(*PULSEAUDIO_pa_context_new)(pa_mainloop_api *,
|
||||
const char *);
|
||||
static void (*PULSEAUDIO_pa_context_set_state_callback)(pa_context *, pa_context_notify_cb_t, void *);
|
||||
static int (*PULSEAUDIO_pa_context_connect)(pa_context *, const char *,
|
||||
pa_context_flags_t, const pa_spawn_api *);
|
||||
static pa_operation *(*PULSEAUDIO_pa_context_get_sink_info_list)(pa_context *, pa_sink_info_cb_t, void *);
|
||||
|
|
@ -94,6 +93,7 @@ static void (*PULSEAUDIO_pa_context_unref)(pa_context *);
|
|||
|
||||
static pa_stream *(*PULSEAUDIO_pa_stream_new)(pa_context *, const char *,
|
||||
const pa_sample_spec *, const pa_channel_map *);
|
||||
static void (*PULSEAUDIO_pa_stream_set_state_callback)(pa_stream *, pa_stream_notify_cb_t, void *);
|
||||
static int (*PULSEAUDIO_pa_stream_connect_playback)(pa_stream *, const char *,
|
||||
const pa_buffer_attr *, pa_stream_flags_t, const pa_cvolume *, pa_stream *);
|
||||
static int (*PULSEAUDIO_pa_stream_connect_record)(pa_stream *, const char *,
|
||||
|
|
@ -112,6 +112,7 @@ static pa_operation *(*PULSEAUDIO_pa_stream_flush)(pa_stream *,
|
|||
static int (*PULSEAUDIO_pa_stream_disconnect)(pa_stream *);
|
||||
static void (*PULSEAUDIO_pa_stream_unref)(pa_stream *);
|
||||
static void (*PULSEAUDIO_pa_stream_set_write_callback)(pa_stream *, pa_stream_request_cb_t, void *);
|
||||
static void (*PULSEAUDIO_pa_stream_set_read_callback)(pa_stream *, pa_stream_request_cb_t, void *);
|
||||
static pa_operation *(*PULSEAUDIO_pa_context_get_server_info)(pa_context *, pa_server_info_cb_t, void *);
|
||||
|
||||
static int load_pulseaudio_syms(void);
|
||||
|
|
@ -124,7 +125,7 @@ static void *pulseaudio_handle = NULL;
|
|||
static int load_pulseaudio_sym(const char *fn, void **addr)
|
||||
{
|
||||
*addr = SDL_LoadFunction(pulseaudio_handle, fn);
|
||||
if (*addr == NULL) {
|
||||
if (!*addr) {
|
||||
/* Don't call SDL_SetError(): SDL_LoadFunction already did. */
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -139,7 +140,7 @@ static int load_pulseaudio_sym(const char *fn, void **addr)
|
|||
|
||||
static void UnloadPulseAudioLibrary(void)
|
||||
{
|
||||
if (pulseaudio_handle != NULL) {
|
||||
if (pulseaudio_handle) {
|
||||
SDL_UnloadObject(pulseaudio_handle);
|
||||
pulseaudio_handle = NULL;
|
||||
}
|
||||
|
|
@ -148,9 +149,9 @@ static void UnloadPulseAudioLibrary(void)
|
|||
static int LoadPulseAudioLibrary(void)
|
||||
{
|
||||
int retval = 0;
|
||||
if (pulseaudio_handle == NULL) {
|
||||
if (!pulseaudio_handle) {
|
||||
pulseaudio_handle = SDL_LoadObject(pulseaudio_library);
|
||||
if (pulseaudio_handle == NULL) {
|
||||
if (!pulseaudio_handle) {
|
||||
retval = -1;
|
||||
/* Don't call SDL_SetError(): SDL_LoadObject already did. */
|
||||
} else {
|
||||
|
|
@ -182,16 +183,20 @@ static int LoadPulseAudioLibrary(void)
|
|||
static int load_pulseaudio_syms(void)
|
||||
{
|
||||
SDL_PULSEAUDIO_SYM(pa_get_library_version);
|
||||
SDL_PULSEAUDIO_SYM(pa_mainloop_new);
|
||||
SDL_PULSEAUDIO_SYM(pa_mainloop_get_api);
|
||||
SDL_PULSEAUDIO_SYM(pa_mainloop_iterate);
|
||||
SDL_PULSEAUDIO_SYM(pa_mainloop_run);
|
||||
SDL_PULSEAUDIO_SYM(pa_mainloop_quit);
|
||||
SDL_PULSEAUDIO_SYM(pa_mainloop_free);
|
||||
SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_new);
|
||||
SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_get_api);
|
||||
SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_start);
|
||||
SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_stop);
|
||||
SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_lock);
|
||||
SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_unlock);
|
||||
SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_wait);
|
||||
SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_signal);
|
||||
SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_free);
|
||||
SDL_PULSEAUDIO_SYM(pa_operation_get_state);
|
||||
SDL_PULSEAUDIO_SYM(pa_operation_cancel);
|
||||
SDL_PULSEAUDIO_SYM(pa_operation_unref);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_new);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_set_state_callback);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_connect);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_get_sink_info_list);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_get_source_info_list);
|
||||
|
|
@ -203,6 +208,7 @@ static int load_pulseaudio_syms(void)
|
|||
SDL_PULSEAUDIO_SYM(pa_context_disconnect);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_unref);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_new);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_set_state_callback);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_connect_playback);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_connect_record);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_get_state);
|
||||
|
|
@ -218,7 +224,18 @@ static int load_pulseaudio_syms(void)
|
|||
SDL_PULSEAUDIO_SYM(pa_channel_map_init_auto);
|
||||
SDL_PULSEAUDIO_SYM(pa_strerror);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_set_write_callback);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_set_read_callback);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_get_server_info);
|
||||
|
||||
/* optional */
|
||||
#ifdef SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC
|
||||
load_pulseaudio_sym("pa_threaded_mainloop_set_name", (void **)(char *)&PULSEAUDIO_pa_threaded_mainloop_set_name);
|
||||
#elif (PA_PROTOCOL_VERSION >= 29)
|
||||
PULSEAUDIO_pa_threaded_mainloop_set_name = pa_threaded_mainloop_set_name;
|
||||
#else
|
||||
PULSEAUDIO_pa_threaded_mainloop_set_name = NULL;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +257,7 @@ static const char *getAppName(void)
|
|||
} else {
|
||||
const char *verstr = PULSEAUDIO_pa_get_library_version();
|
||||
retval = "SDL Application"; /* the "oh well" default. */
|
||||
if (verstr != NULL) {
|
||||
if (verstr) {
|
||||
int maj, min, patch;
|
||||
if (SDL_sscanf(verstr, "%d.%d.%d", &maj, &min, &patch) == 3) {
|
||||
if (squashVersion(maj, min, patch) >= squashVersion(0, 9, 15)) {
|
||||
|
|
@ -252,87 +269,103 @@ static const char *getAppName(void)
|
|||
return retval;
|
||||
}
|
||||
|
||||
static void WaitForPulseOperation(pa_mainloop *mainloop, pa_operation *o)
|
||||
/* This function assume you are holding `mainloop`'s lock and that `o` has a callback that will signal pulseaudio_threaded_mainloop.
|
||||
The caller may optionally call pa_threaded_mainloop_accept() if the signal is blocking. The operation is
|
||||
unref'd in here, assuming you did the work in the callback and just want to know it's done, though. */
|
||||
static void WaitForPulseOperation(pa_operation *o)
|
||||
{
|
||||
/* This checks for NO errors currently. Either fix that, check results elsewhere, or do things you don't care about. */
|
||||
if (mainloop && o) {
|
||||
SDL_bool okay = SDL_TRUE;
|
||||
while (okay && (PULSEAUDIO_pa_operation_get_state(o) == PA_OPERATION_RUNNING)) {
|
||||
okay = (PULSEAUDIO_pa_mainloop_iterate(mainloop, 1, NULL) >= 0);
|
||||
SDL_assert(pulseaudio_threaded_mainloop != NULL);
|
||||
if (o) {
|
||||
while (PULSEAUDIO_pa_operation_get_state(o) == PA_OPERATION_RUNNING) {
|
||||
PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop); /* this releases the lock and blocks on an internal condition variable. */
|
||||
}
|
||||
PULSEAUDIO_pa_operation_unref(o);
|
||||
}
|
||||
}
|
||||
|
||||
static void DisconnectFromPulseServer(pa_mainloop *mainloop, pa_context *context)
|
||||
static void DisconnectFromPulseServer(void)
|
||||
{
|
||||
if (context) {
|
||||
PULSEAUDIO_pa_context_disconnect(context);
|
||||
PULSEAUDIO_pa_context_unref(context);
|
||||
if (pulseaudio_threaded_mainloop) {
|
||||
PULSEAUDIO_pa_threaded_mainloop_stop(pulseaudio_threaded_mainloop);
|
||||
}
|
||||
if (mainloop != NULL) {
|
||||
PULSEAUDIO_pa_mainloop_free(mainloop);
|
||||
if (pulseaudio_context) {
|
||||
PULSEAUDIO_pa_context_disconnect(pulseaudio_context);
|
||||
PULSEAUDIO_pa_context_unref(pulseaudio_context);
|
||||
pulseaudio_context = NULL;
|
||||
}
|
||||
if (pulseaudio_threaded_mainloop) {
|
||||
PULSEAUDIO_pa_threaded_mainloop_free(pulseaudio_threaded_mainloop);
|
||||
pulseaudio_threaded_mainloop = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int ConnectToPulseServer_Internal(pa_mainloop **_mainloop, pa_context **_context)
|
||||
static void PulseContextStateChangeCallback(pa_context *context, void *userdata)
|
||||
{
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); /* just signal any waiting code, it can look up the details. */
|
||||
}
|
||||
|
||||
static int ConnectToPulseServer(void)
|
||||
{
|
||||
pa_mainloop *mainloop = NULL;
|
||||
pa_context *context = NULL;
|
||||
pa_mainloop_api *mainloop_api = NULL;
|
||||
int state = 0;
|
||||
|
||||
*_mainloop = NULL;
|
||||
*_context = NULL;
|
||||
SDL_assert(pulseaudio_threaded_mainloop == NULL);
|
||||
SDL_assert(pulseaudio_context == NULL);
|
||||
|
||||
/* Set up a new main loop */
|
||||
if (!(mainloop = PULSEAUDIO_pa_mainloop_new())) {
|
||||
return SDL_SetError("pa_mainloop_new() failed");
|
||||
if (!(pulseaudio_threaded_mainloop = PULSEAUDIO_pa_threaded_mainloop_new())) {
|
||||
return SDL_SetError("pa_threaded_mainloop_new() failed");
|
||||
}
|
||||
|
||||
mainloop_api = PULSEAUDIO_pa_mainloop_get_api(mainloop);
|
||||
SDL_assert(mainloop_api); /* this never fails, right? */
|
||||
|
||||
context = PULSEAUDIO_pa_context_new(mainloop_api, getAppName());
|
||||
if (context == NULL) {
|
||||
PULSEAUDIO_pa_mainloop_free(mainloop);
|
||||
return SDL_SetError("pa_context_new() failed");
|
||||
if (PULSEAUDIO_pa_threaded_mainloop_set_name) {
|
||||
PULSEAUDIO_pa_threaded_mainloop_set_name(pulseaudio_threaded_mainloop, "PulseMainloop");
|
||||
}
|
||||
|
||||
if (PULSEAUDIO_pa_threaded_mainloop_start(pulseaudio_threaded_mainloop) < 0) {
|
||||
PULSEAUDIO_pa_threaded_mainloop_free(pulseaudio_threaded_mainloop);
|
||||
pulseaudio_threaded_mainloop = NULL;
|
||||
return SDL_SetError("pa_threaded_mainloop_start() failed");
|
||||
}
|
||||
|
||||
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
||||
|
||||
mainloop_api = PULSEAUDIO_pa_threaded_mainloop_get_api(pulseaudio_threaded_mainloop);
|
||||
SDL_assert(mainloop_api != NULL); /* this never fails, right? */
|
||||
|
||||
pulseaudio_context = PULSEAUDIO_pa_context_new(mainloop_api, getAppName());
|
||||
if (!pulseaudio_context) {
|
||||
SDL_SetError("pa_context_new() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
PULSEAUDIO_pa_context_set_state_callback(pulseaudio_context, PulseContextStateChangeCallback, NULL);
|
||||
|
||||
/* Connect to the PulseAudio server */
|
||||
if (PULSEAUDIO_pa_context_connect(context, NULL, 0, NULL) < 0) {
|
||||
PULSEAUDIO_pa_context_unref(context);
|
||||
PULSEAUDIO_pa_mainloop_free(mainloop);
|
||||
return SDL_SetError("Could not setup connection to PulseAudio");
|
||||
if (PULSEAUDIO_pa_context_connect(pulseaudio_context, NULL, 0, NULL) < 0) {
|
||||
SDL_SetError("Could not setup connection to PulseAudio");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
do {
|
||||
if (PULSEAUDIO_pa_mainloop_iterate(mainloop, 1, NULL) < 0) {
|
||||
PULSEAUDIO_pa_context_unref(context);
|
||||
PULSEAUDIO_pa_mainloop_free(mainloop);
|
||||
return SDL_SetError("pa_mainloop_iterate() failed");
|
||||
}
|
||||
state = PULSEAUDIO_pa_context_get_state(context);
|
||||
if (!PA_CONTEXT_IS_GOOD(state)) {
|
||||
PULSEAUDIO_pa_context_unref(context);
|
||||
PULSEAUDIO_pa_mainloop_free(mainloop);
|
||||
return SDL_SetError("Could not connect to PulseAudio");
|
||||
}
|
||||
} while (state != PA_CONTEXT_READY);
|
||||
state = PULSEAUDIO_pa_context_get_state(pulseaudio_context);
|
||||
while (PA_CONTEXT_IS_GOOD(state) && (state != PA_CONTEXT_READY)) {
|
||||
PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop);
|
||||
state = PULSEAUDIO_pa_context_get_state(pulseaudio_context);
|
||||
}
|
||||
|
||||
*_context = context;
|
||||
*_mainloop = mainloop;
|
||||
if (state != PA_CONTEXT_READY) {
|
||||
return SDL_SetError("Could not connect to PulseAudio");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
|
||||
|
||||
return 0; /* connected and ready! */
|
||||
}
|
||||
|
||||
static int ConnectToPulseServer(pa_mainloop **_mainloop, pa_context **_context)
|
||||
{
|
||||
const int retval = ConnectToPulseServer_Internal(_mainloop, _context);
|
||||
if (retval < 0) {
|
||||
DisconnectFromPulseServer(*_mainloop, *_context);
|
||||
}
|
||||
return retval;
|
||||
failed:
|
||||
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
|
||||
DisconnectFromPulseServer();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* This function waits until it is possible to write a full sound buffer */
|
||||
|
|
@ -346,6 +379,7 @@ static void WriteCallback(pa_stream *p, size_t nbytes, void *userdata)
|
|||
struct SDL_PrivateAudioData *h = (struct SDL_PrivateAudioData *)userdata;
|
||||
/*printf("PULSEAUDIO WRITE CALLBACK! nbytes=%u\n", (unsigned int) nbytes);*/
|
||||
h->bytes_requested += nbytes;
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0);
|
||||
}
|
||||
|
||||
static void PULSEAUDIO_PlayDevice(_THIS)
|
||||
|
|
@ -357,12 +391,14 @@ static void PULSEAUDIO_PlayDevice(_THIS)
|
|||
|
||||
/*printf("PULSEAUDIO PLAYDEVICE START! mixlen=%d\n", available);*/
|
||||
|
||||
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
||||
|
||||
while (SDL_AtomicGet(&this->enabled) && (available > 0)) {
|
||||
cpy = SDL_min(h->bytes_requested, available);
|
||||
if (cpy) {
|
||||
if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf + written, cpy, NULL, 0LL, PA_SEEK_RELATIVE) < 0) {
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
/*printf("PULSEAUDIO FEED! nbytes=%u\n", (unsigned int) cpy);*/
|
||||
h->bytes_requested -= cpy;
|
||||
|
|
@ -370,16 +406,21 @@ static void PULSEAUDIO_PlayDevice(_THIS)
|
|||
available -= cpy;
|
||||
}
|
||||
|
||||
/* let WriteCallback fire if necessary. */
|
||||
/*printf("PULSEAUDIO ITERATE!\n");*/
|
||||
if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
|
||||
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
|
||||
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
return;
|
||||
if (available > 0) {
|
||||
/* let WriteCallback fire if necessary. */
|
||||
/*printf("PULSEAUDIO WAIT IN PLAYDEVICE!\n");*/
|
||||
PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop);
|
||||
|
||||
if ((PULSEAUDIO_pa_context_get_state(pulseaudio_context) != PA_CONTEXT_READY) || (PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY)) {
|
||||
/*printf("PULSEAUDIO DEVICE FAILURE IN PLAYDEVICE!\n");*/
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
|
||||
|
||||
/*printf("PULSEAUDIO PLAYDEVICE END! written=%d\n", written);*/
|
||||
}
|
||||
|
||||
|
|
@ -388,14 +429,23 @@ static Uint8 *PULSEAUDIO_GetDeviceBuf(_THIS)
|
|||
return this->hidden->mixbuf;
|
||||
}
|
||||
|
||||
static void ReadCallback(pa_stream *p, size_t nbytes, void *userdata)
|
||||
{
|
||||
/*printf("PULSEAUDIO READ CALLBACK! nbytes=%u\n", (unsigned int) nbytes);*/
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); /* the capture code queries what it needs, we just need to signal to end any wait */
|
||||
}
|
||||
|
||||
static int PULSEAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
const void *data = NULL;
|
||||
size_t nbytes = 0;
|
||||
int retval = 0;
|
||||
|
||||
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
||||
|
||||
while (SDL_AtomicGet(&this->enabled)) {
|
||||
if (h->capturebuf != NULL) {
|
||||
if (h->capturebuf) {
|
||||
const int cpy = SDL_min(buflen, h->capturelen);
|
||||
SDL_memcpy(buffer, h->capturebuf, cpy);
|
||||
/*printf("PULSEAUDIO: fed %d captured bytes\n", cpy);*/
|
||||
|
|
@ -405,25 +455,30 @@ static int PULSEAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
|||
h->capturebuf = NULL;
|
||||
PULSEAUDIO_pa_stream_drop(h->stream); /* done with this fragment. */
|
||||
}
|
||||
return cpy; /* new data, return it. */
|
||||
retval = cpy; /* new data, return it. */
|
||||
break;
|
||||
}
|
||||
|
||||
if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
|
||||
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
|
||||
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
return -1; /* uhoh, pulse failed! */
|
||||
while (SDL_AtomicGet(&this->enabled) && (PULSEAUDIO_pa_stream_readable_size(h->stream) == 0)) {
|
||||
PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop);
|
||||
if ((PULSEAUDIO_pa_context_get_state(pulseaudio_context) != PA_CONTEXT_READY) || (PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY)) {
|
||||
/*printf("PULSEAUDIO DEVICE FAILURE IN CAPTUREFROMDEVICE!\n");*/
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (PULSEAUDIO_pa_stream_readable_size(h->stream) == 0) {
|
||||
continue; /* no data available yet. */
|
||||
if ((retval == -1) || !SDL_AtomicGet(&this->enabled)) { /* in case this happened while we were blocking. */
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* a new fragment is available! */
|
||||
PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes);
|
||||
SDL_assert(nbytes > 0);
|
||||
/* If data == NULL, then the buffer had a hole, ignore that */
|
||||
if (data == NULL) {
|
||||
if (!data) {
|
||||
PULSEAUDIO_pa_stream_drop(h->stream); /* drop this fragment. */
|
||||
} else {
|
||||
/* store this fragment's data, start feeding it to SDL. */
|
||||
|
|
@ -433,50 +488,57 @@ static int PULSEAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
|||
}
|
||||
}
|
||||
|
||||
return -1; /* not enabled? */
|
||||
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void PULSEAUDIO_FlushCapture(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
const void *data = NULL;
|
||||
size_t nbytes = 0;
|
||||
size_t nbytes = 0, buflen = 0;
|
||||
|
||||
if (h->capturebuf != NULL) {
|
||||
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
||||
|
||||
if (h->capturebuf) {
|
||||
PULSEAUDIO_pa_stream_drop(h->stream);
|
||||
h->capturebuf = NULL;
|
||||
h->capturelen = 0;
|
||||
}
|
||||
|
||||
while (SDL_AtomicGet(&this->enabled)) {
|
||||
if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
|
||||
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
|
||||
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
||||
buflen = PULSEAUDIO_pa_stream_readable_size(h->stream);
|
||||
while (SDL_AtomicGet(&this->enabled) && (buflen > 0)) {
|
||||
PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop);
|
||||
if ((PULSEAUDIO_pa_context_get_state(pulseaudio_context) != PA_CONTEXT_READY) || (PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY)) {
|
||||
/*printf("PULSEAUDIO DEVICE FAILURE IN FLUSHCAPTURE!\n");*/
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
return; /* uhoh, pulse failed! */
|
||||
break;
|
||||
}
|
||||
|
||||
if (PULSEAUDIO_pa_stream_readable_size(h->stream) == 0) {
|
||||
break; /* no data available, so we're done. */
|
||||
}
|
||||
|
||||
/* a new fragment is available! Just dump it. */
|
||||
/* a fragment of audio present before FlushCapture was call is
|
||||
available! Just drop it. */
|
||||
PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes);
|
||||
PULSEAUDIO_pa_stream_drop(h->stream); /* drop this fragment. */
|
||||
PULSEAUDIO_pa_stream_drop(h->stream);
|
||||
buflen -= nbytes;
|
||||
}
|
||||
|
||||
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
|
||||
}
|
||||
|
||||
static void PULSEAUDIO_CloseDevice(_THIS)
|
||||
{
|
||||
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
||||
|
||||
if (this->hidden->stream) {
|
||||
if (this->hidden->capturebuf != NULL) {
|
||||
if (this->hidden->capturebuf) {
|
||||
PULSEAUDIO_pa_stream_drop(this->hidden->stream);
|
||||
}
|
||||
PULSEAUDIO_pa_stream_disconnect(this->hidden->stream);
|
||||
PULSEAUDIO_pa_stream_unref(this->hidden->stream);
|
||||
}
|
||||
|
||||
DisconnectFromPulseServer(this->hidden->mainloop, this->hidden->context);
|
||||
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
|
||||
|
||||
SDL_free(this->hidden->mixbuf);
|
||||
SDL_free(this->hidden->device_name);
|
||||
SDL_free(this->hidden);
|
||||
|
|
@ -488,6 +550,7 @@ static void SinkDeviceNameCallback(pa_context *c, const pa_sink_info *i, int is_
|
|||
char **devname = (char **)data;
|
||||
*devname = SDL_strdup(i->name);
|
||||
}
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0);
|
||||
}
|
||||
|
||||
static void SourceDeviceNameCallback(pa_context *c, const pa_source_info *i, int is_last, void *data)
|
||||
|
|
@ -496,29 +559,31 @@ static void SourceDeviceNameCallback(pa_context *c, const pa_source_info *i, int
|
|||
char **devname = (char **)data;
|
||||
*devname = SDL_strdup(i->name);
|
||||
}
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0);
|
||||
}
|
||||
|
||||
static SDL_bool FindDeviceName(struct SDL_PrivateAudioData *h, const SDL_bool iscapture, void *handle)
|
||||
{
|
||||
const uint32_t idx = ((uint32_t)((intptr_t)handle)) - 1;
|
||||
|
||||
if (handle == NULL) { /* NULL == default device. */
|
||||
if (!handle) { /* NULL == default device. */
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
if (iscapture) {
|
||||
WaitForPulseOperation(h->mainloop,
|
||||
PULSEAUDIO_pa_context_get_source_info_by_index(h->context, idx,
|
||||
SourceDeviceNameCallback, &h->device_name));
|
||||
WaitForPulseOperation(PULSEAUDIO_pa_context_get_source_info_by_index(pulseaudio_context, idx, SourceDeviceNameCallback, &h->device_name));
|
||||
} else {
|
||||
WaitForPulseOperation(h->mainloop,
|
||||
PULSEAUDIO_pa_context_get_sink_info_by_index(h->context, idx,
|
||||
SinkDeviceNameCallback, &h->device_name));
|
||||
WaitForPulseOperation(PULSEAUDIO_pa_context_get_sink_info_by_index(pulseaudio_context, idx, SinkDeviceNameCallback, &h->device_name));
|
||||
}
|
||||
|
||||
return h->device_name != NULL;
|
||||
}
|
||||
|
||||
static void PulseStreamStateChangeCallback(pa_stream *stream, void *userdata)
|
||||
{
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); /* just signal any waiting code, it can look up the details. */
|
||||
}
|
||||
|
||||
static int PULSEAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = NULL;
|
||||
|
|
@ -527,14 +592,16 @@ static int PULSEAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
pa_buffer_attr paattr;
|
||||
pa_channel_map pacmap;
|
||||
pa_stream_flags_t flags = 0;
|
||||
const char *name = NULL;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
int state = 0, format = PA_SAMPLE_INVALID;
|
||||
int rc = 0;
|
||||
int format = PA_SAMPLE_INVALID;
|
||||
int retval = 0;
|
||||
|
||||
SDL_assert(pulseaudio_threaded_mainloop != NULL);
|
||||
SDL_assert(pulseaudio_context != NULL);
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
h = this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
|
@ -572,7 +639,7 @@ static int PULSEAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
break;
|
||||
}
|
||||
if (!test_format) {
|
||||
return SDL_SetError("%s: Unsupported audio format", "pulseaudio");
|
||||
return SDL_SetError("pulseaudio: Unsupported audio format");
|
||||
}
|
||||
this->spec.format = test_format;
|
||||
paspec.format = format;
|
||||
|
|
@ -584,7 +651,7 @@ static int PULSEAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
if (!iscapture) {
|
||||
h->mixlen = this->spec.size;
|
||||
h->mixbuf = (Uint8 *)SDL_malloc(h->mixlen);
|
||||
if (h->mixbuf == NULL) {
|
||||
if (!h->mixbuf) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(h->mixbuf, this->spec.silence, this->spec.size);
|
||||
|
|
@ -601,73 +668,66 @@ static int PULSEAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
paattr.minreq = -1;
|
||||
flags |= PA_STREAM_ADJUST_LATENCY;
|
||||
|
||||
if (ConnectToPulseServer(&h->mainloop, &h->context) < 0) {
|
||||
return SDL_SetError("Could not connect to PulseAudio server");
|
||||
}
|
||||
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
||||
|
||||
if (!FindDeviceName(h, iscapture, this->handle)) {
|
||||
return SDL_SetError("Requested PulseAudio sink/source missing?");
|
||||
}
|
||||
|
||||
/* The SDL ALSA output hints us that we use Windows' channel mapping */
|
||||
/* http://bugzilla.libsdl.org/show_bug.cgi?id=110 */
|
||||
PULSEAUDIO_pa_channel_map_init_auto(&pacmap, this->spec.channels,
|
||||
PA_CHANNEL_MAP_WAVEEX);
|
||||
|
||||
name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_NAME);
|
||||
|
||||
h->stream = PULSEAUDIO_pa_stream_new(
|
||||
h->context,
|
||||
(name && *name) ? name : "Audio Stream", /* stream description */
|
||||
&paspec, /* sample format spec */
|
||||
&pacmap /* channel map */
|
||||
);
|
||||
|
||||
if (h->stream == NULL) {
|
||||
return SDL_SetError("Could not set up PulseAudio stream");
|
||||
}
|
||||
|
||||
/* now that we have multi-device support, don't move a stream from
|
||||
a device that was unplugged to something else, unless we're default. */
|
||||
if (h->device_name != NULL) {
|
||||
flags |= PA_STREAM_DONT_MOVE;
|
||||
}
|
||||
|
||||
if (iscapture) {
|
||||
rc = PULSEAUDIO_pa_stream_connect_record(h->stream, h->device_name, &paattr, flags);
|
||||
retval = SDL_SetError("Requested PulseAudio sink/source missing?");
|
||||
} else {
|
||||
PULSEAUDIO_pa_stream_set_write_callback(h->stream, WriteCallback, h);
|
||||
rc = PULSEAUDIO_pa_stream_connect_playback(h->stream, h->device_name, &paattr, flags, NULL, NULL);
|
||||
const char *name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_NAME);
|
||||
/* The SDL ALSA output hints us that we use Windows' channel mapping */
|
||||
/* https://bugzilla.libsdl.org/show_bug.cgi?id=110 */
|
||||
PULSEAUDIO_pa_channel_map_init_auto(&pacmap, this->spec.channels,
|
||||
PA_CHANNEL_MAP_WAVEEX);
|
||||
|
||||
h->stream = PULSEAUDIO_pa_stream_new(
|
||||
pulseaudio_context,
|
||||
(name && *name) ? name : "Audio Stream", /* stream description */
|
||||
&paspec, /* sample format spec */
|
||||
&pacmap /* channel map */
|
||||
);
|
||||
|
||||
if (!h->stream) {
|
||||
retval = SDL_SetError("Could not set up PulseAudio stream");
|
||||
} else {
|
||||
int rc;
|
||||
|
||||
PULSEAUDIO_pa_stream_set_state_callback(h->stream, PulseStreamStateChangeCallback, NULL);
|
||||
/* now that we have multi-device support, don't move a stream from
|
||||
a device that was unplugged to something else, unless we're default. */
|
||||
if (h->device_name) {
|
||||
flags |= PA_STREAM_DONT_MOVE;
|
||||
}
|
||||
|
||||
if (iscapture) {
|
||||
PULSEAUDIO_pa_stream_set_read_callback(h->stream, ReadCallback, h);
|
||||
rc = PULSEAUDIO_pa_stream_connect_record(h->stream, h->device_name, &paattr, flags);
|
||||
} else {
|
||||
PULSEAUDIO_pa_stream_set_write_callback(h->stream, WriteCallback, h);
|
||||
rc = PULSEAUDIO_pa_stream_connect_playback(h->stream, h->device_name, &paattr, flags, NULL, NULL);
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
retval = SDL_SetError("Could not connect PulseAudio stream");
|
||||
} else {
|
||||
int state = PULSEAUDIO_pa_stream_get_state(h->stream);
|
||||
while (PA_STREAM_IS_GOOD(state) && (state != PA_STREAM_READY)) {
|
||||
PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop);
|
||||
state = PULSEAUDIO_pa_stream_get_state(h->stream);
|
||||
}
|
||||
|
||||
if (!PA_STREAM_IS_GOOD(state)) {
|
||||
retval = SDL_SetError("Could not connect PulseAudio stream");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
return SDL_SetError("Could not connect PulseAudio stream");
|
||||
}
|
||||
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
|
||||
|
||||
do {
|
||||
if (PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
||||
return SDL_SetError("pa_mainloop_iterate() failed");
|
||||
}
|
||||
state = PULSEAUDIO_pa_stream_get_state(h->stream);
|
||||
if (!PA_STREAM_IS_GOOD(state)) {
|
||||
return SDL_SetError("Could not connect PulseAudio stream");
|
||||
}
|
||||
} while (state != PA_STREAM_READY);
|
||||
|
||||
/* We're ready to rock and roll. :-) */
|
||||
return 0;
|
||||
/* We're (hopefully) ready to rock and roll. :-) */
|
||||
return retval;
|
||||
}
|
||||
|
||||
static pa_mainloop *hotplug_mainloop = NULL;
|
||||
static pa_context *hotplug_context = NULL;
|
||||
static SDL_Thread *hotplug_thread = NULL;
|
||||
|
||||
/* These are the OS identifiers (i.e. ALSA strings)... */
|
||||
static char *default_sink_path = NULL;
|
||||
static char *default_source_path = NULL;
|
||||
/* ... and these are the descriptions we use in GetDefaultAudioInfo. */
|
||||
static char *default_sink_name = NULL;
|
||||
static char *default_source_name = NULL;
|
||||
|
||||
/* device handles are device index + 1, cast to void*, so we never pass a NULL. */
|
||||
|
||||
|
|
@ -712,13 +772,14 @@ static void SinkInfoCallback(pa_context *c, const pa_sink_info *i, int is_last,
|
|||
SDL_AddAudioDevice(SDL_FALSE, i->description, &spec, (void *)((intptr_t)i->index + 1));
|
||||
}
|
||||
|
||||
if (default_sink_path != NULL && SDL_strcmp(i->name, default_sink_path) == 0) {
|
||||
if (default_sink_name != NULL) {
|
||||
if (default_sink_path && SDL_strcmp(i->name, default_sink_path) == 0) {
|
||||
if (default_sink_name) {
|
||||
SDL_free(default_sink_name);
|
||||
}
|
||||
default_sink_name = SDL_strdup(i->description);
|
||||
}
|
||||
}
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0);
|
||||
}
|
||||
|
||||
/* This is called when PulseAudio adds a capture ("source") device. */
|
||||
|
|
@ -742,26 +803,24 @@ static void SourceInfoCallback(pa_context *c, const pa_source_info *i, int is_la
|
|||
SDL_AddAudioDevice(SDL_TRUE, i->description, &spec, (void *)((intptr_t)i->index + 1));
|
||||
}
|
||||
|
||||
if (default_source_path != NULL && SDL_strcmp(i->name, default_source_path) == 0) {
|
||||
if (default_source_name != NULL) {
|
||||
if (default_source_path && SDL_strcmp(i->name, default_source_path) == 0) {
|
||||
if (default_source_name) {
|
||||
SDL_free(default_source_name);
|
||||
}
|
||||
default_source_name = SDL_strdup(i->description);
|
||||
}
|
||||
}
|
||||
}
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0);
|
||||
}
|
||||
|
||||
static void ServerInfoCallback(pa_context *c, const pa_server_info *i, void *data)
|
||||
{
|
||||
if (default_sink_path != NULL) {
|
||||
SDL_free(default_sink_path);
|
||||
}
|
||||
if (default_source_path != NULL) {
|
||||
SDL_free(default_source_path);
|
||||
}
|
||||
SDL_free(default_sink_path);
|
||||
SDL_free(default_source_path);
|
||||
default_sink_path = SDL_strdup(i->default_sink_name);
|
||||
default_source_path = SDL_strdup(i->default_source_name);
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0);
|
||||
}
|
||||
|
||||
/* This is called when PulseAudio has a device connected/removed/changed. */
|
||||
|
|
@ -776,43 +835,75 @@ static void HotplugCallback(pa_context *c, pa_subscription_event_type_t t, uint3
|
|||
const SDL_bool source = ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE);
|
||||
|
||||
/* adds need sink details from the PulseAudio server. Another callback... */
|
||||
/* (just unref all these operations right away, because we aren't going to wait on them and their callbacks will handle any work, so they can free as soon as that happens.) */
|
||||
if ((added || changed) && sink) {
|
||||
if (changed) {
|
||||
PULSEAUDIO_pa_context_get_server_info(hotplug_context, ServerInfoCallback, NULL);
|
||||
PULSEAUDIO_pa_operation_unref(PULSEAUDIO_pa_context_get_server_info(pulseaudio_context, ServerInfoCallback, NULL));
|
||||
}
|
||||
PULSEAUDIO_pa_context_get_sink_info_by_index(hotplug_context, idx, SinkInfoCallback, (void *)((intptr_t)added));
|
||||
PULSEAUDIO_pa_operation_unref(PULSEAUDIO_pa_context_get_sink_info_by_index(pulseaudio_context, idx, SinkInfoCallback, (void *)((intptr_t)added)));
|
||||
} else if ((added || changed) && source) {
|
||||
if (changed) {
|
||||
PULSEAUDIO_pa_context_get_server_info(hotplug_context, ServerInfoCallback, NULL);
|
||||
PULSEAUDIO_pa_operation_unref(PULSEAUDIO_pa_context_get_server_info(pulseaudio_context, ServerInfoCallback, NULL));
|
||||
}
|
||||
PULSEAUDIO_pa_context_get_source_info_by_index(hotplug_context, idx, SourceInfoCallback, (void *)((intptr_t)added));
|
||||
PULSEAUDIO_pa_operation_unref(PULSEAUDIO_pa_context_get_source_info_by_index(pulseaudio_context, idx, SourceInfoCallback, (void *)((intptr_t)added)));
|
||||
} else if (removed && (sink || source)) {
|
||||
/* removes we can handle just with the device index. */
|
||||
SDL_RemoveAudioDevice(source != 0, (void *)((intptr_t)idx + 1));
|
||||
}
|
||||
}
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0);
|
||||
}
|
||||
|
||||
/* this runs as a thread while the Pulse target is initialized to catch hotplug events. */
|
||||
static int SDLCALL HotplugThread(void *data)
|
||||
{
|
||||
pa_operation *o;
|
||||
pa_operation *op;
|
||||
|
||||
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW);
|
||||
PULSEAUDIO_pa_context_set_subscribe_callback(hotplug_context, HotplugCallback, NULL);
|
||||
o = PULSEAUDIO_pa_context_subscribe(hotplug_context, PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE, NULL, NULL);
|
||||
PULSEAUDIO_pa_operation_unref(o); /* don't wait for it, just do our thing. */
|
||||
PULSEAUDIO_pa_mainloop_run(hotplug_mainloop, NULL);
|
||||
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
||||
PULSEAUDIO_pa_context_set_subscribe_callback(pulseaudio_context, HotplugCallback, NULL);
|
||||
|
||||
/* don't WaitForPulseOperation on the subscription; when it's done we'll be able to get hotplug events, but waiting doesn't changing anything. */
|
||||
op = PULSEAUDIO_pa_context_subscribe(pulseaudio_context, PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE, NULL, NULL);
|
||||
|
||||
SDL_SemPost(data);
|
||||
|
||||
while (SDL_AtomicGet(&pulseaudio_hotplug_thread_active)) {
|
||||
PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop);
|
||||
if (op && PULSEAUDIO_pa_operation_get_state(op) != PA_OPERATION_RUNNING) {
|
||||
PULSEAUDIO_pa_operation_unref(op);
|
||||
op = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (op) {
|
||||
PULSEAUDIO_pa_operation_unref(op);
|
||||
}
|
||||
|
||||
PULSEAUDIO_pa_context_set_subscribe_callback(pulseaudio_context, NULL, NULL);
|
||||
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void PULSEAUDIO_DetectDevices()
|
||||
static void PULSEAUDIO_DetectDevices(void)
|
||||
{
|
||||
WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_server_info(hotplug_context, ServerInfoCallback, NULL));
|
||||
WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_sink_info_list(hotplug_context, SinkInfoCallback, (void *)((intptr_t)SDL_TRUE)));
|
||||
WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_source_info_list(hotplug_context, SourceInfoCallback, (void *)((intptr_t)SDL_TRUE)));
|
||||
SDL_sem *ready_sem = SDL_CreateSemaphore(0);
|
||||
|
||||
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
||||
WaitForPulseOperation(PULSEAUDIO_pa_context_get_server_info(pulseaudio_context, ServerInfoCallback, NULL));
|
||||
WaitForPulseOperation(PULSEAUDIO_pa_context_get_sink_info_list(pulseaudio_context, SinkInfoCallback, (void *)((intptr_t)SDL_TRUE)));
|
||||
WaitForPulseOperation(PULSEAUDIO_pa_context_get_source_info_list(pulseaudio_context, SourceInfoCallback, (void *)((intptr_t)SDL_TRUE)));
|
||||
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
|
||||
|
||||
/* ok, we have a sane list, let's set up hotplug notifications now... */
|
||||
hotplug_thread = SDL_CreateThreadInternal(HotplugThread, "PulseHotplug", 256 * 1024, NULL);
|
||||
SDL_AtomicSet(&pulseaudio_hotplug_thread_active, 1);
|
||||
pulseaudio_hotplug_thread = SDL_CreateThreadInternal(HotplugThread, "PulseHotplug", 0, ready_sem);
|
||||
if (pulseaudio_hotplug_thread) {
|
||||
SDL_SemWait(ready_sem);
|
||||
} else {
|
||||
SDL_AtomicSet(&pulseaudio_hotplug_thread_active, 0); // thread failed to start, we'll go on without hotplug.
|
||||
}
|
||||
SDL_DestroySemaphore(ready_sem);
|
||||
}
|
||||
|
||||
static int PULSEAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
|
|
@ -822,12 +913,12 @@ static int PULSEAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int
|
|||
|
||||
char *target;
|
||||
if (iscapture) {
|
||||
if (default_source_name == NULL) {
|
||||
if (!default_source_name) {
|
||||
return SDL_SetError("PulseAudio could not find a default source");
|
||||
}
|
||||
target = default_source_name;
|
||||
} else {
|
||||
if (default_sink_name == NULL) {
|
||||
if (!default_sink_name) {
|
||||
return SDL_SetError("PulseAudio could not find a default sink");
|
||||
}
|
||||
target = default_sink_name;
|
||||
|
|
@ -836,7 +927,7 @@ static int PULSEAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int
|
|||
numdevices = SDL_GetNumAudioDevices(iscapture);
|
||||
for (i = 0; i < numdevices; i += 1) {
|
||||
if (SDL_strcmp(SDL_GetAudioDeviceName(i, iscapture), target) == 0) {
|
||||
if (name != NULL) {
|
||||
if (name) {
|
||||
*name = SDL_strdup(target);
|
||||
}
|
||||
SDL_GetAudioDeviceSpec(i, iscapture, spec);
|
||||
|
|
@ -848,32 +939,25 @@ static int PULSEAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int
|
|||
|
||||
static void PULSEAUDIO_Deinitialize(void)
|
||||
{
|
||||
if (hotplug_thread) {
|
||||
PULSEAUDIO_pa_mainloop_quit(hotplug_mainloop, 0);
|
||||
SDL_WaitThread(hotplug_thread, NULL);
|
||||
hotplug_thread = NULL;
|
||||
if (pulseaudio_hotplug_thread) {
|
||||
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
||||
SDL_AtomicSet(&pulseaudio_hotplug_thread_active, 0);
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0);
|
||||
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
|
||||
SDL_WaitThread(pulseaudio_hotplug_thread, NULL);
|
||||
pulseaudio_hotplug_thread = NULL;
|
||||
}
|
||||
|
||||
DisconnectFromPulseServer(hotplug_mainloop, hotplug_context);
|
||||
hotplug_mainloop = NULL;
|
||||
hotplug_context = NULL;
|
||||
DisconnectFromPulseServer();
|
||||
|
||||
if (default_sink_path != NULL) {
|
||||
SDL_free(default_sink_path);
|
||||
default_sink_path = NULL;
|
||||
}
|
||||
if (default_source_path != NULL) {
|
||||
SDL_free(default_source_path);
|
||||
default_source_path = NULL;
|
||||
}
|
||||
if (default_sink_name != NULL) {
|
||||
SDL_free(default_sink_name);
|
||||
default_sink_name = NULL;
|
||||
}
|
||||
if (default_source_name != NULL) {
|
||||
SDL_free(default_source_name);
|
||||
default_source_name = NULL;
|
||||
}
|
||||
SDL_free(default_sink_path);
|
||||
default_sink_path = NULL;
|
||||
SDL_free(default_source_path);
|
||||
default_source_path = NULL;
|
||||
SDL_free(default_sink_name);
|
||||
default_sink_name = NULL;
|
||||
SDL_free(default_source_name);
|
||||
default_source_name = NULL;
|
||||
|
||||
UnloadPulseAudioLibrary();
|
||||
}
|
||||
|
|
@ -882,9 +966,7 @@ static SDL_bool PULSEAUDIO_Init(SDL_AudioDriverImpl *impl)
|
|||
{
|
||||
if (LoadPulseAudioLibrary() < 0) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (ConnectToPulseServer(&hotplug_mainloop, &hotplug_context) < 0) {
|
||||
} else if (ConnectToPulseServer() < 0) {
|
||||
UnloadPulseAudioLibrary();
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
#ifndef SDL_pulseaudio_h_
|
||||
#define SDL_pulseaudio_h_
|
||||
|
||||
#include <pulse/simple.h>
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
|
|
@ -35,8 +35,6 @@ struct SDL_PrivateAudioData
|
|||
char *device_name;
|
||||
|
||||
/* pulseaudio structures */
|
||||
pa_mainloop *mainloop;
|
||||
pa_context *context;
|
||||
pa_stream *stream;
|
||||
|
||||
/* Raw mixing buffer */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_QSA
|
||||
#ifdef SDL_AUDIO_DRIVER_QSA
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
|
@ -232,7 +232,7 @@ static Uint8 *QSA_GetDeviceBuf(_THIS)
|
|||
|
||||
static void QSA_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->audio_handle != NULL) {
|
||||
if (this->hidden->audio_handle) {
|
||||
#if _NTO_VERSION < 710
|
||||
if (!this->iscapture) {
|
||||
/* Finish playing available samples */
|
||||
|
|
@ -267,14 +267,14 @@ static int QSA_OpenDevice(_THIS, const char *devname)
|
|||
(sizeof
|
||||
(struct
|
||||
SDL_PrivateAudioData)));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
/* Initialize channel transfer parameters to default */
|
||||
QSA_InitAudioParams(&cparams);
|
||||
|
||||
if (device != NULL) {
|
||||
if (device) {
|
||||
/* Open requested audio device */
|
||||
this->hidden->deviceno = device->deviceno;
|
||||
this->hidden->cardno = device->cardno;
|
||||
|
|
@ -387,7 +387,7 @@ static int QSA_OpenDevice(_THIS, const char *devname)
|
|||
*/
|
||||
this->hidden->pcm_buf =
|
||||
(Uint8 *) SDL_malloc(this->hidden->pcm_len);
|
||||
if (this->hidden->pcm_buf == NULL) {
|
||||
if (!this->hidden->pcm_buf) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(this->hidden->pcm_buf, this->spec.silence,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -21,11 +21,11 @@
|
|||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_SNDIO
|
||||
#ifdef SDL_AUDIO_DRIVER_SNDIO
|
||||
|
||||
/* OpenBSD sndio target */
|
||||
|
||||
#if HAVE_STDIO_H
|
||||
#ifdef HAVE_STDIO_H
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ static void *sndio_handle = NULL;
|
|||
static int load_sndio_sym(const char *fn, void **addr)
|
||||
{
|
||||
*addr = SDL_LoadFunction(sndio_handle, fn);
|
||||
if (*addr == NULL) {
|
||||
if (!*addr) {
|
||||
/* Don't call SDL_SetError(): SDL_LoadFunction already did. */
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -113,7 +113,7 @@ static int load_sndio_syms(void)
|
|||
|
||||
static void UnloadSNDIOLibrary(void)
|
||||
{
|
||||
if (sndio_handle != NULL) {
|
||||
if (sndio_handle) {
|
||||
SDL_UnloadObject(sndio_handle);
|
||||
sndio_handle = NULL;
|
||||
}
|
||||
|
|
@ -122,9 +122,9 @@ static void UnloadSNDIOLibrary(void)
|
|||
static int LoadSNDIOLibrary(void)
|
||||
{
|
||||
int retval = 0;
|
||||
if (sndio_handle == NULL) {
|
||||
if (!sndio_handle) {
|
||||
sndio_handle = SDL_LoadObject(sndio_library);
|
||||
if (sndio_handle == NULL) {
|
||||
if (!sndio_handle) {
|
||||
retval = -1;
|
||||
/* Don't call SDL_SetError(): SDL_LoadObject already did. */
|
||||
} else {
|
||||
|
|
@ -211,10 +211,10 @@ static Uint8 *SNDIO_GetDeviceBuf(_THIS)
|
|||
|
||||
static void SNDIO_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->pfd != NULL) {
|
||||
if (this->hidden->pfd) {
|
||||
SDL_free(this->hidden->pfd);
|
||||
}
|
||||
if (this->hidden->dev != NULL) {
|
||||
if (this->hidden->dev) {
|
||||
SNDIO_sio_stop(this->hidden->dev);
|
||||
SNDIO_sio_close(this->hidden->dev);
|
||||
}
|
||||
|
|
@ -230,7 +230,7 @@ static int SNDIO_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
|
@ -238,16 +238,16 @@ static int SNDIO_OpenDevice(_THIS, const char *devname)
|
|||
this->hidden->mixlen = this->spec.size;
|
||||
|
||||
/* Capture devices must be non-blocking for SNDIO_FlushCapture */
|
||||
this->hidden->dev = SNDIO_sio_open(devname != NULL ? devname : SIO_DEVANY,
|
||||
this->hidden->dev = SNDIO_sio_open(devname ? devname : SIO_DEVANY,
|
||||
iscapture ? SIO_REC : SIO_PLAY, iscapture);
|
||||
if (this->hidden->dev == NULL) {
|
||||
if (!this->hidden->dev) {
|
||||
return SDL_SetError("sio_open() failed");
|
||||
}
|
||||
|
||||
/* Allocate the pollfd array for capture devices */
|
||||
if (iscapture) {
|
||||
this->hidden->pfd = SDL_malloc(sizeof(struct pollfd) * SNDIO_sio_nfds(this->hidden->dev));
|
||||
if (this->hidden->pfd == NULL) {
|
||||
if (!this->hidden->pfd) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
}
|
||||
|
|
@ -315,7 +315,7 @@ static int SNDIO_OpenDevice(_THIS, const char *devname)
|
|||
/* Allocate mixing buffer */
|
||||
this->hidden->mixlen = this->spec.size;
|
||||
this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->hidden->mixlen);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
if (!this->hidden->mixbuf) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_SUNAUDIO
|
||||
#ifdef SDL_AUDIO_DRIVER_SUNAUDIO
|
||||
|
||||
/* Allow access to a raw mixing buffer */
|
||||
|
||||
|
|
@ -194,16 +194,16 @@ static int SUNAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* We don't care what the devname is...we'll try to open anything. */
|
||||
/* ...but default to first name in the list... */
|
||||
if (devname == NULL) {
|
||||
if (!devname) {
|
||||
devname = SDL_GetAudioDeviceName(0, iscapture);
|
||||
if (devname == NULL) {
|
||||
if (!devname) {
|
||||
return SDL_SetError("No such audio device");
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
|
@ -281,7 +281,7 @@ static int SUNAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
break; /* try again */
|
||||
|
||||
case AUDIO_ENCODING_LINEAR:
|
||||
/* linear 16bit didn't work either, resort to µ-law */
|
||||
/* linear 16bit didn't work either, resort to <EFBFBD>-law */
|
||||
enc = AUDIO_ENCODING_ULAW;
|
||||
this->spec.channels = 1;
|
||||
this->spec.freq = 8000;
|
||||
|
|
@ -305,7 +305,7 @@ static int SUNAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
(this->spec.freq / 8);
|
||||
this->hidden->frequency = 8;
|
||||
this->hidden->ulaw_buf = (Uint8 *) SDL_malloc(this->hidden->fragsize);
|
||||
if (this->hidden->ulaw_buf == NULL) {
|
||||
if (!this->hidden->ulaw_buf) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
this->spec.channels = 1;
|
||||
|
|
@ -325,7 +325,7 @@ static int SUNAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* Allocate mixing buffer */
|
||||
this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->spec.size);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
if (!this->hidden->mixbuf) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_VITA
|
||||
#ifdef SDL_AUDIO_DRIVER_VITA
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
|
@ -67,7 +67,7 @@ static int VITAAUD_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(this->hidden, 0, sizeof(*this->hidden));
|
||||
|
|
@ -98,7 +98,7 @@ static int VITAAUD_OpenDevice(_THIS, const char *devname)
|
|||
64, so spec->size should be a multiple of 64 as well. */
|
||||
mixlen = this->spec.size * NUM_BUFFERS;
|
||||
this->hidden->rawbuf = (Uint8 *)memalign(64, mixlen);
|
||||
if (this->hidden->rawbuf == NULL) {
|
||||
if (!this->hidden->rawbuf) {
|
||||
return SDL_SetError("Couldn't allocate mixing buffer");
|
||||
}
|
||||
|
||||
|
|
@ -162,7 +162,7 @@ static void VITAAUD_CloseDevice(_THIS)
|
|||
this->hidden->port = -1;
|
||||
}
|
||||
|
||||
if (!this->iscapture && this->hidden->rawbuf != NULL) {
|
||||
if (!this->iscapture && this->hidden->rawbuf) {
|
||||
free(this->hidden->rawbuf); /* this uses memalign(), not SDL_malloc(). */
|
||||
this->hidden->rawbuf = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_WASAPI
|
||||
#ifdef SDL_AUDIO_DRIVER_WASAPI
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include "../../core/windows/SDL_immdevice.h"
|
||||
|
|
@ -111,10 +111,16 @@ static int UpdateAudioStream(_THIS, const SDL_AudioSpec *oldspec)
|
|||
}
|
||||
}
|
||||
|
||||
/* if the device sample size changed, make sure we're asking for enough data. */
|
||||
if (this->callbackspec.samples != this->spec.samples) {
|
||||
this->callbackspec.samples = this->spec.samples;
|
||||
SDL_CalculateAudioSpec(&this->callbackspec);
|
||||
}
|
||||
|
||||
/* make sure our scratch buffer can cover the new device spec. */
|
||||
if (this->spec.size > this->work_buffer_len) {
|
||||
Uint8 *ptr = (Uint8 *)SDL_realloc(this->work_buffer, this->spec.size);
|
||||
if (ptr == NULL) {
|
||||
if (!ptr) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
this->work_buffer = ptr;
|
||||
|
|
@ -172,13 +178,18 @@ static SDL_bool RecoverWasapiIfLost(_THIS)
|
|||
return lost ? RecoverWasapiDevice(this) : SDL_TRUE;
|
||||
}
|
||||
|
||||
static void WASAPI_WaitDevice(_THIS);
|
||||
|
||||
static Uint8 *WASAPI_GetDeviceBuf(_THIS)
|
||||
{
|
||||
/* get an endpoint buffer from WASAPI. */
|
||||
BYTE *buffer = NULL;
|
||||
|
||||
while (RecoverWasapiIfLost(this) && this->hidden->render) {
|
||||
if (!WasapiFailed(this, IAudioRenderClient_GetBuffer(this->hidden->render, this->spec.samples, &buffer))) {
|
||||
const HRESULT ret = IAudioRenderClient_GetBuffer(this->hidden->render, this->spec.samples, &buffer);
|
||||
if (ret == AUDCLNT_E_BUFFER_TOO_LARGE) {
|
||||
WASAPI_WaitDevice(this); /* see if we can wait on the buffer to drain some more first... */
|
||||
} else if (!WasapiFailed(this, ret)) {
|
||||
return (Uint8 *)buffer;
|
||||
}
|
||||
SDL_assert(buffer == NULL);
|
||||
|
|
@ -189,7 +200,7 @@ static Uint8 *WASAPI_GetDeviceBuf(_THIS)
|
|||
|
||||
static void WASAPI_PlayDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->render != NULL) { /* definitely activated? */
|
||||
if (this->hidden->render) { /* definitely activated? */
|
||||
/* WasapiFailed() will mark the device for reacquisition or removal elsewhere. */
|
||||
WasapiFailed(this, IAudioRenderClient_ReleaseBuffer(this->hidden->render, this->spec.samples, 0));
|
||||
}
|
||||
|
|
@ -415,7 +426,7 @@ int WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
|||
this->hidden->event = CreateEventW(NULL, 0, 0, NULL);
|
||||
#endif
|
||||
|
||||
if (this->hidden->event == NULL) {
|
||||
if (!this->hidden->event) {
|
||||
return WIN_SetError("WASAPI can't create an event handle");
|
||||
}
|
||||
|
||||
|
|
@ -486,6 +497,11 @@ int WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
|||
this->spec.samples = (Uint16)SDL_ceilf(period_frames);
|
||||
}
|
||||
|
||||
/* regardless of what we calculated for the period size, clamp it to the expected hardware buffer size. */
|
||||
if (this->spec.samples > bufsize) {
|
||||
this->spec.samples = bufsize;
|
||||
}
|
||||
|
||||
/* Update the fragment size as size in bytes */
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
|
|
@ -537,7 +553,7 @@ static int WASAPI_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
The code in SDL_wasapi.c is used by both standard Windows and WinRT builds
|
||||
to deal with audio and calls into these functions. */
|
||||
|
||||
#if SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__)
|
||||
#if defined(SDL_AUDIO_DRIVER_WASAPI) && !defined(__WINRT__)
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include "../../core/windows/SDL_immdevice.h"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
// is in SDL_wasapi_win32.c. The code in SDL_wasapi.c is used by both standard
|
||||
// Windows and WinRT builds to deal with audio and calls into these functions.
|
||||
|
||||
#if SDL_AUDIO_DRIVER_WASAPI && defined(__WINRT__)
|
||||
#if defined(SDL_AUDIO_DRIVER_WASAPI) && defined(__WINRT__)
|
||||
|
||||
#include <Windows.h>
|
||||
#include <windows.ui.core.h>
|
||||
|
|
@ -145,7 +145,7 @@ SDL_WasapiDeviceEventHandler::~SDL_WasapiDeviceEventHandler()
|
|||
void SDL_WasapiDeviceEventHandler::OnDeviceAdded(DeviceWatcher ^ sender, DeviceInformation ^ info)
|
||||
{
|
||||
SDL_assert(sender == this->watcher);
|
||||
char *utf8dev = WIN_StringToUTF8(info->Name->Data());
|
||||
char *utf8dev = WIN_StringToUTF8W(info->Name->Data());
|
||||
if (utf8dev) {
|
||||
WAVEFORMATEXTENSIBLE fmt;
|
||||
Platform::Object ^ obj = info->Properties->Lookup(SDL_PKEY_AudioEngine_DeviceFormat);
|
||||
|
|
@ -405,7 +405,7 @@ static void WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, WAVE
|
|||
}
|
||||
|
||||
devidlist = (DevIdList *)SDL_malloc(sizeof(*devidlist));
|
||||
if (devidlist == NULL) {
|
||||
if (!devidlist) {
|
||||
return; /* oh well. */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_WINMM
|
||||
#ifdef SDL_AUDIO_DRIVER_WINMM
|
||||
|
||||
/* Allow access to a raw mixing buffer */
|
||||
|
||||
|
|
@ -279,7 +279,7 @@ static int WINMM_OpenDevice(_THIS, const char *devname)
|
|||
UINT devId = WAVE_MAPPER; /* WAVE_MAPPER == choose system's default */
|
||||
UINT i;
|
||||
|
||||
if (handle != NULL) { /* specific device requested? */
|
||||
if (handle) { /* specific device requested? */
|
||||
/* -1 because we increment the original value to avoid NULL. */
|
||||
const size_t val = ((size_t) handle) - 1;
|
||||
devId = (UINT) val;
|
||||
|
|
@ -287,7 +287,7 @@ static int WINMM_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
if (!this->hidden) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
|
@ -365,14 +365,14 @@ static int WINMM_OpenDevice(_THIS, const char *devname)
|
|||
|
||||
/* Create the audio buffer semaphore */
|
||||
this->hidden->audio_sem = CreateSemaphore(NULL, iscapture ? 0 : NUM_BUFFERS - 1, NUM_BUFFERS, NULL);
|
||||
if (this->hidden->audio_sem == NULL) {
|
||||
if (!this->hidden->audio_sem) {
|
||||
return SDL_SetError("Couldn't create semaphore");
|
||||
}
|
||||
|
||||
/* Create the sound buffers */
|
||||
this->hidden->mixbuf =
|
||||
(Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
if (!this->hidden->mixbuf) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -420,12 +420,12 @@ JNIEnv *Android_JNI_GetEnv(void)
|
|||
{
|
||||
/* Get JNIEnv from the Thread local storage */
|
||||
JNIEnv *env = pthread_getspecific(mThreadKey);
|
||||
if (env == NULL) {
|
||||
if (!env) {
|
||||
/* If it fails, try to attach ! (e.g the thread isn't created with SDL_CreateThread() */
|
||||
int status;
|
||||
|
||||
/* There should be a JVM */
|
||||
if (mJavaVM == NULL) {
|
||||
if (!mJavaVM) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "SDL", "Failed, there is no JavaVM");
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -454,7 +454,7 @@ int Android_JNI_SetupThread(void)
|
|||
int status;
|
||||
|
||||
/* There should be a JVM */
|
||||
if (mJavaVM == NULL) {
|
||||
if (!mJavaVM) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "SDL", "Failed, there is no JavaVM");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -480,7 +480,7 @@ static void Android_JNI_ThreadDestroyed(void *value)
|
|||
{
|
||||
/* The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required */
|
||||
JNIEnv *env = (JNIEnv *)value;
|
||||
if (env != NULL) {
|
||||
if (env) {
|
||||
(*mJavaVM)->DetachCurrentThread(mJavaVM);
|
||||
Android_JNI_SetEnv(NULL);
|
||||
}
|
||||
|
|
@ -506,7 +506,7 @@ static void Android_JNI_CreateKey_once(void)
|
|||
static void register_methods(JNIEnv *env, const char *classname, JNINativeMethod *methods, int nb)
|
||||
{
|
||||
jclass clazz = (*env)->FindClass(env, classname);
|
||||
if (clazz == NULL || (*env)->RegisterNatives(env, clazz, methods, nb) < 0) {
|
||||
if (!clazz || (*env)->RegisterNatives(env, clazz, methods, nb) < 0) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "SDL", "Failed to register methods of %s", classname);
|
||||
return;
|
||||
}
|
||||
|
|
@ -566,28 +566,28 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
|
|||
/* Save JNIEnv of SDLActivity */
|
||||
Android_JNI_SetEnv(env);
|
||||
|
||||
if (mJavaVM == NULL) {
|
||||
if (!mJavaVM) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "SDL", "failed to found a JavaVM");
|
||||
}
|
||||
|
||||
/* Use a mutex to prevent concurrency issues between Java Activity and Native thread code, when using 'Android_Window'.
|
||||
* (Eg. Java sending Touch events, while native code is destroying the main SDL_Window. )
|
||||
*/
|
||||
if (Android_ActivityMutex == NULL) {
|
||||
if (!Android_ActivityMutex) {
|
||||
Android_ActivityMutex = SDL_CreateMutex(); /* Could this be created twice if onCreate() is called a second time ? */
|
||||
}
|
||||
|
||||
if (Android_ActivityMutex == NULL) {
|
||||
if (!Android_ActivityMutex) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "SDL", "failed to create Android_ActivityMutex mutex");
|
||||
}
|
||||
|
||||
Android_PauseSem = SDL_CreateSemaphore(0);
|
||||
if (Android_PauseSem == NULL) {
|
||||
if (!Android_PauseSem) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "SDL", "failed to create Android_PauseSem semaphore");
|
||||
}
|
||||
|
||||
Android_ResumeSem = SDL_CreateSemaphore(0);
|
||||
if (Android_ResumeSem == NULL) {
|
||||
if (!Android_ResumeSem) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "SDL", "failed to create Android_ResumeSem semaphore");
|
||||
}
|
||||
|
||||
|
|
@ -842,18 +842,18 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(
|
|||
}
|
||||
|
||||
/* Lock / Unlock Mutex */
|
||||
void Android_ActivityMutex_Lock()
|
||||
void Android_ActivityMutex_Lock(void)
|
||||
{
|
||||
SDL_LockMutex(Android_ActivityMutex);
|
||||
}
|
||||
|
||||
void Android_ActivityMutex_Unlock()
|
||||
void Android_ActivityMutex_Unlock(void)
|
||||
{
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
}
|
||||
|
||||
/* Lock the Mutex when the Activity is in its 'Running' state */
|
||||
void Android_ActivityMutex_Lock_Running()
|
||||
void Android_ActivityMutex_Lock_Running(void)
|
||||
{
|
||||
int pauseSignaled = 0;
|
||||
int resumeSignaled = 0;
|
||||
|
|
@ -1056,7 +1056,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(JNIEnv *env, j
|
|||
{
|
||||
SDL_LockMutex(Android_ActivityMutex);
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
#ifdef SDL_VIDEO_OPENGL_EGL
|
||||
if (Android_Window) {
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
SDL_WindowData *data = (SDL_WindowData *)Android_Window->driverdata;
|
||||
|
|
@ -1098,7 +1098,7 @@ retry:
|
|||
}
|
||||
}
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
#ifdef SDL_VIDEO_OPENGL_EGL
|
||||
if (data->egl_surface != EGL_NO_SURFACE) {
|
||||
SDL_EGL_DestroySurface(_this, data->egl_surface);
|
||||
data->egl_surface = EGL_NO_SURFACE;
|
||||
|
|
@ -1439,13 +1439,13 @@ void Android_JNI_SetOrientation(int w, int h, int resizable, const char *hint)
|
|||
(*env)->DeleteLocalRef(env, jhint);
|
||||
}
|
||||
|
||||
void Android_JNI_MinizeWindow()
|
||||
void Android_JNI_MinizeWindow(void)
|
||||
{
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
(*env)->CallStaticVoidMethod(env, mActivityClass, midMinimizeWindow);
|
||||
}
|
||||
|
||||
SDL_bool Android_JNI_ShouldMinimizeOnFocusLoss()
|
||||
SDL_bool Android_JNI_ShouldMinimizeOnFocusLoss(void)
|
||||
{
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
return (*env)->CallStaticBooleanMethod(env, mActivityClass, midShouldMinimizeOnFocusLoss);
|
||||
|
|
@ -1557,7 +1557,7 @@ int Android_JNI_OpenAudioDevice(int iscapture, int device_id, SDL_AudioSpec *spe
|
|||
__android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for output");
|
||||
result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midAudioOpen, spec->freq, audioformat, spec->channels, spec->samples, device_id);
|
||||
}
|
||||
if (result == NULL) {
|
||||
if (!result) {
|
||||
/* Error during audio initialization, error printed from Java */
|
||||
return SDL_SetError("Java-side initialization failed");
|
||||
}
|
||||
|
|
@ -1618,7 +1618,7 @@ int Android_JNI_OpenAudioDevice(int iscapture, int device_id, SDL_AudioSpec *spe
|
|||
return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat);
|
||||
}
|
||||
|
||||
if (jbufobj == NULL) {
|
||||
if (!jbufobj) {
|
||||
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer");
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
|
@ -1879,7 +1879,7 @@ static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent)
|
|||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static void Internal_Android_Create_AssetManager()
|
||||
static void Internal_Android_Create_AssetManager(void)
|
||||
{
|
||||
|
||||
struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
|
||||
|
|
@ -1910,7 +1910,7 @@ static void Internal_Android_Create_AssetManager()
|
|||
javaAssetManagerRef = (*env)->NewGlobalRef(env, javaAssetManager);
|
||||
asset_manager = AAssetManager_fromJava(env, javaAssetManagerRef);
|
||||
|
||||
if (asset_manager == NULL) {
|
||||
if (!asset_manager) {
|
||||
(*env)->DeleteGlobalRef(env, javaAssetManagerRef);
|
||||
Android_JNI_ExceptionOccurred(SDL_TRUE);
|
||||
}
|
||||
|
|
@ -1918,7 +1918,7 @@ static void Internal_Android_Create_AssetManager()
|
|||
LocalReferenceHolder_Cleanup(&refs);
|
||||
}
|
||||
|
||||
static void Internal_Android_Destroy_AssetManager()
|
||||
static void Internal_Android_Destroy_AssetManager(void)
|
||||
{
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
|
||||
|
|
@ -1934,17 +1934,17 @@ int Android_JNI_FileOpen(SDL_RWops *ctx,
|
|||
AAsset *asset = NULL;
|
||||
ctx->hidden.androidio.asset = NULL;
|
||||
|
||||
if (asset_manager == NULL) {
|
||||
if (!asset_manager) {
|
||||
Internal_Android_Create_AssetManager();
|
||||
}
|
||||
|
||||
if (asset_manager == NULL) {
|
||||
return -1;
|
||||
if (!asset_manager) {
|
||||
return SDL_SetError("Couldn't create asset manager");
|
||||
}
|
||||
|
||||
asset = AAssetManager_open(asset_manager, fileName, AASSET_MODE_UNKNOWN);
|
||||
if (asset == NULL) {
|
||||
return -1;
|
||||
if (!asset) {
|
||||
return SDL_SetError("Couldn't open asset '%s'", fileName);
|
||||
}
|
||||
|
||||
ctx->hidden.androidio.asset = (void *)asset;
|
||||
|
|
@ -2022,7 +2022,7 @@ char *Android_JNI_GetClipboardText(void)
|
|||
(*env)->DeleteLocalRef(env, string);
|
||||
}
|
||||
|
||||
return (text == NULL) ? SDL_strdup("") : text;
|
||||
return (!text) ? SDL_strdup("") : text;
|
||||
}
|
||||
|
||||
SDL_bool Android_JNI_HasClipboardText(void)
|
||||
|
|
@ -2153,7 +2153,7 @@ int Android_JNI_GetPowerInfo(int *plugged, int *charged, int *battery, int *seco
|
|||
}
|
||||
|
||||
/* Add all touch devices */
|
||||
void Android_JNI_InitTouch()
|
||||
void Android_JNI_InitTouch(void)
|
||||
{
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
(*env)->CallStaticVoidMethod(env, mActivityClass, midInitTouch);
|
||||
|
|
@ -2208,7 +2208,7 @@ void Android_JNI_SuspendScreenSaver(SDL_bool suspend)
|
|||
Android_JNI_SendMessage(COMMAND_SET_KEEP_SCREEN_ON, (suspend == SDL_FALSE) ? 0 : 1);
|
||||
}
|
||||
|
||||
void Android_JNI_ShowTextInput(SDL_Rect *inputRect)
|
||||
void Android_JNI_ShowScreenKeyboard(SDL_Rect *inputRect)
|
||||
{
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
(*env)->CallStaticBooleanMethod(env, mActivityClass, midShowTextInput,
|
||||
|
|
@ -2218,7 +2218,7 @@ void Android_JNI_ShowTextInput(SDL_Rect *inputRect)
|
|||
inputRect->h);
|
||||
}
|
||||
|
||||
void Android_JNI_HideTextInput(void)
|
||||
void Android_JNI_HideScreenKeyboard(void)
|
||||
{
|
||||
/* has to match Activity constant */
|
||||
const int COMMAND_TEXTEDIT_HIDE = 3;
|
||||
|
|
@ -2343,7 +2343,7 @@ void *SDL_AndroidGetActivity(void)
|
|||
/* See SDL_system.h for caveats on using this function. */
|
||||
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
if (env == NULL) {
|
||||
if (!env) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -2397,7 +2397,7 @@ const char *SDL_AndroidGetInternalStoragePath(void)
|
|||
{
|
||||
static char *s_AndroidInternalFilesPath = NULL;
|
||||
|
||||
if (s_AndroidInternalFilesPath == NULL) {
|
||||
if (!s_AndroidInternalFilesPath) {
|
||||
struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
|
||||
jmethodID mid;
|
||||
jobject context;
|
||||
|
|
@ -2490,7 +2490,7 @@ const char *SDL_AndroidGetExternalStoragePath(void)
|
|||
{
|
||||
static char *s_AndroidExternalFilesPath = NULL;
|
||||
|
||||
if (s_AndroidExternalFilesPath == NULL) {
|
||||
if (!s_AndroidExternalFilesPath) {
|
||||
struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
|
||||
jmethodID mid;
|
||||
jobject context;
|
||||
|
|
@ -2646,16 +2646,16 @@ int Android_JNI_GetLocale(char *buf, size_t buflen)
|
|||
/* Need to re-create the asset manager if locale has changed (SDL_LOCALECHANGED) */
|
||||
Internal_Android_Destroy_AssetManager();
|
||||
|
||||
if (asset_manager == NULL) {
|
||||
if (!asset_manager) {
|
||||
Internal_Android_Create_AssetManager();
|
||||
}
|
||||
|
||||
if (asset_manager == NULL) {
|
||||
if (!asset_manager) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cfg = AConfiguration_new();
|
||||
if (cfg == NULL) {
|
||||
if (!cfg) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -43,8 +43,8 @@ extern void Android_JNI_MinizeWindow(void);
|
|||
extern SDL_bool Android_JNI_ShouldMinimizeOnFocusLoss(void);
|
||||
|
||||
extern SDL_bool Android_JNI_GetAccelerometerValues(float values[3]);
|
||||
extern void Android_JNI_ShowTextInput(SDL_Rect *inputRect);
|
||||
extern void Android_JNI_HideTextInput(void);
|
||||
extern void Android_JNI_ShowScreenKeyboard(SDL_Rect *inputRect);
|
||||
extern void Android_JNI_HideScreenKeyboard(void);
|
||||
extern SDL_bool Android_JNI_IsScreenKeyboardShown(void);
|
||||
extern ANativeWindow *Android_JNI_GetNativeWindow(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -88,7 +88,7 @@ static void kbd_cleanup(void)
|
|||
{
|
||||
struct mouse_info mData;
|
||||
SDL_EVDEV_keyboard_state *kbd = kbd_cleanup_state;
|
||||
if (kbd == NULL) {
|
||||
if (!kbd) {
|
||||
return;
|
||||
}
|
||||
kbd_cleanup_state = NULL;
|
||||
|
|
@ -134,7 +134,7 @@ static void kbd_cleanup_signal_action(int signum, siginfo_t *info, void *ucontex
|
|||
SDL_EVDEV_kbd_reraise_signal(signum);
|
||||
}
|
||||
|
||||
static void kbd_unregister_emerg_cleanup()
|
||||
static void kbd_unregister_emerg_cleanup(void)
|
||||
{
|
||||
int tabidx, signum;
|
||||
|
||||
|
|
@ -179,7 +179,7 @@ static void kbd_register_emerg_cleanup(SDL_EVDEV_keyboard_state *kbd)
|
|||
{
|
||||
int tabidx, signum;
|
||||
|
||||
if (kbd_cleanup_state != NULL) {
|
||||
if (kbd_cleanup_state) {
|
||||
return;
|
||||
}
|
||||
kbd_cleanup_state = kbd;
|
||||
|
|
@ -231,7 +231,7 @@ SDL_EVDEV_keyboard_state *SDL_EVDEV_kbd_init(void)
|
|||
SDL_zero(mData);
|
||||
mData.operation = MOUSE_HIDE;
|
||||
kbd = (SDL_EVDEV_keyboard_state *)SDL_calloc(1, sizeof(SDL_EVDEV_keyboard_state));
|
||||
if (kbd == NULL) {
|
||||
if (!kbd) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -297,7 +297,7 @@ void SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *kbd)
|
|||
{
|
||||
struct mouse_info mData;
|
||||
|
||||
if (kbd == NULL) {
|
||||
if (!kbd) {
|
||||
return;
|
||||
}
|
||||
SDL_zero(mData);
|
||||
|
|
@ -321,6 +321,18 @@ void SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *kbd)
|
|||
SDL_free(kbd);
|
||||
}
|
||||
|
||||
void SDL_EVDEV_kbd_set_muted(SDL_EVDEV_keyboard_state *state, SDL_bool muted)
|
||||
{
|
||||
}
|
||||
|
||||
void SDL_EVDEV_kbd_set_vt_switch_callbacks(SDL_EVDEV_keyboard_state *state, void (*release_callback)(void*), void *release_callback_data, void (*acquire_callback)(void*), void *acquire_callback_data)
|
||||
{
|
||||
}
|
||||
|
||||
void SDL_EVDEV_kbd_update(SDL_EVDEV_keyboard_state *state)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper Functions.
|
||||
*/
|
||||
|
|
@ -475,7 +487,7 @@ void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *kbd, unsigned int keycode,
|
|||
unsigned int final_key_state;
|
||||
unsigned int map_from_key_sym;
|
||||
|
||||
if (kbd == NULL) {
|
||||
if (!kbd) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 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
|
||||
|
|
@ -36,6 +36,7 @@ extern "C" {
|
|||
static XTaskQueueHandle GDK_GlobalTaskQueue;
|
||||
|
||||
PAPPSTATE_REGISTRATION hPLM = {};
|
||||
PAPPCONSTRAIN_REGISTRATION hCPLM = {};
|
||||
HANDLE plmSuspendComplete = nullptr;
|
||||
|
||||
extern "C" DECLSPEC int
|
||||
|
|
@ -177,6 +178,23 @@ SDL_GDKRunApp(SDL_main_func mainFunction, void *reserved)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Register constrain/unconstrain handling */
|
||||
auto raccn = [](BOOLEAN constrained, PVOID context) {
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppConstrainedChangeNotification handler");
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
if (_this) {
|
||||
if (constrained) {
|
||||
SDL_SetKeyboardFocus(NULL);
|
||||
} else {
|
||||
SDL_SetKeyboardFocus(_this->windows);
|
||||
}
|
||||
}
|
||||
};
|
||||
if (RegisterAppConstrainedChangeNotification(raccn, NULL, &hCPLM)) {
|
||||
SDL_SetError("[GDK] Unable to call RegisterAppConstrainedChangeNotification");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Run the application main() code */
|
||||
result = mainFunction(argc, argv);
|
||||
|
||||
|
|
@ -184,6 +202,9 @@ SDL_GDKRunApp(SDL_main_func mainFunction, void *reserved)
|
|||
UnregisterAppStateChangeNotification(hPLM);
|
||||
CloseHandle(plmSuspendComplete);
|
||||
|
||||
/* Unregister constrain/unconstrain handling */
|
||||
UnregisterAppConstrainedChangeNotification(hCPLM);
|
||||
|
||||
/* !!! FIXME: This follows the docs exactly, but for some reason still leaks handles on exit? */
|
||||
/* Terminate the task queue and dispatch any pending tasks */
|
||||
XTaskQueueTerminate(taskQueue, false, nullptr, nullptr);
|
||||
|
|
@ -218,3 +239,24 @@ SDL_GDKSuspendComplete()
|
|||
SetEvent(plmSuspendComplete);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" DECLSPEC int
|
||||
SDL_GDKGetDefaultUser(XUserHandle *outUserHandle)
|
||||
{
|
||||
XAsyncBlock block = { 0 };
|
||||
HRESULT result;
|
||||
|
||||
if (FAILED(result = XUserAddAsync(XUserAddOptions::AddDefaultUserAllowingUI, &block))) {
|
||||
return WIN_SetErrorFromHRESULT("XUserAddAsync", result);
|
||||
}
|
||||
|
||||
do {
|
||||
result = XUserAddResult(&block, outUserHandle);
|
||||
} while (result == E_PENDING);
|
||||
if (FAILED(result)) {
|
||||
return WIN_SetErrorFromHRESULT("XUserAddResult", result);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue