mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-14 16:14:38 +00:00
update sdl to https://github.com/libsdl-org/SDL 22March 2022
This commit is contained in:
parent
ee4253c982
commit
2614274639
1225 changed files with 148950 additions and 51674 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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,16 +23,19 @@
|
|||
#if defined(__WIN32__)
|
||||
#include "core/windows/SDL_windows.h"
|
||||
#elif defined(__OS2__)
|
||||
#include <stdlib.h> /* For _exit() */
|
||||
#include <stdlib.h> /* _exit() */
|
||||
#elif !defined(__WINRT__)
|
||||
#include <unistd.h> /* For _exit(), etc. */
|
||||
#include <unistd.h> /* _exit(), etc. */
|
||||
#endif
|
||||
#if defined(__OS2__)
|
||||
#include "core/os2/SDL_os2.h"
|
||||
#endif
|
||||
#if SDL_THREAD_OS2
|
||||
#include "thread/os2/SDL_systls_c.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* this checks for HAVE_DBUS_DBUS_H internally. */
|
||||
#include "core/linux/SDL_dbus.h"
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#include <emscripten.h>
|
||||
|
|
@ -147,21 +150,26 @@ SDL_SetMainReady(void)
|
|||
int
|
||||
SDL_InitSubSystem(Uint32 flags)
|
||||
{
|
||||
Uint32 flags_initialized = 0;
|
||||
|
||||
if (!SDL_MainIsReady) {
|
||||
SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
|
||||
return -1;
|
||||
return SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
|
||||
}
|
||||
|
||||
/* Clear the error message */
|
||||
SDL_ClearError();
|
||||
|
||||
#if 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))) {
|
||||
/* video or joystick implies events */
|
||||
if ((flags & (SDL_INIT_VIDEO|SDL_INIT_JOYSTICK|SDL_INIT_AUDIO))) {
|
||||
/* video or joystick or audio implies events */
|
||||
flags |= SDL_INIT_EVENTS;
|
||||
}
|
||||
|
||||
|
|
@ -172,7 +180,7 @@ SDL_InitSubSystem(Uint32 flags)
|
|||
#if SDL_VIDEO_DRIVER_WINDOWS
|
||||
if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) {
|
||||
if (SDL_HelperWindowCreate() < 0) {
|
||||
return -1;
|
||||
goto quit_and_error;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -186,26 +194,30 @@ SDL_InitSubSystem(Uint32 flags)
|
|||
#if !SDL_EVENTS_DISABLED
|
||||
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_EVENTS)) {
|
||||
if (SDL_EventsInit() < 0) {
|
||||
return (-1);
|
||||
goto quit_and_error;
|
||||
}
|
||||
}
|
||||
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_EVENTS);
|
||||
flags_initialized |= SDL_INIT_EVENTS;
|
||||
#else
|
||||
return SDL_SetError("SDL not built with events support");
|
||||
SDL_SetError("SDL not built with events support");
|
||||
goto quit_and_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Initialize the timer subsystem */
|
||||
if ((flags & SDL_INIT_TIMER)){
|
||||
#if !SDL_TIMERS_DISABLED
|
||||
#if !SDL_TIMERS_DISABLED && !SDL_TIMER_DUMMY
|
||||
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_TIMER)) {
|
||||
if (SDL_TimerInit() < 0) {
|
||||
return (-1);
|
||||
goto quit_and_error;
|
||||
}
|
||||
}
|
||||
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_TIMER);
|
||||
flags_initialized |= SDL_INIT_TIMER;
|
||||
#else
|
||||
return SDL_SetError("SDL not built with timer support");
|
||||
SDL_SetError("SDL not built with timer support");
|
||||
goto quit_and_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -214,12 +226,14 @@ SDL_InitSubSystem(Uint32 flags)
|
|||
#if !SDL_VIDEO_DISABLED
|
||||
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_VIDEO)) {
|
||||
if (SDL_VideoInit(NULL) < 0) {
|
||||
return (-1);
|
||||
goto quit_and_error;
|
||||
}
|
||||
}
|
||||
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_VIDEO);
|
||||
flags_initialized |= SDL_INIT_VIDEO;
|
||||
#else
|
||||
return SDL_SetError("SDL not built with video support");
|
||||
SDL_SetError("SDL not built with video support");
|
||||
goto quit_and_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -228,12 +242,14 @@ SDL_InitSubSystem(Uint32 flags)
|
|||
#if !SDL_AUDIO_DISABLED
|
||||
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_AUDIO)) {
|
||||
if (SDL_AudioInit(NULL) < 0) {
|
||||
return (-1);
|
||||
goto quit_and_error;
|
||||
}
|
||||
}
|
||||
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_AUDIO);
|
||||
flags_initialized |= SDL_INIT_AUDIO;
|
||||
#else
|
||||
return SDL_SetError("SDL not built with audio support");
|
||||
SDL_SetError("SDL not built with audio support");
|
||||
goto quit_and_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -242,12 +258,14 @@ SDL_InitSubSystem(Uint32 flags)
|
|||
#if !SDL_JOYSTICK_DISABLED
|
||||
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_JOYSTICK)) {
|
||||
if (SDL_JoystickInit() < 0) {
|
||||
return (-1);
|
||||
goto quit_and_error;
|
||||
}
|
||||
}
|
||||
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_JOYSTICK);
|
||||
flags_initialized |= SDL_INIT_JOYSTICK;
|
||||
#else
|
||||
return SDL_SetError("SDL not built with joystick support");
|
||||
SDL_SetError("SDL not built with joystick support");
|
||||
goto quit_and_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -255,12 +273,14 @@ SDL_InitSubSystem(Uint32 flags)
|
|||
#if !SDL_JOYSTICK_DISABLED
|
||||
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_GAMECONTROLLER)) {
|
||||
if (SDL_GameControllerInit() < 0) {
|
||||
return (-1);
|
||||
goto quit_and_error;
|
||||
}
|
||||
}
|
||||
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_GAMECONTROLLER);
|
||||
flags_initialized |= SDL_INIT_GAMECONTROLLER;
|
||||
#else
|
||||
return SDL_SetError("SDL not built with joystick support");
|
||||
SDL_SetError("SDL not built with joystick support");
|
||||
goto quit_and_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -269,12 +289,14 @@ SDL_InitSubSystem(Uint32 flags)
|
|||
#if !SDL_HAPTIC_DISABLED
|
||||
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_HAPTIC)) {
|
||||
if (SDL_HapticInit() < 0) {
|
||||
return (-1);
|
||||
goto quit_and_error;
|
||||
}
|
||||
}
|
||||
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_HAPTIC);
|
||||
flags_initialized |= SDL_INIT_HAPTIC;
|
||||
#else
|
||||
return SDL_SetError("SDL not built with haptic (force feedback) support");
|
||||
SDL_SetError("SDL not built with haptic (force feedback) support");
|
||||
goto quit_and_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -283,16 +305,22 @@ SDL_InitSubSystem(Uint32 flags)
|
|||
#if !SDL_SENSOR_DISABLED
|
||||
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_SENSOR)) {
|
||||
if (SDL_SensorInit() < 0) {
|
||||
return (-1);
|
||||
goto quit_and_error;
|
||||
}
|
||||
}
|
||||
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_SENSOR);
|
||||
flags_initialized |= SDL_INIT_SENSOR;
|
||||
#else
|
||||
return SDL_SetError("SDL not built with sensor support");
|
||||
SDL_SetError("SDL not built with sensor support");
|
||||
goto quit_and_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
||||
quit_and_error:
|
||||
SDL_QuitSubSystem(flags_initialized);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -304,10 +332,10 @@ SDL_Init(Uint32 flags)
|
|||
void
|
||||
SDL_QuitSubSystem(Uint32 flags)
|
||||
{
|
||||
#if defined(__OS2__)
|
||||
#if SDL_THREAD_OS2
|
||||
SDL_OS2TLSFree(); /* thread/os2/SDL_systls.c */
|
||||
#endif
|
||||
#if defined(__OS2__)
|
||||
SDL_OS2Quit();
|
||||
#endif
|
||||
|
||||
|
|
@ -373,7 +401,7 @@ SDL_QuitSubSystem(Uint32 flags)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if !SDL_TIMERS_DISABLED
|
||||
#if !SDL_TIMERS_DISABLED && !SDL_TIMER_DUMMY
|
||||
if ((flags & SDL_INIT_TIMER)) {
|
||||
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_TIMER)) {
|
||||
SDL_TimerQuit();
|
||||
|
|
@ -442,6 +470,10 @@ SDL_Quit(void)
|
|||
SDL_AssertionsQuit();
|
||||
SDL_LogResetPriorities();
|
||||
|
||||
#if SDL_USE_LIBDBUS
|
||||
SDL_DBus_Quit();
|
||||
#endif
|
||||
|
||||
/* Now that every subsystem has been quit, we reset the subsystem refcount
|
||||
* and the list of initialized subsystems.
|
||||
*/
|
||||
|
|
@ -468,12 +500,12 @@ SDL_GetRevision(void)
|
|||
int
|
||||
SDL_GetRevisionNumber(void)
|
||||
{
|
||||
return SDL_REVISION_NUMBER;
|
||||
return 0; /* doesn't make sense without Mercurial. */
|
||||
}
|
||||
|
||||
/* Get the name of the platform */
|
||||
const char *
|
||||
SDL_GetPlatform()
|
||||
SDL_GetPlatform(void)
|
||||
{
|
||||
#if __AIX__
|
||||
return "AIX";
|
||||
|
|
@ -527,13 +559,15 @@ SDL_GetPlatform()
|
|||
return "iOS";
|
||||
#elif __PSP__
|
||||
return "PlayStation Portable";
|
||||
#elif __VITA__
|
||||
return "PlayStation Vita";
|
||||
#else
|
||||
return "Unknown (see SDL_platform.h)";
|
||||
#endif
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_IsTablet()
|
||||
SDL_IsTablet(void)
|
||||
{
|
||||
#if __ANDROID__
|
||||
extern SDL_bool SDL_IsAndroidTablet(void);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -121,7 +121,7 @@ SDL_ClearDataQueue(SDL_DataQueue *queue, const size_t slack)
|
|||
queue->queued_bytes = 0;
|
||||
queue->pool = packet;
|
||||
|
||||
/* Optionally keep some slack in the pool to reduce malloc pressure. */
|
||||
/* Optionally keep some slack in the pool to reduce memory allocation pressure. */
|
||||
for (i = 0; packet && (i < slackpackets); i++) {
|
||||
prev = packet;
|
||||
packet = packet->next;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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,6 +51,11 @@
|
|||
|
||||
#include "SDL_config.h"
|
||||
|
||||
/* If you run into a warning that O_CLOEXEC is redefined, update the SDL configuration header for your platform to add HAVE_O_CLOEXEC */
|
||||
#ifndef HAVE_O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
/* A few #defines to reduce SDL2 footprint.
|
||||
Only effective when library is statically linked.
|
||||
You have to manually edit this file. */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -327,7 +327,7 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
|
|||
#if !defined(HAVE_STDIO_H) && !defined(__WINRT__)
|
||||
BOOL attachResult;
|
||||
DWORD attachError;
|
||||
unsigned long charsWritten;
|
||||
DWORD charsWritten;
|
||||
DWORD consoleMode;
|
||||
|
||||
/* Maybe attach console and get stderr handle */
|
||||
|
|
@ -376,7 +376,7 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
|
|||
#if !defined(HAVE_STDIO_H) && !defined(__WINRT__)
|
||||
/* Screen output to stderr, if console was attached. */
|
||||
if (consoleAttached == 1) {
|
||||
if (!WriteConsole(stderrHandle, tstr, lstrlen(tstr), &charsWritten, NULL)) {
|
||||
if (!WriteConsole(stderrHandle, tstr, (DWORD) SDL_tcslen(tstr), &charsWritten, NULL)) {
|
||||
OutputDebugString(TEXT("Error calling WriteConsole\r\n"));
|
||||
if (GetLastError() == ERROR_NOT_ENOUGH_MEMORY) {
|
||||
OutputDebugString(TEXT("Insufficient heap memory to write message\r\n"));
|
||||
|
|
@ -384,7 +384,7 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
|
|||
}
|
||||
|
||||
} else if (consoleAttached == 2) {
|
||||
if (!WriteFile(stderrHandle, output, lstrlenA(output), &charsWritten, NULL)) {
|
||||
if (!WriteFile(stderrHandle, output, (DWORD) SDL_strlen(output), &charsWritten, NULL)) {
|
||||
OutputDebugString(TEXT("Error calling WriteFile\r\n"));
|
||||
}
|
||||
}
|
||||
|
|
@ -422,6 +422,13 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
|
|||
fprintf(pFile, "%s: %s\n", SDL_priority_prefixes[priority], message);
|
||||
fclose (pFile);
|
||||
}
|
||||
#elif defined(__VITA__)
|
||||
{
|
||||
FILE* pFile;
|
||||
pFile = fopen ("ux0:/data/SDL_Log.txt", "a");
|
||||
fprintf(pFile, "%s: %s\n", SDL_priority_prefixes[priority], message);
|
||||
fclose (pFile);
|
||||
}
|
||||
#endif
|
||||
#if HAVE_STDIO_H
|
||||
fprintf(stderr, "%s: %s\n", SDL_priority_prefixes[priority], message);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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,33 +36,31 @@
|
|||
#endif
|
||||
|
||||
/* The __atomic_load_n() intrinsic showed up in different times for different compilers. */
|
||||
#if defined(HAVE_GCC_ATOMICS)
|
||||
# if defined(__clang__)
|
||||
# if __has_builtin(__atomic_load_n)
|
||||
/* !!! FIXME: this advertises as available in the NDK but uses an external symbol we don't have.
|
||||
It might be in a later NDK or we might need an extra library? --ryan. */
|
||||
# if !defined(__ANDROID__)
|
||||
# define HAVE_ATOMIC_LOAD_N 1
|
||||
# endif
|
||||
# endif
|
||||
# elif defined(__GNUC__)
|
||||
#if defined(__clang__)
|
||||
# if __has_builtin(__atomic_load_n) || defined(HAVE_GCC_ATOMICS)
|
||||
/* !!! FIXME: this advertises as available in the NDK but uses an external symbol we don't have.
|
||||
It might be in a later NDK or we might need an extra library? --ryan. */
|
||||
# if !defined(__ANDROID__)
|
||||
# define HAVE_ATOMIC_LOAD_N 1
|
||||
# endif
|
||||
# endif
|
||||
#elif defined(__GNUC__)
|
||||
# if (__GNUC__ >= 5)
|
||||
# define HAVE_ATOMIC_LOAD_N 1
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__WATCOMC__) && defined(__386__)
|
||||
SDL_COMPILE_TIME_ASSERT(intsize, 4==sizeof(int));
|
||||
#define HAVE_WATCOM_ATOMICS
|
||||
extern _inline int _SDL_xchg_watcom(volatile int *a, int v);
|
||||
extern __inline int _SDL_xchg_watcom(volatile int *a, int v);
|
||||
#pragma aux _SDL_xchg_watcom = \
|
||||
"lock xchg [ecx], eax" \
|
||||
parm [ecx] [eax] \
|
||||
value [eax] \
|
||||
modify exact [eax];
|
||||
|
||||
extern _inline unsigned char _SDL_cmpxchg_watcom(volatile int *a, int newval, int oldval);
|
||||
extern __inline unsigned char _SDL_cmpxchg_watcom(volatile int *a, int newval, int oldval);
|
||||
#pragma aux _SDL_cmpxchg_watcom = \
|
||||
"lock cmpxchg [edx], ecx" \
|
||||
"setz al" \
|
||||
|
|
@ -70,7 +68,7 @@ extern _inline unsigned char _SDL_cmpxchg_watcom(volatile int *a, int newval, in
|
|||
value [al] \
|
||||
modify exact [eax];
|
||||
|
||||
extern _inline int _SDL_xadd_watcom(volatile int *a, int v);
|
||||
extern __inline int _SDL_xadd_watcom(volatile int *a, int v);
|
||||
#pragma aux _SDL_xadd_watcom = \
|
||||
"lock xadd [ecx], eax" \
|
||||
parm [ecx] [eax] \
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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 @@
|
|||
|
||||
#if defined(__WATCOMC__) && defined(__386__)
|
||||
SDL_COMPILE_TIME_ASSERT(locksize, 4==sizeof(SDL_SpinLock));
|
||||
extern _inline int _SDL_xchg_watcom(volatile int *a, int v);
|
||||
extern __inline int _SDL_xchg_watcom(volatile int *a, int v);
|
||||
#pragma aux _SDL_xchg_watcom = \
|
||||
"lock xchg [ecx], eax" \
|
||||
parm [ecx] [eax] \
|
||||
|
|
@ -72,6 +72,12 @@ SDL_AtomicTryLock(SDL_SpinLock *lock)
|
|||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
#elif HAVE_GCC_ATOMICS || 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))
|
||||
return (_InterlockedExchange_acq(lock, 1) == 0);
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
SDL_COMPILE_TIME_ASSERT(locksize, sizeof(*lock) == sizeof(long));
|
||||
return (InterlockedExchange((long*)lock, 1) == 0);
|
||||
|
|
@ -79,9 +85,6 @@ SDL_AtomicTryLock(SDL_SpinLock *lock)
|
|||
#elif defined(__WATCOMC__) && defined(__386__)
|
||||
return _SDL_xchg_watcom(lock, 1) == 0;
|
||||
|
||||
#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
|
||||
return (__sync_lock_test_and_set(lock, 1) == 0);
|
||||
|
||||
#elif defined(__GNUC__) && defined(__arm__) && \
|
||||
(defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__) || \
|
||||
defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || \
|
||||
|
|
@ -140,11 +143,15 @@ SDL_AtomicTryLock(SDL_SpinLock *lock)
|
|||
#define PAUSE_INSTRUCTION() __asm__ __volatile__("pause\n") /* Some assemblers can't do REP NOP, so go with PAUSE. */
|
||||
#elif (defined(__arm__) && __ARM_ARCH__ >= 7) || defined(__aarch64__)
|
||||
#define PAUSE_INSTRUCTION() __asm__ __volatile__("yield" ::: "memory")
|
||||
#elif (defined(__powerpc__) || defined(__powerpc64__))
|
||||
#define PAUSE_INSTRUCTION() __asm__ __volatile__("or 27,27,27");
|
||||
#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
|
||||
#define PAUSE_INSTRUCTION() _mm_pause() /* this is actually "rep nop" and not a SIMD instruction. No inline asm in MSVC x86-64! */
|
||||
#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
|
||||
#define PAUSE_INSTRUCTION() __yield()
|
||||
#elif defined(__WATCOMC__) && defined(__386__)
|
||||
/* watcom assembler rejects PAUSE if CPU < i686, and it refuses REP NOP as an invalid combination. Hardcode the bytes. */
|
||||
extern _inline void PAUSE_INSTRUCTION(void);
|
||||
extern __inline void PAUSE_INSTRUCTION(void);
|
||||
#pragma aux PAUSE_INSTRUCTION = "db 0f3h,90h"
|
||||
#else
|
||||
#define PAUSE_INSTRUCTION()
|
||||
|
|
@ -169,7 +176,13 @@ SDL_AtomicLock(SDL_SpinLock *lock)
|
|||
void
|
||||
SDL_AtomicUnlock(SDL_SpinLock *lock)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
#if HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
|
||||
__sync_lock_release(lock);
|
||||
|
||||
#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
|
||||
_InterlockedExchange_rel(lock, 0);
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
_ReadWriteBarrier();
|
||||
*lock = 0;
|
||||
|
||||
|
|
@ -177,9 +190,6 @@ SDL_AtomicUnlock(SDL_SpinLock *lock)
|
|||
SDL_CompilerBarrier ();
|
||||
*lock = 0;
|
||||
|
||||
#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
|
||||
__sync_lock_release(lock);
|
||||
|
||||
#elif defined(__SOLARIS__)
|
||||
/* Used for Solaris when not using gcc. */
|
||||
*lock = 0;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -47,9 +47,6 @@ static const AudioBootStrap *const bootstrap[] = {
|
|||
#if SDL_AUDIO_DRIVER_NETBSD
|
||||
&NETBSDAUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_OSS
|
||||
&DSP_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_QSA
|
||||
&QSAAUDIO_bootstrap,
|
||||
#endif
|
||||
|
|
@ -89,6 +86,9 @@ static const AudioBootStrap *const bootstrap[] = {
|
|||
#if SDL_AUDIO_DRIVER_FUSIONSOUND
|
||||
&FUSIONSOUND_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_AAUDIO
|
||||
&aaudio_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_OPENSLES
|
||||
&openslES_bootstrap,
|
||||
#endif
|
||||
|
|
@ -98,12 +98,21 @@ static const AudioBootStrap *const bootstrap[] = {
|
|||
#if SDL_AUDIO_DRIVER_PSP
|
||||
&PSPAUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_VITA
|
||||
&VITAAUD_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_EMSCRIPTEN
|
||||
&EMSCRIPTENAUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_JACK
|
||||
&JACK_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_PIPEWIRE
|
||||
&PIPEWIRE_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_OSS
|
||||
&DSP_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_OS2
|
||||
&OS2AUDIO_bootstrap,
|
||||
#endif
|
||||
|
|
@ -220,9 +229,9 @@ SDL_AudioDetectDevices_Default(void)
|
|||
SDL_assert(current_audio.impl.OnlyHasDefaultOutputDevice);
|
||||
SDL_assert(current_audio.impl.OnlyHasDefaultCaptureDevice || !current_audio.impl.HasCaptureSupport);
|
||||
|
||||
SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) ((size_t) 0x1));
|
||||
SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, NULL, (void *) ((size_t) 0x1));
|
||||
if (current_audio.impl.HasCaptureSupport) {
|
||||
SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, (void *) ((size_t) 0x2));
|
||||
SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *) ((size_t) 0x2));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -236,11 +245,6 @@ SDL_AudioThreadDeinit_Default(_THIS)
|
|||
{ /* no-op. */
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_AudioBeginLoopIteration_Default(_THIS)
|
||||
{ /* no-op. */
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_AudioWaitDevice_Default(_THIS)
|
||||
{ /* no-op. */
|
||||
|
|
@ -268,11 +272,6 @@ SDL_AudioFlushCapture_Default(_THIS)
|
|||
{ /* no-op. */
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_AudioPrepareToClose_Default(_THIS)
|
||||
{ /* no-op. */
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_AudioCloseDevice_Default(_THIS)
|
||||
{ /* no-op. */
|
||||
|
|
@ -290,7 +289,7 @@ SDL_AudioFreeDeviceHandle_Default(void *handle)
|
|||
|
||||
|
||||
static int
|
||||
SDL_AudioOpenDevice_Default(_THIS, void *handle, const char *devname, int iscapture)
|
||||
SDL_AudioOpenDevice_Default(_THIS, const char *devname)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
|
@ -325,11 +324,6 @@ SDL_AudioUnlockDevice_Default(SDL_AudioDevice * device)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_AudioLockOrUnlockDeviceWithNoMixerLock(SDL_AudioDevice * device)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
finish_audio_entry_points_init(void)
|
||||
{
|
||||
|
|
@ -338,14 +332,6 @@ finish_audio_entry_points_init(void)
|
|||
* blindly call them without having to check for validity first.
|
||||
*/
|
||||
|
||||
if (current_audio.impl.SkipMixerLock) {
|
||||
if (current_audio.impl.LockDevice == NULL) {
|
||||
current_audio.impl.LockDevice = SDL_AudioLockOrUnlockDeviceWithNoMixerLock;
|
||||
}
|
||||
if (current_audio.impl.UnlockDevice == NULL) {
|
||||
current_audio.impl.UnlockDevice = SDL_AudioLockOrUnlockDeviceWithNoMixerLock;
|
||||
}
|
||||
}
|
||||
|
||||
#define FILL_STUB(x) \
|
||||
if (current_audio.impl.x == NULL) { \
|
||||
|
|
@ -355,13 +341,11 @@ finish_audio_entry_points_init(void)
|
|||
FILL_STUB(OpenDevice);
|
||||
FILL_STUB(ThreadInit);
|
||||
FILL_STUB(ThreadDeinit);
|
||||
FILL_STUB(BeginLoopIteration);
|
||||
FILL_STUB(WaitDevice);
|
||||
FILL_STUB(PlayDevice);
|
||||
FILL_STUB(GetDeviceBuf);
|
||||
FILL_STUB(CaptureFromDevice);
|
||||
FILL_STUB(FlushCapture);
|
||||
FILL_STUB(PrepareToClose);
|
||||
FILL_STUB(CloseDevice);
|
||||
FILL_STUB(LockDevice);
|
||||
FILL_STUB(UnlockDevice);
|
||||
|
|
@ -374,7 +358,7 @@ finish_audio_entry_points_init(void)
|
|||
/* device hotplug support... */
|
||||
|
||||
static int
|
||||
add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
|
||||
add_audio_device(const char *name, SDL_AudioSpec *spec, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
|
||||
{
|
||||
int retval = -1;
|
||||
SDL_AudioDeviceItem *item;
|
||||
|
|
@ -397,6 +381,11 @@ add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices,
|
|||
|
||||
item->dupenum = 0;
|
||||
item->name = item->original_name;
|
||||
if (spec != NULL) {
|
||||
SDL_memcpy(&item->spec, spec, sizeof(SDL_AudioSpec));
|
||||
} else {
|
||||
SDL_zero(item->spec);
|
||||
}
|
||||
item->handle = handle;
|
||||
|
||||
SDL_LockMutex(current_audio.detectionLock);
|
||||
|
|
@ -415,8 +404,7 @@ add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices,
|
|||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
SDL_free(item->original_name);
|
||||
SDL_free(item);
|
||||
SDL_OutOfMemory();
|
||||
return -1;
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
SDL_snprintf(replacement, len, "%s (%d)", name, dupenum + 1);
|
||||
|
|
@ -434,16 +422,16 @@ add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices,
|
|||
}
|
||||
|
||||
static SDL_INLINE int
|
||||
add_capture_device(const char *name, void *handle)
|
||||
add_capture_device(const char *name, SDL_AudioSpec *spec, void *handle)
|
||||
{
|
||||
SDL_assert(current_audio.impl.HasCaptureSupport);
|
||||
return add_audio_device(name, handle, ¤t_audio.inputDevices, ¤t_audio.inputDeviceCount);
|
||||
return add_audio_device(name, spec, handle, ¤t_audio.inputDevices, ¤t_audio.inputDeviceCount);
|
||||
}
|
||||
|
||||
static SDL_INLINE int
|
||||
add_output_device(const char *name, void *handle)
|
||||
add_output_device(const char *name, SDL_AudioSpec *spec, void *handle)
|
||||
{
|
||||
return add_audio_device(name, handle, ¤t_audio.outputDevices, ¤t_audio.outputDeviceCount);
|
||||
return add_audio_device(name, spec, handle, ¤t_audio.outputDevices, ¤t_audio.outputDeviceCount);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -469,9 +457,9 @@ free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
|
|||
|
||||
/* The audio backends call this when a new device is plugged in. */
|
||||
void
|
||||
SDL_AddAudioDevice(const int iscapture, const char *name, void *handle)
|
||||
SDL_AddAudioDevice(const SDL_bool iscapture, const char *name, SDL_AudioSpec *spec, void *handle)
|
||||
{
|
||||
const int device_index = iscapture ? add_capture_device(name, handle) : add_output_device(name, handle);
|
||||
const int device_index = iscapture ? add_capture_device(name, spec, handle) : add_output_device(name, spec, handle);
|
||||
if (device_index != -1) {
|
||||
/* Post the event, if desired */
|
||||
if (SDL_GetEventState(SDL_AUDIODEVICEADDED) == SDL_ENABLE) {
|
||||
|
|
@ -531,7 +519,7 @@ mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *remove
|
|||
|
||||
/* The audio backends call this when a device is removed from the system. */
|
||||
void
|
||||
SDL_RemoveAudioDevice(const int iscapture, void *handle)
|
||||
SDL_RemoveAudioDevice(const SDL_bool iscapture, void *handle)
|
||||
{
|
||||
int device_index;
|
||||
SDL_AudioDevice *device = NULL;
|
||||
|
|
@ -673,7 +661,7 @@ SDL_ClearQueuedAudio(SDL_AudioDeviceID devid)
|
|||
/* Blank out the device and release the mutex. Free it afterwards. */
|
||||
current_audio.impl.LockDevice(device);
|
||||
|
||||
/* Keep up to two packets in the pool to reduce future malloc pressure. */
|
||||
/* Keep up to two packets in the pool to reduce future memory allocation pressure. */
|
||||
SDL_ClearDataQueue(device->buffer_queue, SDL_AUDIOBUFFERQUEUE_PACKETLEN * 2);
|
||||
|
||||
current_audio.impl.UnlockDevice(device);
|
||||
|
|
@ -709,7 +697,6 @@ SDL_RunAudio(void *devicep)
|
|||
|
||||
/* Loop, filling the audio buffers */
|
||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||
current_audio.impl.BeginLoopIteration(device);
|
||||
data_len = device->callbackspec.size;
|
||||
|
||||
/* Fill the current buffer with sound */
|
||||
|
|
@ -748,7 +735,7 @@ SDL_RunAudio(void *devicep)
|
|||
int got;
|
||||
data = SDL_AtomicGet(&device->enabled) ? current_audio.impl.GetDeviceBuf(device) : NULL;
|
||||
got = SDL_AudioStreamGet(device->stream, data ? data : device->work_buffer, device->spec.size);
|
||||
SDL_assert((got < 0) || (got == device->spec.size));
|
||||
SDL_assert((got <= 0) || (got == device->spec.size));
|
||||
|
||||
if (data == NULL) { /* device is having issues... */
|
||||
const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
|
||||
|
|
@ -772,8 +759,6 @@ SDL_RunAudio(void *devicep)
|
|||
}
|
||||
}
|
||||
|
||||
current_audio.impl.PrepareToClose(device);
|
||||
|
||||
/* Wait for the audio to drain. */
|
||||
SDL_Delay(((device->spec.samples * 1000) / device->spec.freq) * 2);
|
||||
|
||||
|
|
@ -817,8 +802,6 @@ SDL_CaptureAudio(void *devicep)
|
|||
int still_need;
|
||||
Uint8 *ptr;
|
||||
|
||||
current_audio.impl.BeginLoopIteration(device);
|
||||
|
||||
if (SDL_AtomicGet(&device->paused)) {
|
||||
SDL_Delay(delay); /* just so we don't cook the CPU. */
|
||||
if (device->stream) {
|
||||
|
|
@ -942,15 +925,13 @@ SDL_GetAudioDriver(int index)
|
|||
int
|
||||
SDL_AudioInit(const char *driver_name)
|
||||
{
|
||||
int i = 0;
|
||||
int initialized = 0;
|
||||
int tried_to_init = 0;
|
||||
int i;
|
||||
SDL_bool initialized = SDL_FALSE, tried_to_init = SDL_FALSE;
|
||||
|
||||
if (SDL_WasInit(SDL_INIT_AUDIO)) {
|
||||
if (SDL_GetCurrentAudioDriver()) {
|
||||
SDL_AudioQuit(); /* shutdown driver if already running. */
|
||||
}
|
||||
|
||||
SDL_zero(current_audio);
|
||||
SDL_zeroa(open_devices);
|
||||
|
||||
/* Select the proper audio driver */
|
||||
|
|
@ -958,19 +939,47 @@ SDL_AudioInit(const char *driver_name)
|
|||
driver_name = SDL_getenv("SDL_AUDIODRIVER");
|
||||
}
|
||||
|
||||
for (i = 0; (!initialized) && (bootstrap[i]); ++i) {
|
||||
/* make sure we should even try this driver before doing so... */
|
||||
const AudioBootStrap *backend = bootstrap[i];
|
||||
if ((driver_name && (SDL_strncasecmp(backend->name, driver_name, SDL_strlen(driver_name)) != 0)) ||
|
||||
(!driver_name && backend->demand_only)) {
|
||||
continue;
|
||||
}
|
||||
if (driver_name != NULL && *driver_name != 0) {
|
||||
const char *driver_attempt = driver_name;
|
||||
while (driver_attempt != NULL && *driver_attempt != 0 && !initialized) {
|
||||
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_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)) {
|
||||
driver_attempt = "pulseaudio";
|
||||
driver_attempt_len = SDL_strlen("pulseaudio");
|
||||
}
|
||||
#endif
|
||||
|
||||
tried_to_init = 1;
|
||||
SDL_zero(current_audio);
|
||||
current_audio.name = backend->name;
|
||||
current_audio.desc = backend->desc;
|
||||
initialized = backend->init(¤t_audio.impl);
|
||||
for (i = 0; bootstrap[i]; ++i) {
|
||||
if ((driver_attempt_len == SDL_strlen(bootstrap[i]->name)) &&
|
||||
(SDL_strncasecmp(bootstrap[i]->name, driver_attempt, driver_attempt_len) == 0)) {
|
||||
tried_to_init = SDL_TRUE;
|
||||
SDL_zero(current_audio);
|
||||
current_audio.name = bootstrap[i]->name;
|
||||
current_audio.desc = bootstrap[i]->desc;
|
||||
initialized = bootstrap[i]->init(¤t_audio.impl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
driver_attempt = (driver_attempt_end != NULL) ? (driver_attempt_end + 1) : NULL;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; (!initialized) && (bootstrap[i]); ++i) {
|
||||
if(bootstrap[i]->demand_only) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tried_to_init = SDL_TRUE;
|
||||
SDL_zero(current_audio);
|
||||
current_audio.name = bootstrap[i]->name;
|
||||
current_audio.desc = bootstrap[i]->desc;
|
||||
initialized = bootstrap[i]->init(¤t_audio.impl);
|
||||
}
|
||||
}
|
||||
|
||||
if (!initialized) {
|
||||
|
|
@ -1049,7 +1058,7 @@ SDL_GetNumAudioDevices(int iscapture)
|
|||
{
|
||||
int retval = 0;
|
||||
|
||||
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
|
||||
if (!SDL_GetCurrentAudioDriver()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -1072,39 +1081,63 @@ SDL_GetNumAudioDevices(int iscapture)
|
|||
const char *
|
||||
SDL_GetAudioDeviceName(int index, int iscapture)
|
||||
{
|
||||
const char *retval = NULL;
|
||||
SDL_AudioDeviceItem *item;
|
||||
int i;
|
||||
const char *retval;
|
||||
|
||||
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
|
||||
if (!SDL_GetCurrentAudioDriver()) {
|
||||
SDL_SetError("Audio subsystem is not initialized");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (iscapture && !current_audio.impl.HasCaptureSupport) {
|
||||
SDL_SetError("No capture support");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (index >= 0) {
|
||||
SDL_AudioDeviceItem *item;
|
||||
int i;
|
||||
|
||||
SDL_LockMutex(current_audio.detectionLock);
|
||||
item = iscapture ? current_audio.inputDevices : current_audio.outputDevices;
|
||||
i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
|
||||
if (index < i) {
|
||||
for (i--; i > index; i--, item = item->next) {
|
||||
SDL_assert(item != NULL);
|
||||
}
|
||||
SDL_LockMutex(current_audio.detectionLock);
|
||||
item = iscapture ? current_audio.inputDevices : current_audio.outputDevices;
|
||||
i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
|
||||
if (index >= 0 && index < i) {
|
||||
for (i--; i > index; i--, item = item->next) {
|
||||
SDL_assert(item != NULL);
|
||||
retval = item->name;
|
||||
}
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
SDL_assert(item != NULL);
|
||||
retval = item->name;
|
||||
} else {
|
||||
SDL_InvalidParamError("index");
|
||||
retval = NULL;
|
||||
}
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SDL_GetAudioDeviceSpec(int index, int iscapture, SDL_AudioSpec *spec)
|
||||
{
|
||||
SDL_AudioDeviceItem *item;
|
||||
int i, retval;
|
||||
|
||||
if (spec == NULL) {
|
||||
return SDL_InvalidParamError("spec");
|
||||
}
|
||||
|
||||
if (retval == NULL) {
|
||||
SDL_SetError("No such device");
|
||||
if (!SDL_GetCurrentAudioDriver()) {
|
||||
return SDL_SetError("Audio subsystem is not initialized");
|
||||
}
|
||||
|
||||
SDL_LockMutex(current_audio.detectionLock);
|
||||
item = iscapture ? current_audio.inputDevices : current_audio.outputDevices;
|
||||
i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
|
||||
if (index >= 0 && index < i) {
|
||||
for (i--; i > index; i--, item = item->next) {
|
||||
SDL_assert(item != NULL);
|
||||
}
|
||||
SDL_assert(item != NULL);
|
||||
SDL_memcpy(spec, &item->spec, sizeof(SDL_AudioSpec));
|
||||
retval = 0;
|
||||
} else {
|
||||
retval = SDL_InvalidParamError("index");
|
||||
}
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -1181,13 +1214,14 @@ prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared)
|
|||
const char *env = SDL_getenv("SDL_AUDIO_CHANNELS");
|
||||
if ((!env) || ((prepared->channels = (Uint8) SDL_atoi(env)) == 0)) {
|
||||
prepared->channels = 2; /* a reasonable default */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: /* Mono */
|
||||
case 2: /* Stereo */
|
||||
case 4: /* Quadrophonic */
|
||||
case 6: /* 5.1 surround */
|
||||
case 7: /* 6.1 surround */
|
||||
case 8: /* 7.1 surround */
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1228,7 +1262,7 @@ open_audio_device(const char *devname, int iscapture,
|
|||
void *handle = NULL;
|
||||
int i = 0;
|
||||
|
||||
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
|
||||
if (!SDL_GetCurrentAudioDriver()) {
|
||||
SDL_SetError("Audio subsystem is not initialized");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1340,7 +1374,7 @@ open_audio_device(const char *devname, int iscapture,
|
|||
SDL_AtomicSet(&device->enabled, 1);
|
||||
|
||||
/* Create a mutex for locking the sound buffers */
|
||||
if (!current_audio.impl.SkipMixerLock) {
|
||||
if (current_audio.impl.LockDevice == SDL_AudioLockDevice_Default) {
|
||||
device->mixer_lock = SDL_CreateMutex();
|
||||
if (device->mixer_lock == NULL) {
|
||||
close_audio_device(device);
|
||||
|
|
@ -1349,7 +1383,7 @@ open_audio_device(const char *devname, int iscapture,
|
|||
}
|
||||
}
|
||||
|
||||
if (current_audio.impl.OpenDevice(device, handle, devname, iscapture) < 0) {
|
||||
if (current_audio.impl.OpenDevice(device, devname) < 0) {
|
||||
close_audio_device(device);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1474,8 +1508,7 @@ SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
|
|||
|
||||
/* SDL_OpenAudio() is legacy and can only act on Device ID #1. */
|
||||
if (open_devices[0] != NULL) {
|
||||
SDL_SetError("Audio device is already opened");
|
||||
return -1;
|
||||
return SDL_SetError("Audio device is already opened");
|
||||
}
|
||||
|
||||
if (obtained) {
|
||||
|
|
@ -1672,7 +1705,7 @@ SDL_SilenceValueForFormat(const SDL_AudioFormat format)
|
|||
{
|
||||
switch (format) {
|
||||
/* !!! FIXME: 0x80 isn't perfect for U16, but we can't fit 0x8000 in a
|
||||
!!! FIXME: byte for memset() use. This is actually 0.1953 percent
|
||||
!!! FIXME: byte for SDL_memset() use. This is actually 0.1953 percent
|
||||
!!! FIXME: off from silence. Maybe just don't use U16. */
|
||||
case AUDIO_U16LSB:
|
||||
case AUDIO_U16MSB:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -35,15 +35,40 @@
|
|||
|
||||
#define DEBUG_AUDIOSTREAM 0
|
||||
|
||||
#ifdef __ARM_NEON
|
||||
#define HAVE_NEON_INTRINSICS 1
|
||||
#endif
|
||||
|
||||
#ifdef __SSE__
|
||||
#define HAVE_SSE_INTRINSICS 1
|
||||
#endif
|
||||
|
||||
#ifdef __SSE3__
|
||||
#define HAVE_SSE3_INTRINSICS 1
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H)
|
||||
#define HAVE_AVX_INTRINSICS 1
|
||||
#endif
|
||||
#if defined __clang__
|
||||
# if (!__has_attribute(target))
|
||||
# undef HAVE_AVX_INTRINSICS
|
||||
# endif
|
||||
# if (defined(_MSC_VER) || defined(__SCE__)) && !defined(__AVX__)
|
||||
# undef HAVE_AVX_INTRINSICS
|
||||
# endif
|
||||
#elif defined __GNUC__
|
||||
# if (__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 9)
|
||||
# undef HAVE_AVX_INTRINSICS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if HAVE_SSE3_INTRINSICS
|
||||
/* Convert from stereo to mono. Average left and right. */
|
||||
static void SDLCALL
|
||||
SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
{
|
||||
const __m128 divby2 = _mm_set1_ps(0.5f);
|
||||
float *dst = (float *) cvt->buf;
|
||||
const float *src = dst;
|
||||
int i = cvt->len_cvt / 8;
|
||||
|
|
@ -51,15 +76,12 @@ SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
LOG_DEBUG_CONVERT("stereo", "mono (using SSE3)");
|
||||
SDL_assert(format == AUDIO_F32SYS);
|
||||
|
||||
/* We can only do this if dst is aligned to 16 bytes; since src is the
|
||||
same pointer and it moves by 2, it can't be forcibly aligned. */
|
||||
if ((((size_t) dst) & 15) == 0) {
|
||||
/* Aligned! Do SSE blocks as long as we have 16 bytes available. */
|
||||
const __m128 divby2 = _mm_set1_ps(0.5f);
|
||||
while (i >= 4) { /* 4 * float32 */
|
||||
_mm_store_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_load_ps(src), _mm_load_ps(src+4)), divby2));
|
||||
i -= 4; src += 8; dst += 4;
|
||||
}
|
||||
/* Do SSE blocks as long as we have 16 bytes available.
|
||||
Just use unaligned load/stores, if the memory at runtime is
|
||||
aligned it'll be just as fast on modern processors */
|
||||
while (i >= 4) { /* 4 * float32 */
|
||||
_mm_storeu_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_load_ps(src), _mm_loadu_ps(src+4)), divby2));
|
||||
i -= 4; src += 8; dst += 4;
|
||||
}
|
||||
|
||||
/* Finish off any leftovers with scalar operations. */
|
||||
|
|
@ -96,6 +118,191 @@ SDL_ConvertStereoToMono(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
}
|
||||
}
|
||||
|
||||
#if HAVE_AVX_INTRINSICS
|
||||
/* MSVC will always accept AVX intrinsics when compiling for x64 */
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
__attribute__((target("avx")))
|
||||
#endif
|
||||
/* Convert from 5.1 to stereo. Average left and right, distribute center, discard LFE. */
|
||||
static void SDLCALL
|
||||
SDL_Convert51ToStereo_AVX(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
{
|
||||
float *dst = (float *) cvt->buf;
|
||||
const float *src = dst;
|
||||
int i = cvt->len_cvt / (sizeof (float) * 6);
|
||||
const float two_fifths_f = 1.0f / 2.5f;
|
||||
const __m256 two_fifths_v = _mm256_set1_ps(two_fifths_f);
|
||||
const __m256 half = _mm256_set1_ps(0.5f);
|
||||
|
||||
LOG_DEBUG_CONVERT("5.1", "stereo (using AVX)");
|
||||
SDL_assert(format == AUDIO_F32SYS);
|
||||
|
||||
/* SDL's 5.1 layout: FL+FR+FC+LFE+BL+BR */
|
||||
while (i >= 4) {
|
||||
__m256 in0 = _mm256_loadu_ps(src + 0); /* 0FL 0FR 0FC 0LF 0BL 0BR 1FL 1FR */
|
||||
__m256 in1 = _mm256_loadu_ps(src + 8); /* 1FC 1LF 1BL 1BR 2FL 2FR 2FC 2LF */
|
||||
__m256 in2 = _mm256_loadu_ps(src + 16); /* 2BL 2BR 3FL 3FR 3FC 3LF 3BL 3BR */
|
||||
|
||||
/* 0FL 0FR 0FC 0LF 2FL 2FR 2FC 2LF */
|
||||
__m256 temp0 = _mm256_blend_ps(in0, in1, 0xF0);
|
||||
/* 1FC 1LF 1BL 1BR 3FC 3LF 3BL 3BR */
|
||||
__m256 temp1 = _mm256_blend_ps(in1, in2, 0xF0);
|
||||
|
||||
/* 0FC 0FC 1FC 1FC 2FC 2FC 3FC 3FC */
|
||||
__m256 fc_distributed = _mm256_mul_ps(half, _mm256_shuffle_ps(temp0, temp1, _MM_SHUFFLE(0, 0, 2, 2)));
|
||||
|
||||
/* 0FL 0FR 1BL 1BR 2FL 2FR 3BL 3BR */
|
||||
__m256 permuted0 = _mm256_blend_ps(temp0, temp1, 0xCC);
|
||||
/* 0BL 0BR 1FL 1FR 2BL 2BR 3FL 3FR */
|
||||
__m256 permuted1 = _mm256_permute2f128_ps(in0, in2, 0x21);
|
||||
|
||||
/* 0FL 0FR 1BL 1BR 2FL 2FR 3BL 3BR */
|
||||
/* + 0BL 0BR 1FL 1FR 2BL 2BR 3FL 3FR */
|
||||
/* = 0L 0R 1L 1R 2L 2R 3L 3R */
|
||||
__m256 out = _mm256_add_ps(permuted0, permuted1);
|
||||
out = _mm256_add_ps(out, fc_distributed);
|
||||
out = _mm256_mul_ps(out, two_fifths_v);
|
||||
|
||||
_mm256_storeu_ps(dst, out);
|
||||
|
||||
i -= 4; src += 24; dst += 8;
|
||||
}
|
||||
|
||||
|
||||
/* Finish off any leftovers with scalar operations. */
|
||||
while (i) {
|
||||
const float front_center_distributed = src[2] * 0.5f;
|
||||
dst[0] = (src[0] + front_center_distributed + src[4]) * two_fifths_f; /* left */
|
||||
dst[1] = (src[1] + front_center_distributed + src[5]) * two_fifths_f; /* right */
|
||||
i--; src += 6; dst+=2;
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 3;
|
||||
if (cvt->filters[++cvt->filter_index]) {
|
||||
cvt->filters[cvt->filter_index] (cvt, format);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_SSE_INTRINSICS
|
||||
/* Convert from 5.1 to stereo. Average left and right, distribute center, discard LFE. */
|
||||
static void SDLCALL
|
||||
SDL_Convert51ToStereo_SSE(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
{
|
||||
float *dst = (float *) cvt->buf;
|
||||
const float *src = dst;
|
||||
int i = cvt->len_cvt / (sizeof (float) * 6);
|
||||
const float two_fifths_f = 1.0f / 2.5f;
|
||||
const __m128 two_fifths_v = _mm_set1_ps(two_fifths_f);
|
||||
const __m128 half = _mm_set1_ps(0.5f);
|
||||
|
||||
LOG_DEBUG_CONVERT("5.1", "stereo (using SSE)");
|
||||
SDL_assert(format == AUDIO_F32SYS);
|
||||
|
||||
/* SDL's 5.1 layout: FL+FR+FC+LFE+BL+BR */
|
||||
/* Just use unaligned load/stores, if the memory at runtime is */
|
||||
/* aligned it'll be just as fast on modern processors */
|
||||
while (i >= 2) {
|
||||
/* Two 5.1 samples (12 floats) fit nicely in three 128bit */
|
||||
/* registers. Using shuffles they can be rearranged so that */
|
||||
/* the conversion math can be vectorized. */
|
||||
__m128 in0 = _mm_loadu_ps(src); /* 0FL 0FR 0FC 0LF */
|
||||
__m128 in1 = _mm_loadu_ps(src + 4); /* 0BL 0BR 1FL 1FR */
|
||||
__m128 in2 = _mm_loadu_ps(src + 8); /* 1FC 1LF 1BL 1BR */
|
||||
|
||||
/* 0FC 0FC 1FC 1FC */
|
||||
__m128 fc_distributed = _mm_mul_ps(half, _mm_shuffle_ps(in0, in2, _MM_SHUFFLE(0, 0, 2, 2)));
|
||||
|
||||
/* 0FL 0FR 1BL 1BR */
|
||||
__m128 blended = _mm_shuffle_ps(in0, in2, _MM_SHUFFLE(3, 2, 1, 0));
|
||||
|
||||
/* 0FL 0FR 1BL 1BR */
|
||||
/* + 0BL 0BR 1FL 1FR */
|
||||
/* = 0L 0R 1L 1R */
|
||||
__m128 out = _mm_add_ps(blended, in1);
|
||||
out = _mm_add_ps(out, fc_distributed);
|
||||
out = _mm_mul_ps(out, two_fifths_v);
|
||||
|
||||
_mm_storeu_ps(dst, out);
|
||||
|
||||
i -= 2; src += 12; dst += 4;
|
||||
}
|
||||
|
||||
|
||||
/* Finish off any leftovers with scalar operations. */
|
||||
while (i) {
|
||||
const float front_center_distributed = src[2] * 0.5f;
|
||||
dst[0] = (src[0] + front_center_distributed + src[4]) * two_fifths_f; /* left */
|
||||
dst[1] = (src[1] + front_center_distributed + src[5]) * two_fifths_f; /* right */
|
||||
i--; src += 6; dst+=2;
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 3;
|
||||
if (cvt->filters[++cvt->filter_index]) {
|
||||
cvt->filters[cvt->filter_index] (cvt, format);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_NEON_INTRINSICS
|
||||
/* Convert from 5.1 to stereo. Average left and right, distribute center, discard LFE. */
|
||||
static void SDLCALL
|
||||
SDL_Convert51ToStereo_NEON(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
{
|
||||
float *dst = (float *) cvt->buf;
|
||||
const float *src = dst;
|
||||
int i = cvt->len_cvt / (sizeof (float) * 6);
|
||||
const float two_fifths_f = 1.0f / 2.5f;
|
||||
const float32x4_t two_fifths_v = vdupq_n_f32(two_fifths_f);
|
||||
const float32x4_t half = vdupq_n_f32(0.5f);
|
||||
|
||||
LOG_DEBUG_CONVERT("5.1", "stereo (using NEON)");
|
||||
SDL_assert(format == AUDIO_F32SYS);
|
||||
|
||||
/* SDL's 5.1 layout: FL+FR+FC+LFE+BL+BR */
|
||||
|
||||
/* Just use unaligned load/stores, it's the same NEON instructions and
|
||||
hopefully even unaligned NEON is faster than the scalar fallback. */
|
||||
while (i >= 2) {
|
||||
/* Two 5.1 samples (12 floats) fit nicely in three 128bit */
|
||||
/* registers. Using shuffles they can be rearranged so that */
|
||||
/* the conversion math can be vectorized. */
|
||||
const float32x4_t in0 = vld1q_f32(src); /* 0FL 0FR 0FC 0LF */
|
||||
const float32x4_t in1 = vld1q_f32(src + 4); /* 0BL 0BR 1FL 1FR */
|
||||
const float32x4_t in2 = vld1q_f32(src + 8); /* 1FC 1LF 1BL 1BR */
|
||||
|
||||
/* 0FC 0FC 1FC 1FC */
|
||||
const float32x4_t fc_distributed = vmulq_f32(half, vcombine_f32(vdup_lane_f32(vget_high_f32(in0), 0), vdup_lane_f32(vget_low_f32(in2), 0)));
|
||||
|
||||
/* 0FL 0FR 1BL 1BR */
|
||||
const float32x4_t blended = vcombine_f32(vget_low_f32(in0), vget_high_f32(in2));
|
||||
|
||||
/* 0FL 0FR 1BL 1BR */
|
||||
/* + 0BL 0BR 1FL 1FR */
|
||||
/* = 0L 0R 1L 1R */
|
||||
float32x4_t out = vaddq_f32(blended, in1);
|
||||
out = vaddq_f32(out, fc_distributed);
|
||||
out = vmulq_f32(out, two_fifths_v);
|
||||
|
||||
vst1q_f32(dst, out);
|
||||
|
||||
i -= 2; src += 12; dst += 4;
|
||||
}
|
||||
|
||||
/* Finish off any leftovers with scalar operations. */
|
||||
while (i) {
|
||||
const float front_center_distributed = src[2] * 0.5f;
|
||||
dst[0] = (src[0] + front_center_distributed + src[4]) * two_fifths_f; /* left */
|
||||
dst[1] = (src[1] + front_center_distributed + src[5]) * two_fifths_f; /* right */
|
||||
i--; src += 6; dst+=2;
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 3;
|
||||
if (cvt->filters[++cvt->filter_index]) {
|
||||
cvt->filters[cvt->filter_index] (cvt, format);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Convert from 5.1 to stereo. Average left and right, distribute center, discard LFE. */
|
||||
static void SDLCALL
|
||||
|
|
@ -104,6 +311,7 @@ SDL_Convert51ToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
float *dst = (float *) cvt->buf;
|
||||
const float *src = dst;
|
||||
int i;
|
||||
const float two_fifths = 1.0f / 2.5f;
|
||||
|
||||
LOG_DEBUG_CONVERT("5.1", "stereo");
|
||||
SDL_assert(format == AUDIO_F32SYS);
|
||||
|
|
@ -111,8 +319,8 @@ SDL_Convert51ToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
/* SDL's 5.1 layout: FL+FR+FC+LFE+BL+BR */
|
||||
for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6, dst += 2) {
|
||||
const float front_center_distributed = src[2] * 0.5f;
|
||||
dst[0] = (src[0] + front_center_distributed + src[4]) / 2.5f; /* left */
|
||||
dst[1] = (src[1] + front_center_distributed + src[5]) / 2.5f; /* right */
|
||||
dst[0] = (src[0] + front_center_distributed + src[4]) * two_fifths; /* left */
|
||||
dst[1] = (src[1] + front_center_distributed + src[5]) * two_fifths; /* right */
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 3;
|
||||
|
|
@ -152,6 +360,7 @@ SDL_Convert71To51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
float *dst = (float *) cvt->buf;
|
||||
const float *src = dst;
|
||||
int i;
|
||||
const float two_thirds = 1.0f / 1.5f;
|
||||
|
||||
LOG_DEBUG_CONVERT("7.1", "5.1");
|
||||
SDL_assert(format == AUDIO_F32SYS);
|
||||
|
|
@ -159,12 +368,12 @@ SDL_Convert71To51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
for (i = cvt->len_cvt / (sizeof (float) * 8); i; --i, src += 8, dst += 6) {
|
||||
const float surround_left_distributed = src[6] * 0.5f;
|
||||
const float surround_right_distributed = src[7] * 0.5f;
|
||||
dst[0] = (src[0] + surround_left_distributed) / 1.5f; /* FL */
|
||||
dst[1] = (src[1] + surround_right_distributed) / 1.5f; /* FR */
|
||||
dst[2] = src[2] / 1.5f; /* CC */
|
||||
dst[3] = src[3] / 1.5f; /* LFE */
|
||||
dst[4] = (src[4] + surround_left_distributed) / 1.5f; /* BL */
|
||||
dst[5] = (src[5] + surround_right_distributed) / 1.5f; /* BR */
|
||||
dst[0] = (src[0] + surround_left_distributed) * two_thirds; /* FL */
|
||||
dst[1] = (src[1] + surround_right_distributed) * two_thirds; /* FR */
|
||||
dst[2] = src[2] * two_thirds; /* CC */
|
||||
dst[3] = src[3] * two_thirds; /* LFE */
|
||||
dst[4] = (src[4] + surround_left_distributed) * two_thirds; /* BL */
|
||||
dst[5] = (src[5] + surround_right_distributed) * two_thirds; /* BR */
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 8;
|
||||
|
|
@ -174,6 +383,125 @@ SDL_Convert71To51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
}
|
||||
}
|
||||
|
||||
/* Convert from 7.1 to 6.1 */
|
||||
/* SDL's 6.1 layout: LFE+FC+FR+SR+BackSurround+SL+FL */
|
||||
/* SDL's 7.1 layout: FL+FR+FC+LFE+BL+BR+SL+SR */
|
||||
static void SDLCALL
|
||||
SDL_Convert71To61(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
{
|
||||
float *dst = (float *) cvt->buf;
|
||||
const float *src = dst;
|
||||
int i;
|
||||
|
||||
LOG_DEBUG_CONVERT("7.1", "6.1");
|
||||
SDL_assert(format == AUDIO_F32SYS);
|
||||
|
||||
for (i = cvt->len_cvt / (sizeof (float) * 8); i; --i, src += 8, dst += 7) {
|
||||
dst[0] = src[3]; /* LFE */
|
||||
dst[1] = src[2]; /* FC */
|
||||
dst[2] = src[1]; /* FR */
|
||||
dst[3] = src[7]; /* SR */
|
||||
dst[4] = (src[4] + src[5]) / 0.2f; /* BackSurround */
|
||||
dst[5] = src[6]; /* SL */
|
||||
dst[6] = src[0]; /* FL */
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 8;
|
||||
cvt->len_cvt *= 7;
|
||||
if (cvt->filters[++cvt->filter_index]) {
|
||||
cvt->filters[cvt->filter_index] (cvt, format);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert from 6.1 to 7.1 */
|
||||
/* SDL's 6.1 layout: LFE+FC+FR+SR+BackSurround+SL+FL */
|
||||
/* SDL's 7.1 layout: FL+FR+FC+LFE+BL+BR+SL+SR */
|
||||
static void SDLCALL
|
||||
SDL_Convert61To71(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
{
|
||||
float *dst = (float *) cvt->buf;
|
||||
const float *src = dst;
|
||||
int i;
|
||||
|
||||
LOG_DEBUG_CONVERT("6.1", "7.1");
|
||||
SDL_assert(format == AUDIO_F32SYS);
|
||||
|
||||
for (i = cvt->len_cvt / (sizeof (float) * 7); i; --i, src += 7, dst += 8) {
|
||||
dst[0] = src[6]; /* FL */
|
||||
dst[1] = src[2]; /* FR */
|
||||
dst[2] = src[1]; /* FC */
|
||||
dst[3] = src[0]; /* LFE */
|
||||
dst[4] = src[4]; /* BL */
|
||||
dst[5] = src[4]; /* BR */
|
||||
dst[6] = src[5]; /* SL */
|
||||
dst[7] = src[3]; /* SR */
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 7;
|
||||
cvt->len_cvt *= 8;
|
||||
if (cvt->filters[++cvt->filter_index]) {
|
||||
cvt->filters[cvt->filter_index] (cvt, format);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert from 5.1 to 6.1 */
|
||||
/* SDL's 5.1 layout: FL+FR+FC+LFE+BL+BR */
|
||||
/* SDL's 6.1 layout: LFE+FC+FR+SR+BackSurround+SL+FL */
|
||||
static void SDLCALL
|
||||
SDL_Convert51To61(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
{
|
||||
float *dst = (float *) cvt->buf;
|
||||
const float *src = dst;
|
||||
int i;
|
||||
|
||||
LOG_DEBUG_CONVERT("5.1", "6.1");
|
||||
SDL_assert(format == AUDIO_F32SYS);
|
||||
|
||||
for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6, dst += 7) {
|
||||
dst[0] = src[3]; /* LFE */
|
||||
dst[1] = src[2]; /* FC */
|
||||
dst[2] = src[1]; /* FR */
|
||||
dst[3] = src[5]; /* SR */
|
||||
dst[4] = (src[4] + src[5]) / 0.2f; /* BackSurround */
|
||||
dst[5] = src[4]; /* SL */
|
||||
dst[6] = src[0]; /* FL */
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 6;
|
||||
cvt->len_cvt *= 7;
|
||||
if (cvt->filters[++cvt->filter_index]) {
|
||||
cvt->filters[cvt->filter_index] (cvt, format);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert from 6.1 to 5.1 */
|
||||
/* SDL's 5.1 layout: FL+FR+FC+LFE+BL+BR */
|
||||
/* SDL's 6.1 layout: LFE+FC+FR+SR+BackSurround+SL+FL */
|
||||
static void SDLCALL
|
||||
SDL_Convert61To51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
{
|
||||
float *dst = (float *) cvt->buf;
|
||||
const float *src = dst;
|
||||
int i;
|
||||
|
||||
LOG_DEBUG_CONVERT("6.1", "5.1");
|
||||
SDL_assert(format == AUDIO_F32SYS);
|
||||
|
||||
for (i = cvt->len_cvt / (sizeof (float) * 7); i; --i, src += 7, dst += 6) {
|
||||
dst[0] = src[6]; /* FL */
|
||||
dst[1] = src[2]; /* FR */
|
||||
dst[2] = src[1]; /* FC */
|
||||
dst[3] = src[0]; /* LFE */
|
||||
dst[4] = src[5]; /* BL */
|
||||
dst[5] = src[3]; /* BR */
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 7;
|
||||
cvt->len_cvt *= 6;
|
||||
if (cvt->filters[++cvt->filter_index]) {
|
||||
cvt->filters[cvt->filter_index] (cvt, format);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert from 5.1 to quad. Distribute center across front, discard LFE. */
|
||||
static void SDLCALL
|
||||
|
|
@ -182,6 +510,7 @@ SDL_Convert51ToQuad(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
float *dst = (float *) cvt->buf;
|
||||
const float *src = dst;
|
||||
int i;
|
||||
const float two_thirds = 1.0f / 1.5f;
|
||||
|
||||
LOG_DEBUG_CONVERT("5.1", "quad");
|
||||
SDL_assert(format == AUDIO_F32SYS);
|
||||
|
|
@ -190,10 +519,10 @@ SDL_Convert51ToQuad(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
/* SDL's 5.1 layout: FL+FR+FC+LFE+BL+BR */
|
||||
for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6, dst += 4) {
|
||||
const float front_center_distributed = src[2] * 0.5f;
|
||||
dst[0] = (src[0] + front_center_distributed) / 1.5f; /* FL */
|
||||
dst[1] = (src[1] + front_center_distributed) / 1.5f; /* FR */
|
||||
dst[2] = src[4] / 1.5f; /* BL */
|
||||
dst[3] = src[5] / 1.5f; /* BR */
|
||||
dst[0] = (src[0] + front_center_distributed) * two_thirds; /* FL */
|
||||
dst[1] = (src[1] + front_center_distributed) * two_thirds; /* FR */
|
||||
dst[2] = src[4] * two_thirds; /* BL */
|
||||
dst[3] = src[5] * two_thirds; /* BR */
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 6;
|
||||
|
|
@ -246,9 +575,9 @@ SDL_ConvertStereoTo51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
lf = src[0];
|
||||
rf = src[1];
|
||||
ce = (lf + rf) * 0.5f;
|
||||
/* !!! FIXME: FL and FR may clip */
|
||||
dst[0] = lf + (lf - ce); /* FL */
|
||||
dst[1] = rf + (rf - ce); /* FR */
|
||||
/* Constant 0.571f is approx 4/7 not to saturate */
|
||||
dst[0] = 0.571f * (lf + (lf - 0.5f * ce)); /* FL */
|
||||
dst[1] = 0.571f * (rf + (rf - 0.5f * ce)); /* FR */
|
||||
dst[2] = ce; /* FC */
|
||||
dst[3] = 0; /* LFE (only meant for special LFE effects) */
|
||||
dst[4] = lf; /* BL */
|
||||
|
|
@ -283,9 +612,9 @@ SDL_ConvertQuadTo51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
lb = src[2];
|
||||
rb = src[3];
|
||||
ce = (lf + rf) * 0.5f;
|
||||
/* !!! FIXME: FL and FR may clip */
|
||||
dst[0] = lf + (lf - ce); /* FL */
|
||||
dst[1] = rf + (rf - ce); /* FR */
|
||||
/* Constant 0.571f is approx 4/7 not to saturate */
|
||||
dst[0] = 0.571f * (lf + (lf - 0.5f * ce)); /* FL */
|
||||
dst[1] = 0.571f * (rf + (rf - 0.5f * ce)); /* FR */
|
||||
dst[2] = ce; /* FC */
|
||||
dst[3] = 0; /* LFE (only meant for special LFE effects) */
|
||||
dst[4] = lb; /* BL */
|
||||
|
|
@ -351,19 +680,18 @@ SDL_Convert51To71(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
rb = src[5];
|
||||
ls = (lf + lb) * 0.5f;
|
||||
rs = (rf + rb) * 0.5f;
|
||||
/* !!! FIXME: these four may clip */
|
||||
lf += lf - ls;
|
||||
rf += rf - ls;
|
||||
rf += rf - rs;
|
||||
lb += lb - ls;
|
||||
rb += rb - ls;
|
||||
rb += rb - rs;
|
||||
dst[3] = src[3]; /* LFE */
|
||||
dst[2] = src[2]; /* FC */
|
||||
dst[7] = rs; /* SR */
|
||||
dst[6] = ls; /* SL */
|
||||
dst[5] = rb; /* BR */
|
||||
dst[4] = lb; /* BL */
|
||||
dst[1] = rf; /* FR */
|
||||
dst[0] = lf; /* FL */
|
||||
dst[5] = 0.5f * rb; /* BR */
|
||||
dst[4] = 0.5f * lb; /* BL */
|
||||
dst[1] = 0.5f * rf; /* FR */
|
||||
dst[0] = 0.5f * lf; /* FL */
|
||||
}
|
||||
|
||||
cvt->len_cvt = cvt->len_cvt * 4 / 3;
|
||||
|
|
@ -473,7 +801,8 @@ ResamplerPadding(const int inrate, const int outrate)
|
|||
{
|
||||
if (inrate == outrate) {
|
||||
return 0;
|
||||
} else if (inrate > outrate) {
|
||||
}
|
||||
if (inrate > outrate) {
|
||||
return (int) SDL_ceil(((float) (RESAMPLER_SAMPLES_PER_ZERO_CROSSING * inrate) / ((float) outrate)));
|
||||
}
|
||||
return RESAMPLER_SAMPLES_PER_ZERO_CROSSING;
|
||||
|
|
@ -602,9 +931,7 @@ SDL_AddAudioCVTFilter(SDL_AudioCVT *cvt, const SDL_AudioFilter filter)
|
|||
if (cvt->filter_index >= SDL_AUDIOCVT_MAX_FILTERS) {
|
||||
return SDL_SetError("Too many filters needed for conversion, exceeded maximum of %d", SDL_AUDIOCVT_MAX_FILTERS);
|
||||
}
|
||||
if (filter == NULL) {
|
||||
return SDL_SetError("Audio filter pointer is NULL");
|
||||
}
|
||||
SDL_assert(filter != NULL);
|
||||
cvt->filters[cvt->filter_index++] = filter;
|
||||
cvt->filters[cvt->filter_index] = NULL; /* Moving terminator */
|
||||
return 0;
|
||||
|
|
@ -615,7 +942,7 @@ SDL_BuildAudioTypeCVTToFloat(SDL_AudioCVT *cvt, const SDL_AudioFormat src_fmt)
|
|||
{
|
||||
int retval = 0; /* 0 == no conversion necessary. */
|
||||
|
||||
if ((SDL_AUDIO_ISBIGENDIAN(src_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN)) {
|
||||
if ((SDL_AUDIO_ISBIGENDIAN(src_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN) && SDL_AUDIO_BITSIZE(src_fmt) > 8) {
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -692,7 +1019,7 @@ SDL_BuildAudioTypeCVTFromFloat(SDL_AudioCVT *cvt, const SDL_AudioFormat dst_fmt)
|
|||
retval = 1; /* added a converter. */
|
||||
}
|
||||
|
||||
if ((SDL_AUDIO_ISBIGENDIAN(dst_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN)) {
|
||||
if ((SDL_AUDIO_ISBIGENDIAN(dst_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN) && SDL_AUDIO_BITSIZE(dst_fmt) > 8) {
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -807,8 +1134,8 @@ SDL_BuildAudioResampleCVT(SDL_AudioCVT * cvt, const int dst_channels,
|
|||
if (cvt->filter_index >= (SDL_AUDIOCVT_MAX_FILTERS-2)) {
|
||||
return SDL_SetError("Too many filters needed for conversion, exceeded maximum of %d", SDL_AUDIOCVT_MAX_FILTERS-2);
|
||||
}
|
||||
cvt->filters[SDL_AUDIOCVT_MAX_FILTERS-1] = (SDL_AudioFilter) (size_t) src_rate;
|
||||
cvt->filters[SDL_AUDIOCVT_MAX_FILTERS] = (SDL_AudioFilter) (size_t) dst_rate;
|
||||
cvt->filters[SDL_AUDIOCVT_MAX_FILTERS-1] = (SDL_AudioFilter) (uintptr_t) src_rate;
|
||||
cvt->filters[SDL_AUDIOCVT_MAX_FILTERS] = (SDL_AudioFilter) (uintptr_t) dst_rate;
|
||||
|
||||
if (src_rate < dst_rate) {
|
||||
const double mult = ((double) dst_rate) / ((double) src_rate);
|
||||
|
|
@ -857,6 +1184,7 @@ SDL_SupportedChannelCount(const int channels)
|
|||
case 2: /* stereo */
|
||||
case 4: /* quad */
|
||||
case 6: /* 5.1 */
|
||||
case 7: /* 6.1 */
|
||||
case 8: /* 7.1 */
|
||||
return SDL_TRUE; /* supported. */
|
||||
|
||||
|
|
@ -888,19 +1216,26 @@ SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
|
|||
|
||||
if (!SDL_SupportedAudioFormat(src_fmt)) {
|
||||
return SDL_SetError("Invalid source format");
|
||||
} else if (!SDL_SupportedAudioFormat(dst_fmt)) {
|
||||
}
|
||||
if (!SDL_SupportedAudioFormat(dst_fmt)) {
|
||||
return SDL_SetError("Invalid destination format");
|
||||
} else if (!SDL_SupportedChannelCount(src_channels)) {
|
||||
}
|
||||
if (!SDL_SupportedChannelCount(src_channels)) {
|
||||
return SDL_SetError("Invalid source channels");
|
||||
} else if (!SDL_SupportedChannelCount(dst_channels)) {
|
||||
}
|
||||
if (!SDL_SupportedChannelCount(dst_channels)) {
|
||||
return SDL_SetError("Invalid destination channels");
|
||||
} else if (src_rate <= 0) {
|
||||
}
|
||||
if (src_rate <= 0) {
|
||||
return SDL_SetError("Source rate is equal to or less than zero");
|
||||
} else if (dst_rate <= 0) {
|
||||
}
|
||||
if (dst_rate <= 0) {
|
||||
return SDL_SetError("Destination rate is equal to or less than zero");
|
||||
} else if (src_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) {
|
||||
}
|
||||
if (src_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) {
|
||||
return SDL_SetError("Source rate is too high");
|
||||
} else if (dst_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) {
|
||||
}
|
||||
if (dst_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) {
|
||||
return SDL_SetError("Destination rate is too high");
|
||||
}
|
||||
|
||||
|
|
@ -944,6 +1279,9 @@ SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
|
|||
|
||||
/* just a byteswap needed? */
|
||||
if ((src_fmt & ~SDL_AUDIO_MASK_ENDIAN) == (dst_fmt & ~SDL_AUDIO_MASK_ENDIAN)) {
|
||||
if (SDL_AUDIO_BITSIZE(dst_fmt) == 8) {
|
||||
return 0;
|
||||
}
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -960,6 +1298,16 @@ SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
|
|||
/* Channel conversion */
|
||||
if (src_channels < dst_channels) {
|
||||
/* Upmixing */
|
||||
|
||||
/* 6.1 -> 7.1 */
|
||||
if (src_channels == 7) {
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert61To71) < 0) {
|
||||
return -1;
|
||||
}
|
||||
cvt->len_mult = (cvt->len_mult * 8 + 6) / 7;
|
||||
src_channels = 8;
|
||||
cvt->len_ratio = cvt->len_ratio * 8 / 7;
|
||||
}
|
||||
/* Mono -> Stereo [-> ...] */
|
||||
if ((src_channels == 1) && (dst_channels > 1)) {
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_ConvertMonoToStereo) < 0) {
|
||||
|
|
@ -987,6 +1335,15 @@ SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
|
|||
cvt->len_mult = (cvt->len_mult * 3 + 1) / 2;
|
||||
cvt->len_ratio *= 1.5;
|
||||
}
|
||||
/* 5.1 -> 6.1 */
|
||||
if (src_channels == 6 && dst_channels == 7) {
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert51To61) < 0) {
|
||||
return -1;
|
||||
}
|
||||
src_channels = 7;
|
||||
cvt->len_mult = (cvt->len_mult * 7 + 5) / 6;
|
||||
cvt->len_ratio = cvt->len_ratio * 7 / 6;
|
||||
}
|
||||
/* [[Mono ->] Stereo ->] 5.1 -> 7.1 */
|
||||
if ((src_channels == 6) && (dst_channels == 8)) {
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert51To71) < 0) {
|
||||
|
|
@ -1009,6 +1366,22 @@ SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
|
|||
}
|
||||
} else if (src_channels > dst_channels) {
|
||||
/* Downmixing */
|
||||
/* 7.1 -> 6.1 */
|
||||
if (src_channels == 8 && dst_channels == 7) {
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert71To61) < 0) {
|
||||
return -1;
|
||||
}
|
||||
src_channels = 7;
|
||||
cvt->len_ratio *= 7.0f / 8.0f;
|
||||
}
|
||||
/* 6.1 -> 5.1 [->...] */
|
||||
if (src_channels == 7 && dst_channels != 7) {
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert61To51) < 0) {
|
||||
return -1;
|
||||
}
|
||||
src_channels = 6;
|
||||
cvt->len_ratio *= 6.0f / 7.0f;
|
||||
}
|
||||
/* 7.1 -> 5.1 [-> Stereo [-> Mono]] */
|
||||
/* 7.1 -> 5.1 [-> Quad] */
|
||||
if ((src_channels == 8) && (dst_channels <= 6)) {
|
||||
|
|
@ -1020,7 +1393,31 @@ SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
|
|||
}
|
||||
/* [7.1 ->] 5.1 -> Stereo [-> Mono] */
|
||||
if ((src_channels == 6) && (dst_channels <= 2)) {
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert51ToStereo) < 0) {
|
||||
SDL_AudioFilter filter = NULL;
|
||||
|
||||
#if HAVE_AVX_INTRINSICS
|
||||
if (SDL_HasAVX()) {
|
||||
filter = SDL_Convert51ToStereo_AVX;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_SSE_INTRINSICS
|
||||
if (!filter && SDL_HasSSE()) {
|
||||
filter = SDL_Convert51ToStereo_SSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_NEON_INTRINSICS
|
||||
if (!filter && SDL_HasNEON()) {
|
||||
filter = SDL_Convert51ToStereo_NEON;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!filter) {
|
||||
filter = SDL_Convert51ToStereo;
|
||||
}
|
||||
|
||||
if (SDL_AddAudioCVTFilter(cvt, filter) < 0) {
|
||||
return -1;
|
||||
}
|
||||
src_channels = 2;
|
||||
|
|
@ -1070,7 +1467,7 @@ SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
|
|||
handled by now, but let's be defensive */
|
||||
return SDL_SetError("Invalid channel combination");
|
||||
}
|
||||
|
||||
|
||||
/* Do rate conversion, if necessary. Updates (cvt). */
|
||||
if (SDL_BuildAudioResampleCVT(cvt, dst_channels, src_rate, dst_rate) < 0) {
|
||||
return -1; /* shouldn't happen, but just in case... */
|
||||
|
|
@ -1278,6 +1675,7 @@ SDL_NewAudioStream(const SDL_AudioFormat src_format,
|
|||
|
||||
retval = (SDL_AudioStream *) SDL_calloc(1, sizeof (SDL_AudioStream));
|
||||
if (!retval) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1519,11 +1917,14 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len)
|
|||
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
} else if (!buf) {
|
||||
}
|
||||
if (!buf) {
|
||||
return SDL_InvalidParamError("buf");
|
||||
} else if (len == 0) {
|
||||
}
|
||||
if (len == 0) {
|
||||
return 0; /* nothing to do. */
|
||||
} else if ((len % stream->src_sample_frame_size) != 0) {
|
||||
}
|
||||
if ((len % stream->src_sample_frame_size) != 0) {
|
||||
return SDL_SetError("Can't add partial sample frames");
|
||||
}
|
||||
|
||||
|
|
@ -1552,7 +1953,7 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len)
|
|||
stream->staging_buffer_filled += len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Fill the staging buffer, process it, and continue */
|
||||
amount = (stream->staging_buffer_size - stream->staging_buffer_filled);
|
||||
SDL_assert(amount > 0);
|
||||
|
|
@ -1629,11 +2030,14 @@ SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, int len)
|
|||
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
} else if (!buf) {
|
||||
}
|
||||
if (!buf) {
|
||||
return SDL_InvalidParamError("buf");
|
||||
} else if (len <= 0) {
|
||||
}
|
||||
if (len <= 0) {
|
||||
return 0; /* nothing to do. */
|
||||
} else if ((len % stream->dst_sample_frame_size) != 0) {
|
||||
}
|
||||
if ((len % stream->dst_sample_frame_size) != 0) {
|
||||
return SDL_SetError("Can't request partial sample frames");
|
||||
}
|
||||
|
||||
|
|
@ -1679,4 +2083,3 @@ SDL_FreeAudioStream(SDL_AudioStream *stream)
|
|||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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 @@ test_device(const int iscapture, const char *fname, int flags, int (*test) (int
|
|||
{
|
||||
struct stat sb;
|
||||
if ((stat(fname, &sb) == 0) && (S_ISCHR(sb.st_mode))) {
|
||||
const int audio_fd = open(fname, flags, 0);
|
||||
const int audio_fd = open(fname, flags | O_CLOEXEC, 0);
|
||||
if (audio_fd >= 0) {
|
||||
const int okay = test(audio_fd);
|
||||
close(audio_fd);
|
||||
|
|
@ -59,7 +59,13 @@ test_device(const int iscapture, const char *fname, int flags, int (*test) (int
|
|||
static size_t dummyhandle = 0;
|
||||
dummyhandle++;
|
||||
SDL_assert(dummyhandle != 0);
|
||||
SDL_AddAudioDevice(iscapture, fname, (void *) dummyhandle);
|
||||
|
||||
/* Note that spec is NULL; while we are opening the device
|
||||
* endpoint here, the endpoint does not provide any mix format
|
||||
* information, making this information inaccessible at
|
||||
* enumeration time
|
||||
*/
|
||||
SDL_AddAudioDevice(iscapture, fname, NULL, (void *) (uintptr_t) dummyhandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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,6 @@
|
|||
|
||||
/* This table is used to add two sound values together and pin
|
||||
* the value to avoid overflow. (used with permission from ARDI)
|
||||
* Changed to use 0xFE instead of 0xFF for better sound quality.
|
||||
*/
|
||||
static const Uint8 mix8[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
|
@ -66,24 +65,25 @@ static const Uint8 mix8[] = {
|
|||
0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
|
||||
0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5,
|
||||
0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFE, 0xFE,
|
||||
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
|
||||
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
|
||||
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
|
||||
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
|
||||
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
|
||||
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
|
||||
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
|
||||
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
|
||||
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
|
||||
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
|
||||
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
|
||||
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE
|
||||
0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
|
||||
/* The volume ranges from 0 - 128 */
|
||||
#define ADJUST_VOLUME(s, v) (s = (s*v)/SDL_MIX_MAXVOLUME)
|
||||
#define ADJUST_VOLUME_U8(s, v) (s = (((s-128)*v)/SDL_MIX_MAXVOLUME)+128)
|
||||
#define ADJUST_VOLUME_U16(s, v) (s = (((s-32768)*v)/SDL_MIX_MAXVOLUME)+32768)
|
||||
|
||||
|
||||
void
|
||||
|
|
@ -98,11 +98,6 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
|
|||
|
||||
case AUDIO_U8:
|
||||
{
|
||||
#if defined(__GNUC__) && defined(__M68000__) && !defined(__mcoldfire__) && defined(SDL_ASSEMBLY_ROUTINES)
|
||||
SDL_MixAudio_m68k_U8((char *) dst, (char *) src,
|
||||
(unsigned long) len, (long) volume,
|
||||
(char *) mix8);
|
||||
#else
|
||||
Uint8 src_sample;
|
||||
|
||||
while (len--) {
|
||||
|
|
@ -112,7 +107,6 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
|
|||
++dst;
|
||||
++src;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -121,8 +115,8 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
|
|||
Sint8 *dst8, *src8;
|
||||
Sint8 src_sample;
|
||||
int dst_sample;
|
||||
const int max_audioval = ((1 << (8 - 1)) - 1);
|
||||
const int min_audioval = -(1 << (8 - 1));
|
||||
const int max_audioval = SDL_MAX_SINT8;
|
||||
const int min_audioval = SDL_MIN_SINT8;
|
||||
|
||||
src8 = (Sint8 *) src;
|
||||
dst8 = (Sint8 *) dst;
|
||||
|
|
@ -131,12 +125,11 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
|
|||
ADJUST_VOLUME(src_sample, volume);
|
||||
dst_sample = *dst8 + src_sample;
|
||||
if (dst_sample > max_audioval) {
|
||||
*dst8 = max_audioval;
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
*dst8 = min_audioval;
|
||||
} else {
|
||||
*dst8 = dst_sample;
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
*dst8 = dst_sample;
|
||||
++dst8;
|
||||
++src8;
|
||||
}
|
||||
|
|
@ -147,14 +140,14 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
|
|||
{
|
||||
Sint16 src1, src2;
|
||||
int dst_sample;
|
||||
const int max_audioval = ((1 << (16 - 1)) - 1);
|
||||
const int min_audioval = -(1 << (16 - 1));
|
||||
const int max_audioval = SDL_MAX_SINT16;
|
||||
const int min_audioval = SDL_MIN_SINT16;
|
||||
|
||||
len /= 2;
|
||||
while (len--) {
|
||||
src1 = ((src[1]) << 8 | src[0]);
|
||||
src1 = SDL_SwapLE16(*(Sint16 *)src);
|
||||
ADJUST_VOLUME(src1, volume);
|
||||
src2 = ((dst[1]) << 8 | dst[0]);
|
||||
src2 = SDL_SwapLE16(*(Sint16 *)dst);
|
||||
src += 2;
|
||||
dst_sample = src1 + src2;
|
||||
if (dst_sample > max_audioval) {
|
||||
|
|
@ -162,9 +155,7 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
|
|||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
dst[0] = dst_sample & 0xFF;
|
||||
dst_sample >>= 8;
|
||||
dst[1] = dst_sample & 0xFF;
|
||||
*(Sint16 *)dst = SDL_SwapLE16(dst_sample);
|
||||
dst += 2;
|
||||
}
|
||||
}
|
||||
|
|
@ -172,20 +163,16 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
|
|||
|
||||
case AUDIO_S16MSB:
|
||||
{
|
||||
#if defined(__GNUC__) && defined(__M68000__) && !defined(__mcoldfire__) && defined(SDL_ASSEMBLY_ROUTINES)
|
||||
SDL_MixAudio_m68k_S16MSB((short *) dst, (short *) src,
|
||||
(unsigned long) len, (long) volume);
|
||||
#else
|
||||
Sint16 src1, src2;
|
||||
int dst_sample;
|
||||
const int max_audioval = ((1 << (16 - 1)) - 1);
|
||||
const int min_audioval = -(1 << (16 - 1));
|
||||
const int max_audioval = SDL_MAX_SINT16;
|
||||
const int min_audioval = SDL_MIN_SINT16;
|
||||
|
||||
len /= 2;
|
||||
while (len--) {
|
||||
src1 = ((src[0]) << 8 | src[1]);
|
||||
src1 = SDL_SwapBE16(*(Sint16 *)src);
|
||||
ADJUST_VOLUME(src1, volume);
|
||||
src2 = ((dst[0]) << 8 | dst[1]);
|
||||
src2 = SDL_SwapBE16(*(Sint16 *)dst);
|
||||
src += 2;
|
||||
dst_sample = src1 + src2;
|
||||
if (dst_sample > max_audioval) {
|
||||
|
|
@ -193,12 +180,9 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
|
|||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
dst[1] = dst_sample & 0xFF;
|
||||
dst_sample >>= 8;
|
||||
dst[0] = dst_sample & 0xFF;
|
||||
*(Sint16 *)dst = SDL_SwapBE16(dst_sample);
|
||||
dst += 2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -206,21 +190,23 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
|
|||
{
|
||||
Uint16 src1, src2;
|
||||
int dst_sample;
|
||||
const int max_audioval = 0xFFFF;
|
||||
const int max_audioval = SDL_MAX_SINT16;
|
||||
const int min_audioval = SDL_MIN_SINT16;
|
||||
|
||||
len /= 2;
|
||||
while (len--) {
|
||||
src1 = ((src[1]) << 8 | src[0]);
|
||||
ADJUST_VOLUME(src1, volume);
|
||||
src2 = ((dst[1]) << 8 | dst[0]);
|
||||
src1 = SDL_SwapLE16(*(Uint16 *)src);
|
||||
ADJUST_VOLUME_U16(src1, volume);
|
||||
src2 = SDL_SwapLE16(*(Uint16 *)dst);
|
||||
src += 2;
|
||||
dst_sample = src1 + src2;
|
||||
dst_sample = src1 + src2 - 32768 * 2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
dst[0] = dst_sample & 0xFF;
|
||||
dst_sample >>= 8;
|
||||
dst[1] = dst_sample & 0xFF;
|
||||
dst_sample += 32768;
|
||||
*(Uint16 *)dst = SDL_SwapLE16(dst_sample);
|
||||
dst += 2;
|
||||
}
|
||||
}
|
||||
|
|
@ -230,21 +216,23 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
|
|||
{
|
||||
Uint16 src1, src2;
|
||||
int dst_sample;
|
||||
const int max_audioval = 0xFFFF;
|
||||
const int max_audioval = SDL_MAX_SINT16;
|
||||
const int min_audioval = SDL_MIN_SINT16;
|
||||
|
||||
len /= 2;
|
||||
while (len--) {
|
||||
src1 = ((src[0]) << 8 | src[1]);
|
||||
ADJUST_VOLUME(src1, volume);
|
||||
src2 = ((dst[0]) << 8 | dst[1]);
|
||||
src1 = SDL_SwapBE16(*(Uint16 *)src);
|
||||
ADJUST_VOLUME_U16(src1, volume);
|
||||
src2 = SDL_SwapBE16(*(Uint16 *)dst);
|
||||
src += 2;
|
||||
dst_sample = src1 + src2;
|
||||
dst_sample = src1 + src2 - 32768 * 2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
dst[1] = dst_sample & 0xFF;
|
||||
dst_sample >>= 8;
|
||||
dst[0] = dst_sample & 0xFF;
|
||||
dst_sample += 32768;
|
||||
*(Uint16 *)dst = SDL_SwapBE16(dst_sample);
|
||||
dst += 2;
|
||||
}
|
||||
}
|
||||
|
|
@ -256,8 +244,8 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
|
|||
Uint32 *dst32 = (Uint32 *) dst;
|
||||
Sint64 src1, src2;
|
||||
Sint64 dst_sample;
|
||||
const Sint64 max_audioval = ((((Sint64) 1) << (32 - 1)) - 1);
|
||||
const Sint64 min_audioval = -(((Sint64) 1) << (32 - 1));
|
||||
const Sint64 max_audioval = SDL_MAX_SINT32;
|
||||
const Sint64 min_audioval = SDL_MIN_SINT32;
|
||||
|
||||
len /= 4;
|
||||
while (len--) {
|
||||
|
|
@ -282,8 +270,8 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
|
|||
Uint32 *dst32 = (Uint32 *) dst;
|
||||
Sint64 src1, src2;
|
||||
Sint64 dst_sample;
|
||||
const Sint64 max_audioval = ((((Sint64) 1) << (32 - 1)) - 1);
|
||||
const Sint64 min_audioval = -(((Sint64) 1) << (32 - 1));
|
||||
const Sint64 max_audioval = SDL_MAX_SINT32;
|
||||
const Sint64 min_audioval = SDL_MIN_SINT32;
|
||||
|
||||
len /= 4;
|
||||
while (len--) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -39,11 +39,11 @@ typedef struct SDL_AudioDevice SDL_AudioDevice;
|
|||
/* Audio targets should call this as devices are added to the system (such as
|
||||
a USB headset being plugged in), and should also be called for
|
||||
for every device found during DetectDevices(). */
|
||||
extern void SDL_AddAudioDevice(const int iscapture, const char *name, void *handle);
|
||||
extern void SDL_AddAudioDevice(const SDL_bool iscapture, const char *name, SDL_AudioSpec *spec, void *handle);
|
||||
|
||||
/* Audio targets should call this as devices are removed, so SDL can update
|
||||
its list of available devices. */
|
||||
extern void SDL_RemoveAudioDevice(const int iscapture, void *handle);
|
||||
extern void SDL_RemoveAudioDevice(const SDL_bool iscapture, void *handle);
|
||||
|
||||
/* Audio targets should call this if an opened audio device is lost while
|
||||
being used. This can happen due to i/o errors, or a device being unplugged,
|
||||
|
|
@ -65,16 +65,14 @@ extern void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device);
|
|||
typedef struct SDL_AudioDriverImpl
|
||||
{
|
||||
void (*DetectDevices) (void);
|
||||
int (*OpenDevice) (_THIS, void *handle, const char *devname, int iscapture);
|
||||
int (*OpenDevice) (_THIS, const char *devname);
|
||||
void (*ThreadInit) (_THIS); /* Called by audio thread at start */
|
||||
void (*ThreadDeinit) (_THIS); /* Called by audio thread at end */
|
||||
void (*BeginLoopIteration)(_THIS); /* Called by audio thread at top of loop */
|
||||
void (*WaitDevice) (_THIS);
|
||||
void (*PlayDevice) (_THIS);
|
||||
Uint8 *(*GetDeviceBuf) (_THIS);
|
||||
int (*CaptureFromDevice) (_THIS, void *buffer, int buflen);
|
||||
void (*FlushCapture) (_THIS);
|
||||
void (*PrepareToClose) (_THIS); /**< Called between run and draining wait for playback devices */
|
||||
void (*CloseDevice) (_THIS);
|
||||
void (*LockDevice) (_THIS);
|
||||
void (*UnlockDevice) (_THIS);
|
||||
|
|
@ -84,13 +82,11 @@ typedef struct SDL_AudioDriverImpl
|
|||
/* !!! FIXME: add pause(), so we can optimize instead of mixing silence. */
|
||||
|
||||
/* Some flags to push duplicate code into the core and reduce #ifdefs. */
|
||||
/* !!! FIXME: these should be SDL_bool */
|
||||
int ProvidesOwnCallbackThread;
|
||||
int SkipMixerLock;
|
||||
int HasCaptureSupport;
|
||||
int OnlyHasDefaultOutputDevice;
|
||||
int OnlyHasDefaultCaptureDevice;
|
||||
int AllowsArbitraryDeviceNames;
|
||||
SDL_bool ProvidesOwnCallbackThread;
|
||||
SDL_bool HasCaptureSupport;
|
||||
SDL_bool OnlyHasDefaultOutputDevice;
|
||||
SDL_bool OnlyHasDefaultCaptureDevice;
|
||||
SDL_bool AllowsArbitraryDeviceNames;
|
||||
} SDL_AudioDriverImpl;
|
||||
|
||||
|
||||
|
|
@ -99,6 +95,7 @@ typedef struct SDL_AudioDeviceItem
|
|||
void *handle;
|
||||
char *name;
|
||||
char *original_name;
|
||||
SDL_AudioSpec spec;
|
||||
int dupenum;
|
||||
struct SDL_AudioDeviceItem *next;
|
||||
} SDL_AudioDeviceItem;
|
||||
|
|
@ -177,11 +174,12 @@ typedef struct AudioBootStrap
|
|||
{
|
||||
const char *name;
|
||||
const char *desc;
|
||||
int (*init) (SDL_AudioDriverImpl * impl);
|
||||
int demand_only; /* 1==request explicitly, or it won't be available. */
|
||||
SDL_bool (*init) (SDL_AudioDriverImpl * impl);
|
||||
SDL_bool demand_only; /* 1==request explicitly, or it won't be available. */
|
||||
} AudioBootStrap;
|
||||
|
||||
/* Not all of these are available in a given build. Use #ifdefs, etc. */
|
||||
extern AudioBootStrap PIPEWIRE_bootstrap;
|
||||
extern AudioBootStrap PULSEAUDIO_bootstrap;
|
||||
extern AudioBootStrap ALSA_bootstrap;
|
||||
extern AudioBootStrap JACK_bootstrap;
|
||||
|
|
@ -203,9 +201,11 @@ extern AudioBootStrap COREAUDIO_bootstrap;
|
|||
extern AudioBootStrap DISKAUDIO_bootstrap;
|
||||
extern AudioBootStrap DUMMYAUDIO_bootstrap;
|
||||
extern AudioBootStrap FUSIONSOUND_bootstrap;
|
||||
extern AudioBootStrap aaudio_bootstrap;
|
||||
extern AudioBootStrap openslES_bootstrap;
|
||||
extern AudioBootStrap ANDROIDAUDIO_bootstrap;
|
||||
extern AudioBootStrap PSPAUDIO_bootstrap;
|
||||
extern AudioBootStrap VITAAUD_bootstrap;
|
||||
extern AudioBootStrap EMSCRIPTENAUDIO_bootstrap;
|
||||
extern AudioBootStrap OS2AUDIO_bootstrap;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -313,7 +313,7 @@ WaveDebugDumpFormat(WaveFile *file, Uint32 rifflen, Uint32 fmtlen, Uint32 datale
|
|||
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_AUDIO, "%s", dumpstr);
|
||||
|
||||
free(dumpstr);
|
||||
SDL_free(dumpstr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1715,7 +1715,7 @@ WaveCheckFormat(WaveFile *file, size_t datalength)
|
|||
if (file->facthint == FactStrict && file->fact.status <= 0) {
|
||||
return SDL_SetError("Missing fact chunk in WAVE file");
|
||||
}
|
||||
/* fallthrough */
|
||||
SDL_FALLTHROUGH;
|
||||
case PCM_CODE:
|
||||
/* All supported formats require a non-zero bit depth. */
|
||||
if (file->chunk.size < 16) {
|
||||
|
|
@ -1854,7 +1854,7 @@ WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 **audio_buf,
|
|||
RIFFend = RIFFchunk.position + SDL_MAX_UINT32;
|
||||
break;
|
||||
}
|
||||
/* fallthrough */
|
||||
SDL_FALLTHROUGH;
|
||||
case RiffSizeForce:
|
||||
RIFFend = RIFFchunk.position + RIFFchunk.length;
|
||||
RIFFlengthknown = SDL_TRUE;
|
||||
|
|
@ -1871,7 +1871,7 @@ WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 **audio_buf,
|
|||
while ((Uint64)RIFFend > (Uint64)chunk->position + chunk->length + (chunk->length & 1)) {
|
||||
/* Abort after too many chunks or else corrupt files may waste time. */
|
||||
if (chunkcount++ >= chunkcountlimit) {
|
||||
return SDL_SetError("Chunk count in WAVE file exceeds limit of %u", chunkcountlimit);
|
||||
return SDL_SetError("Chunk count in WAVE file exceeds limit of %" SDL_PRIu32, chunkcountlimit);
|
||||
}
|
||||
|
||||
result = WaveNextChunk(src, chunk);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -96,7 +96,7 @@ typedef struct WaveChunk
|
|||
Uint32 fourcc; /* FOURCC of the chunk. */
|
||||
Uint32 length; /* Size of the chunk data. */
|
||||
Sint64 position; /* Position of the data in the stream. */
|
||||
Uint8 *data; /* When allocated, this points to the chunk data. length is used for the malloc size. */
|
||||
Uint8 *data; /* When allocated, this points to the chunk data. length is used for the memory allocation size. */
|
||||
size_t size; /* Number of bytes in data that could be read from the stream. Can be smaller than length. */
|
||||
} WaveChunk;
|
||||
|
||||
|
|
|
|||
462
Engine/lib/sdl/src/audio/aaudio/SDL_aaudio.c
Normal file
462
Engine/lib/sdl/src/audio/aaudio/SDL_aaudio.c
Normal file
|
|
@ -0,0 +1,462 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_AAUDIO
|
||||
|
||||
#include "SDL_audio.h"
|
||||
#include "SDL_loadso.h"
|
||||
#include "../SDL_audio_c.h"
|
||||
#include "../../core/android/SDL_android.h"
|
||||
#include "SDL_aaudio.h"
|
||||
|
||||
/* Debug */
|
||||
#if 0
|
||||
# define LOGI(...) SDL_Log(__VA_ARGS__);
|
||||
#else
|
||||
# define LOGI(...)
|
||||
#endif
|
||||
|
||||
typedef struct AAUDIO_Data
|
||||
{
|
||||
AAudioStreamBuilder *builder;
|
||||
void *handle;
|
||||
#define SDL_PROC(ret,func,params) ret (*func) params;
|
||||
# include "SDL_aaudiofuncs.h"
|
||||
#undef SDL_PROC
|
||||
} AAUDIO_Data;
|
||||
static AAUDIO_Data ctx;
|
||||
|
||||
static SDL_AudioDevice *audioDevice = NULL;
|
||||
static SDL_AudioDevice *captureDevice = NULL;
|
||||
|
||||
static int aaudio_LoadFunctions(AAUDIO_Data *data)
|
||||
{
|
||||
#define SDL_PROC(ret,func,params) \
|
||||
do { \
|
||||
data->func = SDL_LoadFunction(data->handle, #func); \
|
||||
if (! data->func) { \
|
||||
return SDL_SetError("Couldn't load AAUDIO function %s: %s", #func, SDL_GetError()); \
|
||||
} \
|
||||
} while (0);
|
||||
#include "SDL_aaudiofuncs.h"
|
||||
#undef SDL_PROC
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aaudio_errorCallback( AAudioStream *stream, void *userData, aaudio_result_t error );
|
||||
void aaudio_errorCallback( AAudioStream *stream, void *userData, aaudio_result_t error )
|
||||
{
|
||||
LOGI( "SDL aaudio_errorCallback: %d - %s", error, ctx.AAudio_convertResultToText( error ) );
|
||||
}
|
||||
|
||||
#define LIB_AAUDIO_SO "libaaudio.so"
|
||||
|
||||
static int
|
||||
aaudio_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
struct SDL_PrivateAudioData *private;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
aaudio_result_t res;
|
||||
LOGI(__func__);
|
||||
|
||||
SDL_assert((captureDevice == NULL) || !iscapture);
|
||||
SDL_assert((audioDevice == NULL) || iscapture);
|
||||
|
||||
if (iscapture) {
|
||||
if (!Android_JNI_RequestPermission("android.permission.RECORD_AUDIO")) {
|
||||
LOGI("This app doesn't have RECORD_AUDIO permission");
|
||||
return SDL_SetError("This app doesn't have RECORD_AUDIO permission");
|
||||
}
|
||||
}
|
||||
|
||||
if (iscapture) {
|
||||
captureDevice = this;
|
||||
} else {
|
||||
audioDevice = this;
|
||||
}
|
||||
|
||||
this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
private = this->hidden;
|
||||
|
||||
ctx.AAudioStreamBuilder_setSampleRate(ctx.builder, this->spec.freq);
|
||||
ctx.AAudioStreamBuilder_setChannelCount(ctx.builder, this->spec.channels);
|
||||
{
|
||||
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;
|
||||
}
|
||||
ctx.AAudioStreamBuilder_setFormat(ctx.builder, format);
|
||||
}
|
||||
|
||||
ctx.AAudioStreamBuilder_setErrorCallback( ctx.builder, aaudio_errorCallback, private );
|
||||
|
||||
LOGI("AAudio Try to open %u hz %u bit chan %u %s samples %u",
|
||||
this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
|
||||
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
|
||||
|
||||
res = ctx.AAudioStreamBuilder_openStream(ctx.builder, &private->stream);
|
||||
if (res != AAUDIO_OK) {
|
||||
LOGI("SDL Failed AAudioStreamBuilder_openStream %d", res);
|
||||
return SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||
}
|
||||
|
||||
this->spec.freq = ctx.AAudioStream_getSampleRate(private->stream);
|
||||
this->spec.channels = ctx.AAudioStream_getChannelCount(private->stream);
|
||||
{
|
||||
aaudio_format_t fmt = ctx.AAudioStream_getFormat(private->stream);
|
||||
if (fmt == AAUDIO_FORMAT_PCM_I16) {
|
||||
this->spec.format = AUDIO_S16SYS;
|
||||
} else if (fmt == AAUDIO_FORMAT_PCM_FLOAT) {
|
||||
this->spec.format = AUDIO_F32SYS;
|
||||
}
|
||||
}
|
||||
|
||||
LOGI("AAudio Try to open %u hz %u bit chan %u %s samples %u",
|
||||
this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
|
||||
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
|
||||
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
/* Allocate mixing buffer */
|
||||
if (!iscapture) {
|
||||
private->mixlen = this->spec.size;
|
||||
private->mixbuf = (Uint8 *) SDL_malloc(private->mixlen);
|
||||
if (private->mixbuf == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(private->mixbuf, this->spec.silence, this->spec.size);
|
||||
}
|
||||
|
||||
private->frame_size = this->spec.channels * (SDL_AUDIO_BITSIZE(this->spec.format) / 8);
|
||||
|
||||
res = ctx.AAudioStream_requestStart(private->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));
|
||||
}
|
||||
|
||||
LOGI("SDL AAudioStream_requestStart OK");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
aaudio_CloseDevice(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *private = this->hidden;
|
||||
aaudio_result_t res;
|
||||
LOGI(__func__);
|
||||
|
||||
if (private->stream) {
|
||||
res = ctx.AAudioStream_requestStop(private->stream);
|
||||
if (res != AAUDIO_OK) {
|
||||
LOGI("SDL Failed AAudioStream_requestStop %d", res);
|
||||
SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||
return;
|
||||
}
|
||||
|
||||
res = ctx.AAudioStream_close(private->stream);
|
||||
if (res != AAUDIO_OK) {
|
||||
LOGI("SDL Failed AAudioStreamBuilder_delete %d", res);
|
||||
SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->iscapture) {
|
||||
SDL_assert(captureDevice == this);
|
||||
captureDevice = NULL;
|
||||
} else {
|
||||
SDL_assert(audioDevice == this);
|
||||
audioDevice = NULL;
|
||||
}
|
||||
|
||||
SDL_free(this->hidden->mixbuf);
|
||||
SDL_free(this->hidden);
|
||||
}
|
||||
|
||||
static Uint8 *
|
||||
aaudio_GetDeviceBuf(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *private = this->hidden;
|
||||
return private->mixbuf;
|
||||
}
|
||||
|
||||
static void
|
||||
aaudio_PlayDevice(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *private = this->hidden;
|
||||
aaudio_result_t res;
|
||||
int64_t timeoutNanoseconds = 1 * 1000 * 1000; /* 8 ms */
|
||||
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));
|
||||
} else {
|
||||
LOGI("SDL AAudio play: %d frames, wanted:%d frames", (int)res, private->mixlen / private->frame_size);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Log under-run count */
|
||||
{
|
||||
static int prev = 0;
|
||||
int32_t cnt = ctx.AAudioStream_getXRunCount(private->stream);
|
||||
if (cnt != prev) {
|
||||
SDL_Log("AAudio underrun: %d - total: %d", cnt - prev, cnt);
|
||||
prev = cnt;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
aaudio_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
struct SDL_PrivateAudioData *private = this->hidden;
|
||||
aaudio_result_t res;
|
||||
int64_t timeoutNanoseconds = 8 * 1000 * 1000; /* 8 ms */
|
||||
res = ctx.AAudioStream_read(private->stream, buffer, buflen / private->frame_size, timeoutNanoseconds);
|
||||
if (res < 0) {
|
||||
LOGI("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||
return -1;
|
||||
}
|
||||
LOGI("SDL AAudio capture:%d frames, wanted:%d frames", (int)res, buflen / private->frame_size);
|
||||
return res * private->frame_size;
|
||||
}
|
||||
|
||||
static void
|
||||
aaudio_Deinitialize(void)
|
||||
{
|
||||
LOGI(__func__);
|
||||
if (ctx.handle) {
|
||||
if (ctx.builder) {
|
||||
aaudio_result_t res;
|
||||
res = ctx.AAudioStreamBuilder_delete(ctx.builder);
|
||||
if (res != AAUDIO_OK) {
|
||||
SDL_SetError("Failed AAudioStreamBuilder_delete %s", ctx.AAudio_convertResultToText(res));
|
||||
}
|
||||
}
|
||||
SDL_UnloadObject(ctx.handle);
|
||||
}
|
||||
ctx.handle = NULL;
|
||||
ctx.builder = NULL;
|
||||
LOGI("End AAUDIO %s", SDL_GetError());
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
aaudio_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
aaudio_result_t res;
|
||||
LOGI(__func__);
|
||||
|
||||
/* AAudio was introduced in Android 8.0, but has reference counting crash issues in that release,
|
||||
* so don't use it until 8.1.
|
||||
*
|
||||
* See https://github.com/google/oboe/issues/40 for more information.
|
||||
*/
|
||||
if (SDL_GetAndroidSDKVersion() < 27) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
SDL_zero(ctx);
|
||||
|
||||
ctx.handle = SDL_LoadObject(LIB_AAUDIO_SO);
|
||||
if (ctx.handle == NULL) {
|
||||
LOGI("SDL couldn't find " LIB_AAUDIO_SO);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (aaudio_LoadFunctions(&ctx) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
res = ctx.AAudio_createStreamBuilder(&ctx.builder);
|
||||
if (res != AAUDIO_OK) {
|
||||
LOGI("SDL Failed AAudio_createStreamBuilder %d", res);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (ctx.builder == NULL) {
|
||||
LOGI("SDL Failed AAudio_createStreamBuilder - builder NULL");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
impl->Deinitialize = aaudio_Deinitialize;
|
||||
impl->OpenDevice = aaudio_OpenDevice;
|
||||
impl->CloseDevice = aaudio_CloseDevice;
|
||||
impl->PlayDevice = aaudio_PlayDevice;
|
||||
impl->GetDeviceBuf = aaudio_GetDeviceBuf;
|
||||
impl->CaptureFromDevice = aaudio_CaptureFromDevice;
|
||||
|
||||
/* and the capabilities */
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
|
||||
|
||||
/* this audio target is available. */
|
||||
LOGI("SDL aaudio_Init OK");
|
||||
return SDL_TRUE;
|
||||
|
||||
failure:
|
||||
if (ctx.handle) {
|
||||
if (ctx.builder) {
|
||||
ctx.AAudioStreamBuilder_delete(ctx.builder);
|
||||
}
|
||||
SDL_UnloadObject(ctx.handle);
|
||||
}
|
||||
ctx.handle = NULL;
|
||||
ctx.builder = NULL;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
AudioBootStrap aaudio_bootstrap = {
|
||||
"AAudio", "AAudio audio driver", aaudio_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
/* Pause (block) all non already paused audio devices by taking their mixer lock */
|
||||
void aaudio_PauseDevices(void)
|
||||
{
|
||||
/* TODO: Handle multiple devices? */
|
||||
struct SDL_PrivateAudioData *private;
|
||||
if (audioDevice != NULL && audioDevice->hidden != NULL) {
|
||||
private = (struct SDL_PrivateAudioData *) audioDevice->hidden;
|
||||
|
||||
if (private->stream) {
|
||||
aaudio_result_t res = ctx.AAudioStream_requestPause(private->stream);
|
||||
if (res != AAUDIO_OK) {
|
||||
LOGI("SDL Failed AAudioStream_requestPause %d", res);
|
||||
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) {
|
||||
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);
|
||||
if (res != AAUDIO_OK) {
|
||||
LOGI("SDL Failed AAudioStream_requestStop %d", res);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Resume (unblock) all non already paused audio devices by releasing their mixer lock */
|
||||
void aaudio_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 (private->stream) {
|
||||
aaudio_result_t res = ctx.AAudioStream_requestStart(private->stream);
|
||||
if (res != AAUDIO_OK) {
|
||||
LOGI("SDL Failed AAudioStream_requestStart %d", res);
|
||||
SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 (private->stream) {
|
||||
aaudio_result_t res = ctx.AAudioStream_requestStart(private->stream);
|
||||
if (res != AAUDIO_OK) {
|
||||
LOGI("SDL Failed AAudioStream_requestStart %d", res);
|
||||
SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
We can sometimes get into a state where AAudioStream_write() will just block forever until we pause and unpause.
|
||||
None of the standard state queries indicate any problem in my testing. And the error callback doesn't actually get called.
|
||||
But, AAudioStream_getTimestamp() does return AAUDIO_ERROR_INVALID_STATE
|
||||
*/
|
||||
SDL_bool aaudio_DetectBrokenPlayState( void )
|
||||
{
|
||||
if ( !audioDevice || !audioDevice->hidden ) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
struct SDL_PrivateAudioData *private = audioDevice->hidden;
|
||||
|
||||
int64_t framePosition, timeNanoseconds;
|
||||
aaudio_result_t res = ctx.AAudioStream_getTimestamp( private->stream, CLOCK_MONOTONIC, &framePosition, &timeNanoseconds );
|
||||
if ( res == AAUDIO_ERROR_INVALID_STATE ) {
|
||||
aaudio_stream_state_t currentState = ctx.AAudioStream_getState( private->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 );
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_AAUDIO */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
53
Engine/lib/sdl/src/audio/aaudio/SDL_aaudio.h
Normal file
53
Engine/lib/sdl/src/audio/aaudio/SDL_aaudio.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifndef _SDL_aaudio_h
|
||||
#define _SDL_aaudio_h
|
||||
|
||||
#include "../SDL_sysaudio.h"
|
||||
#include <stdbool.h>
|
||||
#include <aaudio/AAudio.h>
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
AAudioStream *stream;
|
||||
|
||||
/* Raw mixing buffer */
|
||||
Uint8 *mixbuf;
|
||||
int mixlen;
|
||||
int frame_size;
|
||||
|
||||
/* Resume device if it was paused automatically */
|
||||
int resume;
|
||||
};
|
||||
|
||||
void aaudio_ResumeDevices(void);
|
||||
void aaudio_PauseDevices(void);
|
||||
SDL_bool aaudio_DetectBrokenPlayState(void);
|
||||
|
||||
|
||||
#endif /* _SDL_aaudio_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
80
Engine/lib/sdl/src/audio/aaudio/SDL_aaudiofuncs.h
Normal file
80
Engine/lib/sdl/src/audio/aaudio/SDL_aaudiofuncs.h
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright , (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#define SDL_PROC_UNUSED(ret,func,params)
|
||||
|
||||
SDL_PROC(const char *, AAudio_convertResultToText, (aaudio_result_t returnCode))
|
||||
SDL_PROC(const char *, AAudio_convertStreamStateToText, (aaudio_stream_state_t state))
|
||||
SDL_PROC(aaudio_result_t, AAudio_createStreamBuilder, (AAudioStreamBuilder** builder))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setDeviceId, (AAudioStreamBuilder* builder, int32_t deviceId))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setSampleRate, (AAudioStreamBuilder* builder, int32_t sampleRate))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setChannelCount, (AAudioStreamBuilder* builder, int32_t channelCount))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSamplesPerFrame, (AAudioStreamBuilder* builder, int32_t samplesPerFrame))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setFormat, (AAudioStreamBuilder* builder, aaudio_format_t format))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSharingMode, (AAudioStreamBuilder* builder, aaudio_sharing_mode_t sharingMode))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setDirection, (AAudioStreamBuilder* builder, aaudio_direction_t direction))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder* builder, int32_t numFrames))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder* builder, aaudio_performance_mode_t mode))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setUsage, (AAudioStreamBuilder* builder, aaudio_usage_t usage)) /* API 28 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setContentType, (AAudioStreamBuilder* builder, aaudio_content_type_t contentType)) /* API 28 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setInputPreset, (AAudioStreamBuilder* builder, aaudio_input_preset_t inputPreset)) /* API 28 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setAllowedCapturePolicy, (AAudioStreamBuilder* builder, aaudio_allowed_capture_policy_t capturePolicy)) /* API 29 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSessionId, (AAudioStreamBuilder* builder, aaudio_session_id_t sessionId)) /* API 28 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setPrivacySensitive, (AAudioStreamBuilder* builder, bool privacySensitive)) /* API 30 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setDataCallback, (AAudioStreamBuilder* builder, AAudioStream_dataCallback callback, void *userData))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setFramesPerDataCallback, (AAudioStreamBuilder* builder, int32_t numFrames))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setErrorCallback, (AAudioStreamBuilder* builder, AAudioStream_errorCallback callback, void *userData))
|
||||
SDL_PROC(aaudio_result_t , AAudioStreamBuilder_openStream, (AAudioStreamBuilder* builder, AAudioStream** stream))
|
||||
SDL_PROC(aaudio_result_t , AAudioStreamBuilder_delete, (AAudioStreamBuilder* builder))
|
||||
SDL_PROC_UNUSED(aaudio_result_t , AAudioStream_release, (AAudioStream* stream)) /* API 30 */
|
||||
SDL_PROC(aaudio_result_t , AAudioStream_close, (AAudioStream* stream))
|
||||
SDL_PROC(aaudio_result_t , AAudioStream_requestStart, (AAudioStream* stream))
|
||||
SDL_PROC(aaudio_result_t , AAudioStream_requestPause, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(aaudio_result_t , AAudioStream_requestFlush, (AAudioStream* stream))
|
||||
SDL_PROC(aaudio_result_t , AAudioStream_requestStop, (AAudioStream* stream))
|
||||
SDL_PROC(aaudio_stream_state_t, AAudioStream_getState, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_waitForStateChange, (AAudioStream* stream, aaudio_stream_state_t inputState, aaudio_stream_state_t *nextState, int64_t timeoutNanoseconds))
|
||||
SDL_PROC(aaudio_result_t, AAudioStream_read, (AAudioStream* stream, void *buffer, int32_t numFrames, int64_t timeoutNanoseconds))
|
||||
SDL_PROC(aaudio_result_t, AAudioStream_write, (AAudioStream* stream, const void *buffer, int32_t numFrames, int64_t timeoutNanoseconds))
|
||||
SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_setBufferSizeInFrames, (AAudioStream* stream, int32_t numFrames))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getBufferSizeInFrames, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getFramesPerBurst, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getBufferCapacityInFrames, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getFramesPerDataCallback, (AAudioStream* stream))
|
||||
SDL_PROC(int32_t, AAudioStream_getXRunCount, (AAudioStream* stream))
|
||||
SDL_PROC(int32_t, AAudioStream_getSampleRate, (AAudioStream* stream))
|
||||
SDL_PROC(int32_t, AAudioStream_getChannelCount, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getSamplesPerFrame, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getDeviceId, (AAudioStream* stream))
|
||||
SDL_PROC(aaudio_format_t, AAudioStream_getFormat, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(aaudio_sharing_mode_t, AAudioStream_getSharingMode, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(aaudio_performance_mode_t, AAudioStream_getPerformanceMode, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(aaudio_direction_t, AAudioStream_getDirection, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(int64_t, AAudioStream_getFramesWritten, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(int64_t, AAudioStream_getFramesRead, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(aaudio_session_id_t, AAudioStream_getSessionId, (AAudioStream* stream)) /* API 28 */
|
||||
SDL_PROC(aaudio_result_t, AAudioStream_getTimestamp, (AAudioStream* stream, clockid_t clockid, int64_t *framePosition, int64_t *timeNanoseconds))
|
||||
SDL_PROC_UNUSED(aaudio_usage_t, AAudioStream_getUsage, (AAudioStream* stream)) /* API 28 */
|
||||
SDL_PROC_UNUSED(aaudio_content_type_t, AAudioStream_getContentType, (AAudioStream* stream)) /* API 28 */
|
||||
SDL_PROC_UNUSED(aaudio_input_preset_t, AAudioStream_getInputPreset, (AAudioStream* stream)) /* API 28 */
|
||||
SDL_PROC_UNUSED(aaudio_allowed_capture_policy_t, AAudioStream_getAllowedCapturePolicy, ( AAudioStream* stream)) /* API 29 */
|
||||
SDL_PROC_UNUSED(bool, AAudioStream_isPrivacySensitive, (AAudioStream* stream)) /* API 30 */
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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,6 +26,11 @@
|
|||
#define SDL_ALSA_NON_BLOCKING 0
|
||||
#endif
|
||||
|
||||
/* without the thread, you will detect devices on startup, but will not get futher hotplug events. But that might be okay. */
|
||||
#ifndef SDL_ALSA_HOTPLUG_THREAD
|
||||
#define SDL_ALSA_HOTPLUG_THREAD 1
|
||||
#endif
|
||||
|
||||
/* Allow access to a raw mixing buffer */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
|
@ -274,44 +279,61 @@ ALSA_WaitDevice(_THIS)
|
|||
|
||||
/* !!! FIXME: is there a channel swizzler in alsalib instead? */
|
||||
/*
|
||||
* http://bugzilla.libsdl.org/show_bug.cgi?id=110
|
||||
* https://bugzilla.libsdl.org/show_bug.cgi?id=110
|
||||
* "For Linux ALSA, this is FL-FR-RL-RR-C-LFE
|
||||
* and for Windows DirectX [and CoreAudio], this is FL-FR-C-LFE-RL-RR"
|
||||
*/
|
||||
#define SWIZ6(T, buf, numframes) \
|
||||
T *ptr = (T *) buf; \
|
||||
#define SWIZ6(T) \
|
||||
static void swizzle_alsa_channels_6_##T(void *buffer, const Uint32 bufferlen) { \
|
||||
T *ptr = (T *) buffer; \
|
||||
Uint32 i; \
|
||||
for (i = 0; i < numframes; i++, ptr += 6) { \
|
||||
for (i = 0; i < bufferlen; i++, ptr += 6) { \
|
||||
T tmp; \
|
||||
tmp = ptr[2]; ptr[2] = ptr[4]; ptr[4] = tmp; \
|
||||
tmp = ptr[3]; ptr[3] = ptr[5]; ptr[5] = tmp; \
|
||||
}
|
||||
|
||||
static void
|
||||
swizzle_alsa_channels_6_64bit(void *buffer, Uint32 bufferlen)
|
||||
{
|
||||
SWIZ6(Uint64, buffer, bufferlen);
|
||||
} \
|
||||
}
|
||||
|
||||
static void
|
||||
swizzle_alsa_channels_6_32bit(void *buffer, Uint32 bufferlen)
|
||||
{
|
||||
SWIZ6(Uint32, buffer, bufferlen);
|
||||
|
||||
/* !!! FIXME: is there a channel swizzler in alsalib instead? */
|
||||
/* !!! FIXME: this screams for a SIMD shuffle operation. */
|
||||
/*
|
||||
* https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/mapping-stream-formats-to-speaker-configurations
|
||||
* For Linux ALSA, this appears to be FL-FR-RL-RR-C-LFE-SL-SR
|
||||
* and for Windows DirectX [and CoreAudio], this is FL-FR-C-LFE-SL-SR-RL-RR"
|
||||
*/
|
||||
#define SWIZ8(T) \
|
||||
static void swizzle_alsa_channels_8_##T(void *buffer, const Uint32 bufferlen) { \
|
||||
T *ptr = (T *) buffer; \
|
||||
Uint32 i; \
|
||||
for (i = 0; i < bufferlen; i++, ptr += 6) { \
|
||||
const T center = ptr[2]; \
|
||||
const T subwoofer = ptr[3]; \
|
||||
const T side_left = ptr[4]; \
|
||||
const T side_right = ptr[5]; \
|
||||
const T rear_left = ptr[6]; \
|
||||
const T rear_right = ptr[7]; \
|
||||
ptr[2] = rear_left; \
|
||||
ptr[3] = rear_right; \
|
||||
ptr[4] = center; \
|
||||
ptr[5] = subwoofer; \
|
||||
ptr[6] = side_left; \
|
||||
ptr[7] = side_right; \
|
||||
} \
|
||||
}
|
||||
|
||||
static void
|
||||
swizzle_alsa_channels_6_16bit(void *buffer, Uint32 bufferlen)
|
||||
{
|
||||
SWIZ6(Uint16, buffer, bufferlen);
|
||||
}
|
||||
#define CHANNEL_SWIZZLE(x) \
|
||||
x(Uint64) \
|
||||
x(Uint32) \
|
||||
x(Uint16) \
|
||||
x(Uint8)
|
||||
|
||||
static void
|
||||
swizzle_alsa_channels_6_8bit(void *buffer, Uint32 bufferlen)
|
||||
{
|
||||
SWIZ6(Uint8, buffer, bufferlen);
|
||||
}
|
||||
CHANNEL_SWIZZLE(SWIZ6)
|
||||
CHANNEL_SWIZZLE(SWIZ8)
|
||||
|
||||
#undef CHANNEL_SWIZZLE
|
||||
#undef SWIZ6
|
||||
#undef SWIZ8
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -321,17 +343,23 @@ swizzle_alsa_channels_6_8bit(void *buffer, Uint32 bufferlen)
|
|||
static void
|
||||
swizzle_alsa_channels(_THIS, void *buffer, Uint32 bufferlen)
|
||||
{
|
||||
if (this->spec.channels == 6) {
|
||||
switch (SDL_AUDIO_BITSIZE(this->spec.format)) {
|
||||
case 8: swizzle_alsa_channels_6_8bit(buffer, bufferlen); break;
|
||||
case 16: swizzle_alsa_channels_6_16bit(buffer, bufferlen); break;
|
||||
case 32: swizzle_alsa_channels_6_32bit(buffer, bufferlen); break;
|
||||
case 64: swizzle_alsa_channels_6_64bit(buffer, bufferlen); break;
|
||||
default: SDL_assert(!"unhandled bitsize"); break;
|
||||
}
|
||||
}
|
||||
switch (this->spec.channels) {
|
||||
#define CHANSWIZ(chans) \
|
||||
case chans: \
|
||||
switch ((this->spec.format & (0xFF))) { \
|
||||
case 8: swizzle_alsa_channels_##chans##_Uint8(buffer, bufferlen); break; \
|
||||
case 16: swizzle_alsa_channels_##chans##_Uint16(buffer, bufferlen); break; \
|
||||
case 32: swizzle_alsa_channels_##chans##_Uint32(buffer, bufferlen); break; \
|
||||
case 64: swizzle_alsa_channels_##chans##_Uint64(buffer, bufferlen); break; \
|
||||
default: SDL_assert(!"unhandled bitsize"); break; \
|
||||
} \
|
||||
return;
|
||||
|
||||
/* !!! FIXME: update this for 7.1 if needed, later. */
|
||||
CHANSWIZ(6);
|
||||
CHANSWIZ(8);
|
||||
#undef CHANSWIZ
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SND_CHMAP_API_VERSION
|
||||
|
|
@ -515,9 +543,10 @@ ALSA_set_buffer_size(_THIS, snd_pcm_hw_params_t *params)
|
|||
}
|
||||
|
||||
static int
|
||||
ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
ALSA_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
int status = 0;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
snd_pcm_t *pcm_handle = NULL;
|
||||
snd_pcm_hw_params_t *hwparams = NULL;
|
||||
snd_pcm_sw_params_t *swparams = NULL;
|
||||
|
|
@ -541,7 +570,7 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
/* Open the audio device */
|
||||
/* Name of device should depend on # channels in spec */
|
||||
status = ALSA_snd_pcm_open(&pcm_handle,
|
||||
get_audio_device(handle, this->spec.channels),
|
||||
get_audio_device(this->handle, this->spec.channels),
|
||||
iscapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
|
||||
SND_PCM_NONBLOCK);
|
||||
|
||||
|
|
@ -569,10 +598,7 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
}
|
||||
|
||||
/* Try for a closest match on audio format */
|
||||
status = -1;
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
test_format && (status < 0);) {
|
||||
status = 0; /* if we can't support a format, it'll become -1. */
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
switch (test_format) {
|
||||
case AUDIO_U8:
|
||||
format = SND_PCM_FORMAT_U8;
|
||||
|
|
@ -605,19 +631,14 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
format = SND_PCM_FORMAT_FLOAT_BE;
|
||||
break;
|
||||
default:
|
||||
status = -1;
|
||||
continue;
|
||||
}
|
||||
if (ALSA_snd_pcm_hw_params_set_format(pcm_handle, hwparams, format) >= 0) {
|
||||
break;
|
||||
}
|
||||
if (status >= 0) {
|
||||
status = ALSA_snd_pcm_hw_params_set_format(pcm_handle,
|
||||
hwparams, format);
|
||||
}
|
||||
if (status < 0) {
|
||||
test_format = SDL_NextAudioFormat();
|
||||
}
|
||||
}
|
||||
if (status < 0) {
|
||||
return SDL_SetError("ALSA: Couldn't find any hardware audio formats");
|
||||
if (!test_format) {
|
||||
return SDL_SetError("%s: Unsupported audio format", "alsa");
|
||||
}
|
||||
this->spec.format = test_format;
|
||||
|
||||
|
|
@ -628,10 +649,11 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
#ifdef SND_CHMAP_API_VERSION
|
||||
chmap = ALSA_snd_pcm_get_chmap(pcm_handle);
|
||||
if (chmap) {
|
||||
ALSA_snd_pcm_chmap_print(chmap, sizeof(chmap_str), chmap_str);
|
||||
if (SDL_strcmp("FL FR FC LFE RL RR", chmap_str) == 0 ||
|
||||
SDL_strcmp("FL FR FC LFE SL SR", chmap_str) == 0) {
|
||||
this->hidden->swizzle_func = no_swizzle;
|
||||
if (ALSA_snd_pcm_chmap_print(chmap, sizeof(chmap_str), chmap_str) > 0) {
|
||||
if (SDL_strcmp("FL FR FC LFE RL RR", chmap_str) == 0 ||
|
||||
SDL_strcmp("FL FR FC LFE SL SR", chmap_str) == 0) {
|
||||
this->hidden->swizzle_func = no_swizzle;
|
||||
}
|
||||
}
|
||||
free(chmap);
|
||||
}
|
||||
|
|
@ -750,7 +772,7 @@ add_device(const int iscapture, const char *name, void *hint, ALSA_Device **pSee
|
|||
/* some strings have newlines, like "HDA NVidia, HDMI 0\nHDMI Audio Output".
|
||||
just chop the extra lines off, this seems to get a reasonable device
|
||||
name without extra details. */
|
||||
if ((ptr = strchr(desc, '\n')) != NULL) {
|
||||
if ((ptr = SDL_strchr(desc, '\n')) != NULL) {
|
||||
*ptr = '\0';
|
||||
}
|
||||
|
||||
|
|
@ -765,7 +787,11 @@ add_device(const int iscapture, const char *name, void *hint, ALSA_Device **pSee
|
|||
return;
|
||||
}
|
||||
|
||||
SDL_AddAudioDevice(iscapture, desc, handle);
|
||||
/* Note that spec is NULL, because we are required to open the device before
|
||||
* acquiring the mix format, making this information inaccessible at
|
||||
* enumeration time
|
||||
*/
|
||||
SDL_AddAudioDevice(iscapture, desc, NULL, handle);
|
||||
if (hint)
|
||||
free(desc);
|
||||
dev->name = handle;
|
||||
|
|
@ -775,200 +801,200 @@ add_device(const int iscapture, const char *name, void *hint, ALSA_Device **pSee
|
|||
}
|
||||
|
||||
|
||||
static ALSA_Device *hotplug_devices = NULL;
|
||||
|
||||
static void
|
||||
ALSA_HotplugIteration(void)
|
||||
{
|
||||
void **hints = NULL;
|
||||
ALSA_Device *dev;
|
||||
ALSA_Device *unseen;
|
||||
ALSA_Device *seen;
|
||||
ALSA_Device *next;
|
||||
ALSA_Device *prev;
|
||||
|
||||
if (ALSA_snd_device_name_hint(-1, "pcm", &hints) == 0) {
|
||||
int i, j;
|
||||
const char *match = NULL;
|
||||
int bestmatch = 0xFFFF;
|
||||
size_t match_len = 0;
|
||||
int defaultdev = -1;
|
||||
static const char * const prefixes[] = {
|
||||
"hw:", "sysdefault:", "default:", NULL
|
||||
};
|
||||
|
||||
unseen = hotplug_devices;
|
||||
seen = NULL;
|
||||
|
||||
/* Apparently there are several different ways that ALSA lists
|
||||
actual hardware. It could be prefixed with "hw:" or "default:"
|
||||
or "sysdefault:" and maybe others. Go through the list and see
|
||||
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) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* full name, not a prefix */
|
||||
if ((defaultdev == -1) && (SDL_strcmp(name, "default") == 0)) {
|
||||
defaultdev = i;
|
||||
}
|
||||
|
||||
for (j = 0; prefixes[j]; j++) {
|
||||
const char *prefix = prefixes[j];
|
||||
const size_t prefixlen = SDL_strlen(prefix);
|
||||
if (SDL_strncmp(name, prefix, prefixlen) == 0) {
|
||||
if (j < bestmatch) {
|
||||
bestmatch = j;
|
||||
match = prefix;
|
||||
match_len = prefixlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(name);
|
||||
}
|
||||
|
||||
/* look through the list of device names to find matches */
|
||||
for (i = 0; hints[i]; i++) {
|
||||
char *name;
|
||||
|
||||
/* if we didn't find a device name prefix we like at all... */
|
||||
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) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* only want physical hardware interfaces */
|
||||
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);
|
||||
SDL_bool have_output = SDL_FALSE;
|
||||
SDL_bool have_input = SDL_FALSE;
|
||||
|
||||
free(ioid);
|
||||
|
||||
if (!isoutput && !isinput) {
|
||||
free(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
prev = NULL;
|
||||
for (dev = unseen; dev; dev = next) {
|
||||
next = dev->next;
|
||||
if ( (SDL_strcmp(dev->name, name) == 0) && (((isinput) && dev->iscapture) || ((isoutput) && !dev->iscapture)) ) {
|
||||
if (prev) {
|
||||
prev->next = next;
|
||||
} else {
|
||||
unseen = next;
|
||||
}
|
||||
dev->next = seen;
|
||||
seen = dev;
|
||||
if (isinput) have_input = SDL_TRUE;
|
||||
if (isoutput) have_output = SDL_TRUE;
|
||||
} else {
|
||||
prev = dev;
|
||||
}
|
||||
}
|
||||
|
||||
if (isinput && !have_input) {
|
||||
add_device(SDL_TRUE, name, hints[i], &seen);
|
||||
}
|
||||
if (isoutput && !have_output) {
|
||||
add_device(SDL_FALSE, name, hints[i], &seen);
|
||||
}
|
||||
}
|
||||
|
||||
free(name);
|
||||
}
|
||||
|
||||
ALSA_snd_device_name_free_hint(hints);
|
||||
|
||||
hotplug_devices = seen; /* now we have a known-good list of attached devices. */
|
||||
|
||||
/* report anything still in unseen as removed. */
|
||||
for (dev = unseen; dev; dev = next) {
|
||||
/*printf("ALSA: removing usb %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/
|
||||
next = dev->next;
|
||||
SDL_RemoveAudioDevice(dev->iscapture, dev->name);
|
||||
SDL_free(dev->name);
|
||||
SDL_free(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if SDL_ALSA_HOTPLUG_THREAD
|
||||
static SDL_atomic_t ALSA_hotplug_shutdown;
|
||||
static SDL_Thread *ALSA_hotplug_thread;
|
||||
|
||||
static int SDLCALL
|
||||
ALSA_HotplugThread(void *arg)
|
||||
{
|
||||
SDL_sem *first_run_semaphore = (SDL_sem *) arg;
|
||||
ALSA_Device *devices = NULL;
|
||||
ALSA_Device *next;
|
||||
ALSA_Device *dev;
|
||||
Uint32 ticks;
|
||||
|
||||
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW);
|
||||
|
||||
while (!SDL_AtomicGet(&ALSA_hotplug_shutdown)) {
|
||||
void **hints = NULL;
|
||||
ALSA_Device *unseen;
|
||||
ALSA_Device *seen;
|
||||
ALSA_Device *prev;
|
||||
|
||||
if (ALSA_snd_device_name_hint(-1, "pcm", &hints) == 0) {
|
||||
int i, j;
|
||||
const char *match = NULL;
|
||||
int bestmatch = 0xFFFF;
|
||||
size_t match_len = 0;
|
||||
int defaultdev = -1;
|
||||
static const char * const prefixes[] = {
|
||||
"hw:", "sysdefault:", "default:", NULL
|
||||
};
|
||||
|
||||
unseen = devices;
|
||||
seen = NULL;
|
||||
/* Apparently there are several different ways that ALSA lists
|
||||
actual hardware. It could be prefixed with "hw:" or "default:"
|
||||
or "sysdefault:" and maybe others. Go through the list and see
|
||||
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) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* full name, not a prefix */
|
||||
if ((defaultdev == -1) && (SDL_strcmp(name, "default") == 0)) {
|
||||
defaultdev = i;
|
||||
}
|
||||
|
||||
for (j = 0; prefixes[j]; j++) {
|
||||
const char *prefix = prefixes[j];
|
||||
const size_t prefixlen = SDL_strlen(prefix);
|
||||
if (SDL_strncmp(name, prefix, prefixlen) == 0) {
|
||||
if (j < bestmatch) {
|
||||
bestmatch = j;
|
||||
match = prefix;
|
||||
match_len = prefixlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(name);
|
||||
}
|
||||
|
||||
/* look through the list of device names to find matches */
|
||||
for (i = 0; hints[i]; i++) {
|
||||
char *name;
|
||||
|
||||
/* if we didn't find a device name prefix we like at all... */
|
||||
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) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* only want physical hardware interfaces */
|
||||
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);
|
||||
SDL_bool have_output = SDL_FALSE;
|
||||
SDL_bool have_input = SDL_FALSE;
|
||||
|
||||
free(ioid);
|
||||
|
||||
if (!isoutput && !isinput) {
|
||||
free(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
prev = NULL;
|
||||
for (dev = unseen; dev; dev = next) {
|
||||
next = dev->next;
|
||||
if ( (SDL_strcmp(dev->name, name) == 0) && (((isinput) && dev->iscapture) || ((isoutput) && !dev->iscapture)) ) {
|
||||
if (prev) {
|
||||
prev->next = next;
|
||||
} else {
|
||||
unseen = next;
|
||||
}
|
||||
dev->next = seen;
|
||||
seen = dev;
|
||||
if (isinput) have_input = SDL_TRUE;
|
||||
if (isoutput) have_output = SDL_TRUE;
|
||||
} else {
|
||||
prev = dev;
|
||||
}
|
||||
}
|
||||
|
||||
if (isinput && !have_input) {
|
||||
add_device(SDL_TRUE, name, hints[i], &seen);
|
||||
}
|
||||
if (isoutput && !have_output) {
|
||||
add_device(SDL_FALSE, name, hints[i], &seen);
|
||||
}
|
||||
}
|
||||
|
||||
free(name);
|
||||
}
|
||||
|
||||
ALSA_snd_device_name_free_hint(hints);
|
||||
|
||||
devices = seen; /* now we have a known-good list of attached devices. */
|
||||
|
||||
/* report anything still in unseen as removed. */
|
||||
for (dev = unseen; dev; dev = next) {
|
||||
/*printf("ALSA: removing usb %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/
|
||||
next = dev->next;
|
||||
SDL_RemoveAudioDevice(dev->iscapture, dev->name);
|
||||
SDL_free(dev->name);
|
||||
SDL_free(dev);
|
||||
}
|
||||
}
|
||||
|
||||
/* On first run, tell ALSA_DetectDevices() that we have a complete device list so it can return. */
|
||||
if (first_run_semaphore) {
|
||||
SDL_SemPost(first_run_semaphore);
|
||||
first_run_semaphore = NULL; /* let other thread clean it up. */
|
||||
}
|
||||
|
||||
/* Block awhile before checking again, unless we're told to stop. */
|
||||
ticks = SDL_GetTicks() + 5000;
|
||||
const Uint32 ticks = SDL_GetTicks() + 5000;
|
||||
while (!SDL_AtomicGet(&ALSA_hotplug_shutdown) && !SDL_TICKS_PASSED(SDL_GetTicks(), ticks)) {
|
||||
SDL_Delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
/* Shutting down! Clean up any data we've gathered. */
|
||||
for (dev = devices; dev; dev = next) {
|
||||
/*printf("ALSA: at shutdown, removing %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/
|
||||
next = dev->next;
|
||||
SDL_free(dev->name);
|
||||
SDL_free(dev);
|
||||
ALSA_HotplugIteration(); /* run the check. */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
ALSA_DetectDevices(void)
|
||||
{
|
||||
/* Start the device detection thread here, wait for an initial iteration to complete. */
|
||||
SDL_sem *semaphore = SDL_CreateSemaphore(0);
|
||||
if (!semaphore) {
|
||||
return; /* oh well. */
|
||||
}
|
||||
ALSA_HotplugIteration(); /* run once now before a thread continues to check. */
|
||||
|
||||
#if SDL_ALSA_HOTPLUG_THREAD
|
||||
SDL_AtomicSet(&ALSA_hotplug_shutdown, 0);
|
||||
|
||||
ALSA_hotplug_thread = SDL_CreateThread(ALSA_HotplugThread, "SDLHotplugALSA", semaphore);
|
||||
if (ALSA_hotplug_thread) {
|
||||
SDL_SemWait(semaphore); /* wait for the first iteration to finish. */
|
||||
}
|
||||
|
||||
SDL_DestroySemaphore(semaphore);
|
||||
ALSA_hotplug_thread = SDL_CreateThread(ALSA_HotplugThread, "SDLHotplugALSA", NULL);
|
||||
/* if the thread doesn't spin, oh well, you just don't get further hotplug events. */
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
ALSA_Deinitialize(void)
|
||||
{
|
||||
ALSA_Device *dev;
|
||||
ALSA_Device *next;
|
||||
|
||||
#if SDL_ALSA_HOTPLUG_THREAD
|
||||
if (ALSA_hotplug_thread != NULL) {
|
||||
SDL_AtomicSet(&ALSA_hotplug_shutdown, 1);
|
||||
SDL_WaitThread(ALSA_hotplug_thread, NULL);
|
||||
ALSA_hotplug_thread = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Shutting down! Clean up any data we've gathered. */
|
||||
for (dev = hotplug_devices; dev; dev = next) {
|
||||
/*printf("ALSA: at shutdown, removing %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/
|
||||
next = dev->next;
|
||||
SDL_free(dev->name);
|
||||
SDL_free(dev);
|
||||
}
|
||||
hotplug_devices = NULL;
|
||||
|
||||
UnloadALSALibrary();
|
||||
}
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
ALSA_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
if (LoadALSALibrary() < 0) {
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Set the function pointers */
|
||||
|
|
@ -984,12 +1010,12 @@ ALSA_Init(SDL_AudioDriverImpl * impl)
|
|||
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
||||
AudioBootStrap ALSA_bootstrap = {
|
||||
"alsa", "ALSA PCM audio", ALSA_Init, 0
|
||||
"alsa", "ALSA PCM audio", ALSA_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_ALSA */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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,9 +36,10 @@ static SDL_AudioDevice* audioDevice = NULL;
|
|||
static SDL_AudioDevice* captureDevice = NULL;
|
||||
|
||||
static int
|
||||
ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
ANDROIDAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
SDL_AudioFormat test_format;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
|
||||
SDL_assert((captureDevice == NULL) || !iscapture);
|
||||
SDL_assert((audioDevice == NULL) || iscapture);
|
||||
|
|
@ -54,20 +55,18 @@ ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
while (test_format != 0) { /* no "UNKNOWN" constant */
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
if ((test_format == AUDIO_U8) ||
|
||||
(test_format == AUDIO_S16) ||
|
||||
(test_format == AUDIO_F32)) {
|
||||
(test_format == AUDIO_S16) ||
|
||||
(test_format == AUDIO_F32)) {
|
||||
this->spec.format = test_format;
|
||||
break;
|
||||
}
|
||||
test_format = SDL_NextAudioFormat();
|
||||
}
|
||||
|
||||
if (test_format == 0) {
|
||||
if (!test_format) {
|
||||
/* Didn't find a compatible format :( */
|
||||
return SDL_SetError("No compatible audio format!");
|
||||
return SDL_SetError("%s: Unsupported audio format", "android");
|
||||
}
|
||||
|
||||
if (Android_JNI_OpenAudioDevice(iscapture, &this->spec) < 0) {
|
||||
|
|
@ -120,7 +119,7 @@ ANDROIDAUDIO_CloseDevice(_THIS)
|
|||
SDL_free(this->hidden);
|
||||
}
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
ANDROIDAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
|
|
@ -133,14 +132,14 @@ ANDROIDAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
|
||||
/* and the capabilities */
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
impl->OnlyHasDefaultCaptureDevice = 1;
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap ANDROIDAUDIO_bootstrap = {
|
||||
"android", "SDL Android audio driver", ANDROIDAUDIO_Init, 0
|
||||
"android", "SDL Android audio driver", ANDROIDAUDIO_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
/* Pause (block) all non already paused audio devices by taking their mixer lock */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -216,11 +216,11 @@ ARTS_Suspend(void)
|
|||
}
|
||||
|
||||
static int
|
||||
ARTS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
ARTS_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
int rc = 0;
|
||||
int bits = 0, frag_spec = 0;
|
||||
SDL_AudioFormat test_format = 0, format = 0;
|
||||
int bits, frag_spec = 0;
|
||||
SDL_AudioFormat test_format = 0;
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
|
|
@ -231,32 +231,24 @@ ARTS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
SDL_zerop(this->hidden);
|
||||
|
||||
/* Try for a closest match on audio format */
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
!format && test_format;) {
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
#ifdef DEBUG_AUDIO
|
||||
fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
|
||||
#endif
|
||||
switch (test_format) {
|
||||
case AUDIO_U8:
|
||||
bits = 8;
|
||||
format = 1;
|
||||
break;
|
||||
case AUDIO_S16LSB:
|
||||
bits = 16;
|
||||
format = 1;
|
||||
break;
|
||||
default:
|
||||
format = 0;
|
||||
break;
|
||||
}
|
||||
if (!format) {
|
||||
test_format = SDL_NextAudioFormat();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (format == 0) {
|
||||
return SDL_SetError("Couldn't find any hardware audio formats");
|
||||
if (!test_format) {
|
||||
return SDL_SetError("%s: Unsupported audio format", "arts");
|
||||
}
|
||||
this->spec.format = test_format;
|
||||
bits = SDL_AUDIO_BITSIZE(test_format);
|
||||
|
||||
if ((rc = SDL_NAME(arts_init) ()) != 0) {
|
||||
return SDL_SetError("Unable to initialize ARTS: %s",
|
||||
|
|
@ -320,16 +312,16 @@ ARTS_Deinitialize(void)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
ARTS_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
if (LoadARTSLibrary() < 0) {
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
} else {
|
||||
if (SDL_NAME(arts_init) () != 0) {
|
||||
UnloadARTSLibrary();
|
||||
SDL_SetError("ARTS: arts_init failed (no audio server?)");
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Play a stream so aRts doesn't crash */
|
||||
|
|
@ -350,14 +342,14 @@ ARTS_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->GetDeviceBuf = ARTS_GetDeviceBuf;
|
||||
impl->CloseDevice = ARTS_CloseDevice;
|
||||
impl->Deinitialize = ARTS_Deinitialize;
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
||||
AudioBootStrap ARTS_bootstrap = {
|
||||
"arts", "Analog RealTime Synthesizer", ARTS_Init, 0
|
||||
"arts", "Analog RealTime Synthesizer", ARTS_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_ARTS */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -56,7 +56,7 @@ static const AudioObjectPropertyAddress devlist_address = {
|
|||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
typedef void (*addDevFn)(const char *name, const int iscapture, AudioDeviceID devId, void *data);
|
||||
typedef void (*addDevFn)(const char *name, SDL_AudioSpec *spec, const int iscapture, AudioDeviceID devId, void *data);
|
||||
|
||||
typedef struct AudioDeviceList
|
||||
{
|
||||
|
|
@ -88,10 +88,10 @@ add_to_internal_dev_list(const int iscapture, AudioDeviceID devId)
|
|||
}
|
||||
|
||||
static void
|
||||
addToDevList(const char *name, const int iscapture, AudioDeviceID devId, void *data)
|
||||
addToDevList(const char *name, SDL_AudioSpec *spec, const int iscapture, AudioDeviceID devId, void *data)
|
||||
{
|
||||
if (add_to_internal_dev_list(iscapture, devId)) {
|
||||
SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId));
|
||||
SDL_AddAudioDevice(iscapture, name, spec, (void *) ((size_t) devId));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,17 +126,23 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
|
|||
AudioBufferList *buflist = NULL;
|
||||
int usable = 0;
|
||||
CFIndex len = 0;
|
||||
double sampleRate = 0;
|
||||
SDL_AudioSpec spec;
|
||||
const AudioObjectPropertyAddress addr = {
|
||||
kAudioDevicePropertyStreamConfiguration,
|
||||
iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
const AudioObjectPropertyAddress nameaddr = {
|
||||
kAudioObjectPropertyName,
|
||||
iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
const AudioObjectPropertyAddress freqaddr = {
|
||||
kAudioDevicePropertyNominalSampleRate,
|
||||
iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
result = AudioObjectGetPropertyDataSize(dev, &addr, 0, NULL, &size);
|
||||
if (result != noErr)
|
||||
|
|
@ -149,21 +155,24 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
|
|||
result = AudioObjectGetPropertyData(dev, &addr, 0, NULL,
|
||||
&size, buflist);
|
||||
|
||||
SDL_zero(spec);
|
||||
if (result == noErr) {
|
||||
UInt32 j;
|
||||
for (j = 0; j < buflist->mNumberBuffers; j++) {
|
||||
if (buflist->mBuffers[j].mNumberChannels > 0) {
|
||||
usable = 1;
|
||||
break;
|
||||
}
|
||||
spec.channels += buflist->mBuffers[j].mNumberChannels;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_free(buflist);
|
||||
|
||||
if (!usable)
|
||||
if (spec.channels == 0)
|
||||
continue;
|
||||
|
||||
size = sizeof (sampleRate);
|
||||
result = AudioObjectGetPropertyData(dev, &freqaddr, 0, NULL, &size, &sampleRate);
|
||||
if (result == noErr) {
|
||||
spec.freq = (int) sampleRate;
|
||||
}
|
||||
|
||||
size = sizeof (CFStringRef);
|
||||
result = AudioObjectGetPropertyData(dev, &nameaddr, 0, NULL, &size, &cfstr);
|
||||
|
|
@ -197,7 +206,7 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
|
|||
((iscapture) ? "capture" : "output"),
|
||||
(int) i, ptr, (int) dev);
|
||||
#endif
|
||||
addfn(ptr, iscapture, dev, addfndata);
|
||||
addfn(ptr, &spec, iscapture, dev, addfndata);
|
||||
}
|
||||
SDL_free(ptr); /* addfn() would have copied the string. */
|
||||
}
|
||||
|
|
@ -223,7 +232,7 @@ COREAUDIO_DetectDevices(void)
|
|||
}
|
||||
|
||||
static void
|
||||
build_device_change_list(const char *name, const int iscapture, AudioDeviceID devId, void *data)
|
||||
build_device_change_list(const char *name, SDL_AudioSpec *spec, const int iscapture, AudioDeviceID devId, void *data)
|
||||
{
|
||||
AudioDeviceList **list = (AudioDeviceList **) data;
|
||||
AudioDeviceList *item;
|
||||
|
|
@ -235,7 +244,7 @@ build_device_change_list(const char *name, const int iscapture, AudioDeviceID de
|
|||
}
|
||||
|
||||
add_to_internal_dev_list(iscapture, devId); /* new device, add it. */
|
||||
SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId));
|
||||
SDL_AddAudioDevice(iscapture, name, spec, (void *) ((size_t) devId));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -592,7 +601,7 @@ inputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer
|
|||
}
|
||||
|
||||
/* ignore unless we're active. */
|
||||
if (!SDL_AtomicGet(&this->paused) && SDL_AtomicGet(&this->enabled) && !SDL_AtomicGet(&this->paused)) {
|
||||
if (!SDL_AtomicGet(&this->paused) && SDL_AtomicGet(&this->enabled)) {
|
||||
const Uint8 *ptr = (const Uint8 *) inBuffer->mAudioData;
|
||||
UInt32 remaining = inBuffer->mAudioDataByteSize;
|
||||
while (remaining > 0) {
|
||||
|
|
@ -732,8 +741,10 @@ COREAUDIO_CloseDevice(_THIS)
|
|||
|
||||
#if MACOSX_COREAUDIO
|
||||
static int
|
||||
prepare_device(_THIS, void *handle, int iscapture)
|
||||
prepare_device(_THIS)
|
||||
{
|
||||
void *handle = this->handle;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
AudioDeviceID devid = (AudioDeviceID) ((size_t) handle);
|
||||
OSStatus result = noErr;
|
||||
UInt32 size = 0;
|
||||
|
|
@ -974,7 +985,7 @@ audioqueue_thread(void *arg)
|
|||
and quits (flagging the audioqueue for shutdown), or toggles to some other system
|
||||
output device (in which case we'll try again). */
|
||||
const AudioDeviceID prev_devid = this->hidden->deviceID;
|
||||
if (prepare_device(this, this->handle, this->iscapture) && (prev_devid != this->hidden->deviceID)) {
|
||||
if (prepare_device(this) && (prev_devid != this->hidden->deviceID)) {
|
||||
AudioQueueStop(this->hidden->audioQueue, 1);
|
||||
if (assign_device_to_audioqueue(this)) {
|
||||
int i;
|
||||
|
|
@ -1006,11 +1017,11 @@ audioqueue_thread(void *arg)
|
|||
}
|
||||
|
||||
static int
|
||||
COREAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
COREAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
AudioStreamBasicDescription *strdesc;
|
||||
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
int valid_datatype = 0;
|
||||
SDL_AudioFormat test_format;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
SDL_AudioDevice **new_open_devices;
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
|
|
@ -1067,8 +1078,7 @@ COREAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
strdesc->mSampleRate = this->spec.freq;
|
||||
strdesc->mFramesPerPacket = 1;
|
||||
|
||||
while ((!valid_datatype) && (test_format)) {
|
||||
this->spec.format = test_format;
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
/* CoreAudio handles most of SDL's formats natively, but not U16, apparently. */
|
||||
switch (test_format) {
|
||||
case AUDIO_U8:
|
||||
|
|
@ -1079,32 +1089,32 @@ COREAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
case AUDIO_S32MSB:
|
||||
case AUDIO_F32LSB:
|
||||
case AUDIO_F32MSB:
|
||||
valid_datatype = 1;
|
||||
strdesc->mBitsPerChannel = SDL_AUDIO_BITSIZE(this->spec.format);
|
||||
if (SDL_AUDIO_ISBIGENDIAN(this->spec.format))
|
||||
strdesc->mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
|
||||
|
||||
if (SDL_AUDIO_ISFLOAT(this->spec.format))
|
||||
strdesc->mFormatFlags |= kLinearPCMFormatFlagIsFloat;
|
||||
else if (SDL_AUDIO_ISSIGNED(this->spec.format))
|
||||
strdesc->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
|
||||
break;
|
||||
|
||||
default:
|
||||
test_format = SDL_NextAudioFormat();
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!valid_datatype) { /* shouldn't happen, but just in case... */
|
||||
return SDL_SetError("Unsupported audio format");
|
||||
if (!test_format) { /* shouldn't happen, but just in case... */
|
||||
return SDL_SetError("%s: Unsupported audio format", "coreaudio");
|
||||
}
|
||||
this->spec.format = test_format;
|
||||
strdesc->mBitsPerChannel = SDL_AUDIO_BITSIZE(test_format);
|
||||
if (SDL_AUDIO_ISBIGENDIAN(test_format))
|
||||
strdesc->mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
|
||||
|
||||
if (SDL_AUDIO_ISFLOAT(test_format))
|
||||
strdesc->mFormatFlags |= kLinearPCMFormatFlagIsFloat;
|
||||
else if (SDL_AUDIO_ISSIGNED(test_format))
|
||||
strdesc->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
|
||||
|
||||
strdesc->mBytesPerFrame = strdesc->mChannelsPerFrame * strdesc->mBitsPerChannel / 8;
|
||||
strdesc->mBytesPerPacket = strdesc->mBytesPerFrame * strdesc->mFramesPerPacket;
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
if (!prepare_device(this, handle, iscapture)) {
|
||||
if (!prepare_device(this)) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1126,8 +1136,7 @@ COREAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
this->hidden->ready_semaphore = NULL;
|
||||
|
||||
if ((this->hidden->thread != NULL) && (this->hidden->thread_error != NULL)) {
|
||||
SDL_SetError("%s", this->hidden->thread_error);
|
||||
return -1;
|
||||
return SDL_SetError("%s", this->hidden->thread_error);
|
||||
}
|
||||
|
||||
return (this->hidden->thread != NULL) ? 0 : -1;
|
||||
|
|
@ -1143,7 +1152,7 @@ COREAUDIO_Deinitialize(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
COREAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
|
|
@ -1155,18 +1164,18 @@ COREAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->DetectDevices = COREAUDIO_DetectDevices;
|
||||
AudioObjectAddPropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL);
|
||||
#else
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
impl->OnlyHasDefaultCaptureDevice = 1;
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
|
||||
#endif
|
||||
|
||||
impl->ProvidesOwnCallbackThread = 1;
|
||||
impl->HasCaptureSupport = 1;
|
||||
impl->ProvidesOwnCallbackThread = SDL_TRUE;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap COREAUDIO_bootstrap = {
|
||||
"coreaudio", "CoreAudio", COREAUDIO_Init, 0
|
||||
"coreaudio", "CoreAudio", COREAUDIO_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_COREAUDIO */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -98,10 +98,8 @@ DSOUND_Load(void)
|
|||
static int
|
||||
SetDSerror(const char *function, int code)
|
||||
{
|
||||
static const char *error;
|
||||
static char errbuf[1024];
|
||||
const char *error;
|
||||
|
||||
errbuf[0] = 0;
|
||||
switch (code) {
|
||||
case E_NOINTERFACE:
|
||||
error = "Unsupported interface -- Is DirectX 8.0 or later installed?";
|
||||
|
|
@ -137,15 +135,11 @@ SetDSerror(const char *function, int code)
|
|||
error = "Function not supported";
|
||||
break;
|
||||
default:
|
||||
SDL_snprintf(errbuf, SDL_arraysize(errbuf),
|
||||
"%s: Unknown DirectSound error: 0x%x", function, code);
|
||||
error = "Unknown DirectSound error";
|
||||
break;
|
||||
}
|
||||
if (!errbuf[0]) {
|
||||
SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function,
|
||||
error);
|
||||
}
|
||||
return SDL_SetError("%s", errbuf);
|
||||
|
||||
return SDL_SetError("%s: %s (0x%x)", function, error, code);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -163,7 +157,12 @@ FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data)
|
|||
if (str != NULL) {
|
||||
LPGUID cpyguid = (LPGUID) SDL_malloc(sizeof (GUID));
|
||||
SDL_memcpy(cpyguid, guid, sizeof (GUID));
|
||||
SDL_AddAudioDevice(iscapture, str, cpyguid);
|
||||
|
||||
/* Note that spec is NULL, because we are required to connect to the
|
||||
* device before getting the channel mask and output format, making
|
||||
* this information inaccessible at enumeration time
|
||||
*/
|
||||
SDL_AddAudioDevice(iscapture, str, NULL, cpyguid);
|
||||
SDL_free(str); /* addfn() makes a copy of this string. */
|
||||
}
|
||||
}
|
||||
|
|
@ -468,14 +467,14 @@ CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
|
|||
}
|
||||
|
||||
static int
|
||||
DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
DSOUND_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
const DWORD numchunks = 8;
|
||||
HRESULT result;
|
||||
SDL_bool valid_format = SDL_FALSE;
|
||||
SDL_bool tried_format = SDL_FALSE;
|
||||
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
LPGUID guid = (LPGUID) handle;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
SDL_AudioFormat test_format;
|
||||
LPGUID guid = (LPGUID) this->handle;
|
||||
DWORD bufsize;
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
|
|
@ -505,7 +504,7 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
}
|
||||
}
|
||||
|
||||
while ((!valid_format) && (test_format)) {
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
switch (test_format) {
|
||||
case AUDIO_U8:
|
||||
case AUDIO_S16:
|
||||
|
|
@ -542,19 +541,21 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
rc = iscapture ? CreateCaptureBuffer(this, bufsize, &wfmt) : CreateSecondary(this, bufsize, &wfmt);
|
||||
if (rc == 0) {
|
||||
this->hidden->num_buffers = numchunks;
|
||||
valid_format = SDL_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
continue;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
test_format = SDL_NextAudioFormat();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!valid_format) {
|
||||
if (!test_format) {
|
||||
if (tried_format) {
|
||||
return -1; /* CreateSecondary() should have called SDL_SetError(). */
|
||||
}
|
||||
return SDL_SetError("DirectSound: Unsupported audio format");
|
||||
return SDL_SetError("%s: Unsupported audio format", "directsound");
|
||||
}
|
||||
|
||||
/* Playback buffers will auto-start playing in DSOUND_WaitDevice() */
|
||||
|
|
@ -570,11 +571,11 @@ DSOUND_Deinitialize(void)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
DSOUND_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
if (!DSOUND_Load()) {
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Set the function pointers */
|
||||
|
|
@ -591,11 +592,11 @@ DSOUND_Init(SDL_AudioDriverImpl * impl)
|
|||
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap DSOUND_bootstrap = {
|
||||
"directsound", "DirectSound", DSOUND_Init, 0
|
||||
"directsound", "DirectSound", DSOUND_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_DSOUND */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -46,19 +46,19 @@
|
|||
static void
|
||||
DISKAUDIO_WaitDevice(_THIS)
|
||||
{
|
||||
SDL_Delay(this->hidden->io_delay);
|
||||
SDL_Delay(_this->hidden->io_delay);
|
||||
}
|
||||
|
||||
static void
|
||||
DISKAUDIO_PlayDevice(_THIS)
|
||||
{
|
||||
const size_t written = SDL_RWwrite(this->hidden->io,
|
||||
this->hidden->mixbuf,
|
||||
1, this->spec.size);
|
||||
const size_t written = SDL_RWwrite(_this->hidden->io,
|
||||
_this->hidden->mixbuf,
|
||||
1, _this->spec.size);
|
||||
|
||||
/* If we couldn't write, assume fatal error for now */
|
||||
if (written != this->spec.size) {
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
if (written != _this->spec.size) {
|
||||
SDL_OpenedAudioDeviceDisconnected(_this);
|
||||
}
|
||||
#ifdef DEBUG_AUDIO
|
||||
fprintf(stderr, "Wrote %d bytes of audio data\n", written);
|
||||
|
|
@ -68,13 +68,13 @@ DISKAUDIO_PlayDevice(_THIS)
|
|||
static Uint8 *
|
||||
DISKAUDIO_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return (this->hidden->mixbuf);
|
||||
return (_this->hidden->mixbuf);
|
||||
}
|
||||
|
||||
static int
|
||||
DISKAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
struct SDL_PrivateAudioData *h = _this->hidden;
|
||||
const int origbuflen = buflen;
|
||||
|
||||
SDL_Delay(h->io_delay);
|
||||
|
|
@ -90,7 +90,7 @@ DISKAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
|||
}
|
||||
|
||||
/* if we ran out of file, just write silence. */
|
||||
SDL_memset(buffer, this->spec.silence, buflen);
|
||||
SDL_memset(buffer, _this->spec.silence, buflen);
|
||||
|
||||
return origbuflen;
|
||||
}
|
||||
|
|
@ -105,16 +105,16 @@ DISKAUDIO_FlushCapture(_THIS)
|
|||
static void
|
||||
DISKAUDIO_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->io != NULL) {
|
||||
SDL_RWclose(this->hidden->io);
|
||||
if (_this->hidden->io != NULL) {
|
||||
SDL_RWclose(_this->hidden->io);
|
||||
}
|
||||
SDL_free(this->hidden->mixbuf);
|
||||
SDL_free(this->hidden);
|
||||
SDL_free(_this->hidden->mixbuf);
|
||||
SDL_free(_this->hidden);
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
get_filename(const int iscapture, const char *devname)
|
||||
get_filename(const SDL_bool iscapture, const char *devname)
|
||||
{
|
||||
if (devname == NULL) {
|
||||
devname = SDL_getenv(iscapture ? DISKENVR_INFILE : DISKENVR_OUTFILE);
|
||||
|
|
@ -126,38 +126,40 @@ get_filename(const int iscapture, const char *devname)
|
|||
}
|
||||
|
||||
static int
|
||||
DISKAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
DISKAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
void *handle = _this->handle;
|
||||
/* handle != NULL means "user specified the placeholder name on the fake detected device list" */
|
||||
SDL_bool iscapture = _this->iscapture;
|
||||
const char *fname = get_filename(iscapture, handle ? NULL : devname);
|
||||
const char *envr = SDL_getenv(DISKENVR_IODELAY);
|
||||
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
_this->hidden = (struct SDL_PrivateAudioData *)
|
||||
SDL_malloc(sizeof(*_this->hidden));
|
||||
if (_this->hidden == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
SDL_zerop(_this->hidden);
|
||||
|
||||
if (envr != NULL) {
|
||||
this->hidden->io_delay = SDL_atoi(envr);
|
||||
_this->hidden->io_delay = SDL_atoi(envr);
|
||||
} else {
|
||||
this->hidden->io_delay = ((this->spec.samples * 1000) / this->spec.freq);
|
||||
_this->hidden->io_delay = ((_this->spec.samples * 1000) / _this->spec.freq);
|
||||
}
|
||||
|
||||
/* Open the audio device */
|
||||
this->hidden->io = SDL_RWFromFile(fname, iscapture ? "rb" : "wb");
|
||||
if (this->hidden->io == NULL) {
|
||||
_this->hidden->io = SDL_RWFromFile(fname, iscapture ? "rb" : "wb");
|
||||
if (_this->hidden->io == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Allocate mixing buffer */
|
||||
if (!iscapture) {
|
||||
this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->spec.size);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
_this->hidden->mixbuf = (Uint8 *) SDL_malloc(_this->spec.size);
|
||||
if (_this->hidden->mixbuf == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
|
||||
SDL_memset(_this->hidden->mixbuf, _this->spec.silence, _this->spec.size);
|
||||
}
|
||||
|
||||
SDL_LogCritical(SDL_LOG_CATEGORY_AUDIO,
|
||||
|
|
@ -173,11 +175,11 @@ DISKAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
static void
|
||||
DISKAUDIO_DetectDevices(void)
|
||||
{
|
||||
SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) 0x1);
|
||||
SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, (void *) 0x2);
|
||||
SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, NULL, (void *) 0x1);
|
||||
SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *) 0x2);
|
||||
}
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
DISKAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
|
|
@ -191,14 +193,14 @@ DISKAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->CloseDevice = DISKAUDIO_CloseDevice;
|
||||
impl->DetectDevices = DISKAUDIO_DetectDevices;
|
||||
|
||||
impl->AllowsArbitraryDeviceNames = 1;
|
||||
impl->AllowsArbitraryDeviceNames = SDL_TRUE;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap DISKAUDIO_bootstrap = {
|
||||
"disk", "direct-to-disk audio", DISKAUDIO_Init, 1
|
||||
"disk", "direct-to-disk audio", DISKAUDIO_Init, SDL_TRUE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_DISK */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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 @@
|
|||
#include "../SDL_sysaudio.h"
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
#define _THIS SDL_AudioDevice *_this
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -68,8 +68,9 @@ DSP_CloseDevice(_THIS)
|
|||
|
||||
|
||||
static int
|
||||
DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
DSP_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
|
||||
int format;
|
||||
int value;
|
||||
|
|
@ -103,7 +104,7 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
SDL_zerop(this->hidden);
|
||||
|
||||
/* Open the audio device */
|
||||
this->hidden->audio_fd = open(devname, flags, 0);
|
||||
this->hidden->audio_fd = open(devname, flags | O_CLOEXEC, 0);
|
||||
if (this->hidden->audio_fd < 0) {
|
||||
return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
|
||||
}
|
||||
|
|
@ -292,9 +293,25 @@ DSP_FlushCapture(_THIS)
|
|||
}
|
||||
}
|
||||
|
||||
static SDL_bool InitTimeDevicesExist = SDL_FALSE;
|
||||
static int
|
||||
look_for_devices_test(int fd)
|
||||
{
|
||||
InitTimeDevicesExist = SDL_TRUE; /* note that _something_ exists. */
|
||||
/* Don't add to the device list, we're just seeing if any devices exist. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
DSP_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
InitTimeDevicesExist = SDL_FALSE;
|
||||
SDL_EnumUnixAudioDevices(0, look_for_devices_test);
|
||||
if (!InitTimeDevicesExist) {
|
||||
SDL_SetError("dsp: No such audio device");
|
||||
return SDL_FALSE; /* maybe try a different backend. */
|
||||
}
|
||||
|
||||
/* Set the function pointers */
|
||||
impl->DetectDevices = DSP_DetectDevices;
|
||||
impl->OpenDevice = DSP_OpenDevice;
|
||||
|
|
@ -304,15 +321,15 @@ DSP_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->CaptureFromDevice = DSP_CaptureFromDevice;
|
||||
impl->FlushCapture = DSP_FlushCapture;
|
||||
|
||||
impl->AllowsArbitraryDeviceNames = 1;
|
||||
impl->AllowsArbitraryDeviceNames = SDL_TRUE;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
||||
AudioBootStrap DSP_bootstrap = {
|
||||
"dsp", "OSS /dev/dsp standard audio", DSP_Init, 0
|
||||
"dsp", "OSS /dev/dsp standard audio", DSP_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_OSS */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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,8 +28,9 @@
|
|||
#include "SDL_dummyaudio.h"
|
||||
|
||||
static int
|
||||
DUMMYAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
DUMMYAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
_this->hidden = (void *) 0x1; /* just something non-NULL */
|
||||
return 0; /* always succeeds. */
|
||||
}
|
||||
|
||||
|
|
@ -37,29 +38,29 @@ static int
|
|||
DUMMYAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
/* Delay to make this sort of simulate real audio input. */
|
||||
SDL_Delay((this->spec.samples * 1000) / this->spec.freq);
|
||||
SDL_Delay((_this->spec.samples * 1000) / _this->spec.freq);
|
||||
|
||||
/* always return a full buffer of silence. */
|
||||
SDL_memset(buffer, this->spec.silence, buflen);
|
||||
SDL_memset(buffer, _this->spec.silence, buflen);
|
||||
return buflen;
|
||||
}
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
DUMMYAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
impl->OpenDevice = DUMMYAUDIO_OpenDevice;
|
||||
impl->CaptureFromDevice = DUMMYAUDIO_CaptureFromDevice;
|
||||
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
impl->OnlyHasDefaultCaptureDevice = 1;
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap DUMMYAUDIO_bootstrap = {
|
||||
"dummy", "SDL dummy audio driver", DUMMYAUDIO_Init, 1
|
||||
"dummy", "SDL dummy audio driver", DUMMYAUDIO_Init, SDL_TRUE
|
||||
};
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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 @@
|
|||
#include "../SDL_sysaudio.h"
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
#define _THIS SDL_AudioDevice *_this
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -59,6 +59,9 @@ HandleAudioProcess(_THIS)
|
|||
if (this->stream) {
|
||||
SDL_AudioStreamClear(this->stream);
|
||||
}
|
||||
|
||||
SDL_memset(this->work_buffer, this->spec.silence, this->spec.size);
|
||||
FeedAudioDevice(this, this->work_buffer, this->spec.size);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -189,10 +192,10 @@ EMSCRIPTENAUDIO_CloseDevice(_THIS)
|
|||
}
|
||||
|
||||
static int
|
||||
EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
SDL_bool valid_format = SDL_FALSE;
|
||||
SDL_AudioFormat test_format;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
int result;
|
||||
|
||||
/* based on parts of library_sdl.js */
|
||||
|
|
@ -215,6 +218,9 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscaptu
|
|||
} else if (typeof(webkitAudioContext) !== 'undefined') {
|
||||
SDL2.audioContext = new webkitAudioContext();
|
||||
}
|
||||
if (SDL2.audioContext) {
|
||||
autoResumeAudioContext(SDL2.audioContext);
|
||||
}
|
||||
}
|
||||
return SDL2.audioContext === undefined ? -1 : 0;
|
||||
}, iscapture);
|
||||
|
|
@ -222,22 +228,21 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscaptu
|
|||
return SDL_SetError("Web Audio API is not available!");
|
||||
}
|
||||
|
||||
test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
while ((!valid_format) && (test_format)) {
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
switch (test_format) {
|
||||
case AUDIO_F32: /* web audio only supports floats */
|
||||
this->spec.format = test_format;
|
||||
|
||||
valid_format = SDL_TRUE;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
test_format = SDL_NextAudioFormat();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!valid_format) {
|
||||
if (!test_format) {
|
||||
/* Didn't find a compatible format :( */
|
||||
return SDL_SetError("No compatible audio format!");
|
||||
return SDL_SetError("%s: Unsupported audio format", "emscripten");
|
||||
}
|
||||
this->spec.format = test_format;
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
#if 0 /* !!! FIXME: currently not used. Can we move some stuff off the SDL2 namespace? --ryan. */
|
||||
|
|
@ -333,30 +338,34 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscaptu
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
EMSCRIPTENAUDIO_LockOrUnlockDeviceWithNoMixerLock(SDL_AudioDevice * device)
|
||||
{
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
int available;
|
||||
int capture_available;
|
||||
SDL_bool available, capture_available;
|
||||
|
||||
/* Set the function pointers */
|
||||
impl->OpenDevice = EMSCRIPTENAUDIO_OpenDevice;
|
||||
impl->CloseDevice = EMSCRIPTENAUDIO_CloseDevice;
|
||||
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
|
||||
/* no threads here */
|
||||
impl->SkipMixerLock = 1;
|
||||
impl->ProvidesOwnCallbackThread = 1;
|
||||
impl->LockDevice = impl->UnlockDevice = EMSCRIPTENAUDIO_LockOrUnlockDeviceWithNoMixerLock;
|
||||
impl->ProvidesOwnCallbackThread = SDL_TRUE;
|
||||
|
||||
/* check availability */
|
||||
available = EM_ASM_INT_V({
|
||||
if (typeof(AudioContext) !== 'undefined') {
|
||||
return 1;
|
||||
return true;
|
||||
} else if (typeof(webkitAudioContext) !== 'undefined') {
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
return 0;
|
||||
return false;
|
||||
});
|
||||
|
||||
if (!available) {
|
||||
|
|
@ -365,11 +374,11 @@ EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
|
||||
capture_available = available && EM_ASM_INT_V({
|
||||
if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) {
|
||||
return 1;
|
||||
return true;
|
||||
} else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') {
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
return 0;
|
||||
return false;
|
||||
});
|
||||
|
||||
impl->HasCaptureSupport = capture_available ? SDL_TRUE : SDL_FALSE;
|
||||
|
|
@ -379,7 +388,7 @@ EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
}
|
||||
|
||||
AudioBootStrap EMSCRIPTENAUDIO_bootstrap = {
|
||||
"emscripten", "SDL emscripten audio driver", EMSCRIPTENAUDIO_Init, 0
|
||||
"emscripten", "SDL emscripten audio driver", EMSCRIPTENAUDIO_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_EMSCRIPTEN */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -208,7 +208,7 @@ get_progname(void)
|
|||
|
||||
|
||||
static int
|
||||
ESD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
ESD_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
esd_format_t format = (ESD_STREAM | ESD_PLAY);
|
||||
SDL_AudioFormat test_format = 0;
|
||||
|
|
@ -293,11 +293,11 @@ ESD_Deinitialize(void)
|
|||
UnloadESDLibrary();
|
||||
}
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
ESD_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
if (LoadESDLibrary() < 0) {
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
} else {
|
||||
int connection = 0;
|
||||
|
||||
|
|
@ -308,7 +308,7 @@ ESD_Init(SDL_AudioDriverImpl * impl)
|
|||
if (connection < 0) {
|
||||
UnloadESDLibrary();
|
||||
SDL_SetError("ESD: esd_open_sound failed (no audio server?)");
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
SDL_NAME(esd_close) (connection);
|
||||
}
|
||||
|
|
@ -320,14 +320,14 @@ ESD_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->GetDeviceBuf = ESD_GetDeviceBuf;
|
||||
impl->CloseDevice = ESD_CloseDevice;
|
||||
impl->Deinitialize = ESD_Deinitialize;
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
||||
AudioBootStrap ESD_bootstrap = {
|
||||
"esd", "Enlightened Sound Daemon", ESD_Init, 0
|
||||
"esd", "Enlightened Sound Daemon", ESD_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_ESD */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -174,10 +174,10 @@ SDL_FS_CloseDevice(_THIS)
|
|||
|
||||
|
||||
static int
|
||||
SDL_FS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
SDL_FS_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
int bytes;
|
||||
SDL_AudioFormat test_format = 0, format = 0;
|
||||
SDL_AudioFormat test_format;
|
||||
FSSampleFormat fs_format;
|
||||
FSStreamDescription desc;
|
||||
DirectResult ret;
|
||||
|
|
@ -191,45 +191,34 @@ SDL_FS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
SDL_zerop(this->hidden);
|
||||
|
||||
/* Try for a closest match on audio format */
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
!format && test_format;) {
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
#ifdef DEBUG_AUDIO
|
||||
fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
|
||||
#endif
|
||||
switch (test_format) {
|
||||
case AUDIO_U8:
|
||||
fs_format = FSSF_U8;
|
||||
bytes = 1;
|
||||
format = 1;
|
||||
break;
|
||||
case AUDIO_S16SYS:
|
||||
fs_format = FSSF_S16;
|
||||
bytes = 2;
|
||||
format = 1;
|
||||
break;
|
||||
case AUDIO_S32SYS:
|
||||
fs_format = FSSF_S32;
|
||||
bytes = 4;
|
||||
format = 1;
|
||||
break;
|
||||
case AUDIO_F32SYS:
|
||||
fs_format = FSSF_FLOAT;
|
||||
bytes = 4;
|
||||
format = 1;
|
||||
break;
|
||||
default:
|
||||
format = 0;
|
||||
break;
|
||||
}
|
||||
if (!format) {
|
||||
test_format = SDL_NextAudioFormat();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (format == 0) {
|
||||
return SDL_SetError("Couldn't find any hardware audio formats");
|
||||
if (!test_format) {
|
||||
return SDL_SetError("%s: Unsupported audio format", "fusionsound");
|
||||
}
|
||||
this->spec.format = test_format;
|
||||
bytes = SDL_AUDIO_BITSIZE(test_format) / 8;
|
||||
|
||||
/* Retrieve the main sound interface. */
|
||||
ret = SDL_NAME(FusionSoundCreate) (&this->hidden->fs);
|
||||
|
|
@ -288,11 +277,11 @@ SDL_FS_Deinitialize(void)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
SDL_FS_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
if (LoadFusionSoundLibrary() < 0) {
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
} else {
|
||||
DirectResult ret;
|
||||
|
||||
|
|
@ -302,7 +291,7 @@ SDL_FS_Init(SDL_AudioDriverImpl * impl)
|
|||
SDL_SetError
|
||||
("FusionSound: SDL_FS_init failed (FusionSoundInit: %d)",
|
||||
ret);
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -313,14 +302,14 @@ SDL_FS_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->GetDeviceBuf = SDL_FS_GetDeviceBuf;
|
||||
impl->CloseDevice = SDL_FS_CloseDevice;
|
||||
impl->Deinitialize = SDL_FS_Deinitialize;
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
||||
AudioBootStrap FUSIONSOUND_bootstrap = {
|
||||
"fusionsound", "FusionSound", SDL_FS_Init, 0
|
||||
"fusionsound", "FusionSound", SDL_FS_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_FUSIONSOUND */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -120,11 +120,10 @@ UnmaskSignals(sigset_t * omask)
|
|||
|
||||
|
||||
static int
|
||||
HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
HAIKUAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
int valid_datatype = 0;
|
||||
media_raw_audio_format format;
|
||||
SDL_AudioFormat test_format = SDL_FirstAudioFormat(_this->spec.format);
|
||||
SDL_AudioFormat test_format;
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
_this->hidden = new SDL_PrivateAudioData;
|
||||
|
|
@ -138,9 +137,7 @@ HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
format.byte_order = B_MEDIA_LITTLE_ENDIAN;
|
||||
format.frame_rate = (float) _this->spec.freq;
|
||||
format.channel_count = _this->spec.channels; /* !!! FIXME: support > 2? */
|
||||
while ((!valid_datatype) && (test_format)) {
|
||||
valid_datatype = 1;
|
||||
_this->spec.format = test_format;
|
||||
for (test_format = SDL_FirstAudioFormat(_this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
switch (test_format) {
|
||||
case AUDIO_S8:
|
||||
format.format = media_raw_audio_format::B_AUDIO_CHAR;
|
||||
|
|
@ -178,15 +175,15 @@ HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
break;
|
||||
|
||||
default:
|
||||
valid_datatype = 0;
|
||||
test_format = SDL_NextAudioFormat();
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!valid_datatype) { /* shouldn't happen, but just in case... */
|
||||
return SDL_SetError("Unsupported audio format");
|
||||
if (!test_format) { /* shouldn't happen, but just in case... */
|
||||
return SDL_SetError("%s: Unsupported audio format", "haiku");
|
||||
}
|
||||
_this->spec.format = test_format;
|
||||
|
||||
/* Calculate the final parameters for this audio specification */
|
||||
SDL_CalculateAudioSpec(&_this->spec);
|
||||
|
|
@ -216,22 +213,22 @@ HAIKUAUDIO_Deinitialize(void)
|
|||
SDL_QuitBeApp();
|
||||
}
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
HAIKUAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
/* Initialize the Be Application, if it's not already started */
|
||||
if (SDL_InitBeApp() < 0) {
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Set the function pointers */
|
||||
impl->OpenDevice = HAIKUAUDIO_OpenDevice;
|
||||
impl->CloseDevice = HAIKUAUDIO_CloseDevice;
|
||||
impl->Deinitialize = HAIKUAUDIO_Deinitialize;
|
||||
impl->ProvidesOwnCallbackThread = 1;
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
impl->ProvidesOwnCallbackThread = SDL_TRUE;
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
extern "C"
|
||||
|
|
@ -239,7 +236,7 @@ extern "C"
|
|||
extern AudioBootStrap HAIKUAUDIO_bootstrap;
|
||||
}
|
||||
AudioBootStrap HAIKUAUDIO_bootstrap = {
|
||||
"haiku", "Haiku BSoundPlayer", HAIKUAUDIO_Init, 0
|
||||
"haiku", "Haiku BSoundPlayer", HAIKUAUDIO_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_HAIKU */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -280,12 +280,13 @@ JACK_CloseDevice(_THIS)
|
|||
}
|
||||
|
||||
static int
|
||||
JACK_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
JACK_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
/* Note that JACK uses "output" for capture devices (they output audio
|
||||
data to us) and "input" for playback (we input audio data to them).
|
||||
Likewise, SDL's playback port will be "output" (we write data out)
|
||||
and capture will be "input" (we read data in). */
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
const unsigned long sysportflags = iscapture ? JackPortIsOutput : JackPortIsInput;
|
||||
const unsigned long sdlportflags = iscapture ? JackPortIsInput : JackPortIsOutput;
|
||||
const JackProcessCallback callback = iscapture ? jackProcessCaptureCallback : jackProcessPlaybackCallback;
|
||||
|
|
@ -405,18 +406,18 @@ JACK_Deinitialize(void)
|
|||
UnloadJackLibrary();
|
||||
}
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
JACK_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
if (LoadJackLibrary() < 0) {
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
} else {
|
||||
/* 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) {
|
||||
UnloadJackLibrary();
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
JACK_jack_client_close(client);
|
||||
}
|
||||
|
|
@ -433,11 +434,11 @@ JACK_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap JACK_bootstrap = {
|
||||
"jack", "JACK Audio Connection Kit", JACK_Init, 0
|
||||
"jack", "JACK Audio Connection Kit", JACK_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_JACK */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -99,7 +99,7 @@ static void NACLAUDIO_CloseDevice(SDL_AudioDevice *device) {
|
|||
}
|
||||
|
||||
static int
|
||||
NACLAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) {
|
||||
NACLAUDIO_OpenDevice(_THIS, const char *devname) {
|
||||
PP_Instance instance = PSGetInstanceId();
|
||||
const PPB_Audio *ppb_audio = PSInterfaceAudio();
|
||||
const PPB_AudioConfig *ppb_audiocfg = PSInterfaceAudioConfig();
|
||||
|
|
@ -133,18 +133,18 @@ NACLAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
NACLAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
if (PSGetInstanceId() == 0) {
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Set the function pointers */
|
||||
impl->OpenDevice = NACLAUDIO_OpenDevice;
|
||||
impl->CloseDevice = NACLAUDIO_CloseDevice;
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
impl->ProvidesOwnCallbackThread = 1;
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
impl->ProvidesOwnCallbackThread = SDL_TRUE;
|
||||
/*
|
||||
* impl->WaitDevice = NACLAUDIO_WaitDevice;
|
||||
* impl->GetDeviceBuf = NACLAUDIO_GetDeviceBuf;
|
||||
|
|
@ -152,12 +152,12 @@ NACLAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
* impl->Deinitialize = NACLAUDIO_Deinitialize;
|
||||
*/
|
||||
|
||||
return 1;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
AudioBootStrap NACLAUDIO_bootstrap = {
|
||||
NACLAUDIO_DRIVER_NAME, "SDL NaCl Audio Driver",
|
||||
NACLAUDIO_Init, 0
|
||||
NACLAUDIO_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_NACL */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -113,11 +113,11 @@ LoadNASLibrary(void)
|
|||
/* 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;
|
||||
char *err = (char *) alloca(len);
|
||||
char *err = SDL_stack_alloc(char, len);
|
||||
SDL_strlcpy(err, origerr, len);
|
||||
SDL_SetError("NAS: SDL_LoadObject('%s') failed: %s", nas_library, err);
|
||||
SDL_stack_free(err);
|
||||
retval = -1;
|
||||
SDL_SetError("NAS: SDL_LoadObject('%s') failed: %s",
|
||||
nas_library, err);
|
||||
} else {
|
||||
retval = load_nas_syms();
|
||||
if (retval < 0) {
|
||||
|
|
@ -237,26 +237,6 @@ NAS_CloseDevice(_THIS)
|
|||
SDL_free(this->hidden);
|
||||
}
|
||||
|
||||
static unsigned char
|
||||
sdlformat_to_auformat(unsigned int fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
case AUDIO_U8:
|
||||
return AuFormatLinearUnsigned8;
|
||||
case AUDIO_S8:
|
||||
return AuFormatLinearSigned8;
|
||||
case AUDIO_U16LSB:
|
||||
return AuFormatLinearUnsigned16LSB;
|
||||
case AUDIO_U16MSB:
|
||||
return AuFormatLinearUnsigned16MSB;
|
||||
case AUDIO_S16LSB:
|
||||
return AuFormatLinearSigned16LSB;
|
||||
case AUDIO_S16MSB:
|
||||
return AuFormatLinearSigned16MSB;
|
||||
}
|
||||
return AuNone;
|
||||
}
|
||||
|
||||
static AuBool
|
||||
event_handler(AuServer * aud, AuEvent * ev, AuEventHandlerRec * hnd)
|
||||
{
|
||||
|
|
@ -331,11 +311,12 @@ find_device(_THIS)
|
|||
}
|
||||
|
||||
static int
|
||||
NAS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
NAS_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
AuElement elms[3];
|
||||
int buffer_size;
|
||||
SDL_AudioFormat test_format, format;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
SDL_AudioFormat test_format, format = 0;
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
|
|
@ -346,16 +327,33 @@ NAS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
SDL_zerop(this->hidden);
|
||||
|
||||
/* Try for a closest match on audio format */
|
||||
format = 0;
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
!format && test_format;) {
|
||||
format = sdlformat_to_auformat(test_format);
|
||||
if (format == AuNone) {
|
||||
test_format = SDL_NextAudioFormat();
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
switch (test_format) {
|
||||
case AUDIO_U8:
|
||||
format = AuFormatLinearUnsigned8;
|
||||
break;
|
||||
case AUDIO_S8:
|
||||
format = AuFormatLinearSigned8;
|
||||
break;
|
||||
case AUDIO_U16LSB:
|
||||
format = AuFormatLinearUnsigned16LSB;
|
||||
break;
|
||||
case AUDIO_U16MSB:
|
||||
format = AuFormatLinearUnsigned16MSB;
|
||||
break;
|
||||
case AUDIO_S16LSB:
|
||||
format = AuFormatLinearSigned16LSB;
|
||||
break;
|
||||
case AUDIO_S16MSB:
|
||||
format = AuFormatLinearSigned16MSB;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (format == 0) {
|
||||
return SDL_SetError("NAS: Couldn't find any hardware audio formats");
|
||||
if (!test_format) {
|
||||
return SDL_SetError("%s: Unsupported audio format", "nas");
|
||||
}
|
||||
this->spec.format = test_format;
|
||||
|
||||
|
|
@ -423,16 +421,16 @@ NAS_Deinitialize(void)
|
|||
UnloadNASLibrary();
|
||||
}
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
NAS_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
if (LoadNASLibrary() < 0) {
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
} else {
|
||||
AuServer *aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL);
|
||||
if (aud == NULL) {
|
||||
SDL_SetError("NAS: AuOpenServer() failed (no audio server?)");
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
NAS_AuCloseServer(aud);
|
||||
}
|
||||
|
|
@ -447,15 +445,15 @@ NAS_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->CloseDevice = NAS_CloseDevice;
|
||||
impl->Deinitialize = NAS_Deinitialize;
|
||||
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
impl->OnlyHasDefaultCaptureDevice = 1;
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap NAS_bootstrap = {
|
||||
"nas", "Network Audio System", NAS_Init, 0
|
||||
"nas", "Network Audio System", NAS_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_NAS */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -202,10 +202,12 @@ NETBSDAUDIO_CloseDevice(_THIS)
|
|||
}
|
||||
|
||||
static int
|
||||
NETBSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
NETBSDAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
SDL_AudioFormat format = 0;
|
||||
audio_info_t info;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
SDL_AudioFormat test_format;
|
||||
int encoding = AUDIO_ENCODING_NONE;
|
||||
audio_info_t info, hwinfo;
|
||||
struct audio_prinfo *prinfo = iscapture ? &info.record : &info.play;
|
||||
|
||||
/* We don't care what the devname is...we'll try to open anything. */
|
||||
|
|
@ -226,77 +228,82 @@ NETBSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
SDL_zerop(this->hidden);
|
||||
|
||||
/* Open the audio device */
|
||||
this->hidden->audio_fd = open(devname, iscapture ? O_RDONLY : O_WRONLY);
|
||||
this->hidden->audio_fd = open(devname, (iscapture ? O_RDONLY : O_WRONLY) | O_CLOEXEC);
|
||||
if (this->hidden->audio_fd < 0) {
|
||||
return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
|
||||
}
|
||||
|
||||
AUDIO_INITINFO(&info);
|
||||
|
||||
prinfo->encoding = AUDIO_ENCODING_NONE;
|
||||
|
||||
for (format = SDL_FirstAudioFormat(this->spec.format); format;) {
|
||||
switch (format) {
|
||||
case AUDIO_U8:
|
||||
prinfo->encoding = AUDIO_ENCODING_ULINEAR;
|
||||
prinfo->precision = 8;
|
||||
break;
|
||||
case AUDIO_S8:
|
||||
prinfo->encoding = AUDIO_ENCODING_SLINEAR;
|
||||
prinfo->precision = 8;
|
||||
break;
|
||||
case AUDIO_S16LSB:
|
||||
prinfo->encoding = AUDIO_ENCODING_SLINEAR_LE;
|
||||
prinfo->precision = 16;
|
||||
break;
|
||||
case AUDIO_S16MSB:
|
||||
prinfo->encoding = AUDIO_ENCODING_SLINEAR_BE;
|
||||
prinfo->precision = 16;
|
||||
break;
|
||||
case AUDIO_U16LSB:
|
||||
prinfo->encoding = AUDIO_ENCODING_ULINEAR_LE;
|
||||
prinfo->precision = 16;
|
||||
break;
|
||||
case AUDIO_U16MSB:
|
||||
prinfo->encoding = AUDIO_ENCODING_ULINEAR_BE;
|
||||
prinfo->precision = 16;
|
||||
break;
|
||||
case AUDIO_S32LSB:
|
||||
prinfo->encoding = AUDIO_ENCODING_SLINEAR_LE;
|
||||
prinfo->precision = 32;
|
||||
break;
|
||||
case AUDIO_S32MSB:
|
||||
prinfo->encoding = AUDIO_ENCODING_SLINEAR_BE;
|
||||
prinfo->precision = 32;
|
||||
break;
|
||||
}
|
||||
if (prinfo->encoding != AUDIO_ENCODING_NONE) {
|
||||
break;
|
||||
}
|
||||
format = SDL_NextAudioFormat();
|
||||
#ifdef AUDIO_GETFORMAT /* Introduced in NetBSD 9.0 */
|
||||
if (ioctl(this->hidden->audio_fd, AUDIO_GETFORMAT, &hwinfo) != -1) {
|
||||
/*
|
||||
* Use the device's native sample rate so the kernel doesn't have to
|
||||
* resample.
|
||||
*/
|
||||
this->spec.freq = iscapture ?
|
||||
hwinfo.record.sample_rate : hwinfo.play.sample_rate;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (prinfo->encoding == AUDIO_ENCODING_NONE) {
|
||||
return SDL_SetError("No supported encoding for 0x%x", this->spec.format);
|
||||
}
|
||||
|
||||
this->spec.format = format;
|
||||
|
||||
/* Calculate spec parameters based on our chosen format */
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
info.mode = iscapture ? AUMODE_RECORD : AUMODE_PLAY;
|
||||
info.blocksize = this->spec.size;
|
||||
info.hiwat = 5;
|
||||
info.lowat = 3;
|
||||
prinfo->sample_rate = this->spec.freq;
|
||||
prinfo->channels = this->spec.channels;
|
||||
(void) ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info);
|
||||
|
||||
(void) ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info);
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
switch (test_format) {
|
||||
case AUDIO_U8:
|
||||
encoding = AUDIO_ENCODING_ULINEAR;
|
||||
break;
|
||||
case AUDIO_S8:
|
||||
encoding = AUDIO_ENCODING_SLINEAR;
|
||||
break;
|
||||
case AUDIO_S16LSB:
|
||||
encoding = AUDIO_ENCODING_SLINEAR_LE;
|
||||
break;
|
||||
case AUDIO_S16MSB:
|
||||
encoding = AUDIO_ENCODING_SLINEAR_BE;
|
||||
break;
|
||||
case AUDIO_U16LSB:
|
||||
encoding = AUDIO_ENCODING_ULINEAR_LE;
|
||||
break;
|
||||
case AUDIO_U16MSB:
|
||||
encoding = AUDIO_ENCODING_ULINEAR_BE;
|
||||
break;
|
||||
case AUDIO_S32LSB:
|
||||
encoding = AUDIO_ENCODING_SLINEAR_LE;
|
||||
break;
|
||||
case AUDIO_S32MSB:
|
||||
encoding = AUDIO_ENCODING_SLINEAR_BE;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!test_format) {
|
||||
return SDL_SetError("%s: Unsupported audio format", "netbsd");
|
||||
}
|
||||
prinfo->encoding = encoding;
|
||||
prinfo->precision = SDL_AUDIO_BITSIZE(test_format);
|
||||
|
||||
info.hiwat = 5;
|
||||
info.lowat = 3;
|
||||
if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) < 0) {
|
||||
return SDL_SetError("AUDIO_SETINFO failed for %s: %s", devname, strerror(errno));
|
||||
}
|
||||
|
||||
if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) {
|
||||
return SDL_SetError("AUDIO_GETINFO failed for %s: %s", devname, strerror(errno));
|
||||
}
|
||||
|
||||
/* Final spec used for the device. */
|
||||
this->spec.format = test_format;
|
||||
this->spec.freq = prinfo->sample_rate;
|
||||
this->spec.channels = prinfo->channels;
|
||||
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
if (!iscapture) {
|
||||
/* Allocate mixing buffer */
|
||||
this->hidden->mixlen = this->spec.size;
|
||||
|
|
@ -313,7 +320,7 @@ NETBSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
NETBSDAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
|
|
@ -326,14 +333,14 @@ NETBSDAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->FlushCapture = NETBSDAUDIO_FlushCapture;
|
||||
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->AllowsArbitraryDeviceNames = 1;
|
||||
impl->AllowsArbitraryDeviceNames = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
||||
AudioBootStrap NETBSDAUDIO_bootstrap = {
|
||||
"netbsd", "NetBSD audio", NETBSDAUDIO_Init, 0
|
||||
"netbsd", "NetBSD audio", NETBSDAUDIO_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_NETBSD */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -75,24 +75,24 @@
|
|||
#define SL_ANDROID_SPEAKER_7DOT1 (SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT)
|
||||
|
||||
/* engine interfaces */
|
||||
static SLObjectItf engineObject;
|
||||
static SLEngineItf engineEngine;
|
||||
static SLObjectItf engineObject = NULL;
|
||||
static SLEngineItf engineEngine = NULL;
|
||||
|
||||
/* output mix interfaces */
|
||||
static SLObjectItf outputMixObject;
|
||||
static SLObjectItf outputMixObject = NULL;
|
||||
|
||||
/* buffer queue player interfaces */
|
||||
static SLObjectItf bqPlayerObject;
|
||||
static SLPlayItf bqPlayerPlay;
|
||||
static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
|
||||
static SLObjectItf bqPlayerObject = NULL;
|
||||
static SLPlayItf bqPlayerPlay = NULL;
|
||||
static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue = NULL;
|
||||
#if 0
|
||||
static SLVolumeItf bqPlayerVolume;
|
||||
#endif
|
||||
|
||||
/* recorder interfaces */
|
||||
static SLObjectItf recorderObject;
|
||||
static SLRecordItf recorderRecord;
|
||||
static SLAndroidSimpleBufferQueueItf recorderBufferQueue;
|
||||
static SLObjectItf recorderObject = NULL;
|
||||
static SLRecordItf recorderRecord = NULL;
|
||||
static SLAndroidSimpleBufferQueueItf recorderBufferQueue = NULL;
|
||||
|
||||
#if 0
|
||||
static const char *sldevaudiorecorderstr = "SLES Audio Recorder";
|
||||
|
|
@ -355,8 +355,6 @@ openslES_CreatePCMRecorder(_THIS)
|
|||
|
||||
failed:
|
||||
|
||||
openslES_DestroyPCMRecorder(this);
|
||||
|
||||
return SDL_SetError("Open device failed!");
|
||||
}
|
||||
|
||||
|
|
@ -409,6 +407,7 @@ openslES_CreatePCMPlayer(_THIS)
|
|||
{
|
||||
struct SDL_PrivateAudioData *audiodata = this->hidden;
|
||||
SLDataFormat_PCM format_pcm;
|
||||
SLAndroidDataFormat_PCM_EX format_pcm_ex;
|
||||
SLresult result;
|
||||
int i;
|
||||
|
||||
|
|
@ -416,31 +415,30 @@ openslES_CreatePCMPlayer(_THIS)
|
|||
it can be done as described here:
|
||||
https://developer.android.com/ndk/guides/audio/opensl/android-extensions.html#floating-point
|
||||
*/
|
||||
#if 1
|
||||
/* Just go with signed 16-bit audio as it's the most compatible */
|
||||
this->spec.format = AUDIO_S16SYS;
|
||||
#else
|
||||
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
while (test_format != 0) {
|
||||
if (SDL_AUDIO_ISSIGNED(test_format) && SDL_AUDIO_ISINT(test_format)) {
|
||||
break;
|
||||
if(SDL_GetAndroidSDKVersion() >= 21) {
|
||||
SDL_AudioFormat test_format;
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
if (SDL_AUDIO_ISSIGNED(test_format)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
test_format = SDL_NextAudioFormat();
|
||||
}
|
||||
|
||||
if (test_format == 0) {
|
||||
/* Didn't find a compatible format : */
|
||||
LOGI( "No compatible audio format, using signed 16-bit audio" );
|
||||
test_format = AUDIO_S16SYS;
|
||||
if (!test_format) {
|
||||
/* Didn't find a compatible format : */
|
||||
LOGI( "No compatible audio format, using signed 16-bit audio" );
|
||||
test_format = AUDIO_S16SYS;
|
||||
}
|
||||
this->spec.format = test_format;
|
||||
} else {
|
||||
/* Just go with signed 16-bit audio as it's the most compatible */
|
||||
this->spec.format = AUDIO_S16SYS;
|
||||
}
|
||||
this->spec.format = test_format;
|
||||
#endif
|
||||
|
||||
/* Update the fragment size as size in bytes */
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
LOGI("Try to open %u hz %u bit chan %u %s samples %u",
|
||||
this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
|
||||
LOGI("Try to open %u hz %s %u bit chan %u %s samples %u",
|
||||
this->spec.freq, SDL_AUDIO_ISFLOAT(this->spec.format) ? "float" : "pcm", SDL_AUDIO_BITSIZE(this->spec.format),
|
||||
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
|
||||
|
||||
/* configure audio source */
|
||||
|
|
@ -491,7 +489,19 @@ openslES_CreatePCMPlayer(_THIS)
|
|||
break;
|
||||
}
|
||||
|
||||
SLDataSource audioSrc = { &loc_bufq, &format_pcm };
|
||||
if(SDL_AUDIO_ISFLOAT(this->spec.format)) {
|
||||
/* Copy all setup into PCM EX structure */
|
||||
format_pcm_ex.formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
|
||||
format_pcm_ex.endianness = format_pcm.endianness;
|
||||
format_pcm_ex.channelMask = format_pcm.channelMask;
|
||||
format_pcm_ex.numChannels = format_pcm.numChannels;
|
||||
format_pcm_ex.sampleRate = format_pcm.samplesPerSec;
|
||||
format_pcm_ex.bitsPerSample = format_pcm.bitsPerSample;
|
||||
format_pcm_ex.containerSize = format_pcm.containerSize;
|
||||
format_pcm_ex.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT;
|
||||
}
|
||||
|
||||
SLDataSource audioSrc = { &loc_bufq, SDL_AUDIO_ISFLOAT(this->spec.format) ? (void*)&format_pcm_ex : (void*)&format_pcm };
|
||||
|
||||
/* configure audio sink */
|
||||
SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, outputMixObject };
|
||||
|
|
@ -581,25 +591,39 @@ openslES_CreatePCMPlayer(_THIS)
|
|||
|
||||
failed:
|
||||
|
||||
openslES_DestroyPCMPlayer(this);
|
||||
|
||||
return SDL_SetError("Open device failed!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
openslES_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
openslES_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
if (iscapture) {
|
||||
if (this->iscapture) {
|
||||
LOGI("openslES_OpenDevice() %s for capture", devname);
|
||||
return openslES_CreatePCMRecorder(this);
|
||||
} else {
|
||||
int ret;
|
||||
LOGI("openslES_OpenDevice() %s for playing", devname);
|
||||
return openslES_CreatePCMPlayer(this);
|
||||
ret = openslES_CreatePCMPlayer(this);
|
||||
if (ret < 0) {
|
||||
/* Another attempt to open the device with a lower frequency */
|
||||
if (this->spec.freq > 48000) {
|
||||
openslES_DestroyPCMPlayer(this);
|
||||
this->spec.freq = 48000;
|
||||
ret = openslES_CreatePCMPlayer(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return SDL_SetError("Open device failed!");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -702,13 +726,13 @@ openslES_CloseDevice(_THIS)
|
|||
SDL_free(this->hidden);
|
||||
}
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
openslES_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
LOGI("openslES_Init() called");
|
||||
|
||||
if (!openslES_CreateEngine()) {
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
LOGI("openslES_Init() - set pointers");
|
||||
|
|
@ -724,18 +748,18 @@ openslES_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->Deinitialize = openslES_DestroyEngine;
|
||||
|
||||
/* and the capabilities */
|
||||
impl->HasCaptureSupport = 1;
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
impl->OnlyHasDefaultCaptureDevice = 1;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
|
||||
|
||||
LOGI("openslES_Init() - success");
|
||||
|
||||
/* this audio target is available. */
|
||||
return 1;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
AudioBootStrap openslES_bootstrap = {
|
||||
"openslES", "opensl ES audio driver", openslES_Init, 0
|
||||
"openslES", "opensl ES audio driver", openslES_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
void openslES_ResumeDevices(void)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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,36 +42,36 @@ void lockDecr(volatile int *piVal);
|
|||
parm [eax];
|
||||
*/
|
||||
|
||||
static ULONG _getEnvULong(PSZ pszName, ULONG ulMax, ULONG ulDefault)
|
||||
static ULONG _getEnvULong(const char *name, ULONG ulMax, ULONG ulDefault)
|
||||
{
|
||||
ULONG ulValue;
|
||||
PCHAR pcEnd;
|
||||
PSZ pszEnvVal = SDL_getenv(pszName);
|
||||
char* end;
|
||||
char* envval = SDL_getenv(name);
|
||||
|
||||
if (pszEnvVal == NULL)
|
||||
if (envval == NULL)
|
||||
return ulDefault;
|
||||
|
||||
ulValue = SDL_strtoul((const char *)pszEnvVal, &pcEnd, 10);
|
||||
return (pcEnd == pszEnvVal) || (ulValue > ulMax)? ulDefault : ulMax;
|
||||
ulValue = SDL_strtoul(envval, &end, 10);
|
||||
return (end == envval) || (ulValue > ulMax)? ulDefault : ulMax;
|
||||
}
|
||||
|
||||
static int _MCIError(PSZ pszFunc, ULONG ulResult)
|
||||
static int _MCIError(const char *func, ULONG ulResult)
|
||||
{
|
||||
CHAR acBuf[128];
|
||||
mciGetErrorString(ulResult, acBuf, sizeof(acBuf));
|
||||
return SDL_SetError("[%s] %s", pszFunc, acBuf);
|
||||
return SDL_SetError("[%s] %s", func, acBuf);
|
||||
}
|
||||
|
||||
static void _mixIOError(PSZ pszFunction, ULONG ulRC)
|
||||
static void _mixIOError(const char *function, ULONG ulRC)
|
||||
{
|
||||
debug_os2("%s() - failed, rc = 0x%X (%s)",
|
||||
pszFunction, ulRC,
|
||||
function, ulRC,
|
||||
(ulRC == MCIERR_INVALID_MODE) ? "Mixer mode does not match request" :
|
||||
(ulRC == MCIERR_INVALID_BUFFER) ? "Caller sent an invalid buffer" : "unknown");
|
||||
}
|
||||
|
||||
LONG APIENTRY cbAudioWriteEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
|
||||
ULONG ulFlags)
|
||||
static LONG APIENTRY cbAudioWriteEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
|
||||
ULONG ulFlags)
|
||||
{
|
||||
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)pBuffer->ulUserParm;
|
||||
ULONG ulRC;
|
||||
|
|
@ -87,11 +87,11 @@ LONG APIENTRY cbAudioWriteEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
|
|||
debug_os2("DosPostEventSem(), rc = %u", ulRC);
|
||||
}
|
||||
|
||||
return 1; /* It seems, return value is not matter. */
|
||||
return 1; /* return value doesn't seem to matter. */
|
||||
}
|
||||
|
||||
LONG APIENTRY cbAudioReadEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
|
||||
ULONG ulFlags)
|
||||
static LONG APIENTRY cbAudioReadEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
|
||||
ULONG ulFlags)
|
||||
{
|
||||
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)pBuffer->ulUserParm;
|
||||
ULONG ulRC;
|
||||
|
|
@ -133,7 +133,7 @@ static void OS2_DetectDevices(void)
|
|||
return;
|
||||
}
|
||||
|
||||
ulDevicesNum = atol(stMCISysInfo.pszReturn);
|
||||
ulDevicesNum = SDL_strtoul(stMCISysInfo.pszReturn, NULL, 10);
|
||||
|
||||
for (stSysInfoParams.ulNumber = 0; stSysInfoParams.ulNumber < ulDevicesNum;
|
||||
stSysInfoParams.ulNumber++) {
|
||||
|
|
@ -151,7 +151,7 @@ static void OS2_DetectDevices(void)
|
|||
/* Get textual product description. */
|
||||
stSysInfoParams.ulItem = MCI_SYSINFO_QUERY_DRIVER;
|
||||
stSysInfoParams.pSysInfoParm = &stLogDevice;
|
||||
strcpy(stLogDevice.szInstallName, stSysInfoParams.pszReturn);
|
||||
SDL_strlcpy(stLogDevice.szInstallName, stSysInfoParams.pszReturn, MAX_DEVICE_NAME);
|
||||
ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_ITEM,
|
||||
&stSysInfoParams, 0);
|
||||
if (ulRC != NO_ERROR) {
|
||||
|
|
@ -160,9 +160,9 @@ static void OS2_DetectDevices(void)
|
|||
}
|
||||
|
||||
ulHandle++;
|
||||
SDL_AddAudioDevice(0, stLogDevice.szProductInfo, (void *)(ulHandle));
|
||||
SDL_AddAudioDevice(0, stLogDevice.szProductInfo, NULL, (void *)(ulHandle));
|
||||
ulHandle++;
|
||||
SDL_AddAudioDevice(1, stLogDevice.szProductInfo, (void *)(ulHandle));
|
||||
SDL_AddAudioDevice(1, stLogDevice.szProductInfo, NULL, (void *)(ulHandle));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -211,10 +211,8 @@ static void OS2_CloseDevice(_THIS)
|
|||
return;
|
||||
|
||||
/* Close up audio */
|
||||
if (pAData->usDeviceId != (USHORT)~0) {
|
||||
/* Device is open. */
|
||||
if (pAData->stMCIMixSetup.ulBitsPerSample != 0) {
|
||||
/* Mixer was initialized. */
|
||||
if (pAData->usDeviceId != (USHORT)~0) { /* Device is open. */
|
||||
if (pAData->stMCIMixSetup.ulBitsPerSample != 0) { /* Mixer was initialized. */
|
||||
ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP,
|
||||
MCI_WAIT | MCI_MIXSETUP_DEINIT,
|
||||
&pAData->stMCIMixSetup, 0);
|
||||
|
|
@ -223,8 +221,7 @@ static void OS2_CloseDevice(_THIS)
|
|||
}
|
||||
}
|
||||
|
||||
if (pAData->cMixBuffers != 0) {
|
||||
/* Buffers was allocated. */
|
||||
if (pAData->cMixBuffers != 0) { /* Buffers was allocated. */
|
||||
MCI_BUFFER_PARMS stMCIBuffer;
|
||||
|
||||
stMCIBuffer.ulBufferSize = pAData->aMixBuffers[0].ulBufferLength;
|
||||
|
|
@ -251,29 +248,28 @@ static void OS2_CloseDevice(_THIS)
|
|||
SDL_free(pAData);
|
||||
}
|
||||
|
||||
static int OS2_OpenDevice(_THIS, void *handle, const char *devname,
|
||||
int iscapture)
|
||||
static int OS2_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
SDL_PrivateAudioData *pAData;
|
||||
SDL_AudioFormat SDLAudioFmt;
|
||||
SDL_AudioFormat test_format;
|
||||
MCI_AMP_OPEN_PARMS stMCIAmpOpen;
|
||||
MCI_BUFFER_PARMS stMCIBuffer;
|
||||
ULONG ulRC;
|
||||
ULONG ulIdx;
|
||||
BOOL new_freq;
|
||||
SDL_bool iscapture = _this->iscapture;
|
||||
|
||||
new_freq = FALSE;
|
||||
SDL_zero(stMCIAmpOpen);
|
||||
SDL_zero(stMCIBuffer);
|
||||
|
||||
for (SDLAudioFmt = SDL_FirstAudioFormat(_this->spec.format);
|
||||
SDLAudioFmt != 0; SDLAudioFmt = SDL_NextAudioFormat()) {
|
||||
if (SDLAudioFmt == AUDIO_U8 || SDLAudioFmt == AUDIO_S16)
|
||||
for (test_format = SDL_FirstAudioFormat(_this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
if (test_format == AUDIO_U8 || test_format == AUDIO_S16)
|
||||
break;
|
||||
}
|
||||
if (SDLAudioFmt == 0) {
|
||||
if (!test_format) {
|
||||
debug_os2("Unsupported audio format, AUDIO_S16 used");
|
||||
SDLAudioFmt = AUDIO_S16;
|
||||
test_format = AUDIO_S16;
|
||||
}
|
||||
|
||||
pAData = (SDL_PrivateAudioData *) SDL_calloc(1, sizeof(struct SDL_PrivateAudioData));
|
||||
|
|
@ -288,7 +284,7 @@ static int OS2_OpenDevice(_THIS, void *handle, const char *devname,
|
|||
}
|
||||
|
||||
/* Open audio device */
|
||||
stMCIAmpOpen.usDeviceID = (handle != NULL) ? ((ULONG)handle - 1) : 0;
|
||||
stMCIAmpOpen.usDeviceID = (_this->handle != NULL) ? ((ULONG)_this->handle - 1) : 0;
|
||||
stMCIAmpOpen.pszDeviceType = (PSZ)MCI_DEVTYPE_AUDIO_AMPMIX;
|
||||
ulRC = mciSendCommand(0, MCI_OPEN,
|
||||
(_getEnvULong("SDL_AUDIO_SHARE", 1, 0) != 0)?
|
||||
|
|
@ -301,7 +297,7 @@ static int OS2_OpenDevice(_THIS, void *handle, const char *devname,
|
|||
}
|
||||
pAData->usDeviceId = stMCIAmpOpen.usDeviceID;
|
||||
|
||||
if (iscapture != 0) {
|
||||
if (iscapture) {
|
||||
MCI_CONNECTOR_PARMS stMCIConnector;
|
||||
MCI_AMP_SET_PARMS stMCIAmpSet;
|
||||
BOOL fLineIn = _getEnvULong("SDL_AUDIO_LINEIN", 1, 0);
|
||||
|
|
@ -333,7 +329,7 @@ static int OS2_OpenDevice(_THIS, void *handle, const char *devname,
|
|||
&stMCIAmpSet, 0);
|
||||
}
|
||||
|
||||
_this->spec.format = SDLAudioFmt;
|
||||
_this->spec.format = test_format;
|
||||
_this->spec.channels = _this->spec.channels > 1 ? 2 : 1;
|
||||
if (_this->spec.freq < 8000) {
|
||||
_this->spec.freq = 8000;
|
||||
|
|
@ -345,11 +341,11 @@ static int OS2_OpenDevice(_THIS, void *handle, const char *devname,
|
|||
|
||||
/* Setup mixer. */
|
||||
pAData->stMCIMixSetup.ulFormatTag = MCI_WAVE_FORMAT_PCM;
|
||||
pAData->stMCIMixSetup.ulBitsPerSample = SDL_AUDIO_BITSIZE(SDLAudioFmt);
|
||||
pAData->stMCIMixSetup.ulBitsPerSample = SDL_AUDIO_BITSIZE(test_format);
|
||||
pAData->stMCIMixSetup.ulSamplesPerSec = _this->spec.freq;
|
||||
pAData->stMCIMixSetup.ulChannels = _this->spec.channels;
|
||||
pAData->stMCIMixSetup.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
|
||||
if (iscapture == 0) {
|
||||
if (!iscapture) {
|
||||
pAData->stMCIMixSetup.ulFormatMode= MCI_PLAY;
|
||||
pAData->stMCIMixSetup.pmixEvent = cbAudioWriteEvent;
|
||||
} else {
|
||||
|
|
@ -410,15 +406,13 @@ static int OS2_OpenDevice(_THIS, void *handle, const char *devname,
|
|||
pAData->aMixBuffers[ulIdx].ulBufferLength = stMCIBuffer.ulBufferSize;
|
||||
pAData->aMixBuffers[ulIdx].ulUserParm = (ULONG)pAData;
|
||||
|
||||
memset(((PMCI_MIX_BUFFER)stMCIBuffer.pBufList)[ulIdx].pBuffer,
|
||||
_this->spec.silence, stMCIBuffer.ulBufferSize);
|
||||
SDL_memset(((PMCI_MIX_BUFFER)stMCIBuffer.pBufList)[ulIdx].pBuffer,
|
||||
_this->spec.silence, stMCIBuffer.ulBufferSize);
|
||||
}
|
||||
|
||||
/* Write buffers to kick off the amp mixer */
|
||||
/*pAData->ulQueuedBuf = 1;//stMCIBuffer.ulNumBuffers */
|
||||
ulRC = pAData->stMCIMixSetup.pmixWrite(pAData->stMCIMixSetup.ulMixHandle,
|
||||
pAData->aMixBuffers,
|
||||
1 /*stMCIBuffer.ulNumBuffers*/);
|
||||
pAData->aMixBuffers, 1);
|
||||
if (ulRC != MCIERR_SUCCESS) {
|
||||
_mixIOError("pmixWrite", ulRC);
|
||||
return -1;
|
||||
|
|
@ -428,7 +422,7 @@ static int OS2_OpenDevice(_THIS, void *handle, const char *devname,
|
|||
}
|
||||
|
||||
|
||||
static int OS2_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool OS2_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
impl->DetectDevices = OS2_DetectDevices;
|
||||
|
|
@ -443,11 +437,13 @@ static int OS2_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->FlushCapture = ;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
*/
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
||||
AudioBootStrap OS2AUDIO_bootstrap = { "MMOS2", "OS/2 DART", OS2_Init, 0 };
|
||||
AudioBootStrap OS2AUDIO_bootstrap = {
|
||||
"DART", "OS/2 DART", OS2_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_OS2 */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -156,7 +156,7 @@ PAUDIO_WaitDevice(_THIS)
|
|||
#ifdef DEBUG_AUDIO
|
||||
fprintf(stderr, "Waiting for audio to get ready\n");
|
||||
#endif
|
||||
if (SDL_IOReady(this->hidden->audio_fd, SDL_TRUE, timeoutMS) <= 0) {
|
||||
if (SDL_IOReady(this->hidden->audio_fd, SDL_IOR_WRITE, timeoutMS) <= 0) {
|
||||
/*
|
||||
* In general we should never print to the screen,
|
||||
* but in this case we have no other way of letting
|
||||
|
|
@ -223,12 +223,12 @@ PAUDIO_CloseDevice(_THIS)
|
|||
}
|
||||
|
||||
static int
|
||||
PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
PAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
const char *workaround = SDL_getenv("SDL_DSP_NOSELECT");
|
||||
char audiodev[1024];
|
||||
const char *err = NULL;
|
||||
int format;
|
||||
int flags;
|
||||
int bytes_per_sample;
|
||||
SDL_AudioFormat test_format;
|
||||
audio_init paud_init;
|
||||
|
|
@ -316,63 +316,44 @@ PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
paud_init.channels = this->spec.channels;
|
||||
|
||||
/* Try for a closest match on audio format */
|
||||
format = 0;
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
!format && test_format;) {
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
#ifdef DEBUG_AUDIO
|
||||
fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
|
||||
#endif
|
||||
switch (test_format) {
|
||||
case AUDIO_U8:
|
||||
bytes_per_sample = 1;
|
||||
paud_init.bits_per_sample = 8;
|
||||
paud_init.flags = TWOS_COMPLEMENT | FIXED;
|
||||
format = 1;
|
||||
flags = TWOS_COMPLEMENT | FIXED;
|
||||
break;
|
||||
case AUDIO_S8:
|
||||
bytes_per_sample = 1;
|
||||
paud_init.bits_per_sample = 8;
|
||||
paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED;
|
||||
format = 1;
|
||||
flags = SIGNED | TWOS_COMPLEMENT | FIXED;
|
||||
break;
|
||||
case AUDIO_S16LSB:
|
||||
bytes_per_sample = 2;
|
||||
paud_init.bits_per_sample = 16;
|
||||
paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED;
|
||||
format = 1;
|
||||
flags = SIGNED | TWOS_COMPLEMENT | FIXED;
|
||||
break;
|
||||
case AUDIO_S16MSB:
|
||||
bytes_per_sample = 2;
|
||||
paud_init.bits_per_sample = 16;
|
||||
paud_init.flags = BIG_ENDIAN | SIGNED | TWOS_COMPLEMENT | FIXED;
|
||||
format = 1;
|
||||
flags = BIG_ENDIAN | SIGNED | TWOS_COMPLEMENT | FIXED;
|
||||
break;
|
||||
case AUDIO_U16LSB:
|
||||
bytes_per_sample = 2;
|
||||
paud_init.bits_per_sample = 16;
|
||||
paud_init.flags = TWOS_COMPLEMENT | FIXED;
|
||||
format = 1;
|
||||
flags = TWOS_COMPLEMENT | FIXED;
|
||||
break;
|
||||
case AUDIO_U16MSB:
|
||||
bytes_per_sample = 2;
|
||||
paud_init.bits_per_sample = 16;
|
||||
paud_init.flags = BIG_ENDIAN | TWOS_COMPLEMENT | FIXED;
|
||||
format = 1;
|
||||
flags = BIG_ENDIAN | TWOS_COMPLEMENT | FIXED;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!format) {
|
||||
test_format = SDL_NextAudioFormat();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (format == 0) {
|
||||
if (!test_format) {
|
||||
#ifdef DEBUG_AUDIO
|
||||
fprintf(stderr, "Couldn't find any hardware audio formats\n");
|
||||
#endif
|
||||
return SDL_SetError("Couldn't find any hardware audio formats");
|
||||
return SDL_SetError("%s: Unsupported audio format", "paud");
|
||||
}
|
||||
this->spec.format = test_format;
|
||||
paud_init.bits_per_sample = SDL_AUDIO_BITSIZE(test_format);
|
||||
bytes_per_sample = SDL_AUDIO_BITSIZE(test_format) / 8;
|
||||
paud_init.flags = flags;
|
||||
|
||||
/*
|
||||
* We know the buffer size and the max number of subsequent writes
|
||||
|
|
@ -406,28 +387,25 @@ PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
if (ioctl(fd, AUDIO_INIT, &paud_init) < 0) {
|
||||
switch (paud_init.rc) {
|
||||
case 1:
|
||||
err = "Couldn't set audio format: DSP can't do play requests";
|
||||
err = "DSP can't do play requests";
|
||||
break;
|
||||
case 2:
|
||||
err = "Couldn't set audio format: DSP can't do record requests";
|
||||
err = "DSP can't do record requests";
|
||||
break;
|
||||
case 4:
|
||||
err = "Couldn't set audio format: request was invalid";
|
||||
err = "request was invalid";
|
||||
break;
|
||||
case 5:
|
||||
err = "Couldn't set audio format: conflict with open's flags";
|
||||
err = "conflict with open's flags";
|
||||
break;
|
||||
case 6:
|
||||
err = "Couldn't set audio format: out of DSP MIPS or memory";
|
||||
err = "out of DSP MIPS or memory";
|
||||
break;
|
||||
default:
|
||||
err = "Couldn't set audio format: not documented in sys/audio.h";
|
||||
err = "not documented in sys/audio.h";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (err != NULL) {
|
||||
return SDL_SetError("Paudio: %s", err);
|
||||
return SDL_SetError("paud: Couldn't set audio format (%s)", err);
|
||||
}
|
||||
|
||||
/* Allocate mixing buffer */
|
||||
|
|
@ -485,14 +463,14 @@ PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
PAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
/* !!! FIXME: not right for device enum? */
|
||||
int fd = OpenAudioPath(NULL, 0, OPEN_FLAGS, 0);
|
||||
if (fd < 0) {
|
||||
SDL_SetError("PAUDIO: Couldn't open audio device");
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
|
|
@ -502,13 +480,13 @@ PAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->PlayDevice = PAUDIO_WaitDevice;
|
||||
impl->GetDeviceBuf = PAUDIO_GetDeviceBuf;
|
||||
impl->CloseDevice = PAUDIO_CloseDevice;
|
||||
impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: add device enum! */
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE; /* !!! FIXME: add device enum! */
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap PAUDIO_bootstrap = {
|
||||
"paud", "AIX Paudio", PAUDIO_Init, 0
|
||||
"paud", "AIX Paudio", PAUDIO_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_PAUDIO */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
|
|||
1276
Engine/lib/sdl/src/audio/pipewire/SDL_pipewire.c
Normal file
1276
Engine/lib/sdl/src/audio/pipewire/SDL_pipewire.c
Normal file
File diff suppressed because it is too large
Load diff
47
Engine/lib/sdl/src/audio/pipewire/SDL_pipewire.h
Normal file
47
Engine/lib/sdl/src/audio/pipewire/SDL_pipewire.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifndef SDL_pipewire_h_
|
||||
#define SDL_pipewire_h_
|
||||
|
||||
#include "../SDL_sysaudio.h"
|
||||
#include <pipewire/pipewire.h>
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
struct pw_thread_loop *loop;
|
||||
struct pw_stream *stream;
|
||||
struct pw_context *context;
|
||||
struct SDL_DataQueue *buffer;
|
||||
|
||||
size_t input_buffer_packet_size;
|
||||
Sint32 stride; /* Bytes-per-frame */
|
||||
int stream_init_status;
|
||||
};
|
||||
|
||||
#endif /* SDL_pipewire_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <malloc.h> /* memalign() */
|
||||
|
||||
#include "SDL_audio.h"
|
||||
#include "SDL_error.h"
|
||||
|
|
@ -39,30 +39,48 @@
|
|||
#include <pspthreadman.h>
|
||||
|
||||
/* The tag name used by PSP audio */
|
||||
#define PSPAUDIO_DRIVER_NAME "psp"
|
||||
#define PSPAUDIO_DRIVER_NAME "psp"
|
||||
|
||||
static int
|
||||
PSPAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
PSPAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
int format, mixlen, i;
|
||||
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
switch (this->spec.format & 0xff) {
|
||||
case 8:
|
||||
case 16:
|
||||
this->spec.format = AUDIO_S16LSB;
|
||||
break;
|
||||
default:
|
||||
return SDL_SetError("Unsupported audio format");
|
||||
}
|
||||
|
||||
/* device only natively supports S16LSB */
|
||||
this->spec.format = AUDIO_S16LSB;
|
||||
|
||||
/* The sample count must be a multiple of 64. */
|
||||
this->spec.samples = PSP_AUDIO_SAMPLE_ALIGN(this->spec.samples);
|
||||
this->spec.freq = 44100;
|
||||
|
||||
/* Setup the hardware channel. */
|
||||
if (this->spec.channels == 1) {
|
||||
format = PSP_AUDIO_FORMAT_MONO;
|
||||
} else {
|
||||
format = PSP_AUDIO_FORMAT_STEREO;
|
||||
this->spec.channels = 2; /* we're forcing the hardware to stereo. */
|
||||
}
|
||||
|
||||
/* PSP has some limitations with the Audio. It fully supports 44.1KHz (Mono & Stereo),
|
||||
however with frequencies differents than 44.1KHz, it just supports Stereo,
|
||||
so a resampler must be done for these scenarios */
|
||||
if (this->spec.freq == 44100) {
|
||||
this->hidden->channel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, this->spec.samples, format);
|
||||
} else {
|
||||
this->hidden->channel = sceAudioSRCChReserve(this->spec.samples, this->spec.freq, 2);
|
||||
}
|
||||
|
||||
if (this->hidden->channel < 0) {
|
||||
free(this->hidden->rawbuf);
|
||||
this->hidden->rawbuf = NULL;
|
||||
return SDL_SetError("Couldn't reserve hardware channel");
|
||||
}
|
||||
|
||||
/* Update the fragment size as size in bytes. */
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
|
@ -76,21 +94,7 @@ PSPAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
return SDL_SetError("Couldn't allocate mixing buffer");
|
||||
}
|
||||
|
||||
/* Setup the hardware channel. */
|
||||
if (this->spec.channels == 1) {
|
||||
format = PSP_AUDIO_FORMAT_MONO;
|
||||
} else {
|
||||
this->spec.channels = 2;
|
||||
format = PSP_AUDIO_FORMAT_STEREO;
|
||||
}
|
||||
this->hidden->channel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, this->spec.samples, format);
|
||||
if (this->hidden->channel < 0) {
|
||||
free(this->hidden->rawbuf);
|
||||
this->hidden->rawbuf = NULL;
|
||||
return SDL_SetError("Couldn't reserve hardware channel");
|
||||
}
|
||||
|
||||
memset(this->hidden->rawbuf, 0, mixlen);
|
||||
SDL_memset(this->hidden->rawbuf, 0, mixlen);
|
||||
for (i = 0; i < NUM_BUFFERS; i++) {
|
||||
this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size];
|
||||
}
|
||||
|
|
@ -101,11 +105,12 @@ PSPAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
|
||||
static void PSPAUDIO_PlayDevice(_THIS)
|
||||
{
|
||||
Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
|
||||
|
||||
if (this->spec.channels == 1) {
|
||||
sceAudioOutputBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, mixbuf);
|
||||
if (this->spec.freq != 44100){
|
||||
Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
|
||||
SDL_assert(this->spec.channels == 2);
|
||||
sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, mixbuf);
|
||||
} else {
|
||||
Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
|
||||
sceAudioOutputPannedBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, mixbuf);
|
||||
}
|
||||
|
||||
|
|
@ -117,6 +122,7 @@ static void PSPAUDIO_WaitDevice(_THIS)
|
|||
{
|
||||
/* Because we block when sending audio, there's no need for this function to do anything. */
|
||||
}
|
||||
|
||||
static Uint8 *PSPAUDIO_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return this->hidden->mixbufs[this->hidden->next_buffer];
|
||||
|
|
@ -125,10 +131,18 @@ static Uint8 *PSPAUDIO_GetDeviceBuf(_THIS)
|
|||
static void PSPAUDIO_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->channel >= 0) {
|
||||
sceAudioChRelease(this->hidden->channel);
|
||||
if (this->spec.freq != 44100){
|
||||
sceAudioSRCChRelease();
|
||||
} else {
|
||||
sceAudioChRelease(this->hidden->channel);
|
||||
}
|
||||
this->hidden->channel = -1;
|
||||
}
|
||||
|
||||
if (this->hidden->rawbuf != NULL) {
|
||||
free(this->hidden->rawbuf);
|
||||
this->hidden->rawbuf = NULL;
|
||||
}
|
||||
free(this->hidden->rawbuf); /* this uses memalign(), not SDL_malloc(). */
|
||||
SDL_free(this->hidden);
|
||||
}
|
||||
|
||||
static void PSPAUDIO_ThreadInit(_THIS)
|
||||
|
|
@ -144,8 +158,7 @@ static void PSPAUDIO_ThreadInit(_THIS)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
PSPAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
|
|
@ -157,25 +170,18 @@ PSPAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->ThreadInit = PSPAUDIO_ThreadInit;
|
||||
|
||||
/* PSP audio device */
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
/*
|
||||
impl->HasCaptureSupport = 1;
|
||||
|
||||
impl->OnlyHasDefaultCaptureDevice = 1;
|
||||
*/
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
/*
|
||||
impl->DetectDevices = DSOUND_DetectDevices;
|
||||
impl->Deinitialize = DSOUND_Deinitialize;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
|
||||
*/
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap PSPAUDIO_bootstrap = {
|
||||
"psp", "PSP audio driver", PSPAUDIO_Init, 0
|
||||
"psp", "PSP audio driver", PSPAUDIO_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
/* SDL_AUDI */
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_PSP */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -46,6 +46,10 @@
|
|||
#include "SDL_loadso.h"
|
||||
#include "../../thread/SDL_systhread.h"
|
||||
|
||||
/* 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) {
|
||||
|
|
@ -76,7 +80,7 @@ static void (*PULSEAUDIO_pa_mainloop_quit) (pa_mainloop *, int);
|
|||
static void (*PULSEAUDIO_pa_mainloop_free) (pa_mainloop *);
|
||||
|
||||
static pa_operation_state_t (*PULSEAUDIO_pa_operation_get_state) (
|
||||
pa_operation *);
|
||||
const pa_operation *);
|
||||
static void (*PULSEAUDIO_pa_operation_cancel) (pa_operation *);
|
||||
static void (*PULSEAUDIO_pa_operation_unref) (pa_operation *);
|
||||
|
||||
|
|
@ -88,7 +92,7 @@ static pa_operation * (*PULSEAUDIO_pa_context_get_sink_info_list) (pa_context *,
|
|||
static pa_operation * (*PULSEAUDIO_pa_context_get_source_info_list) (pa_context *, pa_source_info_cb_t, void *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_get_sink_info_by_index) (pa_context *, uint32_t, pa_sink_info_cb_t, void *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_get_source_info_by_index) (pa_context *, uint32_t, pa_source_info_cb_t, void *);
|
||||
static pa_context_state_t (*PULSEAUDIO_pa_context_get_state) (pa_context *);
|
||||
static pa_context_state_t (*PULSEAUDIO_pa_context_get_state) (const pa_context *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_subscribe) (pa_context *, pa_subscription_mask_t, pa_context_success_cb_t, void *);
|
||||
static void (*PULSEAUDIO_pa_context_set_subscribe_callback) (pa_context *, pa_context_subscribe_cb_t, void *);
|
||||
static void (*PULSEAUDIO_pa_context_disconnect) (pa_context *);
|
||||
|
|
@ -97,12 +101,14 @@ 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 int (*PULSEAUDIO_pa_stream_connect_playback) (pa_stream *, const char *,
|
||||
const pa_buffer_attr *, pa_stream_flags_t, pa_cvolume *, pa_stream *);
|
||||
const pa_buffer_attr *, pa_stream_flags_t, const pa_cvolume *, pa_stream *);
|
||||
static int (*PULSEAUDIO_pa_stream_connect_record) (pa_stream *, const char *,
|
||||
const pa_buffer_attr *, pa_stream_flags_t);
|
||||
static pa_stream_state_t (*PULSEAUDIO_pa_stream_get_state) (pa_stream *);
|
||||
static size_t (*PULSEAUDIO_pa_stream_writable_size) (pa_stream *);
|
||||
static size_t (*PULSEAUDIO_pa_stream_readable_size) (pa_stream *);
|
||||
static pa_stream_state_t (*PULSEAUDIO_pa_stream_get_state) (const pa_stream *);
|
||||
static size_t (*PULSEAUDIO_pa_stream_writable_size) (const pa_stream *);
|
||||
static size_t (*PULSEAUDIO_pa_stream_readable_size) (const pa_stream *);
|
||||
static int (*PULSEAUDIO_pa_stream_begin_write) (pa_stream *, void **, size_t*);
|
||||
static int (*PULSEAUDIO_pa_stream_cancel_write) (pa_stream *);
|
||||
static int (*PULSEAUDIO_pa_stream_write) (pa_stream *, const void *, size_t,
|
||||
pa_free_cb_t, int64_t, pa_seek_mode_t);
|
||||
static pa_operation * (*PULSEAUDIO_pa_stream_drain) (pa_stream *,
|
||||
|
|
@ -216,6 +222,8 @@ load_pulseaudio_syms(void)
|
|||
SDL_PULSEAUDIO_SYM(pa_stream_writable_size);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_readable_size);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_write);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_begin_write);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_cancel_write);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_drain);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_disconnect);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_peek);
|
||||
|
|
@ -238,7 +246,13 @@ static const char *
|
|||
getAppName(void)
|
||||
{
|
||||
const char *retval = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME);
|
||||
if (!retval || !*retval) {
|
||||
if (retval && *retval) {
|
||||
return retval;
|
||||
}
|
||||
retval = SDL_GetHint(SDL_HINT_APP_NAME);
|
||||
if (retval && *retval) {
|
||||
return retval;
|
||||
} else {
|
||||
const char *verstr = PULSEAUDIO_pa_get_library_version();
|
||||
retval = "SDL Application"; /* the "oh well" default. */
|
||||
if (verstr != NULL) {
|
||||
|
|
@ -354,7 +368,7 @@ PULSEAUDIO_WaitDevice(_THIS)
|
|||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
return;
|
||||
}
|
||||
if (PULSEAUDIO_pa_stream_writable_size(h->stream) >= h->mixlen) {
|
||||
if (PULSEAUDIO_pa_stream_writable_size(h->stream) >= (h->mixlen/8)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -366,7 +380,7 @@ PULSEAUDIO_PlayDevice(_THIS)
|
|||
/* Write the audio data */
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
if (SDL_AtomicGet(&this->enabled)) {
|
||||
if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) {
|
||||
if (PULSEAUDIO_pa_stream_write(h->stream, h->pabuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) {
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -375,7 +389,21 @@ PULSEAUDIO_PlayDevice(_THIS)
|
|||
static Uint8 *
|
||||
PULSEAUDIO_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return (this->hidden->mixbuf);
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
size_t nbytes = h->mixlen;
|
||||
int ret;
|
||||
|
||||
ret = PULSEAUDIO_pa_stream_begin_write(h->stream, &h->pabuf, &nbytes);
|
||||
|
||||
if (ret != 0) {
|
||||
/* fall back it intermediate buffer */
|
||||
h->pabuf = h->mixbuf;
|
||||
} else if (nbytes < h->mixlen) {
|
||||
PULSEAUDIO_pa_stream_cancel_write(h->stream);
|
||||
h->pabuf = h->mixbuf;
|
||||
}
|
||||
|
||||
return (Uint8 *)h->pabuf;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -494,7 +522,7 @@ SourceDeviceNameCallback(pa_context *c, const pa_source_info *i, int is_last, vo
|
|||
}
|
||||
|
||||
static SDL_bool
|
||||
FindDeviceName(struct SDL_PrivateAudioData *h, const int iscapture, void *handle)
|
||||
FindDeviceName(struct SDL_PrivateAudioData *h, const SDL_bool iscapture, void *handle)
|
||||
{
|
||||
const uint32_t idx = ((uint32_t) ((size_t) handle)) - 1;
|
||||
|
||||
|
|
@ -516,16 +544,17 @@ FindDeviceName(struct SDL_PrivateAudioData *h, const int iscapture, void *handle
|
|||
}
|
||||
|
||||
static int
|
||||
PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
PULSEAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = NULL;
|
||||
Uint16 test_format = 0;
|
||||
SDL_AudioFormat test_format;
|
||||
pa_sample_spec paspec;
|
||||
pa_buffer_attr paattr;
|
||||
pa_channel_map pacmap;
|
||||
pa_stream_flags_t flags = 0;
|
||||
const char *name = NULL;
|
||||
int state = 0;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
int state = 0, format = PA_SAMPLE_INVALID;
|
||||
int rc = 0;
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
|
|
@ -536,48 +565,43 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
||||
paspec.format = PA_SAMPLE_INVALID;
|
||||
|
||||
/* Try for a closest match on audio format */
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
(paspec.format == PA_SAMPLE_INVALID) && test_format;) {
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
#ifdef DEBUG_AUDIO
|
||||
fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
|
||||
#endif
|
||||
switch (test_format) {
|
||||
case AUDIO_U8:
|
||||
paspec.format = PA_SAMPLE_U8;
|
||||
format = PA_SAMPLE_U8;
|
||||
break;
|
||||
case AUDIO_S16LSB:
|
||||
paspec.format = PA_SAMPLE_S16LE;
|
||||
format = PA_SAMPLE_S16LE;
|
||||
break;
|
||||
case AUDIO_S16MSB:
|
||||
paspec.format = PA_SAMPLE_S16BE;
|
||||
format = PA_SAMPLE_S16BE;
|
||||
break;
|
||||
case AUDIO_S32LSB:
|
||||
paspec.format = PA_SAMPLE_S32LE;
|
||||
format = PA_SAMPLE_S32LE;
|
||||
break;
|
||||
case AUDIO_S32MSB:
|
||||
paspec.format = PA_SAMPLE_S32BE;
|
||||
format = PA_SAMPLE_S32BE;
|
||||
break;
|
||||
case AUDIO_F32LSB:
|
||||
paspec.format = PA_SAMPLE_FLOAT32LE;
|
||||
format = PA_SAMPLE_FLOAT32LE;
|
||||
break;
|
||||
case AUDIO_F32MSB:
|
||||
paspec.format = PA_SAMPLE_FLOAT32BE;
|
||||
format = PA_SAMPLE_FLOAT32BE;
|
||||
break;
|
||||
default:
|
||||
paspec.format = PA_SAMPLE_INVALID;
|
||||
break;
|
||||
}
|
||||
if (paspec.format == PA_SAMPLE_INVALID) {
|
||||
test_format = SDL_NextAudioFormat();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (paspec.format == PA_SAMPLE_INVALID) {
|
||||
return SDL_SetError("Couldn't find any hardware audio formats");
|
||||
if (!test_format) {
|
||||
return SDL_SetError("%s: Unsupported audio format", "pulseaudio");
|
||||
}
|
||||
this->spec.format = test_format;
|
||||
paspec.format = format;
|
||||
|
||||
/* Calculate the final parameters for this audio specification */
|
||||
#ifdef PA_STREAM_ADJUST_LATENCY
|
||||
|
|
@ -600,6 +624,7 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
|
||||
/* Reduced prebuffering compared to the defaults. */
|
||||
#ifdef PA_STREAM_ADJUST_LATENCY
|
||||
paattr.fragsize = this->spec.size;
|
||||
/* 2x original requested bufsize */
|
||||
paattr.tlength = h->mixlen * 4;
|
||||
paattr.prebuf = -1;
|
||||
|
|
@ -608,6 +633,7 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
paattr.minreq = h->mixlen;
|
||||
flags = PA_STREAM_ADJUST_LATENCY;
|
||||
#else
|
||||
paattr.fragsize = this->spec.size;
|
||||
paattr.tlength = h->mixlen*2;
|
||||
paattr.prebuf = h->mixlen*2;
|
||||
paattr.maxlength = h->mixlen*2;
|
||||
|
|
@ -618,7 +644,7 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
return SDL_SetError("Could not connect to PulseAudio server");
|
||||
}
|
||||
|
||||
if (!FindDeviceName(h, iscapture, handle)) {
|
||||
if (!FindDeviceName(h, iscapture, this->handle)) {
|
||||
return SDL_SetError("Requested PulseAudio sink/source missing?");
|
||||
}
|
||||
|
||||
|
|
@ -676,12 +702,45 @@ static SDL_Thread *hotplug_thread = NULL;
|
|||
|
||||
/* device handles are device index + 1, cast to void*, so we never pass a NULL. */
|
||||
|
||||
static SDL_AudioFormat
|
||||
PulseFormatToSDLFormat(pa_sample_format_t format)
|
||||
{
|
||||
switch (format) {
|
||||
case PA_SAMPLE_U8:
|
||||
return AUDIO_U8;
|
||||
case PA_SAMPLE_S16LE:
|
||||
return AUDIO_S16LSB;
|
||||
case PA_SAMPLE_S16BE:
|
||||
return AUDIO_S16MSB;
|
||||
case PA_SAMPLE_S32LE:
|
||||
return AUDIO_S32LSB;
|
||||
case PA_SAMPLE_S32BE:
|
||||
return AUDIO_S32MSB;
|
||||
case PA_SAMPLE_FLOAT32LE:
|
||||
return AUDIO_F32LSB;
|
||||
case PA_SAMPLE_FLOAT32BE:
|
||||
return AUDIO_F32MSB;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* This is called when PulseAudio adds an output ("sink") device. */
|
||||
static void
|
||||
SinkInfoCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
|
||||
{
|
||||
SDL_AudioSpec spec;
|
||||
if (i) {
|
||||
SDL_AddAudioDevice(SDL_FALSE, i->description, (void *) ((size_t) i->index+1));
|
||||
spec.freq = i->sample_spec.rate;
|
||||
spec.channels = i->sample_spec.channels;
|
||||
spec.format = PulseFormatToSDLFormat(i->sample_spec.format);
|
||||
spec.silence = 0;
|
||||
spec.samples = 0;
|
||||
spec.size = 0;
|
||||
spec.callback = NULL;
|
||||
spec.userdata = NULL;
|
||||
|
||||
SDL_AddAudioDevice(SDL_FALSE, i->description, &spec, (void *) ((size_t) i->index+1));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -689,10 +748,20 @@ SinkInfoCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
|
|||
static void
|
||||
SourceInfoCallback(pa_context *c, const pa_source_info *i, int is_last, void *data)
|
||||
{
|
||||
SDL_AudioSpec spec;
|
||||
if (i) {
|
||||
/* Skip "monitor" sources. These are just output from other sinks. */
|
||||
if (i->monitor_of_sink == PA_INVALID_INDEX) {
|
||||
SDL_AddAudioDevice(SDL_TRUE, i->description, (void *) ((size_t) i->index+1));
|
||||
/* Maybe skip "monitor" sources. These are just output from other sinks. */
|
||||
if (include_monitors || (i->monitor_of_sink == PA_INVALID_INDEX)) {
|
||||
spec.freq = i->sample_spec.rate;
|
||||
spec.channels = i->sample_spec.channels;
|
||||
spec.format = PulseFormatToSDLFormat(i->sample_spec.format);
|
||||
spec.silence = 0;
|
||||
spec.samples = 0;
|
||||
spec.size = 0;
|
||||
spec.callback = NULL;
|
||||
spec.userdata = NULL;
|
||||
|
||||
SDL_AddAudioDevice(SDL_TRUE, i->description, &spec, (void *) ((size_t) i->index+1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -759,18 +828,20 @@ PULSEAUDIO_Deinitialize(void)
|
|||
UnloadPulseAudioLibrary();
|
||||
}
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
PULSEAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
if (LoadPulseAudioLibrary() < 0) {
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (ConnectToPulseServer(&hotplug_mainloop, &hotplug_context) < 0) {
|
||||
UnloadPulseAudioLibrary();
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
include_monitors = SDL_GetHintBoolean(SDL_HINT_AUDIO_INCLUDE_MONITORS, SDL_FALSE);
|
||||
|
||||
/* Set the function pointers */
|
||||
impl->DetectDevices = PULSEAUDIO_DetectDevices;
|
||||
impl->OpenDevice = PULSEAUDIO_OpenDevice;
|
||||
|
|
@ -784,11 +855,11 @@ PULSEAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap PULSEAUDIO_bootstrap = {
|
||||
"pulseaudio", "PulseAudio", PULSEAUDIO_Init, 0
|
||||
"pulseaudio", "PulseAudio", PULSEAUDIO_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_PULSEAUDIO */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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,6 +43,12 @@ struct SDL_PrivateAudioData
|
|||
Uint8 *mixbuf;
|
||||
int mixlen;
|
||||
|
||||
/* Pointer to the actual buffer in use in the current
|
||||
GetDeviceBuf() -> PlayDevice() iteration.
|
||||
Can be either the pointer returned by pa_stream_begin_write()
|
||||
or mixbuf */
|
||||
void *pabuf;
|
||||
|
||||
const Uint8 *capturebuf;
|
||||
int capturelen;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -120,7 +120,9 @@ QSA_WaitDevice(_THIS)
|
|||
/* If timeout occured than something wrong with hardware or driver */
|
||||
/* For example, Vortex 8820 audio driver stucks on second DAC because */
|
||||
/* it doesn't exist ! */
|
||||
result = SDL_IOReady(this->hidden->audio_fd, !this->hidden->iscapture, 2 * 1000);
|
||||
result = SDL_IOReady(this->hidden->audio_fd,
|
||||
this->iscapture ? SDL_IOR_READ : SDL_IOR_WRITE,
|
||||
2 * 1000);
|
||||
switch (result) {
|
||||
case -1:
|
||||
SDL_SetError("QSA: SDL_IOReady() failed: %s", strerror(errno));
|
||||
|
|
@ -178,7 +180,7 @@ QSA_PlayDevice(_THIS)
|
|||
} else {
|
||||
if ((errno == EINVAL) || (errno == EIO)) {
|
||||
SDL_zero(cstatus);
|
||||
if (!this->hidden->iscapture) {
|
||||
if (!this->iscapture) {
|
||||
cstatus.channel = SND_PCM_CHANNEL_PLAYBACK;
|
||||
} else {
|
||||
cstatus.channel = SND_PCM_CHANNEL_CAPTURE;
|
||||
|
|
@ -194,7 +196,7 @@ QSA_PlayDevice(_THIS)
|
|||
|
||||
if ((cstatus.status == SND_PCM_STATUS_UNDERRUN) ||
|
||||
(cstatus.status == SND_PCM_STATUS_READY)) {
|
||||
if (!this->hidden->iscapture) {
|
||||
if (!this->iscapture) {
|
||||
status =
|
||||
snd_pcm_plugin_prepare(this->hidden->
|
||||
audio_handle,
|
||||
|
|
@ -238,7 +240,7 @@ static void
|
|||
QSA_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->audio_handle != NULL) {
|
||||
if (!this->hidden->iscapture) {
|
||||
if (!this->iscapture) {
|
||||
/* Finish playing available samples */
|
||||
snd_pcm_plugin_flush(this->hidden->audio_handle,
|
||||
SND_PCM_CHANNEL_PLAYBACK);
|
||||
|
|
@ -255,13 +257,13 @@ QSA_CloseDevice(_THIS)
|
|||
}
|
||||
|
||||
static int
|
||||
QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
QSA_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
const QSA_Device *device = (const QSA_Device *) handle;
|
||||
const QSA_Device *device = (const QSA_Device *) this->handle;
|
||||
SDL_Bool iscapture = this->iscapture;
|
||||
int status = 0;
|
||||
int format = 0;
|
||||
SDL_AudioFormat test_format = 0;
|
||||
int found = 0;
|
||||
SDL_AudioFormat test_format;
|
||||
snd_pcm_channel_setup_t csetup;
|
||||
snd_pcm_channel_params_t cparams;
|
||||
|
||||
|
|
@ -278,9 +280,6 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
/* Initialize channel transfer parameters to default */
|
||||
QSA_InitAudioParams(&cparams);
|
||||
|
||||
/* Initialize channel direction: capture or playback */
|
||||
this->hidden->iscapture = iscapture ? SDL_TRUE : SDL_FALSE;
|
||||
|
||||
if (device != NULL) {
|
||||
/* Open requested audio device */
|
||||
this->hidden->deviceno = device->deviceno;
|
||||
|
|
@ -303,89 +302,49 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
}
|
||||
|
||||
/* Try for a closest match on audio format */
|
||||
format = 0;
|
||||
/* can't use format as SND_PCM_SFMT_U8 = 0 in qsa */
|
||||
found = 0;
|
||||
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); !found;) {
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
/* if match found set format to equivalent QSA format */
|
||||
switch (test_format) {
|
||||
case AUDIO_U8:
|
||||
{
|
||||
format = SND_PCM_SFMT_U8;
|
||||
found = 1;
|
||||
}
|
||||
format = SND_PCM_SFMT_U8;
|
||||
break;
|
||||
case AUDIO_S8:
|
||||
{
|
||||
format = SND_PCM_SFMT_S8;
|
||||
found = 1;
|
||||
}
|
||||
format = SND_PCM_SFMT_S8;
|
||||
break;
|
||||
case AUDIO_S16LSB:
|
||||
{
|
||||
format = SND_PCM_SFMT_S16_LE;
|
||||
found = 1;
|
||||
}
|
||||
format = SND_PCM_SFMT_S16_LE;
|
||||
break;
|
||||
case AUDIO_S16MSB:
|
||||
{
|
||||
format = SND_PCM_SFMT_S16_BE;
|
||||
found = 1;
|
||||
}
|
||||
format = SND_PCM_SFMT_S16_BE;
|
||||
break;
|
||||
case AUDIO_U16LSB:
|
||||
{
|
||||
format = SND_PCM_SFMT_U16_LE;
|
||||
found = 1;
|
||||
}
|
||||
format = SND_PCM_SFMT_U16_LE;
|
||||
break;
|
||||
case AUDIO_U16MSB:
|
||||
{
|
||||
format = SND_PCM_SFMT_U16_BE;
|
||||
found = 1;
|
||||
}
|
||||
format = SND_PCM_SFMT_U16_BE;
|
||||
break;
|
||||
case AUDIO_S32LSB:
|
||||
{
|
||||
format = SND_PCM_SFMT_S32_LE;
|
||||
found = 1;
|
||||
}
|
||||
format = SND_PCM_SFMT_S32_LE;
|
||||
break;
|
||||
case AUDIO_S32MSB:
|
||||
{
|
||||
format = SND_PCM_SFMT_S32_BE;
|
||||
found = 1;
|
||||
}
|
||||
format = SND_PCM_SFMT_S32_BE;
|
||||
break;
|
||||
case AUDIO_F32LSB:
|
||||
{
|
||||
format = SND_PCM_SFMT_FLOAT_LE;
|
||||
found = 1;
|
||||
}
|
||||
format = SND_PCM_SFMT_FLOAT_LE;
|
||||
break;
|
||||
case AUDIO_F32MSB:
|
||||
{
|
||||
format = SND_PCM_SFMT_FLOAT_BE;
|
||||
found = 1;
|
||||
}
|
||||
format = SND_PCM_SFMT_FLOAT_BE;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
test_format = SDL_NextAudioFormat();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* assumes test_format not 0 on success */
|
||||
if (test_format == 0) {
|
||||
return SDL_SetError("QSA: Couldn't find any hardware audio formats");
|
||||
/* can't use format as SND_PCM_SFMT_U8 = 0 in qsa */
|
||||
if (!test_format) {
|
||||
return SDL_SetError("%s: Unsupported audio format", "qsa");
|
||||
}
|
||||
|
||||
this->spec.format = test_format;
|
||||
|
||||
/* Set the audio format */
|
||||
|
|
@ -405,7 +364,7 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
|
||||
/* Make sure channel is setup right one last time */
|
||||
SDL_zero(csetup);
|
||||
if (!this->hidden->iscapture) {
|
||||
if (!this->iscapture) {
|
||||
csetup.channel = SND_PCM_CHANNEL_PLAYBACK;
|
||||
} else {
|
||||
csetup.channel = SND_PCM_CHANNEL_CAPTURE;
|
||||
|
|
@ -441,7 +400,7 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
this->hidden->pcm_len);
|
||||
|
||||
/* get the file descriptor */
|
||||
if (!this->hidden->iscapture) {
|
||||
if (!this->iscapture) {
|
||||
this->hidden->audio_fd =
|
||||
snd_pcm_file_descriptor(this->hidden->audio_handle,
|
||||
SND_PCM_CHANNEL_PLAYBACK);
|
||||
|
|
@ -456,7 +415,7 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
}
|
||||
|
||||
/* Prepare an audio channel */
|
||||
if (!this->hidden->iscapture) {
|
||||
if (!this->iscapture) {
|
||||
/* Prepare audio playback */
|
||||
status =
|
||||
snd_pcm_plugin_prepare(this->hidden->audio_handle,
|
||||
|
|
@ -528,7 +487,11 @@ QSA_DetectDevices(void)
|
|||
devices;
|
||||
status = snd_pcm_close(handle);
|
||||
if (status == EOK) {
|
||||
SDL_AddAudioDevice(SDL_FALSE, qsa_playback_device[qsa_playback_devices].name, &qsa_playback_device[qsa_playback_devices]);
|
||||
/* Note that spec is NULL, because we are required to open the device before
|
||||
* acquiring the mix format, making this information inaccessible at
|
||||
* enumeration time
|
||||
*/
|
||||
SDL_AddAudioDevice(SDL_FALSE, qsa_playback_device[qsa_playback_devices].name, NULL, &qsa_playback_device[qsa_playback_devices]);
|
||||
qsa_playback_devices++;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -586,7 +549,11 @@ QSA_DetectDevices(void)
|
|||
devices;
|
||||
status = snd_pcm_close(handle);
|
||||
if (status == EOK) {
|
||||
SDL_AddAudioDevice(SDL_TRUE, qsa_capture_device[qsa_capture_devices].name, &qsa_capture_device[qsa_capture_devices]);
|
||||
/* Note that spec is NULL, because we are required to open the device before
|
||||
* acquiring the mix format, making this information inaccessible at
|
||||
* enumeration time
|
||||
*/
|
||||
SDL_AddAudioDevice(SDL_TRUE, qsa_capture_device[qsa_capture_devices].name, NULL, &qsa_capture_device[qsa_capture_devices]);
|
||||
qsa_capture_devices++;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -625,7 +592,7 @@ QSA_Deinitialize(void)
|
|||
qsa_capture_devices = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
QSA_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
/* Clear devices array */
|
||||
|
|
@ -645,20 +612,14 @@ QSA_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->GetDeviceBuf = QSA_GetDeviceBuf;
|
||||
impl->CloseDevice = QSA_CloseDevice;
|
||||
impl->Deinitialize = QSA_Deinitialize;
|
||||
impl->LockDevice = NULL;
|
||||
impl->UnlockDevice = NULL;
|
||||
|
||||
impl->ProvidesOwnCallbackThread = 0;
|
||||
impl->SkipMixerLock = 0;
|
||||
impl->HasCaptureSupport = 1;
|
||||
impl->OnlyHasDefaultOutputDevice = 0;
|
||||
impl->OnlyHasDefaultCaptureDevice = 0;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap QSAAUDIO_bootstrap = {
|
||||
"qsa", "QNX QSA Audio", QSA_Init, 0
|
||||
"qsa", "QNX QSA Audio", QSA_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_QSA */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -33,9 +33,6 @@
|
|||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
/* SDL capture state */
|
||||
SDL_bool iscapture;
|
||||
|
||||
/* The audio device handle */
|
||||
int cardno;
|
||||
int deviceno;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -237,11 +237,11 @@ SNDIO_CloseDevice(_THIS)
|
|||
}
|
||||
|
||||
static int
|
||||
SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
SNDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
SDL_AudioFormat test_format;
|
||||
struct sio_par par;
|
||||
int status;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
SDL_malloc(sizeof(*this->hidden));
|
||||
|
|
@ -273,8 +273,7 @@ SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
par.appbufsz = par.round * 2;
|
||||
|
||||
/* Try for a closest match on audio format */
|
||||
status = -1;
|
||||
while (test_format && (status < 0)) {
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
if (!SDL_AUDIO_ISFLOAT(test_format)) {
|
||||
par.le = SDL_AUDIO_ISLITTLEENDIAN(test_format) ? 1 : 0;
|
||||
par.sig = SDL_AUDIO_ISSIGNED(test_format) ? 1 : 0;
|
||||
|
|
@ -290,15 +289,13 @@ SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
continue;
|
||||
}
|
||||
if ((par.bits == 8 * par.bps) || (par.msb)) {
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
test_format = SDL_NextAudioFormat();
|
||||
}
|
||||
|
||||
if (status < 0) {
|
||||
return SDL_SetError("sndio: Couldn't find any hardware audio formats");
|
||||
if (!test_format) {
|
||||
return SDL_SetError("%s: Unsupported audio format", "sndio");
|
||||
}
|
||||
|
||||
if ((par.bps == 4) && (par.sig) && (par.le))
|
||||
|
|
@ -350,11 +347,18 @@ SNDIO_Deinitialize(void)
|
|||
UnloadSNDIOLibrary();
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
SNDIO_DetectDevices(void)
|
||||
{
|
||||
SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, NULL, (void *) 0x1);
|
||||
SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *) 0x2);
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
SNDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
if (LoadSNDIOLibrary() < 0) {
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Set the function pointers */
|
||||
|
|
@ -366,15 +370,16 @@ SNDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->CaptureFromDevice = SNDIO_CaptureFromDevice;
|
||||
impl->FlushCapture = SNDIO_FlushCapture;
|
||||
impl->Deinitialize = SNDIO_Deinitialize;
|
||||
impl->DetectDevices = SNDIO_DetectDevices;
|
||||
|
||||
impl->AllowsArbitraryDeviceNames = 1;
|
||||
impl->AllowsArbitraryDeviceNames = SDL_TRUE;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap SNDIO_bootstrap = {
|
||||
"sndio", "OpenBSD sndio", SNDIO_Init, 0
|
||||
"sndio", "OpenBSD sndio", SNDIO_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_SNDIO */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -98,7 +98,7 @@ SUNAUDIO_WaitDevice(_THIS)
|
|||
}
|
||||
}
|
||||
#else
|
||||
SDL_IOReady(this->hidden->audio_fd, SDL_TRUE, -1);
|
||||
SDL_IOReady(this->hidden->audio_fd, SDL_IOR_WRITE, -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -188,11 +188,12 @@ SUNAUDIO_CloseDevice(_THIS)
|
|||
}
|
||||
|
||||
static int
|
||||
SUNAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
SUNAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
#ifdef AUDIO_SETINFO
|
||||
int enc;
|
||||
#endif
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
int desired_freq = 0;
|
||||
const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
|
||||
SDL_AudioFormat format = 0;
|
||||
|
|
@ -394,7 +395,7 @@ snd2au(int sample)
|
|||
return (mask & sample);
|
||||
}
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
SUNAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
|
|
@ -405,13 +406,13 @@ SUNAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->GetDeviceBuf = SUNAUDIO_GetDeviceBuf;
|
||||
impl->CloseDevice = SUNAUDIO_CloseDevice;
|
||||
|
||||
impl->AllowsArbitraryDeviceNames = 1;
|
||||
impl->AllowsArbitraryDeviceNames = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap SUNAUDIO_bootstrap = {
|
||||
"audio", "UNIX /dev/audio interface", SUNAUDIO_Init, 0
|
||||
"audio", "UNIX /dev/audio interface", SUNAUDIO_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_SUNAUDIO */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
|
|||
183
Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.c
Normal file
183
Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.c
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_VITA
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h> /* memalign() */
|
||||
|
||||
#include "SDL_audio.h"
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_timer.h"
|
||||
#include "../SDL_audio_c.h"
|
||||
#include "../SDL_audiodev_c.h"
|
||||
#include "../SDL_sysaudio.h"
|
||||
#include "SDL_vitaaudio.h"
|
||||
|
||||
#include <psp2/kernel/threadmgr.h>
|
||||
#include <psp2/audioout.h>
|
||||
|
||||
#define SCE_AUDIO_SAMPLE_ALIGN(s) (((s) + 63) & ~63)
|
||||
#define SCE_AUDIO_MAX_VOLUME 0x8000
|
||||
|
||||
/* The tag name used by VITA audio */
|
||||
#define VITAAUD_DRIVER_NAME "vita"
|
||||
|
||||
static int
|
||||
VITAAUD_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
int format, mixlen, i, port = SCE_AUDIO_OUT_PORT_TYPE_MAIN;
|
||||
int vols[2] = {SCE_AUDIO_MAX_VOLUME, SCE_AUDIO_MAX_VOLUME};
|
||||
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
SDL_malloc(sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(this->hidden, 0, sizeof(*this->hidden));
|
||||
switch (this->spec.format & 0xff) {
|
||||
case 8:
|
||||
case 16:
|
||||
this->spec.format = AUDIO_S16LSB;
|
||||
break;
|
||||
default:
|
||||
return SDL_SetError("Unsupported audio format");
|
||||
}
|
||||
|
||||
/* The sample count must be a multiple of 64. */
|
||||
this->spec.samples = SCE_AUDIO_SAMPLE_ALIGN(this->spec.samples);
|
||||
|
||||
/* Update the fragment size as size in bytes. */
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
/* Allocate the mixing buffer. Its size and starting address must
|
||||
be a multiple of 64 bytes. Our sample count is already a multiple of
|
||||
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) {
|
||||
return SDL_SetError("Couldn't allocate mixing buffer");
|
||||
}
|
||||
|
||||
/* Setup the hardware channel. */
|
||||
if (this->spec.channels == 1) {
|
||||
format = SCE_AUDIO_OUT_MODE_MONO;
|
||||
} else {
|
||||
format = SCE_AUDIO_OUT_MODE_STEREO;
|
||||
}
|
||||
|
||||
if(this->spec.freq < 48000) {
|
||||
port = SCE_AUDIO_OUT_PORT_TYPE_BGM;
|
||||
}
|
||||
|
||||
this->hidden->channel = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format);
|
||||
if (this->hidden->channel < 0) {
|
||||
free(this->hidden->rawbuf);
|
||||
this->hidden->rawbuf = NULL;
|
||||
return SDL_SetError("Couldn't reserve hardware channel");
|
||||
}
|
||||
|
||||
sceAudioOutSetVolume(this->hidden->channel, SCE_AUDIO_VOLUME_FLAG_L_CH|SCE_AUDIO_VOLUME_FLAG_R_CH, vols);
|
||||
|
||||
SDL_memset(this->hidden->rawbuf, 0, mixlen);
|
||||
for (i = 0; i < NUM_BUFFERS; i++) {
|
||||
this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size];
|
||||
}
|
||||
|
||||
this->hidden->next_buffer = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void VITAAUD_PlayDevice(_THIS)
|
||||
{
|
||||
Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
|
||||
|
||||
sceAudioOutOutput(this->hidden->channel, mixbuf);
|
||||
|
||||
this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
|
||||
}
|
||||
|
||||
/* This function waits until it is possible to write a full sound buffer */
|
||||
static void VITAAUD_WaitDevice(_THIS)
|
||||
{
|
||||
/* Because we block when sending audio, there's no need for this function to do anything. */
|
||||
}
|
||||
static Uint8 *VITAAUD_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return this->hidden->mixbufs[this->hidden->next_buffer];
|
||||
}
|
||||
|
||||
static void VITAAUD_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->channel >= 0) {
|
||||
sceAudioOutReleasePort(this->hidden->channel);
|
||||
this->hidden->channel = -1;
|
||||
}
|
||||
|
||||
if (this->hidden->rawbuf != NULL) {
|
||||
free(this->hidden->rawbuf); /* this uses memalign(), not SDL_malloc(). */
|
||||
this->hidden->rawbuf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void VITAAUD_ThreadInit(_THIS)
|
||||
{
|
||||
/* Increase the priority of this audio thread by 1 to put it
|
||||
ahead of other SDL threads. */
|
||||
SceUID thid;
|
||||
SceKernelThreadInfo info;
|
||||
thid = sceKernelGetThreadId();
|
||||
info.size = sizeof(SceKernelThreadInfo);
|
||||
if (sceKernelGetThreadInfo(thid, &info) == 0) {
|
||||
sceKernelChangeThreadPriority(thid, info.currentPriority - 1);
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
VITAAUD_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
impl->OpenDevice = VITAAUD_OpenDevice;
|
||||
impl->PlayDevice = VITAAUD_PlayDevice;
|
||||
impl->WaitDevice = VITAAUD_WaitDevice;
|
||||
impl->GetDeviceBuf = VITAAUD_GetDeviceBuf;
|
||||
impl->CloseDevice = VITAAUD_CloseDevice;
|
||||
impl->ThreadInit = VITAAUD_ThreadInit;
|
||||
|
||||
/* VITA audio device */
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
/*
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->OnlyHasDefaultInputDevice = SDL_TRUE;
|
||||
*/
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap VITAAUD_bootstrap = {
|
||||
"vita", "VITA audio driver", VITAAUD_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_VITA */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
45
Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.h
Normal file
45
Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef _SDL_vitaaudio_h
|
||||
#define _SDL_vitaaudio_h
|
||||
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
#define NUM_BUFFERS 2
|
||||
|
||||
struct SDL_PrivateAudioData {
|
||||
/* The hardware output channel. */
|
||||
int channel;
|
||||
/* The raw allocated mixing buffer. */
|
||||
Uint8 *rawbuf;
|
||||
/* Individual mixing buffers. */
|
||||
Uint8 *mixbufs[NUM_BUFFERS];
|
||||
/* Index of the next available mixing buffer. */
|
||||
int next_buffer;
|
||||
};
|
||||
|
||||
#endif /* _SDL_vitaaudio_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -34,10 +34,16 @@
|
|||
|
||||
#include "SDL_wasapi.h"
|
||||
|
||||
/* This constant isn't available on MinGW-w64 */
|
||||
/* These constants aren't available in older SDKs */
|
||||
#ifndef AUDCLNT_STREAMFLAGS_RATEADJUST
|
||||
#define AUDCLNT_STREAMFLAGS_RATEADJUST 0x00100000
|
||||
#endif
|
||||
#ifndef AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY
|
||||
#define AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY 0x08000000
|
||||
#endif
|
||||
#ifndef AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM
|
||||
#define AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM 0x80000000
|
||||
#endif
|
||||
|
||||
/* these increment as default devices change. Opened default devices pick up changes in their threads. */
|
||||
SDL_atomic_t WASAPI_DefaultPlaybackGeneration;
|
||||
|
|
@ -58,42 +64,6 @@ static const IID SDL_IID_IAudioCaptureClient = { 0xc8adbd64, 0xe71e, 0x48a0,{ 0x
|
|||
static const GUID SDL_KSDATAFORMAT_SUBTYPE_PCM = { 0x00000001, 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
|
||||
static const GUID SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { 0x00000003, 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
|
||||
|
||||
static SDL_bool
|
||||
WStrEqual(const WCHAR *a, const WCHAR *b)
|
||||
{
|
||||
while (*a) {
|
||||
if (*a != *b) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
return *b == 0;
|
||||
}
|
||||
|
||||
static size_t
|
||||
WStrLen(const WCHAR *wstr)
|
||||
{
|
||||
size_t retval = 0;
|
||||
if (wstr) {
|
||||
while (*(wstr++)) {
|
||||
retval++;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static WCHAR *
|
||||
WStrDupe(const WCHAR *wstr)
|
||||
{
|
||||
const size_t len = (WStrLen(wstr) + 1) * sizeof (WCHAR);
|
||||
WCHAR *retval = (WCHAR *) SDL_malloc(len);
|
||||
if (retval) {
|
||||
SDL_memcpy(retval, wstr, len);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid)
|
||||
|
|
@ -103,7 +73,7 @@ WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid)
|
|||
DevIdList *prev = NULL;
|
||||
for (i = deviceid_list; i; i = next) {
|
||||
next = i->next;
|
||||
if (WStrEqual(i->str, devid)) {
|
||||
if (SDL_wcscmp(i->str, devid) == 0) {
|
||||
if (prev) {
|
||||
prev->next = next;
|
||||
} else {
|
||||
|
|
@ -117,10 +87,33 @@ WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid)
|
|||
}
|
||||
}
|
||||
|
||||
static SDL_AudioFormat
|
||||
WaveFormatToSDLFormat(WAVEFORMATEX *waveformat)
|
||||
{
|
||||
if ((waveformat->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) && (waveformat->wBitsPerSample == 32)) {
|
||||
return AUDIO_F32SYS;
|
||||
} else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 16)) {
|
||||
return AUDIO_S16SYS;
|
||||
} else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 32)) {
|
||||
return AUDIO_S32SYS;
|
||||
} else if (waveformat->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
|
||||
const WAVEFORMATEXTENSIBLE *ext = (const WAVEFORMATEXTENSIBLE *) waveformat;
|
||||
if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof (GUID)) == 0) && (waveformat->wBitsPerSample == 32)) {
|
||||
return AUDIO_F32SYS;
|
||||
} else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof (GUID)) == 0) && (waveformat->wBitsPerSample == 16)) {
|
||||
return AUDIO_S16SYS;
|
||||
} else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof (GUID)) == 0) && (waveformat->wBitsPerSample == 32)) {
|
||||
return AUDIO_S32SYS;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, LPCWSTR devid)
|
||||
WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTENSIBLE *fmt, LPCWSTR devid)
|
||||
{
|
||||
DevIdList *devidlist;
|
||||
SDL_AudioSpec spec;
|
||||
|
||||
/* You can have multiple endpoints on a device that are mutually exclusive ("Speakers" vs "Line Out" or whatever).
|
||||
In a perfect world, things that are unplugged won't be in this collection. The only gotcha is probably for
|
||||
|
|
@ -129,7 +122,7 @@ WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, LPCWSTR devid)
|
|||
|
||||
/* see if we already have this one. */
|
||||
for (devidlist = deviceid_list; devidlist; devidlist = devidlist->next) {
|
||||
if (WStrEqual(devidlist->str, devid)) {
|
||||
if (SDL_wcscmp(devidlist->str, devid) == 0) {
|
||||
return; /* we already have this. */
|
||||
}
|
||||
}
|
||||
|
|
@ -139,7 +132,7 @@ WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, LPCWSTR devid)
|
|||
return; /* oh well. */
|
||||
}
|
||||
|
||||
devid = WStrDupe(devid);
|
||||
devid = SDL_wcsdup(devid);
|
||||
if (!devid) {
|
||||
SDL_free(devidlist);
|
||||
return; /* oh well. */
|
||||
|
|
@ -149,7 +142,11 @@ WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, LPCWSTR devid)
|
|||
devidlist->next = deviceid_list;
|
||||
deviceid_list = devidlist;
|
||||
|
||||
SDL_AddAudioDevice(iscapture, devname, (void *) devid);
|
||||
SDL_zero(spec);
|
||||
spec.channels = (Uint8)fmt->Format.nChannels;
|
||||
spec.freq = fmt->Format.nSamplesPerSec;
|
||||
spec.format = WaveFormatToSDLFormat((WAVEFORMATEX *) fmt);
|
||||
SDL_AddAudioDevice(iscapture, devname, &spec, (void *) devid);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -212,7 +209,7 @@ UpdateAudioStream(_THIS, const SDL_AudioSpec *oldspec)
|
|||
}
|
||||
|
||||
if (!this->stream) {
|
||||
return -1;
|
||||
return -1; /* SDL_NewAudioStream should have called SDL_SetError. */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -315,8 +312,14 @@ WASAPI_WaitDevice(_THIS)
|
|||
UINT32 padding = 0;
|
||||
if (!WasapiFailed(this, IAudioClient_GetCurrentPadding(this->hidden->client, &padding))) {
|
||||
/*SDL_Log("WASAPI EVENT! padding=%u maxpadding=%u", (unsigned int)padding, (unsigned int)maxpadding);*/
|
||||
if (padding <= maxpadding) {
|
||||
break;
|
||||
if (this->iscapture) {
|
||||
if (padding > 0) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (padding <= maxpadding) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (waitResult != WAIT_TIMEOUT) {
|
||||
|
|
@ -422,7 +425,6 @@ ReleaseWasapiDevice(_THIS)
|
|||
{
|
||||
if (this->hidden->client) {
|
||||
IAudioClient_Stop(this->hidden->client);
|
||||
IAudioClient_SetEventHandle(this->hidden->client, NULL);
|
||||
IAudioClient_Release(this->hidden->client);
|
||||
this->hidden->client = NULL;
|
||||
}
|
||||
|
|
@ -510,9 +512,8 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
|||
IAudioRenderClient *render = NULL;
|
||||
IAudioCaptureClient *capture = NULL;
|
||||
WAVEFORMATEX *waveformat = NULL;
|
||||
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
SDL_AudioFormat test_format;
|
||||
SDL_AudioFormat wasapi_format = 0;
|
||||
SDL_bool valid_format = SDL_FALSE;
|
||||
HRESULT ret = S_OK;
|
||||
DWORD streamflags = 0;
|
||||
|
||||
|
|
@ -539,34 +540,17 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
|||
this->spec.channels = (Uint8) waveformat->nChannels;
|
||||
|
||||
/* Make sure we have a valid format that we can convert to whatever WASAPI wants. */
|
||||
if ((waveformat->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) && (waveformat->wBitsPerSample == 32)) {
|
||||
wasapi_format = AUDIO_F32SYS;
|
||||
} else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 16)) {
|
||||
wasapi_format = AUDIO_S16SYS;
|
||||
} else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 32)) {
|
||||
wasapi_format = AUDIO_S32SYS;
|
||||
} else if (waveformat->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
|
||||
const WAVEFORMATEXTENSIBLE *ext = (const WAVEFORMATEXTENSIBLE *) waveformat;
|
||||
if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof (GUID)) == 0) && (waveformat->wBitsPerSample == 32)) {
|
||||
wasapi_format = AUDIO_F32SYS;
|
||||
} else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof (GUID)) == 0) && (waveformat->wBitsPerSample == 16)) {
|
||||
wasapi_format = AUDIO_S16SYS;
|
||||
} else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof (GUID)) == 0) && (waveformat->wBitsPerSample == 32)) {
|
||||
wasapi_format = AUDIO_S32SYS;
|
||||
}
|
||||
}
|
||||
wasapi_format = WaveFormatToSDLFormat(waveformat);
|
||||
|
||||
while ((!valid_format) && (test_format)) {
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
if (test_format == wasapi_format) {
|
||||
this->spec.format = test_format;
|
||||
valid_format = SDL_TRUE;
|
||||
break;
|
||||
}
|
||||
test_format = SDL_NextAudioFormat();
|
||||
}
|
||||
|
||||
if (!valid_format) {
|
||||
return SDL_SetError("WASAPI: Unsupported audio format");
|
||||
if (!test_format) {
|
||||
return SDL_SetError("%s: Unsupported audio format", "wasapi");
|
||||
}
|
||||
|
||||
ret = IAudioClient_GetDevicePeriod(client, &default_period, NULL);
|
||||
|
|
@ -574,17 +558,11 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
|||
return WIN_SetErrorFromHRESULT("WASAPI can't determine minimum device period", ret);
|
||||
}
|
||||
|
||||
/* favor WASAPI's resampler over our own, in Win7+. */
|
||||
/* favor WASAPI's resampler over our own */
|
||||
if (this->spec.freq != waveformat->nSamplesPerSec) {
|
||||
/* RATEADJUST only works with output devices in share mode, and is available in Win7 and later.*/
|
||||
if (WIN_IsWindows7OrGreater() && !this->iscapture && (sharemode == AUDCLNT_SHAREMODE_SHARED)) {
|
||||
streamflags |= AUDCLNT_STREAMFLAGS_RATEADJUST;
|
||||
waveformat->nSamplesPerSec = this->spec.freq;
|
||||
waveformat->nAvgBytesPerSec = waveformat->nSamplesPerSec * waveformat->nChannels * (waveformat->wBitsPerSample / 8);
|
||||
}
|
||||
else {
|
||||
this->spec.freq = waveformat->nSamplesPerSec; /* force sampling rate so our resampler kicks in. */
|
||||
}
|
||||
streamflags |= (AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY);
|
||||
waveformat->nSamplesPerSec = this->spec.freq;
|
||||
waveformat->nAvgBytesPerSec = waveformat->nSamplesPerSec * waveformat->nChannels * (waveformat->wBitsPerSample / 8);
|
||||
}
|
||||
|
||||
streamflags |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
|
||||
|
|
@ -650,9 +628,7 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
|||
}
|
||||
|
||||
if (updatestream) {
|
||||
if (UpdateAudioStream(this, &oldspec) == -1) {
|
||||
return -1;
|
||||
}
|
||||
return UpdateAudioStream(this, &oldspec);
|
||||
}
|
||||
|
||||
return 0; /* good to go. */
|
||||
|
|
@ -660,9 +636,9 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
|||
|
||||
|
||||
static int
|
||||
WASAPI_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
WASAPI_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
LPCWSTR devid = (LPCWSTR) handle;
|
||||
LPCWSTR devid = (LPCWSTR) this->handle;
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
|
|
@ -675,9 +651,9 @@ WASAPI_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
WASAPI_RefDevice(this); /* so CloseDevice() will unref to zero. */
|
||||
|
||||
if (!devid) { /* is default device? */
|
||||
this->hidden->default_device_generation = SDL_AtomicGet(iscapture ? &WASAPI_DefaultCaptureGeneration : &WASAPI_DefaultPlaybackGeneration);
|
||||
this->hidden->default_device_generation = SDL_AtomicGet(this->iscapture ? &WASAPI_DefaultCaptureGeneration : &WASAPI_DefaultPlaybackGeneration);
|
||||
} else {
|
||||
this->hidden->devid = WStrDupe(devid);
|
||||
this->hidden->devid = SDL_wcsdup(devid);
|
||||
if (!this->hidden->devid) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
|
@ -710,12 +686,6 @@ WASAPI_ThreadDeinit(_THIS)
|
|||
WASAPI_PlatformThreadDeinit(this);
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_BeginLoopIteration(_THIS)
|
||||
{
|
||||
/* no-op. */
|
||||
}
|
||||
|
||||
static void
|
||||
WASAPI_Deinitialize(void)
|
||||
{
|
||||
|
|
@ -732,21 +702,20 @@ WASAPI_Deinitialize(void)
|
|||
deviceid_list = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
WASAPI_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
SDL_AtomicSet(&WASAPI_DefaultPlaybackGeneration, 1);
|
||||
SDL_AtomicSet(&WASAPI_DefaultCaptureGeneration, 1);
|
||||
|
||||
if (WASAPI_PlatformInit() == -1) {
|
||||
return 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Set the function pointers */
|
||||
impl->DetectDevices = WASAPI_DetectDevices;
|
||||
impl->ThreadInit = WASAPI_ThreadInit;
|
||||
impl->ThreadDeinit = WASAPI_ThreadDeinit;
|
||||
impl->BeginLoopIteration = WASAPI_BeginLoopIteration;
|
||||
impl->OpenDevice = WASAPI_OpenDevice;
|
||||
impl->PlayDevice = WASAPI_PlayDevice;
|
||||
impl->WaitDevice = WASAPI_WaitDevice;
|
||||
|
|
@ -755,13 +724,13 @@ WASAPI_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->FlushCapture = WASAPI_FlushCapture;
|
||||
impl->CloseDevice = WASAPI_CloseDevice;
|
||||
impl->Deinitialize = WASAPI_Deinitialize;
|
||||
impl->HasCaptureSupport = 1;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap WASAPI_bootstrap = {
|
||||
"wasapi", "WASAPI", WASAPI_Init, 0
|
||||
"wasapi", "WASAPI", WASAPI_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_WASAPI */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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,7 +63,7 @@ extern SDL_atomic_t WASAPI_DefaultCaptureGeneration;
|
|||
int WASAPI_PrepDevice(_THIS, const SDL_bool updatestream);
|
||||
void WASAPI_RefDevice(_THIS);
|
||||
void WASAPI_UnrefDevice(_THIS);
|
||||
void WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, LPCWSTR devid);
|
||||
void WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTENSIBLE *fmt, LPCWSTR devid);
|
||||
void WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid);
|
||||
|
||||
/* These are functions that are implemented differently for Windows vs WinRT. */
|
||||
|
|
@ -74,7 +74,6 @@ int WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery);
|
|||
void WASAPI_PlatformThreadInit(_THIS);
|
||||
void WASAPI_PlatformThreadDeinit(_THIS);
|
||||
void WASAPI_PlatformDeleteActivationHandler(void *handler);
|
||||
void WASAPI_BeginLoopIteration(_THIS);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -53,7 +53,7 @@ static IMMDeviceEnumerator *enumerator = NULL;
|
|||
|
||||
/* handle to Avrt.dll--Vista and later!--for flagging the callback thread as "Pro Audio" (low latency). */
|
||||
static HMODULE libavrt = NULL;
|
||||
typedef HANDLE(WINAPI *pfnAvSetMmThreadCharacteristicsW)(LPWSTR, LPDWORD);
|
||||
typedef HANDLE(WINAPI *pfnAvSetMmThreadCharacteristicsW)(LPCWSTR, LPDWORD);
|
||||
typedef BOOL(WINAPI *pfnAvRevertMmThreadCharacteristics)(HANDLE);
|
||||
static pfnAvSetMmThreadCharacteristicsW pAvSetMmThreadCharacteristicsW = NULL;
|
||||
static pfnAvRevertMmThreadCharacteristics pAvRevertMmThreadCharacteristics = NULL;
|
||||
|
|
@ -65,26 +65,31 @@ static const IID SDL_IID_IMMNotificationClient = { 0x7991eec9, 0x7e89, 0x4d85,{
|
|||
static const IID SDL_IID_IMMEndpoint = { 0x1be09788, 0x6894, 0x4089,{ 0x85, 0x86, 0x9a, 0x2a, 0x6c, 0x26, 0x5a, 0xc5 } };
|
||||
static const IID SDL_IID_IAudioClient = { 0x1cb9ad4c, 0xdbfa, 0x4c32,{ 0xb1, 0x78, 0xc2, 0xf5, 0x68, 0xa7, 0x03, 0xb2 } };
|
||||
static const PROPERTYKEY SDL_PKEY_Device_FriendlyName = { { 0xa45c254e, 0xdf1c, 0x4efd,{ 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, } }, 14 };
|
||||
static const PROPERTYKEY SDL_PKEY_AudioEngine_DeviceFormat = { { 0xf19f064d, 0x82c, 0x4e27,{ 0xbc, 0x73, 0x68, 0x82, 0xa1, 0xbb, 0x8e, 0x4c, } }, 0 };
|
||||
|
||||
|
||||
static char *
|
||||
GetWasapiDeviceName(IMMDevice *device)
|
||||
static void
|
||||
GetWasapiDeviceInfo(IMMDevice *device, char **utf8dev, WAVEFORMATEXTENSIBLE *fmt)
|
||||
{
|
||||
/* PKEY_Device_FriendlyName gives you "Speakers (SoundBlaster Pro)" which drives me nuts. I'd rather it be
|
||||
"SoundBlaster Pro (Speakers)" but I guess that's developers vs users. Windows uses the FriendlyName in
|
||||
its own UIs, like Volume Control, etc. */
|
||||
char *utf8dev = NULL;
|
||||
IPropertyStore *props = NULL;
|
||||
*utf8dev = NULL;
|
||||
SDL_zerop(fmt);
|
||||
if (SUCCEEDED(IMMDevice_OpenPropertyStore(device, STGM_READ, &props))) {
|
||||
PROPVARIANT var;
|
||||
PropVariantInit(&var);
|
||||
if (SUCCEEDED(IPropertyStore_GetValue(props, &SDL_PKEY_Device_FriendlyName, &var))) {
|
||||
utf8dev = WIN_StringToUTF8(var.pwszVal);
|
||||
*utf8dev = WIN_StringToUTF8W(var.pwszVal);
|
||||
}
|
||||
PropVariantClear(&var);
|
||||
if (SUCCEEDED(IPropertyStore_GetValue(props, &SDL_PKEY_AudioEngine_DeviceFormat, &var))) {
|
||||
SDL_memcpy(fmt, var.blob.pBlobData, SDL_min(var.blob.cbSize, sizeof(WAVEFORMATEXTENSIBLE)));
|
||||
}
|
||||
PropVariantClear(&var);
|
||||
IPropertyStore_Release(props);
|
||||
}
|
||||
return utf8dev;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -194,9 +199,11 @@ SDLMMNotificationClient_OnDeviceStateChanged(IMMNotificationClient *ithis, LPCWS
|
|||
if (SUCCEEDED(IMMEndpoint_GetDataFlow(endpoint, &flow))) {
|
||||
const SDL_bool iscapture = (flow == eCapture);
|
||||
if (dwNewState == DEVICE_STATE_ACTIVE) {
|
||||
char *utf8dev = GetWasapiDeviceName(device);
|
||||
char *utf8dev;
|
||||
WAVEFORMATEXTENSIBLE fmt;
|
||||
GetWasapiDeviceInfo(device, &utf8dev, &fmt);
|
||||
if (utf8dev) {
|
||||
WASAPI_AddDevice(iscapture, utf8dev, pwstrDeviceId);
|
||||
WASAPI_AddDevice(iscapture, utf8dev, &fmt, pwstrDeviceId);
|
||||
SDL_free(utf8dev);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -251,7 +258,7 @@ WASAPI_PlatformInit(void)
|
|||
return WIN_SetErrorFromHRESULT("WASAPI CoCreateInstance(MMDeviceEnumerator)", ret);
|
||||
}
|
||||
|
||||
libavrt = LoadLibraryW(L"avrt.dll"); /* this library is available in Vista and later. No WinXP, so have to LoadLibrary to use it for now! */
|
||||
libavrt = LoadLibrary(TEXT("avrt.dll")); /* this library is available in Vista and later. No WinXP, so have to LoadLibrary to use it for now! */
|
||||
if (libavrt) {
|
||||
pAvSetMmThreadCharacteristicsW = (pfnAvSetMmThreadCharacteristicsW) GetProcAddress(libavrt, "AvSetMmThreadCharacteristicsW");
|
||||
pAvRevertMmThreadCharacteristics = (pfnAvRevertMmThreadCharacteristics) GetProcAddress(libavrt, "AvRevertMmThreadCharacteristics");
|
||||
|
|
@ -291,7 +298,7 @@ WASAPI_PlatformThreadInit(_THIS)
|
|||
/* Set this thread to very high "Pro Audio" priority. */
|
||||
if (pAvSetMmThreadCharacteristicsW) {
|
||||
DWORD idx = 0;
|
||||
this->hidden->task = pAvSetMmThreadCharacteristicsW(TEXT("Pro Audio"), &idx);
|
||||
this->hidden->task = pAvSetMmThreadCharacteristicsW(L"Pro Audio", &idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -352,6 +359,7 @@ typedef struct
|
|||
{
|
||||
LPWSTR devid;
|
||||
char *devname;
|
||||
WAVEFORMATEXTENSIBLE fmt;
|
||||
} EndpointItem;
|
||||
|
||||
static int sort_endpoints(const void *_a, const void *_b)
|
||||
|
|
@ -408,7 +416,7 @@ WASAPI_EnumerateEndpointsForFlow(const SDL_bool iscapture)
|
|||
IMMDevice *device = NULL;
|
||||
if (SUCCEEDED(IMMDeviceCollection_Item(collection, i, &device))) {
|
||||
if (SUCCEEDED(IMMDevice_GetId(device, &item->devid))) {
|
||||
item->devname = GetWasapiDeviceName(device);
|
||||
GetWasapiDeviceInfo(device, &item->devname, &item->fmt);
|
||||
}
|
||||
IMMDevice_Release(device);
|
||||
}
|
||||
|
|
@ -421,7 +429,7 @@ WASAPI_EnumerateEndpointsForFlow(const SDL_bool iscapture)
|
|||
for (i = 0; i < total; i++) {
|
||||
EndpointItem *item = items + i;
|
||||
if ((item->devid) && (item->devname)) {
|
||||
WASAPI_AddDevice(iscapture, item->devname, item->devid);
|
||||
WASAPI_AddDevice(iscapture, item->devname, &item->fmt, item->devid);
|
||||
}
|
||||
SDL_free(item->devname);
|
||||
CoTaskMemFree(item->devid);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -32,6 +32,7 @@
|
|||
#include <windows.devices.enumeration.h>
|
||||
#include <windows.media.devices.h>
|
||||
#include <wrl/implements.h>
|
||||
#include <collection.h>
|
||||
|
||||
extern "C" {
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
|
|
@ -52,6 +53,8 @@ using namespace Windows::Media::Devices;
|
|||
using namespace Windows::Foundation;
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
static Platform::String^ SDL_PKEY_AudioEngine_DeviceFormat = L"{f19f064d-082c-4e27-bc73-6882a1bb8e4c} 0";
|
||||
|
||||
class SDL_WasapiDeviceEventHandler
|
||||
{
|
||||
public:
|
||||
|
|
@ -78,9 +81,16 @@ private:
|
|||
SDL_WasapiDeviceEventHandler::SDL_WasapiDeviceEventHandler(const SDL_bool _iscapture)
|
||||
: iscapture(_iscapture)
|
||||
, completed(SDL_CreateSemaphore(0))
|
||||
, watcher(DeviceInformation::CreateWatcher(_iscapture ? DeviceClass::AudioCapture : DeviceClass::AudioRender))
|
||||
{
|
||||
if (!watcher || !completed)
|
||||
if (!completed)
|
||||
return; // uhoh.
|
||||
|
||||
Platform::String^ selector = _iscapture ? MediaDevice::GetAudioCaptureSelector() :
|
||||
MediaDevice::GetAudioRenderSelector();
|
||||
Platform::Collections::Vector<Platform::String^> properties;
|
||||
properties.Append(SDL_PKEY_AudioEngine_DeviceFormat);
|
||||
watcher = DeviceInformation::CreateWatcher(selector, properties.GetView());
|
||||
if (!watcher)
|
||||
return; // uhoh.
|
||||
|
||||
// !!! FIXME: this doesn't need a lambda here, I think, if I make SDL_WasapiDeviceEventHandler a proper C++/CX class. --ryan.
|
||||
|
|
@ -124,7 +134,18 @@ SDL_WasapiDeviceEventHandler::OnDeviceAdded(DeviceWatcher^ sender, DeviceInforma
|
|||
SDL_assert(sender == this->watcher);
|
||||
char *utf8dev = WIN_StringToUTF8(info->Name->Data());
|
||||
if (utf8dev) {
|
||||
WASAPI_AddDevice(this->iscapture, utf8dev, info->Id->Data());
|
||||
WAVEFORMATEXTENSIBLE fmt;
|
||||
Platform::Object^ obj = info->Properties->Lookup(SDL_PKEY_AudioEngine_DeviceFormat);
|
||||
if (obj) {
|
||||
IPropertyValue^ property = (IPropertyValue^) obj;
|
||||
Platform::Array<unsigned char>^ data;
|
||||
property->GetUInt8Array(&data);
|
||||
SDL_memcpy(&fmt, data->Data, SDL_min(data->Length, sizeof(WAVEFORMATEXTENSIBLE)));
|
||||
} else {
|
||||
SDL_zero(fmt);
|
||||
}
|
||||
|
||||
WASAPI_AddDevice(this->iscapture, utf8dev, &fmt, info->Id->Data());
|
||||
SDL_free(utf8dev);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -75,12 +75,19 @@ static void DetectWave##typ##Devs(void) { \
|
|||
const UINT iscapture = iscap ? 1 : 0; \
|
||||
const UINT devcount = wave##typ##GetNumDevs(); \
|
||||
capstyp##2W caps; \
|
||||
SDL_AudioSpec spec; \
|
||||
UINT i; \
|
||||
SDL_zero(spec); \
|
||||
for (i = 0; i < devcount; i++) { \
|
||||
if (wave##typ##GetDevCaps(i,(LP##capstyp##W)&caps,sizeof(caps))==MMSYSERR_NOERROR) { \
|
||||
char *name = WIN_LookupAudioDeviceName(caps.szPname,&caps.NameGuid); \
|
||||
if (name != NULL) { \
|
||||
SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \
|
||||
/* Note that freq/format are not filled in, as this information \
|
||||
* is not provided by the caps struct! At best, we get possible \
|
||||
* sample formats, but not an _active_ format. \
|
||||
*/ \
|
||||
spec.channels = (Uint8)caps.wChannels; \
|
||||
SDL_AddAudioDevice((int) iscapture, name, &spec, (void *) ((size_t) i+1)); \
|
||||
SDL_free(name); \
|
||||
} \
|
||||
} \
|
||||
|
|
@ -128,7 +135,7 @@ FillSound(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance,
|
|||
}
|
||||
|
||||
static int
|
||||
SetMMerror(char *function, MMRESULT code)
|
||||
SetMMerror(const char *function, MMRESULT code)
|
||||
{
|
||||
int len;
|
||||
char errbuf[MAXERRORLENGTH];
|
||||
|
|
@ -276,10 +283,11 @@ PrepWaveFormat(_THIS, UINT devId, WAVEFORMATEX *pfmt, const int iscapture)
|
|||
}
|
||||
|
||||
static int
|
||||
WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
WINMM_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
int valid_datatype = 0;
|
||||
SDL_AudioFormat test_format;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
void *handle = this->handle;
|
||||
MMRESULT result;
|
||||
WAVEFORMATEX waveformat;
|
||||
UINT devId = WAVE_MAPPER; /* WAVE_MAPPER == choose system's default */
|
||||
|
|
@ -306,7 +314,7 @@ WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
if (this->spec.channels > 2)
|
||||
this->spec.channels = 2; /* !!! FIXME: is this right? */
|
||||
|
||||
while ((!valid_datatype) && (test_format)) {
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
switch (test_format) {
|
||||
case AUDIO_U8:
|
||||
case AUDIO_S16:
|
||||
|
|
@ -314,20 +322,17 @@ WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
case AUDIO_F32:
|
||||
this->spec.format = test_format;
|
||||
if (PrepWaveFormat(this, devId, &waveformat, iscapture)) {
|
||||
valid_datatype = 1;
|
||||
} else {
|
||||
test_format = SDL_NextAudioFormat();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
continue;
|
||||
default:
|
||||
test_format = SDL_NextAudioFormat();
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!valid_datatype) {
|
||||
return SDL_SetError("Unsupported audio format");
|
||||
if (!test_format) {
|
||||
return SDL_SetError("%s: Unsupported audio format", "winmm");
|
||||
}
|
||||
|
||||
/* Update the fragment size as size in bytes */
|
||||
|
|
@ -427,8 +432,7 @@ WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
|||
return 0; /* Ready to go! */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
static SDL_bool
|
||||
WINMM_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
|
|
@ -443,11 +447,11 @@ WINMM_Init(SDL_AudioDriverImpl * impl)
|
|||
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap WINMM_bootstrap = {
|
||||
"winmm", "Windows Waveform Audio", WINMM_Init, 0
|
||||
"winmm", "Windows Waveform Audio", WINMM_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_WINMM */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -79,7 +79,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(
|
|||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetScreenResolution)(
|
||||
JNIEnv *env, jclass jcls,
|
||||
jint surfaceWidth, jint surfaceHeight,
|
||||
jint deviceWidth, jint deviceHeight, jint format, jfloat rate);
|
||||
jint deviceWidth, jint deviceHeight, jfloat rate);
|
||||
|
||||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)(
|
||||
JNIEnv *env, jclass cls);
|
||||
|
|
@ -148,6 +148,10 @@ JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)(
|
|||
JNIEnv *env, jclass cls,
|
||||
jstring name);
|
||||
|
||||
JNIEXPORT jboolean JNICALL SDL_JAVA_INTERFACE(nativeGetHintBoolean)(
|
||||
JNIEnv *env, jclass cls,
|
||||
jstring name, jboolean default_value);
|
||||
|
||||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)(
|
||||
JNIEnv *env, jclass cls,
|
||||
jstring name, jstring value);
|
||||
|
|
@ -168,7 +172,7 @@ static JNINativeMethod SDLActivity_tab[] = {
|
|||
{ "nativeSetupJNI", "()I", SDL_JAVA_INTERFACE(nativeSetupJNI) },
|
||||
{ "nativeRunMain", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)I", SDL_JAVA_INTERFACE(nativeRunMain) },
|
||||
{ "onNativeDropFile", "(Ljava/lang/String;)V", SDL_JAVA_INTERFACE(onNativeDropFile) },
|
||||
{ "nativeSetScreenResolution", "(IIIIIF)V", SDL_JAVA_INTERFACE(nativeSetScreenResolution) },
|
||||
{ "nativeSetScreenResolution", "(IIIIF)V", SDL_JAVA_INTERFACE(nativeSetScreenResolution) },
|
||||
{ "onNativeResize", "()V", SDL_JAVA_INTERFACE(onNativeResize) },
|
||||
{ "onNativeSurfaceCreated", "()V", SDL_JAVA_INTERFACE(onNativeSurfaceCreated) },
|
||||
{ "onNativeSurfaceChanged", "()V", SDL_JAVA_INTERFACE(onNativeSurfaceChanged) },
|
||||
|
|
@ -189,6 +193,7 @@ static JNINativeMethod SDLActivity_tab[] = {
|
|||
{ "nativeResume", "()V", SDL_JAVA_INTERFACE(nativeResume) },
|
||||
{ "nativeFocusChanged", "(Z)V", SDL_JAVA_INTERFACE(nativeFocusChanged) },
|
||||
{ "nativeGetHint", "(Ljava/lang/String;)Ljava/lang/String;", SDL_JAVA_INTERFACE(nativeGetHint) },
|
||||
{ "nativeGetHintBoolean", "(Ljava/lang/String;Z)Z", SDL_JAVA_INTERFACE(nativeGetHintBoolean) },
|
||||
{ "nativeSetenv", "(Ljava/lang/String;Ljava/lang/String;)V", SDL_JAVA_INTERFACE(nativeSetenv) },
|
||||
{ "onNativeOrientationChanged", "(I)V", SDL_JAVA_INTERFACE(onNativeOrientationChanged) },
|
||||
{ "nativeAddTouch", "(ILjava/lang/String;)V", SDL_JAVA_INTERFACE(nativeAddTouch) },
|
||||
|
|
@ -298,6 +303,7 @@ static jmethodID midClipboardGetText;
|
|||
static jmethodID midClipboardHasText;
|
||||
static jmethodID midClipboardSetText;
|
||||
static jmethodID midCreateCustomCursor;
|
||||
static jmethodID midDestroyCustomCursor;
|
||||
static jmethodID midGetContext;
|
||||
static jmethodID midGetDisplayDPI;
|
||||
static jmethodID midGetManifestEnvironmentVariables;
|
||||
|
|
@ -312,12 +318,12 @@ static jmethodID midManualBackButton;
|
|||
static jmethodID midMinimizeWindow;
|
||||
static jmethodID midOpenURL;
|
||||
static jmethodID midRequestPermission;
|
||||
static jmethodID midShowToast;
|
||||
static jmethodID midSendMessage;
|
||||
static jmethodID midSetActivityTitle;
|
||||
static jmethodID midSetCustomCursor;
|
||||
static jmethodID midSetOrientation;
|
||||
static jmethodID midSetRelativeMouseEnabled;
|
||||
static jmethodID midSetSurfaceViewFormat;
|
||||
static jmethodID midSetSystemCursor;
|
||||
static jmethodID midSetWindowStyle;
|
||||
static jmethodID midShouldMinimizeOnFocusLoss;
|
||||
|
|
@ -577,6 +583,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
|
|||
midClipboardHasText = (*env)->GetStaticMethodID(env, mActivityClass, "clipboardHasText", "()Z");
|
||||
midClipboardSetText = (*env)->GetStaticMethodID(env, mActivityClass, "clipboardSetText", "(Ljava/lang/String;)V");
|
||||
midCreateCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass, "createCustomCursor", "([IIIII)I");
|
||||
midDestroyCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass, "destroyCustomCursor", "(I)V");
|
||||
midGetContext = (*env)->GetStaticMethodID(env, mActivityClass, "getContext","()Landroid/content/Context;");
|
||||
midGetDisplayDPI = (*env)->GetStaticMethodID(env, mActivityClass, "getDisplayDPI", "()Landroid/util/DisplayMetrics;");
|
||||
midGetManifestEnvironmentVariables = (*env)->GetStaticMethodID(env, mActivityClass, "getManifestEnvironmentVariables", "()Z");
|
||||
|
|
@ -591,12 +598,12 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
|
|||
midMinimizeWindow = (*env)->GetStaticMethodID(env, mActivityClass, "minimizeWindow","()V");
|
||||
midOpenURL = (*env)->GetStaticMethodID(env, mActivityClass, "openURL", "(Ljava/lang/String;)I");
|
||||
midRequestPermission = (*env)->GetStaticMethodID(env, mActivityClass, "requestPermission", "(Ljava/lang/String;I)V");
|
||||
midShowToast = (*env)->GetStaticMethodID(env, mActivityClass, "showToast", "(Ljava/lang/String;IIII)I");
|
||||
midSendMessage = (*env)->GetStaticMethodID(env, mActivityClass, "sendMessage", "(II)Z");
|
||||
midSetActivityTitle = (*env)->GetStaticMethodID(env, mActivityClass, "setActivityTitle","(Ljava/lang/String;)Z");
|
||||
midSetCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass, "setCustomCursor", "(I)Z");
|
||||
midSetOrientation = (*env)->GetStaticMethodID(env, mActivityClass, "setOrientation","(IIZLjava/lang/String;)V");
|
||||
midSetRelativeMouseEnabled = (*env)->GetStaticMethodID(env, mActivityClass, "setRelativeMouseEnabled", "(Z)Z");
|
||||
midSetSurfaceViewFormat = (*env)->GetStaticMethodID(env, mActivityClass, "setSurfaceViewFormat","(I)V");
|
||||
midSetSystemCursor = (*env)->GetStaticMethodID(env, mActivityClass, "setSystemCursor", "(I)Z");
|
||||
midSetWindowStyle = (*env)->GetStaticMethodID(env, mActivityClass, "setWindowStyle","(Z)V");
|
||||
midShouldMinimizeOnFocusLoss = (*env)->GetStaticMethodID(env, mActivityClass, "shouldMinimizeOnFocusLoss","()Z");
|
||||
|
|
@ -607,6 +614,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
|
|||
!midClipboardHasText ||
|
||||
!midClipboardSetText ||
|
||||
!midCreateCustomCursor ||
|
||||
!midDestroyCustomCursor ||
|
||||
!midGetContext ||
|
||||
!midGetDisplayDPI ||
|
||||
!midGetManifestEnvironmentVariables ||
|
||||
|
|
@ -621,12 +629,12 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
|
|||
!midMinimizeWindow ||
|
||||
!midOpenURL ||
|
||||
!midRequestPermission ||
|
||||
!midShowToast ||
|
||||
!midSendMessage ||
|
||||
!midSetActivityTitle ||
|
||||
!midSetCustomCursor ||
|
||||
!midSetOrientation ||
|
||||
!midSetRelativeMouseEnabled ||
|
||||
!midSetSurfaceViewFormat ||
|
||||
!midSetSystemCursor ||
|
||||
!midSetWindowStyle ||
|
||||
!midShouldMinimizeOnFocusLoss ||
|
||||
|
|
@ -842,11 +850,11 @@ retry:
|
|||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetScreenResolution)(
|
||||
JNIEnv *env, jclass jcls,
|
||||
jint surfaceWidth, jint surfaceHeight,
|
||||
jint deviceWidth, jint deviceHeight, jint format, jfloat rate)
|
||||
jint deviceWidth, jint deviceHeight, jfloat rate)
|
||||
{
|
||||
SDL_LockMutex(Android_ActivityMutex);
|
||||
|
||||
Android_SetScreenResolution(surfaceWidth, surfaceHeight, deviceWidth, deviceHeight, format, rate);
|
||||
Android_SetScreenResolution(surfaceWidth, surfaceHeight, deviceWidth, deviceHeight, rate);
|
||||
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
}
|
||||
|
|
@ -1001,6 +1009,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(JNIEnv *env, j
|
|||
{
|
||||
SDL_LockMutex(Android_ActivityMutex);
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
if (Android_Window)
|
||||
{
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
|
|
@ -1013,6 +1022,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(JNIEnv *env, j
|
|||
|
||||
/* GL Context handling is done in the event loop because this function is run from the Java thread */
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
}
|
||||
|
|
@ -1043,10 +1053,12 @@ retry:
|
|||
}
|
||||
}
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
if (data->egl_surface != EGL_NO_SURFACE) {
|
||||
SDL_EGL_DestroySurface(_this, data->egl_surface);
|
||||
data->egl_surface = EGL_NO_SURFACE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data->native_window) {
|
||||
ANativeWindow_release(data->native_window);
|
||||
|
|
@ -1306,6 +1318,19 @@ JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)(
|
|||
return result;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL SDL_JAVA_INTERFACE(nativeGetHintBoolean)(
|
||||
JNIEnv *env, jclass cls,
|
||||
jstring name, jboolean default_value)
|
||||
{
|
||||
jboolean result;
|
||||
|
||||
const char *utfname = (*env)->GetStringUTFChars(env, name, NULL);
|
||||
result = SDL_GetHintBoolean(utfname, default_value);
|
||||
(*env)->ReleaseStringUTFChars(env, name, utfname);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)(
|
||||
JNIEnv *env, jclass cls,
|
||||
jstring name, jstring value)
|
||||
|
|
@ -1381,26 +1406,6 @@ ANativeWindow* Android_JNI_GetNativeWindow(void)
|
|||
return anw;
|
||||
}
|
||||
|
||||
void Android_JNI_SetSurfaceViewFormat(int format)
|
||||
{
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
int new_format = 0;
|
||||
|
||||
/* Format from android/native_window.h,
|
||||
* convert to temporary arbitrary values,
|
||||
* then to java PixelFormat */
|
||||
if (format == WINDOW_FORMAT_RGBA_8888) {
|
||||
new_format = 1;
|
||||
} else if (format == WINDOW_FORMAT_RGBX_8888) {
|
||||
new_format = 2;
|
||||
} else if (format == WINDOW_FORMAT_RGB_565) {
|
||||
/* Default */
|
||||
new_format = 0;
|
||||
}
|
||||
|
||||
(*env)->CallStaticVoidMethod(env, mActivityClass, midSetSurfaceViewFormat, new_format);
|
||||
}
|
||||
|
||||
void Android_JNI_SetActivityTitle(const char *title)
|
||||
{
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
|
|
@ -2125,6 +2130,15 @@ void Android_JNI_HapticStop(int device_id)
|
|||
/* See SDLActivity.java for constants. */
|
||||
#define COMMAND_SET_KEEP_SCREEN_ON 5
|
||||
|
||||
|
||||
int SDL_AndroidSendMessage(Uint32 command, int param)
|
||||
{
|
||||
if (command >= 0x8000) {
|
||||
return Android_JNI_SendMessage(command, param);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* sends message to be handled on the UI event dispatch thread */
|
||||
int Android_JNI_SendMessage(int command, int param)
|
||||
{
|
||||
|
|
@ -2468,6 +2482,11 @@ SDL_bool SDL_AndroidRequestPermission(const char *permission)
|
|||
return Android_JNI_RequestPermission(permission);
|
||||
}
|
||||
|
||||
int SDL_AndroidShowToast(const char* message, int duration, int gravity, int xOffset, int yOffset)
|
||||
{
|
||||
return Android_JNI_ShowToast(message, duration, gravity, xOffset, yOffset);
|
||||
}
|
||||
|
||||
void Android_JNI_GetManifestEnvironmentVariables(void)
|
||||
{
|
||||
if (!mActivityClass || !midGetManifestEnvironmentVariables) {
|
||||
|
|
@ -2500,6 +2519,12 @@ int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y)
|
|||
return custom_cursor;
|
||||
}
|
||||
|
||||
void Android_JNI_DestroyCustomCursor(int cursorID)
|
||||
{
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
(*env)->CallStaticVoidMethod(env, mActivityClass, midDestroyCustomCursor, cursorID);
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_bool Android_JNI_SetCustomCursor(int cursorID)
|
||||
{
|
||||
|
|
@ -2528,23 +2553,34 @@ SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled)
|
|||
SDL_bool Android_JNI_RequestPermission(const char *permission)
|
||||
{
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
const int requestCode = 1;
|
||||
const int requestCode = 1;
|
||||
|
||||
/* Wait for any pending request on another thread */
|
||||
while (SDL_AtomicGet(&bPermissionRequestPending) == SDL_TRUE) {
|
||||
SDL_Delay(10);
|
||||
}
|
||||
SDL_AtomicSet(&bPermissionRequestPending, SDL_TRUE);
|
||||
/* Wait for any pending request on another thread */
|
||||
while (SDL_AtomicGet(&bPermissionRequestPending) == SDL_TRUE) {
|
||||
SDL_Delay(10);
|
||||
}
|
||||
SDL_AtomicSet(&bPermissionRequestPending, SDL_TRUE);
|
||||
|
||||
jstring jpermission = (*env)->NewStringUTF(env, permission);
|
||||
(*env)->CallStaticVoidMethod(env, mActivityClass, midRequestPermission, jpermission, requestCode);
|
||||
(*env)->DeleteLocalRef(env, jpermission);
|
||||
|
||||
/* Wait for the request to complete */
|
||||
while (SDL_AtomicGet(&bPermissionRequestPending) == SDL_TRUE) {
|
||||
SDL_Delay(10);
|
||||
}
|
||||
return bPermissionRequestResult;
|
||||
/* Wait for the request to complete */
|
||||
while (SDL_AtomicGet(&bPermissionRequestPending) == SDL_TRUE) {
|
||||
SDL_Delay(10);
|
||||
}
|
||||
return bPermissionRequestResult;
|
||||
}
|
||||
|
||||
/* Show toast notification */
|
||||
int Android_JNI_ShowToast(const char* message, int duration, int gravity, int xOffset, int yOffset)
|
||||
{
|
||||
int result = 0;
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
jstring jmessage = (*env)->NewStringUTF(env, message);
|
||||
result = (*env)->CallStaticIntMethod(env, mActivityClass, midShowToast, jmessage, duration, gravity, xOffset, yOffset);
|
||||
(*env)->DeleteLocalRef(env, jmessage);
|
||||
return result;
|
||||
}
|
||||
|
||||
int Android_JNI_GetLocale(char *buf, size_t buflen)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -47,7 +47,6 @@ extern void Android_JNI_ShowTextInput(SDL_Rect *inputRect);
|
|||
extern void Android_JNI_HideTextInput(void);
|
||||
extern SDL_bool Android_JNI_IsScreenKeyboardShown(void);
|
||||
extern ANativeWindow* Android_JNI_GetNativeWindow(void);
|
||||
extern void Android_JNI_SetSurfaceViewFormat(int format);
|
||||
|
||||
extern SDL_DisplayOrientation Android_JNI_GetDisplayOrientation(void);
|
||||
extern int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi);
|
||||
|
|
@ -119,6 +118,7 @@ int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *bu
|
|||
|
||||
/* Cursor support */
|
||||
int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y);
|
||||
void Android_JNI_DestroyCustomCursor(int cursorID);
|
||||
SDL_bool Android_JNI_SetCustomCursor(int cursorID);
|
||||
SDL_bool Android_JNI_SetSystemCursor(int cursorID);
|
||||
|
||||
|
|
@ -129,6 +129,9 @@ SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled);
|
|||
/* Request permission */
|
||||
SDL_bool Android_JNI_RequestPermission(const char *permission);
|
||||
|
||||
/* Show toast notification */
|
||||
int Android_JNI_ShowToast(const char* message, int duration, int gravity, int xOffset, int yOffset);
|
||||
|
||||
int Android_JNI_OpenURL(const char *url);
|
||||
|
||||
int SDL_GetAndroidSDKVersion(void);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -87,15 +87,18 @@ static int fatal_signals[] =
|
|||
|
||||
static void kbd_cleanup(void)
|
||||
{
|
||||
struct mouse_info mData;
|
||||
SDL_EVDEV_keyboard_state* kbd = kbd_cleanup_state;
|
||||
if (kbd == NULL) {
|
||||
return;
|
||||
}
|
||||
kbd_cleanup_state = NULL;
|
||||
|
||||
SDL_zero(mData);
|
||||
mData.operation = MOUSE_SHOW;
|
||||
ioctl(kbd->keyboard_fd, KDSKBMODE, kbd->old_kbd_mode);
|
||||
if (kbd->keyboard_fd != kbd->console_fd) close(kbd->keyboard_fd);
|
||||
ioctl(kbd->console_fd, CONS_SETKBD, (unsigned long)(kbd->kbInfo->kb_index));
|
||||
ioctl(kbd->console_fd, CONS_MOUSECTL, &mData);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -221,9 +224,12 @@ SDL_EVDEV_keyboard_state *
|
|||
SDL_EVDEV_kbd_init(void)
|
||||
{
|
||||
SDL_EVDEV_keyboard_state *kbd;
|
||||
struct mouse_info mData;
|
||||
char flag_state;
|
||||
char* devicePath;
|
||||
|
||||
SDL_zero(mData);
|
||||
mData.operation = MOUSE_HIDE;
|
||||
kbd = (SDL_EVDEV_keyboard_state *)SDL_calloc(1, sizeof(SDL_EVDEV_keyboard_state));
|
||||
if (!kbd) {
|
||||
return NULL;
|
||||
|
|
@ -232,7 +238,7 @@ SDL_EVDEV_kbd_init(void)
|
|||
kbd->npadch = -1;
|
||||
|
||||
/* This might fail if we're not connected to a tty (e.g. on the Steam Link) */
|
||||
kbd->keyboard_fd = kbd->console_fd = open("/dev/tty", O_RDONLY);
|
||||
kbd->keyboard_fd = kbd->console_fd = open("/dev/tty", O_RDONLY | O_CLOEXEC);
|
||||
|
||||
kbd->shift_state = 0;
|
||||
|
||||
|
|
@ -241,7 +247,8 @@ SDL_EVDEV_kbd_init(void)
|
|||
kbd->kbInfo = SDL_calloc(sizeof(keyboard_info_t), 1);
|
||||
|
||||
ioctl(kbd->console_fd, KDGKBINFO, kbd->kbInfo);
|
||||
|
||||
ioctl(kbd->console_fd, CONS_MOUSECTL, &mData);
|
||||
|
||||
if (ioctl(kbd->console_fd, KDGKBSTATE, &flag_state) == 0) {
|
||||
kbd->ledflagstate = flag_state;
|
||||
}
|
||||
|
|
@ -261,13 +268,13 @@ SDL_EVDEV_kbd_init(void)
|
|||
kbd->key_map = &keymap_default_us_acc;
|
||||
}
|
||||
/* Allow inhibiting keyboard mute with env. variable for debugging etc. */
|
||||
if (getenv("SDL_INPUT_FREEBSD_KEEP_KBD") == NULL) {
|
||||
if (SDL_getenv("SDL_INPUT_FREEBSD_KEEP_KBD") == NULL) {
|
||||
/* Take keyboard from console and open the actual keyboard device.
|
||||
* Ensures that the keystrokes do not leak through to the console.
|
||||
*/
|
||||
ioctl(kbd->console_fd, CONS_RELKBD, 1ul);
|
||||
asprintf(&devicePath, "/dev/kbd%d", kbd->kbInfo->kb_index);
|
||||
kbd->keyboard_fd = open(devicePath, O_WRONLY);
|
||||
SDL_asprintf(&devicePath, "/dev/kbd%d", kbd->kbInfo->kb_index);
|
||||
kbd->keyboard_fd = open(devicePath, O_WRONLY | O_CLOEXEC);
|
||||
if (kbd->keyboard_fd == -1)
|
||||
{
|
||||
// Give keyboard back.
|
||||
|
|
@ -281,7 +288,7 @@ SDL_EVDEV_kbd_init(void)
|
|||
if (!SDL_GetHintBoolean(SDL_HINT_NO_SIGNAL_HANDLERS, SDL_FALSE)) {
|
||||
kbd_register_emerg_cleanup(kbd);
|
||||
}
|
||||
free(devicePath);
|
||||
SDL_free(devicePath);
|
||||
}
|
||||
else kbd->keyboard_fd = kbd->console_fd;
|
||||
}
|
||||
|
|
@ -292,9 +299,14 @@ SDL_EVDEV_kbd_init(void)
|
|||
void
|
||||
SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *kbd)
|
||||
{
|
||||
struct mouse_info mData;
|
||||
|
||||
if (!kbd) {
|
||||
return;
|
||||
}
|
||||
SDL_zero(mData);
|
||||
mData.operation = MOUSE_SHOW;
|
||||
ioctl(kbd->console_fd, CONS_MOUSECTL, &mData);
|
||||
|
||||
kbd_unregister_emerg_cleanup();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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,7 +19,9 @@
|
|||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_dbus.h"
|
||||
#include "SDL_atomic.h"
|
||||
|
||||
#if SDL_USE_LIBDBUS
|
||||
/* we never link directly to libdbus. */
|
||||
|
|
@ -113,8 +115,12 @@ LoadDBUSLibrary(void)
|
|||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_DBus_Init(void)
|
||||
|
||||
static SDL_SpinLock spinlock_dbus_init = 0;
|
||||
|
||||
/* you must hold spinlock_dbus_init before calling this! */
|
||||
static void
|
||||
SDL_DBus_Init_Spinlocked(void)
|
||||
{
|
||||
static SDL_bool is_dbus_available = SDL_TRUE;
|
||||
if (!is_dbus_available) {
|
||||
|
|
@ -156,6 +162,14 @@ SDL_DBus_Init(void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDL_DBus_Init(void)
|
||||
{
|
||||
SDL_AtomicLock(&spinlock_dbus_init); /* make sure two threads can't init at same time, since this can happen before SDL_Init. */
|
||||
SDL_DBus_Init_Spinlocked();
|
||||
SDL_AtomicUnlock(&spinlock_dbus_init);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_DBus_Quit(void)
|
||||
{
|
||||
|
|
@ -352,8 +366,15 @@ SDL_DBus_ScreensaverInhibit(SDL_bool inhibit)
|
|||
const char *interface = "org.freedesktop.ScreenSaver";
|
||||
|
||||
if (inhibit) {
|
||||
const char *app = "My SDL application";
|
||||
const char *reason = "Playing a game";
|
||||
const char *app = SDL_GetHint(SDL_HINT_APP_NAME);
|
||||
const char *reason = SDL_GetHint(SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME);
|
||||
if (!app || !app[0]) {
|
||||
app = "My SDL application";
|
||||
}
|
||||
if (!reason || !reason[0]) {
|
||||
reason = "Playing a game";
|
||||
}
|
||||
|
||||
if (!SDL_DBus_CallMethod(node, path, interface, "Inhibit",
|
||||
DBUS_TYPE_STRING, &app, DBUS_TYPE_STRING, &reason, DBUS_TYPE_INVALID,
|
||||
DBUS_TYPE_UINT32, &screensaver_cookie, DBUS_TYPE_INVALID)) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -57,6 +57,10 @@
|
|||
#define ABS_MT_TRACKING_ID 0x39
|
||||
#define ABS_MT_PRESSURE 0x3a
|
||||
#endif
|
||||
#ifndef REL_WHEEL_HI_RES
|
||||
#define REL_WHEEL_HI_RES 0x0b
|
||||
#define REL_HWHEEL_HI_RES 0x0c
|
||||
#endif
|
||||
|
||||
typedef struct SDL_evdevlist_item
|
||||
{
|
||||
|
|
@ -92,6 +96,9 @@ typedef struct SDL_evdevlist_item
|
|||
|
||||
} * touchscreen_data;
|
||||
|
||||
SDL_bool high_res_wheel;
|
||||
SDL_bool high_res_hwheel;
|
||||
|
||||
struct SDL_evdevlist_item *next;
|
||||
} SDL_evdevlist_item;
|
||||
|
||||
|
|
@ -218,8 +225,14 @@ static void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_event, int udev_cl
|
|||
|
||||
switch(udev_event) {
|
||||
case SDL_UDEV_DEVICEADDED:
|
||||
if (!(udev_class & (SDL_UDEV_DEVICE_MOUSE | SDL_UDEV_DEVICE_KEYBOARD |
|
||||
SDL_UDEV_DEVICE_TOUCHSCREEN)))
|
||||
if (udev_class & SDL_UDEV_DEVICE_TOUCHPAD) {
|
||||
udev_class |= SDL_UDEV_DEVICE_TOUCHSCREEN;
|
||||
}
|
||||
|
||||
if (!(udev_class & (SDL_UDEV_DEVICE_MOUSE | SDL_UDEV_DEVICE_KEYBOARD | SDL_UDEV_DEVICE_TOUCHSCREEN)))
|
||||
return;
|
||||
|
||||
if ((udev_class & SDL_UDEV_DEVICE_JOYSTICK))
|
||||
return;
|
||||
|
||||
SDL_EVDEV_device_added(dev_path, udev_class);
|
||||
|
|
@ -372,10 +385,20 @@ SDL_EVDEV_Poll(void)
|
|||
SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_TRUE, 0, events[i].value);
|
||||
break;
|
||||
case REL_WHEEL:
|
||||
SDL_SendMouseWheel(mouse->focus, mouse->mouseID, 0, events[i].value, SDL_MOUSEWHEEL_NORMAL);
|
||||
if (!item->high_res_wheel)
|
||||
SDL_SendMouseWheel(mouse->focus, mouse->mouseID, 0, events[i].value, SDL_MOUSEWHEEL_NORMAL);
|
||||
break;
|
||||
case REL_WHEEL_HI_RES:
|
||||
SDL_assert(item->high_res_wheel);
|
||||
SDL_SendMouseWheel(mouse->focus, mouse->mouseID, 0, events[i].value / 120.0f, SDL_MOUSEWHEEL_NORMAL);
|
||||
break;
|
||||
case REL_HWHEEL:
|
||||
SDL_SendMouseWheel(mouse->focus, mouse->mouseID, events[i].value, 0, SDL_MOUSEWHEEL_NORMAL);
|
||||
if (!item->high_res_hwheel)
|
||||
SDL_SendMouseWheel(mouse->focus, mouse->mouseID, events[i].value, 0, SDL_MOUSEWHEEL_NORMAL);
|
||||
break;
|
||||
case REL_HWHEEL_HI_RES:
|
||||
SDL_assert(item->high_res_hwheel);
|
||||
SDL_SendMouseWheel(mouse->focus, mouse->mouseID, events[i].value / 120.0f, 0, SDL_MOUSEWHEEL_NORMAL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -709,6 +732,7 @@ SDL_EVDEV_device_added(const char *dev_path, int udev_class)
|
|||
{
|
||||
int ret;
|
||||
SDL_evdevlist_item *item;
|
||||
unsigned long relbit[NBITS(REL_MAX)] = { 0 };
|
||||
|
||||
/* Check to make sure it's not already in list. */
|
||||
for (item = _this->first; item != NULL; item = item->next) {
|
||||
|
|
@ -722,7 +746,7 @@ SDL_EVDEV_device_added(const char *dev_path, int udev_class)
|
|||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
item->fd = open(dev_path, O_RDONLY | O_NONBLOCK);
|
||||
item->fd = open(dev_path, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
|
||||
if (item->fd < 0) {
|
||||
SDL_free(item);
|
||||
return SDL_SetError("Unable to open %s", dev_path);
|
||||
|
|
@ -735,11 +759,17 @@ SDL_EVDEV_device_added(const char *dev_path, int udev_class)
|
|||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
if (ioctl(item->fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0) {
|
||||
item->high_res_wheel = test_bit(REL_WHEEL_HI_RES, relbit);
|
||||
item->high_res_hwheel = test_bit(REL_HWHEEL_HI_RES, relbit);
|
||||
}
|
||||
|
||||
if (udev_class & SDL_UDEV_DEVICE_TOUCHSCREEN) {
|
||||
item->is_touchscreen = 1;
|
||||
|
||||
if ((ret = SDL_EVDEV_init_touchscreen(item)) < 0) {
|
||||
close(item->fd);
|
||||
SDL_free(item->path);
|
||||
SDL_free(item);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 2020 Collabora Ltd.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
|
|
@ -24,12 +24,34 @@
|
|||
|
||||
#if HAVE_LIBUDEV_H || defined(SDL_JOYSTICK_LINUX)
|
||||
|
||||
/* missing defines in older Linux kernel headers */
|
||||
#ifndef BTN_TRIGGER_HAPPY
|
||||
#define BTN_TRIGGER_HAPPY 0x2c0
|
||||
#endif
|
||||
#ifndef BTN_DPAD_UP
|
||||
#define BTN_DPAD_UP 0x220
|
||||
#endif
|
||||
#ifndef KEY_ALS_TOGGLE
|
||||
#define KEY_ALS_TOGGLE 0x230
|
||||
#endif
|
||||
|
||||
extern int
|
||||
SDL_EVDEV_GuessDeviceClass(unsigned long bitmask_ev[NBITS(EV_MAX)],
|
||||
unsigned long bitmask_abs[NBITS(ABS_MAX)],
|
||||
unsigned long bitmask_key[NBITS(KEY_MAX)],
|
||||
unsigned long bitmask_rel[NBITS(REL_MAX)])
|
||||
{
|
||||
struct range {
|
||||
unsigned start;
|
||||
unsigned end;
|
||||
};
|
||||
|
||||
/* key code ranges above BTN_MISC (start is inclusive, stop is exclusive)*/
|
||||
static const struct range high_key_blocks[] = {
|
||||
{ KEY_OK, BTN_DPAD_UP },
|
||||
{ KEY_ALS_TOGGLE, BTN_TRIGGER_HAPPY }
|
||||
};
|
||||
|
||||
int devclass = 0;
|
||||
unsigned long keyboard_mask;
|
||||
|
||||
|
|
@ -56,7 +78,7 @@ SDL_EVDEV_GuessDeviceClass(unsigned long bitmask_ev[NBITS(EV_MAX)],
|
|||
if (test_bit(BTN_STYLUS, bitmask_key) || test_bit(BTN_TOOL_PEN, bitmask_key)) {
|
||||
; /* ID_INPUT_TABLET */
|
||||
} else if (test_bit(BTN_TOOL_FINGER, bitmask_key) && !test_bit(BTN_TOOL_PEN, bitmask_key)) {
|
||||
; /* ID_INPUT_TOUCHPAD */
|
||||
devclass |= SDL_UDEV_DEVICE_TOUCHPAD; /* ID_INPUT_TOUCHPAD */
|
||||
} else if (test_bit(BTN_MOUSE, bitmask_key)) {
|
||||
devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */
|
||||
} else if (test_bit(BTN_TOUCH, bitmask_key)) {
|
||||
|
|
@ -86,6 +108,31 @@ SDL_EVDEV_GuessDeviceClass(unsigned long bitmask_ev[NBITS(EV_MAX)],
|
|||
devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */
|
||||
}
|
||||
|
||||
if (test_bit(EV_KEY, bitmask_ev)) {
|
||||
unsigned i;
|
||||
unsigned long found = 0;
|
||||
|
||||
for (i = 0; i < BTN_MISC/BITS_PER_LONG; ++i) {
|
||||
found |= bitmask_key[i];
|
||||
}
|
||||
/* If there are no keys in the lower block, check the higher blocks */
|
||||
if (!found) {
|
||||
unsigned block;
|
||||
for (block = 0; block < (sizeof(high_key_blocks) / sizeof(struct range)); ++block) {
|
||||
for (i = high_key_blocks[block].start; i < high_key_blocks[block].end; ++i) {
|
||||
if (test_bit(i, bitmask_key)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found > 0) {
|
||||
devclass |= SDL_UDEV_DEVICE_KEYBOARD; /* ID_INPUT_KEY */
|
||||
}
|
||||
}
|
||||
|
||||
/* the first 32 bits are ESC, numbers, and Q to D; if we have any of
|
||||
* those, consider it a keyboard device; do not test KEY_RESERVED, though */
|
||||
keyboard_mask = 0xFFFFFFFE;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 2020 Collabora Ltd.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
|
|
@ -38,7 +38,8 @@ typedef enum
|
|||
SDL_UDEV_DEVICE_JOYSTICK = 0x0004,
|
||||
SDL_UDEV_DEVICE_SOUND = 0x0008,
|
||||
SDL_UDEV_DEVICE_TOUCHSCREEN = 0x0010,
|
||||
SDL_UDEV_DEVICE_ACCELEROMETER = 0x0020
|
||||
SDL_UDEV_DEVICE_ACCELEROMETER = 0x0020,
|
||||
SDL_UDEV_DEVICE_TOUCHPAD = 0x0040
|
||||
} SDL_UDEV_deviceclass;
|
||||
|
||||
#define BITS_PER_LONG (sizeof(unsigned long) * 8)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -219,7 +219,7 @@ static void kbd_cleanup(void)
|
|||
ioctl(kbd->console_fd, KDSKBMODE, kbd->old_kbd_mode);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SDL_EVDEV_kbd_reraise_signal(int sig)
|
||||
{
|
||||
raise(sig);
|
||||
|
|
@ -354,7 +354,7 @@ SDL_EVDEV_kbd_init(void)
|
|||
kbd->npadch = -1;
|
||||
|
||||
/* This might fail if we're not connected to a tty (e.g. on the Steam Link) */
|
||||
kbd->console_fd = open("/dev/tty", O_RDONLY);
|
||||
kbd->console_fd = open("/dev/tty", O_RDONLY | O_CLOEXEC);
|
||||
|
||||
if (ioctl(kbd->console_fd, TIOCLINUX, shift_state) == 0) {
|
||||
kbd->shift_state = *shift_state;
|
||||
|
|
@ -386,7 +386,7 @@ SDL_EVDEV_kbd_init(void)
|
|||
}
|
||||
|
||||
/* Allow inhibiting keyboard mute with env. variable for debugging etc. */
|
||||
if (getenv("SDL_INPUT_LINUX_KEEP_KBD") == NULL) {
|
||||
if (SDL_getenv("SDL_INPUT_LINUX_KEEP_KBD") == NULL) {
|
||||
/* Mute the keyboard so keystrokes only generate evdev events
|
||||
* and do not leak through to the console
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
@ -84,7 +84,8 @@ GetAppName()
|
|||
return SDL_strdup("SDL_App");
|
||||
}
|
||||
|
||||
size_t Fcitx_GetPreeditString(SDL_DBusContext *dbus, DBusMessage *msg, char **ret) {
|
||||
static size_t
|
||||
Fcitx_GetPreeditString(SDL_DBusContext *dbus, DBusMessage *msg, char **ret) {
|
||||
char *text = NULL, *subtext;
|
||||
size_t text_bytes = 0;
|
||||
DBusMessageIter iter, array, sub;
|
||||
|
|
@ -204,7 +205,7 @@ Fcitx_SetCapabilities(void *data,
|
|||
const char *internal_editing)
|
||||
{
|
||||
FcitxClient *client = (FcitxClient *)data;
|
||||
Uint32 caps = 0;
|
||||
Uint64 caps = 0;
|
||||
if (!client->ic_path) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 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
|
||||
|
|
|
|||
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