early-access version 2835

This commit is contained in:
pineappleEA
2022-07-15 04:00:50 +02:00
parent 5c0ee5eba6
commit 0e7aef7e36
1173 changed files with 55320 additions and 18881 deletions

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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,6 +47,7 @@
#include "SDL_bits.h"
#include "SDL_revision.h"
#include "SDL_assert_c.h"
#include "SDL_log_c.h"
#include "events/SDL_events_c.h"
#include "haptic/SDL_haptic_c.h"
#include "joystick/SDL_joystick_c.h"
@@ -61,6 +62,26 @@ extern int SDL_HelperWindowCreate(void);
extern int SDL_HelperWindowDestroy(void);
#endif
#ifdef SDL_BUILD_MAJOR_VERSION
SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MAJOR_VERSION,
SDL_MAJOR_VERSION == SDL_BUILD_MAJOR_VERSION);
SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MINOR_VERSION,
SDL_MINOR_VERSION == SDL_BUILD_MINOR_VERSION);
SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MICRO_VERSION,
SDL_PATCHLEVEL == SDL_BUILD_MICRO_VERSION);
#endif
SDL_COMPILE_TIME_ASSERT(SDL_MAJOR_VERSION_min, SDL_MAJOR_VERSION >= 0);
/* Limited only by the need to fit in SDL_version */
SDL_COMPILE_TIME_ASSERT(SDL_MAJOR_VERSION_max, SDL_MAJOR_VERSION <= 255);
SDL_COMPILE_TIME_ASSERT(SDL_MINOR_VERSION_min, SDL_MINOR_VERSION >= 0);
/* Limited only by the need to fit in SDL_version */
SDL_COMPILE_TIME_ASSERT(SDL_MINOR_VERSION_max, SDL_MINOR_VERSION <= 255);
SDL_COMPILE_TIME_ASSERT(SDL_PATCHLEVEL_min, SDL_PATCHLEVEL >= 0);
/* Limited by its encoding in SDL_VERSIONNUM and in the ABI versions */
SDL_COMPILE_TIME_ASSERT(SDL_PATCHLEVEL_max, SDL_PATCHLEVEL <= 99);
/* This is not declared in any header, although it is shared between some
parts of SDL, because we don't want anything calling it without an
@@ -153,10 +174,11 @@ 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?");
}
SDL_LogInit();
/* Clear the error message */
SDL_ClearError();
@@ -169,8 +191,8 @@ SDL_InitSubSystem(Uint32 flags)
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;
}
@@ -208,7 +230,7 @@ SDL_InitSubSystem(Uint32 flags)
/* 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) {
goto quit_and_error;
@@ -317,6 +339,8 @@ SDL_InitSubSystem(Uint32 flags)
#endif
}
(void) flags_initialized; /* make static analysis happy, since this only gets used in error cases. */
return (0);
quit_and_error:
@@ -402,7 +426,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();
@@ -469,12 +493,13 @@ SDL_Quit(void)
SDL_ClearHints();
SDL_AssertionsQuit();
SDL_LogResetPriorities();
#if SDL_USE_LIBDBUS
SDL_DBus_Quit();
#endif
SDL_LogQuit();
/* Now that every subsystem has been quit, we reset the subsystem refcount
* and the list of initialized subsystems.
*/
@@ -558,10 +583,14 @@ SDL_GetPlatform(void)
return "tvOS";
#elif __IPHONEOS__
return "iOS";
#elif __PS2__
return "PlayStation 2";
#elif __PSP__
return "PlayStation Portable";
#elif __VITA__
return "PlayStation Vita";
#elif __NGAGE__
return "Nokia N-Gage";
#else
return "Unknown (see SDL_platform.h)";
#endif

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -45,6 +45,8 @@
#include <emscripten.h>
#endif
/* The size of the stack buffer to use for rendering assert messages. */
#define SDL_MAX_ASSERT_MESSAGE_STACK 256
static SDL_assert_state SDLCALL
SDL_PromptAssertion(const SDL_assert_data *data, void *userdata);
@@ -88,6 +90,20 @@ static void SDL_AddAssertionToReport(SDL_assert_data *data)
}
}
#ifdef __WIN32__
#define ENDLINE "\r\n"
#else
#define ENDLINE "\n"
#endif
static int SDL_RenderAssertMessage(char *buf, size_t buf_len, const SDL_assert_data *data) {
return SDL_snprintf(buf, buf_len,
"Assertion failure at %s (%s:%d), triggered %u %s:" ENDLINE " '%s'",
data->function, data->filename, data->linenum,
data->trigger_count, (data->trigger_count == 1) ? "time" : "times",
data->condition
);
}
static void SDL_GenerateAssertionReport(void)
{
@@ -137,16 +153,9 @@ static SDL_NORETURN void SDL_AbortAssertion(void)
SDL_ExitProcess(42);
}
static SDL_assert_state SDLCALL
SDL_PromptAssertion(const SDL_assert_data *data, void *userdata)
{
#ifdef __WIN32__
#define ENDLINE "\r\n"
#else
#define ENDLINE "\n"
#endif
const char *envr;
SDL_assert_state state = SDL_ASSERTION_ABORT;
SDL_Window *window;
@@ -160,30 +169,46 @@ SDL_PromptAssertion(const SDL_assert_data *data, void *userdata)
{ SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT,
SDL_ASSERTION_ALWAYS_IGNORE, "Always Ignore" }
};
char *message;
int selected;
char stack_buf[SDL_MAX_ASSERT_MESSAGE_STACK];
char *message = stack_buf;
size_t buf_len = sizeof(stack_buf);
int len;
(void) userdata; /* unused in default handler. */
/* !!! FIXME: why is this using SDL_stack_alloc and not just "char message[SDL_MAX_LOG_MESSAGE];" ? */
message = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE);
if (!message) {
/* Uh oh, we're in real trouble now... */
/* Assume the output will fit... */
len = SDL_RenderAssertMessage(message, buf_len, data);
/* .. and if it didn't, try to allocate as much room as we actually need. */
if (len >= (int)buf_len) {
if (SDL_size_add_overflow(len, 1, &buf_len) == 0) {
message = (char *)SDL_malloc(buf_len);
if (message) {
len = SDL_RenderAssertMessage(message, buf_len, data);
} else {
message = stack_buf;
}
}
}
/* Something went very wrong */
if (len < 0) {
if (message != stack_buf) {
SDL_free(message);
}
return SDL_ASSERTION_ABORT;
}
SDL_snprintf(message, SDL_MAX_LOG_MESSAGE,
"Assertion failure at %s (%s:%d), triggered %u %s:" ENDLINE
" '%s'",
data->function, data->filename, data->linenum,
data->trigger_count, (data->trigger_count == 1) ? "time" : "times",
data->condition);
debug_print("\n\n%s\n\n", message);
/* let env. variable override, so unit tests won't block in a GUI. */
envr = SDL_getenv("SDL_ASSERT");
if (envr != NULL) {
SDL_stack_free(message);
if (message != stack_buf) {
SDL_free(message);
}
if (SDL_strcmp(envr, "abort") == 0) {
return SDL_ASSERTION_ABORT;
@@ -301,7 +326,9 @@ SDL_PromptAssertion(const SDL_assert_data *data, void *userdata)
SDL_RestoreWindow(window);
}
SDL_stack_free(message);
if (message != stack_buf) {
SDL_free(message);
}
return state;
}

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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,8 +25,6 @@
#include "SDL_error.h"
#include "SDL_error_c.h"
#define SDL_ERRBUFIZE 1024
int
SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

91
externals/SDL/src/SDL_guid.c vendored Executable file
View File

@@ -0,0 +1,91 @@
/*
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"
#include "SDL_guid.h"
/* convert the guid to a printable string */
void SDL_GUIDToString(SDL_GUID guid, char *pszGUID, int cbGUID)
{
static const char k_rgchHexToASCII[] = "0123456789abcdef";
int i;
if ((pszGUID == NULL) || (cbGUID <= 0)) {
return;
}
for (i = 0; i < sizeof(guid.data) && i < (cbGUID-1)/2; i++) {
/* each input byte writes 2 ascii chars, and might write a null byte. */
/* If we don't have room for next input byte, stop */
unsigned char c = guid.data[i];
*pszGUID++ = k_rgchHexToASCII[c >> 4];
*pszGUID++ = k_rgchHexToASCII[c & 0x0F];
}
*pszGUID = '\0';
}
/*-----------------------------------------------------------------------------
* Purpose: Returns the 4 bit nibble for a hex character
* Input : c -
* Output : unsigned char
*-----------------------------------------------------------------------------*/
static unsigned char nibble(unsigned char c)
{
if ((c >= '0') && (c <= '9')) {
return (c - '0');
}
if ((c >= 'A') && (c <= 'F')) {
return (c - 'A' + 0x0a);
}
if ((c >= 'a') && (c <= 'f')) {
return (c - 'a' + 0x0a);
}
/* received an invalid character, and no real way to return an error */
/* AssertMsg1(false, "Q_nibble invalid hex character '%c' ", c); */
return 0;
}
/* convert the string version of a guid to the struct */
SDL_GUID SDL_GUIDFromString(const char *pchGUID)
{
SDL_GUID guid;
int maxoutputbytes= sizeof(guid);
size_t len = SDL_strlen(pchGUID);
Uint8 *p;
size_t i;
/* Make sure it's even */
len = (len) & ~0x1;
SDL_memset(&guid, 0x00, sizeof(guid));
p = (Uint8 *)&guid;
for (i = 0; (i < len) && ((p - (Uint8 *)&guid) < maxoutputbytes); i+=2, p++) {
*p = (nibble((unsigned char)pchGUID[i]) << 4) | nibble((unsigned char)pchGUID[i+1]);
}
return guid;
}

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -52,7 +52,7 @@ SDL_SetHintWithPriority(const char *name, const char *value,
SDL_Hint *hint;
SDL_HintWatch *entry;
if (!name || !value) {
if (!name) {
return SDL_FALSE;
}
@@ -66,7 +66,7 @@ SDL_SetHintWithPriority(const char *name, const char *value,
if (priority < hint->priority) {
return SDL_FALSE;
}
if (!hint->value || !value || SDL_strcmp(hint->value, value) != 0) {
if (((hint->value == NULL) != (value == NULL)) || (value && (SDL_strcmp(hint->value, value) != 0))) {
for (entry = hint->callbacks; entry; ) {
/* Save the next entry in case this one is deleted */
SDL_HintWatch *next = entry->next;
@@ -178,6 +178,12 @@ SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata)
return;
}
hint->name = SDL_strdup(name);
if (!hint->name) {
SDL_free(entry);
SDL_free(hint);
SDL_OutOfMemory();
return;
}
hint->value = NULL;
hint->priority = SDL_HINT_DEFAULT;
hint->callbacks = NULL;

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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,14 +43,14 @@
#if SDL_DYNAMIC_API
#include "dynapi/SDL_dynapi_overrides.h"
/* force DECLSPEC and SDLCALL off...it's all internal symbols now.
/* force DECLSPEC off...it's all internal symbols now.
These will have actual #defines during SDL_dynapi.c only */
#define DECLSPEC
#define SDLCALL
#endif
#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

93
externals/SDL/src/SDL_list.c vendored Executable file
View File

@@ -0,0 +1,93 @@
/*
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"
#include "SDL.h"
#include "./SDL_list.h"
/* Push */
int
SDL_ListAdd(SDL_ListNode **head, void *ent)
{
SDL_ListNode *node = SDL_malloc(sizeof (*node));
if (node == NULL) {
return SDL_OutOfMemory();
}
node->entry = ent;
node->next = *head;
*head = node;
return 0;
}
/* Pop from end as a FIFO (if add with SDL_ListAdd) */
void
SDL_ListPop(SDL_ListNode **head, void **ent)
{
SDL_ListNode **ptr = head;
/* Invalid or empty */
if (head == NULL || *head == NULL) {
return;
}
while ((*ptr)->next) {
ptr = &(*ptr)->next;
}
if (ent) {
*ent = (*ptr)->entry;
}
SDL_free(*ptr);
*ptr = NULL;
}
void
SDL_ListRemove(SDL_ListNode **head, void *ent)
{
SDL_ListNode **ptr = head;
while (*ptr) {
if ((*ptr)->entry == ent) {
SDL_ListNode *tmp = *ptr;
*ptr = (*ptr)->next;
SDL_free(tmp);
return;
}
ptr = &(*ptr)->next;
}
}
void
SDL_ListClear(SDL_ListNode **head)
{
SDL_ListNode *l = *head;
*head = NULL;
while (l) {
SDL_ListNode *tmp = l;
l = l->next;
SDL_free(tmp);
}
}
/* vi: set ts=4 sw=4 expandtab: */

39
externals/SDL/src/SDL_list.h vendored Executable file
View File

@@ -0,0 +1,39 @@
/*
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_list_h_
#define SDL_list_h_
typedef struct SDL_ListNode
{
void *entry;
struct SDL_ListNode *next;
} SDL_ListNode;
int SDL_ListAdd(SDL_ListNode **head, void *ent);
void SDL_ListPop(SDL_ListNode **head, void **ent);
void SDL_ListRemove(SDL_ListNode **head, void *ent);
void SDL_ListClear(SDL_ListNode **head);
#endif /* SDL_list_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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,6 +28,8 @@
#include "SDL_error.h"
#include "SDL_log.h"
#include "SDL_mutex.h"
#include "SDL_log_c.h"
#if HAVE_STDIO_H
#include <stdio.h>
@@ -37,6 +39,12 @@
#include <android/log.h>
#endif
#include "stdlib/SDL_vacopy.h"
/* The size of the stack buffer to use for rendering log messages. */
#define SDL_MAX_LOG_MESSAGE_STACK 256
#define DEFAULT_PRIORITY SDL_LOG_PRIORITY_CRITICAL
#define DEFAULT_ASSERT_PRIORITY SDL_LOG_PRIORITY_WARN
#define DEFAULT_APPLICATION_PRIORITY SDL_LOG_PRIORITY_INFO
@@ -59,6 +67,7 @@ static SDL_LogPriority SDL_application_priority = DEFAULT_APPLICATION_PRIORITY;
static SDL_LogPriority SDL_test_priority = DEFAULT_TEST_PRIORITY;
static SDL_LogOutputFunction SDL_log_function = SDL_LogOutput;
static void *SDL_log_userdata = NULL;
static SDL_mutex *log_function_mutex = NULL;
static const char *SDL_priority_prefixes[SDL_NUM_LOG_PRIORITIES] = {
NULL,
@@ -92,6 +101,24 @@ static int SDL_android_priority[SDL_NUM_LOG_PRIORITIES] = {
};
#endif /* __ANDROID__ */
void
SDL_LogInit(void)
{
if (!log_function_mutex) {
/* if this fails we'll try to continue without it. */
log_function_mutex = SDL_CreateMutex();
}
}
void
SDL_LogQuit(void)
{
SDL_LogResetPriorities();
if (log_function_mutex) {
SDL_DestroyMutex(log_function_mutex);
log_function_mutex = NULL;
}
}
void
SDL_LogSetAllPriority(SDL_LogPriority priority)
@@ -264,8 +291,11 @@ GetCategoryPrefix(int category)
void
SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list ap)
{
char *message;
size_t len;
char *message = NULL;
char stack_buf[SDL_MAX_LOG_MESSAGE_STACK];
size_t len_plus_term;
int len;
va_list aq;
/* Nothing to do if we don't have an output function */
if (!SDL_log_function) {
@@ -282,16 +312,33 @@ SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list
return;
}
/* !!! FIXME: why not just "char message[SDL_MAX_LOG_MESSAGE];" ? */
message = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE);
if (!message) {
return;
if (!log_function_mutex) {
/* this mutex creation can race if you log from two threads at startup. You should have called SDL_Init first! */
log_function_mutex = SDL_CreateMutex();
}
SDL_vsnprintf(message, SDL_MAX_LOG_MESSAGE, fmt, ap);
/* Render into stack buffer */
va_copy(aq, ap);
len = SDL_vsnprintf(stack_buf, sizeof(stack_buf), fmt, aq);
va_end(aq);
if (len < 0)
return;
/* If message truncated, allocate and re-render */
if (len >= sizeof(stack_buf) && SDL_size_add_overflow(len, 1, &len_plus_term) == 0) {
/* Allocate exactly what we need, including the zero-terminator */
message = (char *)SDL_malloc(len_plus_term);
if (!message)
return;
va_copy(aq, ap);
len = SDL_vsnprintf(message, len_plus_term, fmt, aq);
va_end(aq);
} else {
message = stack_buf;
}
/* Chop off final endline. */
len = SDL_strlen(message);
if ((len > 0) && (message[len-1] == '\n')) {
message[--len] = '\0';
if ((len > 0) && (message[len-1] == '\r')) { /* catch "\r\n", too. */
@@ -299,8 +346,20 @@ SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list
}
}
if (log_function_mutex) {
SDL_LockMutex(log_function_mutex);
}
SDL_log_function(SDL_log_userdata, category, priority, message);
SDL_stack_free(message);
if (log_function_mutex) {
SDL_UnlockMutex(log_function_mutex);
}
/* Free only if dynamically allocated */
if (message != stack_buf) {
SDL_free(message);
}
}
#if defined(__WIN32__) && !defined(HAVE_STDIO_H) && !defined(__WINRT__)
@@ -403,19 +462,12 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
#elif defined(__APPLE__) && (defined(SDL_VIDEO_DRIVER_COCOA) || defined(SDL_VIDEO_DRIVER_UIKIT))
/* Technically we don't need Cocoa/UIKit, but that's where this function is defined for now.
*/
extern void SDL_NSLog(const char *text);
extern void SDL_NSLog(const char *prefix, const char *text);
{
char *text;
/* !!! FIXME: why not just "char text[SDL_MAX_LOG_MESSAGE];" ? */
text = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE);
if (text) {
SDL_snprintf(text, SDL_MAX_LOG_MESSAGE, "%s: %s", SDL_priority_prefixes[priority], message);
SDL_NSLog(text);
SDL_stack_free(text);
return;
}
SDL_NSLog(SDL_priority_prefixes[priority], message);
return;
}
#elif defined(__PSP__)
#elif defined(__PSP__) || defined(__PS2__)
{
FILE* pFile;
pFile = fopen ("SDL_Log.txt", "a");

33
externals/SDL/src/SDL_log_c.h vendored Executable file
View File

@@ -0,0 +1,33 @@
/*
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"
/* This file defines useful function for working with SDL logging */
#ifndef SDL_log_c_h_
#define SDL_log_c_h_
extern void SDL_LogInit(void);
extern void SDL_LogQuit(void);
#endif /* SDL_log_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -40,6 +40,10 @@
#include <xmmintrin.h>
#endif
#if defined(PS2)
#include <kernel.h>
#endif
#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);
@@ -131,7 +135,19 @@ SDL_AtomicTryLock(SDL_SpinLock *lock)
#elif defined(__SOLARIS__) && !defined(_LP64)
/* Used for Solaris with non-gcc compilers. */
return (SDL_bool) ((int) atomic_cas_32((volatile uint32_t*)lock, 0, 1) == 0);
#elif defined(PS2)
uint32_t oldintr;
SDL_bool res = SDL_FALSE;
// disable interuption
oldintr = DIntr();
if (*lock == 0) {
*lock = 1;
res = SDL_TRUE;
}
// enable interuption
if(oldintr) { EIntr(); }
return res;
#else
#error Please implement for your platform.
return SDL_FALSE;

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -245,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. */
@@ -277,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. */
@@ -299,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();
}
@@ -334,11 +324,6 @@ SDL_AudioUnlockDevice_Default(SDL_AudioDevice * device)
}
}
static void
SDL_AudioLockOrUnlockDeviceWithNoMixerLock(SDL_AudioDevice * device)
{
}
static void
finish_audio_entry_points_init(void)
{
@@ -347,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) { \
@@ -364,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);
@@ -429,8 +404,7 @@ add_audio_device(const char *name, SDL_AudioSpec *spec, void *handle, SDL_AudioD
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);
@@ -483,7 +457,7 @@ 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, SDL_AudioSpec *spec, 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, spec, handle) : add_output_device(name, spec, handle);
if (device_index != -1) {
@@ -545,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;
@@ -723,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 */
@@ -786,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);
@@ -831,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) {
@@ -956,20 +925,18 @@ 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_GetCurrentAudioDriver()) {
SDL_AudioQuit(); /* shutdown driver if already running. */
}
SDL_zero(current_audio);
SDL_zeroa(open_devices);
/* Select the proper audio driver */
if (driver_name == NULL) {
driver_name = SDL_getenv("SDL_AUDIODRIVER");
driver_name = SDL_GetHint(SDL_HINT_AUDIODRIVER);
}
if (driver_name != NULL && *driver_name != 0) {
@@ -990,7 +957,7 @@ SDL_AudioInit(const char *driver_name)
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 = 1;
tried_to_init = SDL_TRUE;
SDL_zero(current_audio);
current_audio.name = bootstrap[i]->name;
current_audio.desc = bootstrap[i]->desc;
@@ -1007,7 +974,7 @@ SDL_AudioInit(const char *driver_name)
continue;
}
tried_to_init = 1;
tried_to_init = SDL_TRUE;
SDL_zero(current_audio);
current_audio.name = bootstrap[i]->name;
current_audio.desc = bootstrap[i]->desc;
@@ -1114,38 +1081,29 @@ 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_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);
}
if (retval == NULL) {
SDL_SetError("No such device");
SDL_assert(item != NULL);
retval = item->name;
} else {
SDL_InvalidParamError("index");
retval = NULL;
}
SDL_UnlockMutex(current_audio.detectionLock);
return retval;
}
@@ -1154,38 +1112,33 @@ SDL_GetAudioDeviceName(int index, int iscapture)
int
SDL_GetAudioDeviceSpec(int index, int iscapture, SDL_AudioSpec *spec)
{
SDL_AudioDeviceItem *item;
int i, retval;
if (spec == NULL) {
return SDL_InvalidParamError("spec");
}
SDL_zerop(spec);
if (!SDL_GetCurrentAudioDriver()) {
return SDL_SetError("Audio subsystem is not initialized");
}
if (iscapture && !current_audio.impl.HasCaptureSupport) {
return SDL_SetError("No capture support");
}
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);
SDL_memcpy(spec, &item->spec, sizeof(SDL_AudioSpec));
}
SDL_UnlockMutex(current_audio.detectionLock);
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 0;
return retval;
}
@@ -1421,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);
@@ -1430,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;
}
@@ -1555,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) {
@@ -1697,8 +1649,6 @@ SDL_AudioQuit(void)
#ifdef HAVE_LIBSAMPLERATE_H
UnloadLibSampleRate();
#endif
SDL_FreeResampleFilter();
}
#define NUM_FORMATS 10

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -70,11 +70,6 @@ extern SDL_AudioFilter SDL_Convert_F32_to_S16;
extern SDL_AudioFilter SDL_Convert_F32_to_U16;
extern SDL_AudioFilter SDL_Convert_F32_to_S32;
/* You need to call SDL_PrepareResampleFilter() before using the internal resampler.
SDL_AudioQuit() calls SDL_FreeResamplerFilter(), you should never call it yourself. */
extern int SDL_PrepareResampleFilter(void);
extern void SDL_FreeResampleFilter(void);
#endif /* SDL_audio_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -80,7 +80,7 @@ SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT * cvt, SDL_AudioFormat format)
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));
_mm_storeu_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_loadu_ps(src), _mm_loadu_ps(src+4)), divby2));
i -= 4; src += 8; dst += 4;
}
@@ -369,11 +369,11 @@ SDL_Convert71To51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
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) * two_thirds; /* FL */
dst[1] = (src[1] + surround_right_distributed) * two_thirds; /* FR */
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 */
dst[5] = (src[5] + surround_right_distributed) * two_thirds; /* BR */
}
cvt->len_cvt /= 8;
@@ -398,12 +398,12 @@ SDL_Convert71To61(SDL_AudioCVT * cvt, SDL_AudioFormat format)
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[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 */
dst[6] = src[0]; /* FL */
}
cvt->len_cvt /= 8;
@@ -428,13 +428,13 @@ SDL_Convert61To71(SDL_AudioCVT * cvt, SDL_AudioFormat format)
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[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 */
dst[6] = src[5]; /* SL */
dst[7] = src[3]; /* SR */
}
cvt->len_cvt /= 7;
@@ -459,12 +459,12 @@ SDL_Convert51To61(SDL_AudioCVT * cvt, SDL_AudioFormat format)
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[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 */
dst[6] = src[0]; /* FL */
}
cvt->len_cvt /= 6;
@@ -489,7 +489,7 @@ SDL_Convert61To51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
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[1] = src[2]; /* FR */
dst[2] = src[1]; /* FC */
dst[3] = src[0]; /* LFE */
dst[4] = src[5]; /* BL */
@@ -614,7 +614,7 @@ SDL_ConvertQuadTo51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
ce = (lf + rf) * 0.5f;
/* 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[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 */
@@ -704,105 +704,16 @@ SDL_Convert51To71(SDL_AudioCVT * cvt, SDL_AudioFormat format)
/* SDL's resampler uses a "bandlimited interpolation" algorithm:
https://ccrma.stanford.edu/~jos/resample/ */
#define RESAMPLER_ZERO_CROSSINGS 5
#define RESAMPLER_BITS_PER_SAMPLE 16
#define RESAMPLER_SAMPLES_PER_ZERO_CROSSING (1 << ((RESAMPLER_BITS_PER_SAMPLE / 2) + 1))
#define RESAMPLER_FILTER_SIZE ((RESAMPLER_SAMPLES_PER_ZERO_CROSSING * RESAMPLER_ZERO_CROSSINGS) + 1)
/* This is a "modified" bessel function, so you can't use POSIX j0() */
static double
bessel(const double x)
{
const double xdiv2 = x / 2.0;
double i0 = 1.0f;
double f = 1.0f;
int i = 1;
while (SDL_TRUE) {
const double diff = SDL_pow(xdiv2, i * 2) / SDL_pow(f, 2);
if (diff < 1.0e-21f) {
break;
}
i0 += diff;
i++;
f *= (double) i;
}
return i0;
}
/* build kaiser table with cardinal sine applied to it, and array of differences between elements. */
static void
kaiser_and_sinc(float *table, float *diffs, const int tablelen, const double beta)
{
const int lenm1 = tablelen - 1;
const int lenm1div2 = lenm1 / 2;
int i;
table[0] = 1.0f;
for (i = 1; i < tablelen; i++) {
const double kaiser = bessel(beta * SDL_sqrt(1.0 - SDL_pow(((i - lenm1) / 2.0) / lenm1div2, 2.0))) / bessel(beta);
table[tablelen - i] = (float) kaiser;
}
for (i = 1; i < tablelen; i++) {
const float x = (((float) i) / ((float) RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) * ((float) M_PI);
table[i] *= SDL_sinf(x) / x;
diffs[i - 1] = table[i] - table[i - 1];
}
diffs[lenm1] = 0.0f;
}
static SDL_SpinLock ResampleFilterSpinlock = 0;
static float *ResamplerFilter = NULL;
static float *ResamplerFilterDifference = NULL;
int
SDL_PrepareResampleFilter(void)
{
SDL_AtomicLock(&ResampleFilterSpinlock);
if (!ResamplerFilter) {
/* if dB > 50, beta=(0.1102 * (dB - 8.7)), according to Matlab. */
const double dB = 80.0;
const double beta = 0.1102 * (dB - 8.7);
const size_t alloclen = RESAMPLER_FILTER_SIZE * sizeof (float);
ResamplerFilter = (float *) SDL_malloc(alloclen);
if (!ResamplerFilter) {
SDL_AtomicUnlock(&ResampleFilterSpinlock);
return SDL_OutOfMemory();
}
ResamplerFilterDifference = (float *) SDL_malloc(alloclen);
if (!ResamplerFilterDifference) {
SDL_free(ResamplerFilter);
ResamplerFilter = NULL;
SDL_AtomicUnlock(&ResampleFilterSpinlock);
return SDL_OutOfMemory();
}
kaiser_and_sinc(ResamplerFilter, ResamplerFilterDifference, RESAMPLER_FILTER_SIZE, beta);
}
SDL_AtomicUnlock(&ResampleFilterSpinlock);
return 0;
}
void
SDL_FreeResampleFilter(void)
{
SDL_free(ResamplerFilter);
SDL_free(ResamplerFilterDifference);
ResamplerFilter = NULL;
ResamplerFilterDifference = NULL;
}
#include "SDL_audio_resampler_filter.h"
static int
ResamplerPadding(const int inrate, const int outrate)
{
if (inrate == outrate) {
return 0;
} else if (inrate > outrate) {
return (int) SDL_ceil(((float) (RESAMPLER_SAMPLES_PER_ZERO_CROSSING * inrate) / ((float) outrate)));
}
if (inrate > outrate) {
return (int) SDL_ceilf(((float) (RESAMPLER_SAMPLES_PER_ZERO_CROSSING * inrate) / ((float) outrate)));
}
return RESAMPLER_SAMPLES_PER_ZERO_CROSSING;
}
@@ -814,33 +725,38 @@ SDL_ResampleAudio(const int chans, const int inrate, const int outrate,
const float *inbuf, const int inbuflen,
float *outbuf, const int outbuflen)
{
const double finrate = (double) inrate;
const double outtimeincr = 1.0 / ((float) outrate);
const double ratio = ((float) outrate) / ((float) inrate);
/* Note that this used to be double, but it looks like we can get by with float in most cases at
almost twice the speed on Intel processors, and orders of magnitude more
on CPUs that need a software fallback for double calculations. */
typedef float ResampleFloatType;
const ResampleFloatType finrate = (ResampleFloatType) inrate;
const ResampleFloatType outtimeincr = ((ResampleFloatType) 1.0f) / ((ResampleFloatType) outrate);
const ResampleFloatType ratio = ((float) outrate) / ((float) inrate);
const int paddinglen = ResamplerPadding(inrate, outrate);
const int framelen = chans * (int)sizeof (float);
const int inframes = inbuflen / framelen;
const int wantedoutframes = (int) ((inbuflen / framelen) * ratio); /* outbuflen isn't total to write, it's total available. */
const int maxoutframes = outbuflen / framelen;
const int outframes = SDL_min(wantedoutframes, maxoutframes);
ResampleFloatType outtime = 0.0f;
float *dst = outbuf;
double outtime = 0.0;
int i, j, chan;
for (i = 0; i < outframes; i++) {
const int srcindex = (int) (outtime * inrate);
const double intime = ((double) srcindex) / finrate;
const double innexttime = ((double) (srcindex + 1)) / finrate;
const double interpolation1 = 1.0 - ((innexttime - outtime) / (innexttime - intime));
const ResampleFloatType intime = ((ResampleFloatType) srcindex) / finrate;
const ResampleFloatType innexttime = ((ResampleFloatType) (srcindex + 1)) / finrate;
const ResampleFloatType indeltatime = innexttime - intime;
const ResampleFloatType interpolation1 = (indeltatime == 0.0f) ? 1.0f : (1.0f - ((innexttime - outtime) / indeltatime));
const int filterindex1 = (int) (interpolation1 * RESAMPLER_SAMPLES_PER_ZERO_CROSSING);
const double interpolation2 = 1.0 - interpolation1;
const ResampleFloatType interpolation2 = 1.0f - interpolation1;
const int filterindex2 = (int) (interpolation2 * RESAMPLER_SAMPLES_PER_ZERO_CROSSING);
for (chan = 0; chan < chans; chan++) {
float outsample = 0.0f;
/* do this twice to calculate the sample, once for the "left wing" and then same for the right. */
/* !!! FIXME: do both wings in one loop */
for (j = 0; (filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) < RESAMPLER_FILTER_SIZE; j++) {
const int srcframe = srcindex - j;
/* !!! FIXME: we can bubble this conditional out of here by doing a pre loop. */
@@ -848,12 +764,15 @@ SDL_ResampleAudio(const int chans, const int inrate, const int outrate,
outsample += (float)(insample * (ResamplerFilter[filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)] + (interpolation1 * ResamplerFilterDifference[filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)])));
}
/* Do the right wing! */
for (j = 0; (filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) < RESAMPLER_FILTER_SIZE; j++) {
const int jsamples = j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING;
const int srcframe = srcindex + 1 + j;
/* !!! FIXME: we can bubble this conditional out of here by doing a post loop. */
const float insample = (srcframe >= inframes) ? rpadding[((srcframe - inframes) * chans) + chan] : inbuf[(srcframe * chans) + chan];
outsample += (float)(insample * (ResamplerFilter[filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)] + (interpolation2 * ResamplerFilterDifference[filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)])));
outsample += (float)(insample * (ResamplerFilter[filterindex2 + jsamples] + (interpolation2 * ResamplerFilterDifference[filterindex2 + jsamples])));
}
*(dst++) = outsample;
}
@@ -930,9 +849,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;
@@ -943,7 +860,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;
}
@@ -1020,7 +937,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;
}
@@ -1120,10 +1037,6 @@ SDL_BuildAudioResampleCVT(SDL_AudioCVT * cvt, const int dst_channels,
return SDL_SetError("No conversion available for these rates");
}
if (SDL_PrepareResampleFilter() < 0) {
return -1;
}
/* Update (cvt) with filter details... */
if (SDL_AddAudioCVTFilter(cvt, filter) < 0) {
return -1;
@@ -1217,19 +1130,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");
}
@@ -1273,6 +1193,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;
}
@@ -1666,6 +1589,7 @@ SDL_NewAudioStream(const SDL_AudioFormat src_format,
retval = (SDL_AudioStream *) SDL_calloc(1, sizeof (SDL_AudioStream));
if (!retval) {
SDL_OutOfMemory();
return NULL;
}
@@ -1733,13 +1657,6 @@ SDL_NewAudioStream(const SDL_AudioFormat src_format,
return NULL;
}
if (SDL_PrepareResampleFilter() < 0) {
SDL_free(retval->resampler_state);
retval->resampler_state = NULL;
SDL_FreeAudioStream(retval);
return NULL;
}
retval->resampler_func = SDL_ResampleAudioStream;
retval->reset_resampler_func = SDL_ResetAudioStreamResampler;
retval->cleanup_resampler_func = SDL_CleanupAudioStreamResampler;
@@ -1907,11 +1824,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");
}
@@ -2017,11 +1937,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");
}
@@ -2067,4 +1990,3 @@ SDL_FreeAudioStream(SDL_AudioStream *stream)
}
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -115,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;
@@ -125,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;
}
@@ -141,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) {
@@ -156,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;
}
}
@@ -168,14 +165,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[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) {
@@ -183,9 +180,7 @@ 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;
}
}
@@ -195,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;
}
}
@@ -219,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;
}
}
@@ -245,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--) {
@@ -271,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--) {

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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, SDL_AudioSpec *spec, 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;
@@ -178,8 +174,8 @@ 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. */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -685,7 +685,7 @@ MS_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
state.output.pos = 0;
state.output.size = outputsize / sizeof(Sint16);
state.output.data = (Sint16 *)SDL_malloc(outputsize);
state.output.data = (Sint16 *)SDL_calloc(1, outputsize);
if (state.output.data == NULL) {
return SDL_OutOfMemory();
}

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -71,9 +71,10 @@ void aaudio_errorCallback( AAudioStream *stream, void *userData, aaudio_result_t
#define LIB_AAUDIO_SO "libaaudio.so"
static int
aaudio_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
aaudio_OpenDevice(_THIS, const char *devname)
{
struct SDL_PrivateAudioData *private;
SDL_bool iscapture = this->iscapture;
aaudio_result_t res;
LOGI(__func__);
@@ -268,7 +269,7 @@ aaudio_Deinitialize(void)
LOGI("End AAUDIO %s", SDL_GetError());
}
static int
static SDL_bool
aaudio_Init(SDL_AudioDriverImpl *impl)
{
aaudio_result_t res;
@@ -280,7 +281,7 @@ aaudio_Init(SDL_AudioDriverImpl *impl)
* See https://github.com/google/oboe/issues/40 for more information.
*/
if (SDL_GetAndroidSDKVersion() < 27) {
return 0;
return SDL_FALSE;
}
SDL_zero(ctx);
@@ -315,12 +316,12 @@ aaudio_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;
/* this audio target is available. */
LOGI("SDL aaudio_Init OK");
return 1;
return SDL_TRUE;
failure:
if (ctx.handle) {
@@ -331,11 +332,11 @@ failure:
}
ctx.handle = NULL;
ctx.builder = NULL;
return 0;
return SDL_FALSE;
}
AudioBootStrap aaudio_bootstrap = {
"AAudio", "AAudio audio driver", aaudio_Init, 0
"AAudio", "AAudio audio driver", aaudio_Init, SDL_FALSE
};
/* Pause (block) all non already paused audio devices by taking their mixer lock */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -24,6 +24,7 @@
#define _SDL_aaudio_h
#include "../SDL_sysaudio.h"
#include <stdbool.h>
#include <aaudio/AAudio.h>
/* Hidden "this" pointer for the audio functions */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright , (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -543,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;
@@ -569,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);
@@ -597,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;
@@ -633,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;
@@ -997,11 +990,11 @@ ALSA_Deinitialize(void)
UnloadALSALibrary();
}
static int
static SDL_bool
ALSA_Init(SDL_AudioDriverImpl * impl)
{
if (LoadALSALibrary() < 0) {
return 0;
return SDL_FALSE;
}
/* Set the function pointers */
@@ -1017,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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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)) {
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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -522,8 +522,12 @@ static void
outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer)
{
SDL_AudioDevice *this = (SDL_AudioDevice *) inUserData;
SDL_LockMutex(this->mixer_lock);
if (SDL_AtomicGet(&this->hidden->shutdown)) {
return; /* don't do anything. */
SDL_UnlockMutex(this->mixer_lock);
return; /* don't do anything, since we don't even want to enqueue this buffer again. */
}
if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) {
@@ -536,10 +540,8 @@ outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffe
while (remaining > 0) {
if (SDL_AudioStreamAvailable(this->stream) == 0) {
/* Generate the data */
SDL_LockMutex(this->mixer_lock);
(*this->callbackspec.callback)(this->callbackspec.userdata,
this->hidden->buffer, this->hidden->bufferSize);
SDL_UnlockMutex(this->mixer_lock);
this->hidden->bufferOffset = 0;
SDL_AudioStreamPut(this->stream, this->hidden->buffer, this->hidden->bufferSize);
}
@@ -565,10 +567,8 @@ outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffe
UInt32 len;
if (this->hidden->bufferOffset >= this->hidden->bufferSize) {
/* Generate the data */
SDL_LockMutex(this->mixer_lock);
(*this->callbackspec.callback)(this->callbackspec.userdata,
this->hidden->buffer, this->hidden->bufferSize);
SDL_UnlockMutex(this->mixer_lock);
this->hidden->bufferOffset = 0;
}
@@ -587,6 +587,8 @@ outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffe
AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL);
inBuffer->mAudioDataByteSize = inBuffer->mAudioDataBytesCapacity;
SDL_UnlockMutex(this->mixer_lock);
}
static void
@@ -741,8 +743,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;
@@ -983,7 +987,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;
@@ -1015,11 +1019,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 */
@@ -1076,8 +1080,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:
@@ -1088,32 +1091,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
@@ -1135,8 +1138,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;
@@ -1152,7 +1154,7 @@ COREAUDIO_Deinitialize(void)
#endif
}
static int
static SDL_bool
COREAUDIO_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
@@ -1164,18 +1166,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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -473,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 */
@@ -510,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:
@@ -547,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() */
@@ -575,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 */
@@ -596,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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -114,7 +114,7 @@ DISKAUDIO_CloseDevice(_THIS)
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,9 +126,11 @@ 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);
@@ -177,7 +179,7 @@ DISKAUDIO_DetectDevices(void)
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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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;
@@ -301,13 +302,14 @@ look_for_devices_test(int fd)
return 0;
}
static int
static SDL_bool
DSP_Init(SDL_AudioDriverImpl * impl)
{
InitTimeDevicesExist = SDL_FALSE;
SDL_EnumUnixAudioDevices(0, look_for_devices_test);
if (!InitTimeDevicesExist) {
return 0; /* maybe try a different backend. */
SDL_SetError("dsp: No such audio device");
return SDL_FALSE; /* maybe try a different backend. */
}
/* Set the function pointers */
@@ -319,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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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,7 +28,7 @@
#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. */
@@ -45,22 +45,22 @@ DUMMYAUDIO_CaptureFromDevice(_THIS, void *buffer, int 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: */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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,11 +28,16 @@
#include <emscripten/emscripten.h>
/* !!! FIXME: this currently expects that the audio callback runs in the main thread,
!!! FIXME: in intervals when the application isn't running, but that may not be
!!! FIXME: true always once pthread support becomes widespread. Revisit this code
!!! FIXME: at some point and see what needs to be done for that! */
static void
FeedAudioDevice(_THIS, const void *buf, const int buflen)
{
const int framelen = (SDL_AUDIO_BITSIZE(this->spec.format) / 8) * this->spec.channels;
EM_ASM_ARGS({
MAIN_THREAD_EM_ASM({
var SDL2 = Module['SDL2'];
var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels'];
for (var c = 0; c < numChannels; ++c) {
@@ -101,7 +106,7 @@ HandleCaptureProcess(_THIS)
return;
}
EM_ASM_ARGS({
MAIN_THREAD_EM_ASM({
var SDL2 = Module['SDL2'];
var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels;
for (var c = 0; c < numChannels; ++c) {
@@ -147,7 +152,7 @@ HandleCaptureProcess(_THIS)
static void
EMSCRIPTENAUDIO_CloseDevice(_THIS)
{
EM_ASM_({
MAIN_THREAD_EM_ASM({
var SDL2 = Module['SDL2'];
if ($0) {
if (SDL2.capture.silenceTimer !== undefined) {
@@ -192,16 +197,16 @@ 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 */
/* create context */
result = EM_ASM_INT({
result = MAIN_THREAD_EM_ASM_INT({
if(typeof(Module['SDL2']) === 'undefined') {
Module['SDL2'] = {};
}
@@ -228,22 +233,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. */
@@ -281,7 +285,7 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscaptu
feels like it's a pretty inefficient tapdance in similar ways,
to be honest. */
EM_ASM_({
MAIN_THREAD_EM_ASM({
var SDL2 = Module['SDL2'];
var have_microphone = function(stream) {
//console.log('SDL audio capture: we have a microphone! Replacing silence callback.');
@@ -324,7 +328,7 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscaptu
}, this->spec.channels, this->spec.samples, HandleCaptureProcess, this);
} else {
/* setup a ScriptProcessorNode */
EM_ASM_ARGS({
MAIN_THREAD_EM_ASM({
var SDL2 = Module['SDL2'];
SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0);
SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) {
@@ -339,43 +343,47 @@ 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({
available = MAIN_THREAD_EM_ASM_INT({
if (typeof(AudioContext) !== 'undefined') {
return 1;
return true;
} else if (typeof(webkitAudioContext) !== 'undefined') {
return 1;
return true;
}
return 0;
return false;
});
if (!available) {
SDL_SetError("No audio context available");
}
capture_available = available && EM_ASM_INT_V({
capture_available = available && MAIN_THREAD_EM_ASM_INT({
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;
@@ -385,7 +393,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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -49,39 +49,40 @@ FillSound(void *device, void *stream, size_t len,
SDL_AudioDevice *audio = (SDL_AudioDevice *) device;
SDL_AudioCallback callback = audio->callbackspec.callback;
SDL_LockMutex(audio->mixer_lock);
/* Only do something if audio is enabled */
if (!SDL_AtomicGet(&audio->enabled) || SDL_AtomicGet(&audio->paused)) {
if (audio->stream) {
SDL_AudioStreamClear(audio->stream);
}
SDL_memset(stream, audio->spec.silence, len);
return;
}
} else {
SDL_assert(audio->spec.size == len);
SDL_assert(audio->spec.size == len);
if (audio->stream == NULL) { /* no conversion necessary. */
callback(audio->callbackspec.userdata, (Uint8 *) stream, len);
} else { /* streaming/converting */
const int stream_len = audio->callbackspec.size;
const int ilen = (int) len;
while (SDL_AudioStreamAvailable(audio->stream) < ilen) {
callback(audio->callbackspec.userdata, audio->work_buffer, stream_len);
if (SDL_AudioStreamPut(audio->stream, audio->work_buffer, stream_len) == -1) {
SDL_AudioStreamClear(audio->stream);
SDL_AtomicSet(&audio->enabled, 0);
break;
}
}
if (audio->stream == NULL) { /* no conversion necessary. */
SDL_LockMutex(audio->mixer_lock);
callback(audio->callbackspec.userdata, (Uint8 *) stream, len);
SDL_UnlockMutex(audio->mixer_lock);
} else { /* streaming/converting */
const int stream_len = audio->callbackspec.size;
const int ilen = (int) len;
while (SDL_AudioStreamAvailable(audio->stream) < ilen) {
callback(audio->callbackspec.userdata, audio->work_buffer, stream_len);
if (SDL_AudioStreamPut(audio->stream, audio->work_buffer, stream_len) == -1) {
SDL_AudioStreamClear(audio->stream);
SDL_AtomicSet(&audio->enabled, 0);
break;
const int got = SDL_AudioStreamGet(audio->stream, stream, ilen);
SDL_assert((got < 0) || (got == ilen));
if (got != ilen) {
SDL_memset(stream, audio->spec.silence, len);
}
}
const int got = SDL_AudioStreamGet(audio->stream, stream, ilen);
SDL_assert((got < 0) || (got == ilen));
if (got != ilen) {
SDL_memset(stream, audio->spec.silence, len);
}
}
SDL_UnlockMutex(audio->mixer_lock);
}
static void
@@ -120,11 +121,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 +138,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 +176,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 +214,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 +237,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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -49,8 +49,8 @@ static void nacl_audio_callback(void* stream, uint32_t buffer_size, PP_TimeDelta
const int len = (int) buffer_size;
SDL_AudioDevice* _this = (SDL_AudioDevice*) data;
SDL_AudioCallback callback = _this->callbackspec.callback;
SDL_LockMutex(private->mutex); /* !!! FIXME: is this mutex necessary? */
SDL_LockMutex(_this->mixer_lock);
/* Only do something if audio is enabled */
if (!SDL_AtomicGet(&_this->enabled) || SDL_AtomicGet(&_this->paused)) {
@@ -58,34 +58,31 @@ static void nacl_audio_callback(void* stream, uint32_t buffer_size, PP_TimeDelta
SDL_AudioStreamClear(_this->stream);
}
SDL_memset(stream, _this->spec.silence, len);
return;
}
} else {
SDL_assert(_this->spec.size == len);
SDL_assert(_this->spec.size == len);
if (_this->stream == NULL) { /* no conversion necessary. */
callback(_this->callbackspec.userdata, stream, len);
} else { /* streaming/converting */
const int stream_len = _this->callbackspec.size;
while (SDL_AudioStreamAvailable(_this->stream) < len) {
callback(_this->callbackspec.userdata, _this->work_buffer, stream_len);
if (SDL_AudioStreamPut(_this->stream, _this->work_buffer, stream_len) == -1) {
SDL_AudioStreamClear(_this->stream);
SDL_AtomicSet(&_this->enabled, 0);
break;
}
}
if (_this->stream == NULL) { /* no conversion necessary. */
SDL_LockMutex(_this->mixer_lock);
callback(_this->callbackspec.userdata, stream, len);
SDL_UnlockMutex(_this->mixer_lock);
} else { /* streaming/converting */
const int stream_len = _this->callbackspec.size;
while (SDL_AudioStreamAvailable(_this->stream) < len) {
callback(_this->callbackspec.userdata, _this->work_buffer, stream_len);
if (SDL_AudioStreamPut(_this->stream, _this->work_buffer, stream_len) == -1) {
SDL_AudioStreamClear(_this->stream);
SDL_AtomicSet(&_this->enabled, 0);
break;
const int got = SDL_AudioStreamGet(_this->stream, stream, len);
SDL_assert((got < 0) || (got == len));
if (got != len) {
SDL_memset(stream, _this->spec.silence, len);
}
}
const int got = SDL_AudioStreamGet(_this->stream, stream, len);
SDL_assert((got < 0) || (got == len));
if (got != len) {
SDL_memset(stream, _this->spec.silence, len);
}
}
SDL_UnlockMutex(private->mutex);
SDL_UnlockMutex(_this->mixer_lock);
}
static void NACLAUDIO_CloseDevice(SDL_AudioDevice *device) {
@@ -94,12 +91,11 @@ static void NACLAUDIO_CloseDevice(SDL_AudioDevice *device) {
SDL_PrivateAudioData *hidden = (SDL_PrivateAudioData *) device->hidden;
ppb_audio->StopPlayback(hidden->audio);
SDL_DestroyMutex(hidden->mutex);
core->ReleaseResource(hidden->audio);
}
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();
@@ -109,7 +105,6 @@ NACLAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) {
return SDL_OutOfMemory();
}
private->mutex = SDL_CreateMutex();
_this->spec.freq = 44100;
_this->spec.format = AUDIO_S16LSB;
_this->spec.channels = 2;
@@ -133,18 +128,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 +147,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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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,8 +34,7 @@
#define private _this->hidden
typedef struct SDL_PrivateAudioData {
SDL_mutex* mutex;
PP_Resource audio;
PP_Resource audio;
} SDL_PrivateAudioData;
#endif /* SDL_naclaudio_h_ */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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,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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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 void
NETBSDAUDIO_Status(_THIS)
{
#ifdef DEBUG_AUDIO
/* *INDENT-OFF* */
/* *INDENT-OFF* */ /* clang-format off */
audio_info_t info;
const struct audio_prinfo *prinfo;
@@ -118,7 +118,7 @@ NETBSDAUDIO_Status(_THIS)
"",
this->spec.format,
this->spec.size);
/* *INDENT-ON* */
/* *INDENT-ON* */ /* clang-format on */
#endif /* DEBUG_AUDIO */
}
@@ -202,9 +202,11 @@ 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;
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;
@@ -244,54 +246,46 @@ NETBSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
}
#endif
prinfo->encoding = AUDIO_ENCODING_NONE;
prinfo->sample_rate = this->spec.freq;
prinfo->channels = this->spec.channels;
for (format = SDL_FirstAudioFormat(this->spec.format); format;) {
switch (format) {
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
switch (test_format) {
case AUDIO_U8:
prinfo->encoding = AUDIO_ENCODING_ULINEAR;
prinfo->precision = 8;
encoding = AUDIO_ENCODING_ULINEAR;
break;
case AUDIO_S8:
prinfo->encoding = AUDIO_ENCODING_SLINEAR;
prinfo->precision = 8;
encoding = AUDIO_ENCODING_SLINEAR;
break;
case AUDIO_S16LSB:
prinfo->encoding = AUDIO_ENCODING_SLINEAR_LE;
prinfo->precision = 16;
encoding = AUDIO_ENCODING_SLINEAR_LE;
break;
case AUDIO_S16MSB:
prinfo->encoding = AUDIO_ENCODING_SLINEAR_BE;
prinfo->precision = 16;
encoding = AUDIO_ENCODING_SLINEAR_BE;
break;
case AUDIO_U16LSB:
prinfo->encoding = AUDIO_ENCODING_ULINEAR_LE;
prinfo->precision = 16;
encoding = AUDIO_ENCODING_ULINEAR_LE;
break;
case AUDIO_U16MSB:
prinfo->encoding = AUDIO_ENCODING_ULINEAR_BE;
prinfo->precision = 16;
encoding = AUDIO_ENCODING_ULINEAR_BE;
break;
case AUDIO_S32LSB:
prinfo->encoding = AUDIO_ENCODING_SLINEAR_LE;
prinfo->precision = 32;
encoding = AUDIO_ENCODING_SLINEAR_LE;
break;
case AUDIO_S32MSB:
prinfo->encoding = AUDIO_ENCODING_SLINEAR_BE;
prinfo->precision = 32;
encoding = AUDIO_ENCODING_SLINEAR_BE;
break;
default:
continue;
}
if (prinfo->encoding != AUDIO_ENCODING_NONE) {
break;
}
format = SDL_NextAudioFormat();
break;
}
if (prinfo->encoding == AUDIO_ENCODING_NONE) {
return SDL_SetError("No supported encoding for 0x%x", this->spec.format);
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;
@@ -304,7 +298,7 @@ NETBSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
}
/* Final spec used for the device. */
this->spec.format = format;
this->spec.format = test_format;
this->spec.freq = prinfo->sample_rate;
this->spec.channels = prinfo->channels;
@@ -326,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 */
@@ -339,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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -407,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;
@@ -414,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 */
@@ -489,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 };
@@ -583,14 +595,14 @@ failed:
}
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 {
@@ -714,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");
@@ -736,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)

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -248,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));
@@ -285,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)?
@@ -298,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);
@@ -330,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;
@@ -342,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 {
@@ -423,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;
@@ -438,12 +437,12 @@ 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 = {
"DART", "OS/2 DART", OS2_Init, 0
"DART", "OS/2 DART", OS2_Init, SDL_FALSE
};
#endif /* SDL_AUDIO_DRIVER_OS2 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -31,8 +31,22 @@
#include <pipewire/extensions/metadata.h>
#include <spa/param/audio/format-utils.h>
/* Older versions of Pipewire may not define this, but it's safe to pass at
* runtime even if older installations don't recognize it.
/*
* The following keys are defined for compatability when building against older versions of Pipewire
* prior to their introduction and can be removed if the minimum required Pipewire version is increased
* to or beyond their point of introduction.
*/
/*
* Introduced in 0.3.22
* Taken from /src/pipewire/keys.h
*/
#ifndef PW_KEY_CONFIG_NAME
#define PW_KEY_CONFIG_NAME "config.name"
#endif
/*
* Introduced in 0.3.33
* Taken from src/pipewire/keys.h
*/
#ifndef PW_KEY_NODE_RATE
@@ -40,19 +54,22 @@
#endif
/*
* These seem to be sane limits as Pipewire
* uses them in several of it's own modules.
*
* NOTE: 8192 is a hard upper limit in Pipewire and
* increasing this value can lead to buffer overflows.
* This seems to be a sane lower limit as Pipewire
* uses it in several of it's own modules.
*/
#define PW_MIN_SAMPLES 32 /* About 0.67ms at 48kHz */
#define PW_MAX_SAMPLES 8192 /* About 170.6ms at 48kHz */
#define PW_MIN_SAMPLES 32 /* About 0.67ms at 48kHz */
#define PW_BASE_CLOCK_RATE 48000
#define PW_POD_BUFFER_LENGTH 1024
#define PW_THREAD_NAME_BUFFER_LENGTH 128
enum PW_READY_FLAGS
{
PW_READY_FLAG_BUFFER_ADDED = 0x1,
PW_READY_FLAG_STREAM_READY = 0x2,
PW_READY_FLAG_ALL_BITS = 0x3
};
#define PW_ID_TO_HANDLE(x) (void *)((uintptr_t)x)
#define PW_HANDLE_TO_ID(x) (uint32_t)((uintptr_t)x)
@@ -86,14 +103,13 @@ static enum pw_stream_state (*PIPEWIRE_pw_stream_get_state)(struct pw_stream *st
static struct pw_buffer *(*PIPEWIRE_pw_stream_dequeue_buffer)(struct pw_stream *);
static int (*PIPEWIRE_pw_stream_queue_buffer)(struct pw_stream *, struct pw_buffer *);
static struct pw_properties *(*PIPEWIRE_pw_properties_new)(const char *, ...)SPA_SENTINEL;
static void (*PIPEWIRE_pw_properties_free)(struct pw_properties *);
static int (*PIPEWIRE_pw_properties_set)(struct pw_properties *, const char *, const char *);
static int (*PIPEWIRE_pw_properties_setf)(struct pw_properties *, const char *, const char *, ...) SPA_PRINTF_FUNC(3, 4);
#ifdef SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC
static const char *pipewire_library = SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC;
static void * pipewire_handle = NULL;
static void *pipewire_handle = NULL;
static int
pipewire_dlsym(const char *fn, void **addr)
@@ -176,7 +192,6 @@ load_pipewire_syms()
SDL_PIPEWIRE_SYM(pw_stream_dequeue_buffer);
SDL_PIPEWIRE_SYM(pw_stream_queue_buffer);
SDL_PIPEWIRE_SYM(pw_properties_new);
SDL_PIPEWIRE_SYM(pw_properties_free);
SDL_PIPEWIRE_SYM(pw_properties_set);
SDL_PIPEWIRE_SYM(pw_properties_setf);
@@ -239,16 +254,16 @@ struct io_node
/* The global hotplug thread and associated objects. */
static struct pw_thread_loop *hotplug_loop;
static struct pw_core * hotplug_core;
static struct pw_context * hotplug_context;
static struct pw_registry * hotplug_registry;
static struct pw_core *hotplug_core;
static struct pw_context *hotplug_context;
static struct pw_registry *hotplug_registry;
static struct spa_hook hotplug_registry_listener;
static struct spa_hook hotplug_core_listener;
static struct spa_list hotplug_pending_list;
static struct spa_list hotplug_io_list;
static int hotplug_init_seq_val;
static SDL_atomic_t hotplug_init_complete;
static SDL_atomic_t hotplug_events_enabled;
static SDL_bool hotplug_init_complete;
static SDL_bool hotplug_events_enabled;
static Uint32 pipewire_default_sink_id = SPA_ID_INVALID;
static Uint32 pipewire_default_source_id = SPA_ID_INVALID;
@@ -260,8 +275,6 @@ io_list_check_add(struct io_node *node)
struct io_node *n;
SDL_bool ret = SDL_TRUE;
PIPEWIRE_pw_thread_loop_lock(hotplug_loop);
/* See if the node is already in the list */
spa_list_for_each (n, &hotplug_io_list, link) {
if (n->id == node->id) {
@@ -273,14 +286,12 @@ io_list_check_add(struct io_node *node)
/* Add to the list if the node doesn't already exist */
spa_list_append(&hotplug_io_list, &node->link);
if (SDL_AtomicGet(&hotplug_events_enabled)) {
if (hotplug_events_enabled) {
SDL_AddAudioDevice(node->is_capture, node->name, &node->spec, PW_ID_TO_HANDLE(node->id));
}
dup_found:
PIPEWIRE_pw_thread_loop_unlock(hotplug_loop);
return ret;
}
@@ -289,14 +300,12 @@ io_list_remove(Uint32 id)
{
struct io_node *n, *temp;
PIPEWIRE_pw_thread_loop_lock(hotplug_loop);
/* Find and remove the node from the list */
spa_list_for_each_safe (n, temp, &hotplug_io_list, link) {
if (n->id == id) {
spa_list_remove(&n->link);
if (SDL_AtomicGet(&hotplug_events_enabled)) {
if (hotplug_events_enabled) {
SDL_RemoveAudioDevice(n->is_capture, PW_ID_TO_HANDLE(id));
}
@@ -305,8 +314,6 @@ io_list_remove(Uint32 id)
break;
}
}
PIPEWIRE_pw_thread_loop_unlock(hotplug_loop);
}
static void
@@ -315,8 +322,6 @@ io_list_sort()
struct io_node *default_sink = NULL, *default_source = NULL;
struct io_node *n, *temp;
PIPEWIRE_pw_thread_loop_lock(hotplug_loop);
/* Find and move the default nodes to the beginning of the list */
spa_list_for_each_safe (n, temp, &hotplug_io_list, link) {
if (n->id == pipewire_default_sink_id) {
@@ -335,8 +340,6 @@ io_list_sort()
if (default_sink) {
spa_list_prepend(&hotplug_io_list, &default_sink->link);
}
PIPEWIRE_pw_thread_loop_unlock(hotplug_loop);
}
static void
@@ -395,7 +398,7 @@ pending_list_clear()
static void *
node_object_new(Uint32 id, const char *type, Uint32 version, const void *funcs, const struct pw_core_events *core_events)
{
struct pw_proxy * proxy;
struct pw_proxy *proxy;
struct node_object *node;
/* Create the proxy object */
@@ -430,7 +433,7 @@ core_events_hotplug_init_callback(void *object, uint32_t id, int seq)
spa_hook_remove(&hotplug_core_listener);
/* Signal that the initial I/O list is populated */
SDL_AtomicSet(&hotplug_init_complete, 1);
hotplug_init_complete = SDL_TRUE;
PIPEWIRE_pw_thread_loop_signal(hotplug_loop, false);
}
}
@@ -439,7 +442,7 @@ static void
core_events_interface_callback(void *object, uint32_t id, int seq)
{
struct node_object *node = object;
struct io_node * io = node->userdata;
struct io_node *io = node->userdata;
if (id == PW_ID_CORE && seq == node->seq) {
/*
@@ -479,7 +482,7 @@ hotplug_core_sync(struct node_object *node)
node->seq = pw_core_sync(hotplug_core, PW_ID_CORE, node->seq);
}
if (!SDL_AtomicGet(&hotplug_init_complete)) {
if (!hotplug_init_complete) {
hotplug_init_seq_val = pw_core_sync(hotplug_core, PW_ID_CORE, hotplug_init_seq_val);
}
}
@@ -489,7 +492,7 @@ static SDL_bool
get_range_param(const struct spa_pod *param, Uint32 key, int *def, int *min, int *max)
{
const struct spa_pod_prop *prop;
struct spa_pod * value;
struct spa_pod *value;
Uint32 n_values, choice;
prop = spa_pod_find_prop(param, NULL, key);
@@ -543,8 +546,8 @@ static void
node_event_info(void *object, const struct pw_node_info *info)
{
struct node_object *node = object;
struct io_node * io = node->userdata;
const char * prop_val;
struct io_node *io = node->userdata;
const char *prop_val;
Uint32 i;
if (info) {
@@ -566,7 +569,7 @@ static void
node_event_param(void *object, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param)
{
struct node_object *node = object;
struct io_node * io = node->userdata;
struct io_node *io = node->userdata;
/* Get the default frequency */
if (io->spec.freq == 0) {
@@ -619,7 +622,7 @@ registry_event_global_callback(void *object, uint32_t id, uint32_t permissions,
const char *media_class = spa_dict_lookup(props, PW_KEY_MEDIA_CLASS);
if (media_class) {
const char * node_desc;
const char *node_desc;
struct io_node *io;
SDL_bool is_capture;
int str_buffer_len;
@@ -738,23 +741,30 @@ hotplug_loop_destroy()
pending_list_clear();
io_list_clear();
SDL_AtomicSet(&hotplug_init_complete, 0);
SDL_AtomicSet(&hotplug_events_enabled, 0);
hotplug_init_complete = SDL_FALSE;
hotplug_events_enabled = SDL_FALSE;
pipewire_default_sink_id = SPA_ID_INVALID;
pipewire_default_source_id = SPA_ID_INVALID;
if (hotplug_registry) {
PIPEWIRE_pw_proxy_destroy((struct pw_proxy *)hotplug_registry);
hotplug_registry = NULL;
}
if (hotplug_core) {
PIPEWIRE_pw_core_disconnect(hotplug_core);
hotplug_core = NULL;
}
if (hotplug_context) {
PIPEWIRE_pw_context_destroy(hotplug_context);
hotplug_context = NULL;
}
if (hotplug_loop) {
PIPEWIRE_pw_thread_loop_destroy(hotplug_loop);
hotplug_loop = NULL;
}
}
@@ -766,7 +776,7 @@ PIPEWIRE_DetectDevices()
PIPEWIRE_pw_thread_loop_lock(hotplug_loop);
/* Wait until the initial registry enumeration is complete */
if (!SDL_AtomicGet(&hotplug_init_complete)) {
if (!hotplug_init_complete) {
PIPEWIRE_pw_thread_loop_wait(hotplug_loop);
}
@@ -777,7 +787,7 @@ PIPEWIRE_DetectDevices()
SDL_AddAudioDevice(io->is_capture, io->name, &io->spec, PW_ID_TO_HANDLE(io->id));
}
SDL_AtomicSet(&hotplug_events_enabled, 1);
hotplug_events_enabled = SDL_TRUE;
PIPEWIRE_pw_thread_loop_unlock(hotplug_loop);
}
@@ -790,14 +800,14 @@ static const enum spa_audio_channel PIPEWIRE_channel_map_4[] = { SPA_AUDIO_CHANN
SPA_AUDIO_CHANNEL_RR };
static const enum spa_audio_channel PIPEWIRE_channel_map_5[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC,
SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR };
static const enum spa_audio_channel PIPEWIRE_channel_map_6[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC,
static const enum spa_audio_channel PIPEWIRE_channel_map_6[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC,
SPA_AUDIO_CHANNEL_LFE, SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR };
static const enum spa_audio_channel PIPEWIRE_channel_map_7[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC,
static const enum spa_audio_channel PIPEWIRE_channel_map_7[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC,
SPA_AUDIO_CHANNEL_LFE, SPA_AUDIO_CHANNEL_RC, SPA_AUDIO_CHANNEL_RL,
SPA_AUDIO_CHANNEL_RR };
static const enum spa_audio_channel PIPEWIRE_channel_map_8[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC,
static const enum spa_audio_channel PIPEWIRE_channel_map_8[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC,
SPA_AUDIO_CHANNEL_LFE, SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR,
SPA_AUDIO_CHANNEL_SL, SPA_AUDIO_CHANNEL_SR };
SPA_AUDIO_CHANNEL_SL, SPA_AUDIO_CHANNEL_SR };
#define COPY_CHANNEL_MAP(c) SDL_memcpy(info->position, PIPEWIRE_channel_map_##c, sizeof(PIPEWIRE_channel_map_##c))
@@ -872,9 +882,9 @@ initialize_spa_info(const SDL_AudioSpec *spec, struct spa_audio_info_raw *info)
static void
output_callback(void *data)
{
struct pw_buffer * pw_buf;
struct pw_buffer *pw_buf;
struct spa_buffer *spa_buf;
Uint8 * dst;
Uint8 *dst;
_THIS = (SDL_AudioDevice *)data;
struct pw_stream *stream = this->hidden->stream;
@@ -900,6 +910,7 @@ output_callback(void *data)
* and run the callback with the work buffer to keep the callback
* firing regularly in case the audio is being used as a timer.
*/
SDL_LockMutex(this->mixer_lock);
if (!SDL_AtomicGet(&this->paused)) {
if (SDL_AtomicGet(&this->enabled)) {
dst = spa_buf->datas[0].data;
@@ -909,18 +920,13 @@ output_callback(void *data)
}
if (!this->stream) {
SDL_LockMutex(this->mixer_lock);
this->callbackspec.callback(this->callbackspec.userdata, dst, this->callbackspec.size);
SDL_UnlockMutex(this->mixer_lock);
} else {
int got;
/* Fire the callback until we have enough to fill a buffer */
while (SDL_AudioStreamAvailable(this->stream) < this->spec.size) {
SDL_LockMutex(this->mixer_lock);
this->callbackspec.callback(this->callbackspec.userdata, this->work_buffer, this->callbackspec.size);
SDL_UnlockMutex(this->mixer_lock);
SDL_AudioStreamPut(this->stream, this->work_buffer, this->callbackspec.size);
}
@@ -930,6 +936,7 @@ output_callback(void *data)
} else {
SDL_memset(spa_buf->datas[0].data, this->spec.silence, this->spec.size);
}
SDL_UnlockMutex(this->mixer_lock);
spa_buf->datas[0].chunk->offset = 0;
spa_buf->datas[0].chunk->stride = this->hidden->stride;
@@ -941,9 +948,9 @@ output_callback(void *data)
static void
input_callback(void *data)
{
struct pw_buffer * pw_buf;
struct pw_buffer *pw_buf;
struct spa_buffer *spa_buf;
Uint8 * src;
Uint8 *src;
_THIS = (SDL_AudioDevice *)data;
struct pw_stream *stream = this->hidden->stream;
@@ -985,35 +992,71 @@ input_callback(void *data)
this->callbackspec.callback(this->callbackspec.userdata, this->work_buffer, this->callbackspec.size);
SDL_UnlockMutex(this->mixer_lock);
}
} else { /* Flush the buffer when paused */
} else if (this->hidden->buffer) { /* Flush the buffer when paused */
if (SDL_CountDataQueue(this->hidden->buffer) != 0) {
SDL_ClearDataQueue(this->hidden->buffer, this->hidden->buffer_period_size * 2);
SDL_ClearDataQueue(this->hidden->buffer, this->hidden->input_buffer_packet_size);
}
}
PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf);
}
static void
stream_add_buffer_callback(void *data, struct pw_buffer *buffer)
{
_THIS = data;
if (this->iscapture == SDL_FALSE) {
/*
* Clamp the output spec samples and size to the max size of the Pipewire buffer.
* If they exceed the maximum size of the Pipewire buffer, double buffering will be used.
*/
if (this->spec.size > buffer->buffer->datas[0].maxsize) {
this->spec.samples = buffer->buffer->datas[0].maxsize / this->hidden->stride;
this->spec.size = buffer->buffer->datas[0].maxsize;
}
} else if (this->hidden->buffer == NULL) {
/*
* The latency of source nodes can change, so buffering is always required.
*
* Ensure that the intermediate input buffer is large enough to hold the requested
* application packet size or a full buffer of data from Pipewire, whichever is larger.
*
* A packet size of 2 periods should be more than is ever needed.
*/
this->hidden->input_buffer_packet_size = SPA_MAX(this->spec.size, buffer->buffer->datas[0].maxsize) * 2;
this->hidden->buffer = SDL_NewDataQueue(this->hidden->input_buffer_packet_size, this->hidden->input_buffer_packet_size);
}
this->hidden->stream_init_status |= PW_READY_FLAG_BUFFER_ADDED;
PIPEWIRE_pw_thread_loop_signal(this->hidden->loop, false);
}
static void
stream_state_changed_callback(void *data, enum pw_stream_state old, enum pw_stream_state state, const char *error)
{
_THIS = data;
if (state == PW_STREAM_STATE_STREAMING) {
this->hidden->stream_init_status |= PW_READY_FLAG_STREAM_READY;
}
if (state == PW_STREAM_STATE_STREAMING || state == PW_STREAM_STATE_ERROR) {
SDL_AtomicSet(&this->hidden->stream_initialized, 1);
PIPEWIRE_pw_thread_loop_signal(this->hidden->loop, false);
}
}
static const struct pw_stream_events stream_output_events = { PW_VERSION_STREAM_EVENTS,
.state_changed = stream_state_changed_callback,
.add_buffer = stream_add_buffer_callback,
.process = output_callback };
static const struct pw_stream_events stream_input_events = { PW_VERSION_STREAM_EVENTS,
.state_changed = stream_state_changed_callback,
.process = input_callback };
.state_changed = stream_state_changed_callback,
.add_buffer = stream_add_buffer_callback,
.process = input_callback };
static int
PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
PIPEWIRE_OpenDevice(_THIS, const char *devname)
{
/*
* NOTE: The PW_STREAM_FLAG_RT_PROCESS flag can be set to call the stream
@@ -1028,23 +1071,22 @@ PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
Uint8 pod_buffer[PW_POD_BUFFER_LENGTH];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(pod_buffer, sizeof(pod_buffer));
struct spa_audio_info_raw spa_info = { 0 };
const struct spa_pod * params = NULL;
const struct spa_pod *params = NULL;
struct SDL_PrivateAudioData *priv;
struct pw_properties * props;
const char * app_name, *stream_name, *stream_role, *error;
const Uint32 node_id = this->handle == NULL ? PW_ID_ANY : PW_HANDLE_TO_ID(this->handle);
enum pw_stream_state state;
struct pw_properties *props;
const char *app_name, *stream_name, *stream_role, *error;
const Uint32 node_id = this->handle == NULL ? PW_ID_ANY : PW_HANDLE_TO_ID(this->handle);
SDL_bool iscapture = this->iscapture;
int res;
/* Clamp the period size to sane values */
const int min_period = PW_MIN_SAMPLES * SPA_MAX(this->spec.freq / PW_BASE_CLOCK_RATE, 1);
const int adjusted_samples = SPA_CLAMP(this->spec.samples, min_period, PW_MAX_SAMPLES);
const int min_period = PW_MIN_SAMPLES * SPA_MAX(this->spec.freq / PW_BASE_CLOCK_RATE, 1);
/* Get the hints for the application name, stream name and role */
app_name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME);
if (!app_name || *app_name == '\0') {
app_name = SDL_GetHint(SDL_HINT_APP_NAME);
if (!app_name || *app_name == '\0') {
if (!app_name || *app_name == '\0') {
app_name = "SDL Application";
}
}
@@ -1077,38 +1119,34 @@ PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
/* Size of a single audio frame in bytes */
priv->stride = (SDL_AUDIO_BITSIZE(this->spec.format) >> 3) * this->spec.channels;
if (this->spec.samples != adjusted_samples && !iscapture) {
this->spec.samples = adjusted_samples;
if (this->spec.samples < min_period) {
this->spec.samples = min_period;
this->spec.size = this->spec.samples * priv->stride;
}
/* The latency of source nodes can change, so buffering is required. */
if (iscapture) {
priv->buffer_period_size = SPA_MAX(this->spec.samples, adjusted_samples) * priv->stride;
/* A packet size of 4 periods should be more than is ever needed (no more than 2 should be queued in practice). */
priv->buffer = SDL_NewDataQueue(priv->buffer_period_size * 4, priv->buffer_period_size * 2);
if (priv->buffer == NULL) {
return SDL_SetError("Pipewire: Failed to allocate source buffer");
}
}
SDL_snprintf(thread_name, sizeof(thread_name), "SDLAudio%c%ld", (iscapture) ? 'C' : 'P', (long)handle);
SDL_snprintf(thread_name, sizeof(thread_name), "SDLAudio%c%ld", (iscapture) ? 'C' : 'P', (long)this->handle);
priv->loop = PIPEWIRE_pw_thread_loop_new(thread_name, NULL);
if (priv->loop == NULL) {
return SDL_SetError("Pipewire: Failed to create stream loop (%i)", errno);
}
/* Load the rtkit module so Pipewire can set the loop thread to the appropriate priority */
props = PIPEWIRE_pw_properties_new(PW_KEY_CONTEXT_PROFILE_MODULES, "default,rtkit", NULL);
/*
* Load the realtime module so Pipewire can set the loop thread to the appropriate priority.
*
* NOTE: Pipewire versions 0.3.22 or higher require the PW_KEY_CONFIG_NAME property (with client-rt.conf),
* lower versions require explicitly specifying the 'rtkit' module.
*
* PW_KEY_CONTEXT_PROFILE_MODULES is deprecated and can be safely removed if the minimum required
* Pipewire version is increased to 0.3.22 or higher at some point.
*/
props = PIPEWIRE_pw_properties_new(PW_KEY_CONFIG_NAME, "client-rt.conf",
PW_KEY_CONTEXT_PROFILE_MODULES, "default,rtkit", NULL);
if (props == NULL) {
return SDL_SetError("Pipewire: Failed to create stream context properties (%i)", errno);
}
/* On success, the context owns the properties object and will free it at destruction time. */
priv->context = PIPEWIRE_pw_context_new(PIPEWIRE_pw_thread_loop_get_loop(priv->loop), props, 0);
if (priv->context == NULL) {
PIPEWIRE_pw_properties_free(props);
return SDL_SetError("Pipewire: Failed to create stream context (%i)", errno);
}
@@ -1123,18 +1161,14 @@ PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
PIPEWIRE_pw_properties_set(props, PW_KEY_APP_NAME, app_name);
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_NAME, stream_name);
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, stream_name);
PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%u/%i", adjusted_samples, this->spec.freq);
PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%u/%i", this->spec.samples, this->spec.freq);
PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_RATE, "1/%u", this->spec.freq);
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_ALWAYS_PROCESS, "true");
/*
* Create the new stream
* On success, the stream owns the properties object and will free it at destruction time.
*/
/* Create the new stream */
priv->stream = PIPEWIRE_pw_stream_new_simple(PIPEWIRE_pw_thread_loop_get_loop(priv->loop), stream_name, props,
iscapture ? &stream_input_events : &stream_output_events, this);
if (priv->stream == NULL) {
PIPEWIRE_pw_properties_free(props);
return SDL_SetError("Pipewire: Failed to create stream (%i)", errno);
}
@@ -1149,19 +1183,23 @@ PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
return SDL_SetError("Pipewire: Failed to start stream loop");
}
/* Wait until the stream is either running or failed */
/* Wait until all init flags are set or the stream has failed. */
PIPEWIRE_pw_thread_loop_lock(priv->loop);
if (!SDL_AtomicGet(&priv->stream_initialized)) {
while (priv->stream_init_status != PW_READY_FLAG_ALL_BITS &&
PIPEWIRE_pw_stream_get_state(priv->stream, NULL) != PW_STREAM_STATE_ERROR) {
PIPEWIRE_pw_thread_loop_wait(priv->loop);
}
PIPEWIRE_pw_thread_loop_unlock(priv->loop);
state = PIPEWIRE_pw_stream_get_state(priv->stream, &error);
if (state == PW_STREAM_STATE_ERROR) {
if (PIPEWIRE_pw_stream_get_state(priv->stream, &error) == PW_STREAM_STATE_ERROR) {
return SDL_SetError("Pipewire: Stream error: %s", error);
}
/* If this is a capture stream, make sure the intermediate buffer was successfully allocated. */
if (iscapture && priv->buffer == NULL) {
return SDL_SetError("Pipewire: Failed to allocate source buffer");
}
return 0;
}
@@ -1200,19 +1238,19 @@ PIPEWIRE_Deinitialize()
}
}
static int
static SDL_bool
PIPEWIRE_Init(SDL_AudioDriverImpl *impl)
{
if (!pipewire_initialized) {
if (init_pipewire_library() < 0) {
return 0;
return SDL_FALSE;
}
pipewire_initialized = SDL_TRUE;
if (hotplug_loop_init() < 0) {
PIPEWIRE_Deinitialize();
return 0;
return SDL_FALSE;
}
}
@@ -1222,13 +1260,13 @@ PIPEWIRE_Init(SDL_AudioDriverImpl *impl)
impl->CloseDevice = PIPEWIRE_CloseDevice;
impl->Deinitialize = PIPEWIRE_Deinitialize;
impl->HasCaptureSupport = 1;
impl->ProvidesOwnCallbackThread = 1;
impl->HasCaptureSupport = SDL_TRUE;
impl->ProvidesOwnCallbackThread = SDL_TRUE;
return 1;
return SDL_TRUE;
}
AudioBootStrap PIPEWIRE_bootstrap = { "pipewire", "Pipewire", PIPEWIRE_Init, 0 };
AudioBootStrap PIPEWIRE_bootstrap = { "pipewire", "Pipewire", PIPEWIRE_Init, SDL_FALSE };
#endif /* SDL_AUDIO_DRIVER_PIPEWIRE */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -37,9 +37,9 @@ struct SDL_PrivateAudioData
struct pw_context *context;
struct SDL_DataQueue *buffer;
size_t buffer_period_size;
Sint32 stride; /* Bytes-per-frame */
SDL_atomic_t stream_initialized;
size_t input_buffer_packet_size;
Sint32 stride; /* Bytes-per-frame */
int stream_init_status;
};
#endif /* SDL_pipewire_h_ */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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,27 +42,45 @@
#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,20 +94,6 @@ 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");
}
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);
}
@@ -126,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)
@@ -145,7 +158,7 @@ static void PSPAUDIO_ThreadInit(_THIS)
}
}
static int
static SDL_bool
PSPAUDIO_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
@@ -157,16 +170,16 @@ PSPAUDIO_Init(SDL_AudioDriverImpl * impl)
impl->ThreadInit = PSPAUDIO_ThreadInit;
/* PSP audio device */
impl->OnlyHasDefaultOutputDevice = 1;
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
/*
impl->HasCaptureSupport = 1;
impl->OnlyHasDefaultCaptureDevice = 1;
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
};
#endif /* SDL_AUDIO_DRIVER_PSP */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -107,8 +107,6 @@ static int (*PULSEAUDIO_pa_stream_connect_record) (pa_stream *, const char *,
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 *,
@@ -119,6 +117,7 @@ static pa_operation * (*PULSEAUDIO_pa_stream_flush) (pa_stream *,
pa_stream_success_cb_t, void *);
static int (*PULSEAUDIO_pa_stream_disconnect) (pa_stream *);
static void (*PULSEAUDIO_pa_stream_unref) (pa_stream *);
static void (*PULSEAUDIO_pa_stream_set_write_callback)(pa_stream *, pa_stream_request_cb_t, void *);
static int load_pulseaudio_syms(void);
@@ -222,8 +221,6 @@ 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);
@@ -232,6 +229,7 @@ load_pulseaudio_syms(void)
SDL_PULSEAUDIO_SYM(pa_stream_unref);
SDL_PULSEAUDIO_SYM(pa_channel_map_init_auto);
SDL_PULSEAUDIO_SYM(pa_strerror);
SDL_PULSEAUDIO_SYM(pa_stream_set_write_callback);
return 0;
}
@@ -359,51 +357,56 @@ ConnectToPulseServer(pa_mainloop **_mainloop, pa_context **_context)
static void
PULSEAUDIO_WaitDevice(_THIS)
{
struct SDL_PrivateAudioData *h = this->hidden;
/* this is a no-op; we wait in PULSEAUDIO_PlayDevice now. */
}
while (SDL_AtomicGet(&this->enabled)) {
static void WriteCallback(pa_stream *p, size_t nbytes, void *userdata)
{
struct SDL_PrivateAudioData *h = (struct SDL_PrivateAudioData *) userdata;
/*printf("PULSEAUDIO WRITE CALLBACK! nbytes=%u\n", (unsigned int) nbytes);*/
h->bytes_requested += nbytes;
}
static void
PULSEAUDIO_PlayDevice(_THIS)
{
struct SDL_PrivateAudioData *h = this->hidden;
int available = h->mixlen;
int written = 0;
int cpy;
/*printf("PULSEAUDIO PLAYDEVICE START! mixlen=%d\n", available);*/
while (SDL_AtomicGet(&this->enabled) && (available > 0)) {
cpy = SDL_min(h->bytes_requested, available);
if (cpy) {
if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf + written, cpy, NULL, 0LL, PA_SEEK_RELATIVE) < 0) {
SDL_OpenedAudioDeviceDisconnected(this);
return;
}
/*printf("PULSEAUDIO FEED! nbytes=%u\n", (unsigned int) cpy);*/
h->bytes_requested -= cpy;
written += cpy;
available -= cpy;
}
/* let WriteCallback fire if necessary. */
/*printf("PULSEAUDIO ITERATE!\n");*/
if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
SDL_OpenedAudioDeviceDisconnected(this);
return;
}
if (PULSEAUDIO_pa_stream_writable_size(h->stream) >= (h->mixlen/8)) {
return;
}
}
}
static void
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->pabuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) {
SDL_OpenedAudioDeviceDisconnected(this);
}
}
/*printf("PULSEAUDIO PLAYDEVICE END! written=%d\n", written);*/
}
static Uint8 *
PULSEAUDIO_GetDeviceBuf(_THIS)
{
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;
return this->hidden->mixbuf;
}
@@ -522,7 +525,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;
@@ -544,16 +547,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 */
@@ -564,53 +568,45 @@ 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
this->spec.samples /= 2; /* Mix in smaller chunck to avoid underruns */
#endif
SDL_CalculateAudioSpec(&this->spec);
/* Allocate mixing buffer */
@@ -627,28 +623,18 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
paspec.rate = this->spec.freq;
/* 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.tlength = h->mixlen;
paattr.prebuf = -1;
paattr.maxlength = -1;
/* -1 can lead to pa_stream_writable_size() >= mixlen never being true */
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;
paattr.minreq = h->mixlen;
#endif
paattr.minreq = -1;
flags |= PA_STREAM_ADJUST_LATENCY;
if (ConnectToPulseServer(&h->mainloop, &h->context) < 0) {
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?");
}
@@ -679,6 +665,7 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
if (iscapture) {
rc = PULSEAUDIO_pa_stream_connect_record(h->stream, h->device_name, &paattr, flags);
} else {
PULSEAUDIO_pa_stream_set_write_callback(h->stream, WriteCallback, h);
rc = PULSEAUDIO_pa_stream_connect_playback(h->stream, h->device_name, &paattr, flags, NULL, NULL);
}
@@ -832,16 +819,16 @@ 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);
@@ -859,11 +846,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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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,11 +43,7 @@ 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;
int bytes_requested; /* bytes of data the hardware wants _now_. */
const Uint8 *capturebuf;
int capturelen;

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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 @@ QSA_WaitDevice(_THIS)
/* 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 ? SDL_IOR_READ : SDL_IOR_WRITE,
this->iscapture ? SDL_IOR_READ : SDL_IOR_WRITE,
2 * 1000);
switch (result) {
case -1:
@@ -180,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;
@@ -196,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,
@@ -240,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);
@@ -257,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;
@@ -280,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;
@@ -305,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 */
@@ -407,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;
@@ -443,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);
@@ -458,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,
@@ -635,7 +592,7 @@ QSA_Deinitialize(void)
qsa_capture_devices = 0;
}
static int
static SDL_bool
QSA_Init(SDL_AudioDriverImpl * impl)
{
/* Clear devices array */
@@ -655,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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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;

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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
@@ -37,18 +37,35 @@
#include <psp2/kernel/threadmgr.h>
#include <psp2/audioout.h>
#include <psp2/audioin.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_OpenCaptureDevice(_THIS)
{
this->spec.freq = 16000;
this->spec.samples = 512;
this->spec.channels = 1;
SDL_CalculateAudioSpec(&this->spec);
this->hidden->port = sceAudioInOpenPort(SCE_AUDIO_IN_PORT_TYPE_VOICE , 512, 16000, SCE_AUDIO_IN_PARAM_FORMAT_S16_MONO);
if (this->hidden->port < 0) {
return SDL_SetError("Couldn't open audio in port: %x", this->hidden->port);
}
return 0;
}
static int
VITAAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
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};
SDL_AudioFormat test_format;
this->hidden = (struct SDL_PrivateAudioData *)
SDL_malloc(sizeof(*this->hidden));
@@ -56,13 +73,20 @@ VITAAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
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;
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
if (test_format == AUDIO_S16LSB) {
this->spec.format = test_format;
break;
default:
return SDL_SetError("Unsupported audio format");
}
}
if(!test_format) {
return SDL_SetError("Unsupported audio format");
}
if (this->iscapture) {
return VITAAUD_OpenCaptureDevice(this);
}
/* The sample count must be a multiple of 64. */
@@ -91,14 +115,14 @@ VITAAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
port = SCE_AUDIO_OUT_PORT_TYPE_BGM;
}
this->hidden->channel = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format);
if (this->hidden->channel < 0) {
this->hidden->port = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format);
if (this->hidden->port < 0) {
free(this->hidden->rawbuf);
this->hidden->rawbuf = NULL;
return SDL_SetError("Couldn't reserve hardware channel");
return SDL_SetError("Couldn't open audio out port: %x", this->hidden->port);
}
sceAudioOutSetVolume(this->hidden->channel, SCE_AUDIO_VOLUME_FLAG_L_CH|SCE_AUDIO_VOLUME_FLAG_R_CH, vols);
sceAudioOutSetVolume(this->hidden->port, 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++) {
@@ -113,7 +137,7 @@ static void VITAAUD_PlayDevice(_THIS)
{
Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
sceAudioOutOutput(this->hidden->channel, mixbuf);
sceAudioOutOutput(this->hidden->port, mixbuf);
this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
}
@@ -123,6 +147,7 @@ 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];
@@ -130,17 +155,32 @@ static Uint8 *VITAAUD_GetDeviceBuf(_THIS)
static void VITAAUD_CloseDevice(_THIS)
{
if (this->hidden->channel >= 0) {
sceAudioOutReleasePort(this->hidden->channel);
this->hidden->channel = -1;
if (this->hidden->port >= 0) {
if (this->iscapture) {
sceAudioInReleasePort(this->hidden->port);
} else {
sceAudioOutReleasePort(this->hidden->port);
}
this->hidden->port = -1;
}
if (this->hidden->rawbuf != NULL) {
if (!this->iscapture && this->hidden->rawbuf != NULL) {
free(this->hidden->rawbuf); /* this uses memalign(), not SDL_malloc(). */
this->hidden->rawbuf = NULL;
}
}
static int VITAAUD_CaptureFromDevice(_THIS, void *buffer, int buflen)
{
int ret;
SDL_assert(buflen == this->spec.size);
ret = sceAudioInInput(this->hidden->port, buffer);
if (ret < 0) {
return SDL_SetError("Failed to capture from device: %x", ret);
}
return this->spec.size;
}
static void VITAAUD_ThreadInit(_THIS)
{
/* Increase the priority of this audio thread by 1 to put it
@@ -154,7 +194,7 @@ static void VITAAUD_ThreadInit(_THIS)
}
}
static int
static SDL_bool
VITAAUD_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
@@ -165,17 +205,18 @@ VITAAUD_Init(SDL_AudioDriverImpl * impl)
impl->CloseDevice = VITAAUD_CloseDevice;
impl->ThreadInit = VITAAUD_ThreadInit;
/* VITA audio device */
impl->OnlyHasDefaultOutputDevice = 1;
/*
impl->HasCaptureSupport = 1;
impl->OnlyHasDefaultInputDevice = 1;
*/
return 1; /* this audio target is available. */
impl->CaptureFromDevice = VITAAUD_CaptureFromDevice;
/* and the capabilities */
impl->HasCaptureSupport = SDL_TRUE;
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
}
AudioBootStrap VITAAUD_bootstrap = {
"vita", "VITA audio driver", VITAAUD_Init, 0
"vita", "VITA audio driver", VITAAUD_Init, SDL_FALSE
};
#endif /* SDL_AUDIO_DRIVER_VITA */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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
@@ -30,8 +30,8 @@
#define NUM_BUFFERS 2
struct SDL_PrivateAudioData {
/* The hardware output channel. */
int channel;
/* The hardware input/output port. */
int port;
/* The raw allocated mixing buffer. */
Uint8 *rawbuf;
/* Individual mixing buffers. */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -209,7 +209,7 @@ UpdateAudioStream(_THIS, const SDL_AudioSpec *oldspec)
}
if (!this->stream) {
return -1;
return -1; /* SDL_NewAudioStream should have called SDL_SetError. */
}
}
@@ -512,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;
@@ -543,17 +542,15 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
/* Make sure we have a valid format that we can convert to whatever WASAPI wants. */
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);
@@ -561,12 +558,16 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
return WIN_SetErrorFromHRESULT("WASAPI can't determine minimum device period", ret);
}
#if 1 /* we're getting reports that WASAPI's resampler introduces distortions, so it's disabled for now. --ryan. */
this->spec.freq = waveformat->nSamplesPerSec; /* force sampling rate so our resampler kicks in, if necessary. */
#else
/* favor WASAPI's resampler over our own */
if (this->spec.freq != waveformat->nSamplesPerSec) {
streamflags |= (AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY);
waveformat->nSamplesPerSec = this->spec.freq;
waveformat->nAvgBytesPerSec = waveformat->nSamplesPerSec * waveformat->nChannels * (waveformat->wBitsPerSample / 8);
}
#endif
streamflags |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
ret = IAudioClient_Initialize(client, sharemode, streamflags, 0, 0, waveformat, NULL);
@@ -631,9 +632,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. */
@@ -641,9 +640,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 *)
@@ -656,7 +655,7 @@ 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 = SDL_wcsdup(devid);
if (!this->hidden->devid) {
@@ -691,12 +690,6 @@ WASAPI_ThreadDeinit(_THIS)
WASAPI_PlatformThreadDeinit(this);
}
void
WASAPI_BeginLoopIteration(_THIS)
{
/* no-op. */
}
static void
WASAPI_Deinitialize(void)
{
@@ -713,21 +706,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;
@@ -736,13 +728,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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -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
}

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -362,7 +362,7 @@ typedef struct
WAVEFORMATEXTENSIBLE fmt;
} EndpointItem;
static int sort_endpoints(const void *_a, const void *_b)
static int SDLCALL sort_endpoints(const void *_a, const void *_b)
{
LPWSTR a = ((const EndpointItem *) _a)->devid;
LPWSTR b = ((const EndpointItem *) _b)->devid;

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -283,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 */
@@ -313,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:
@@ -321,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 */
@@ -434,7 +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 */
@@ -449,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 */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -303,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;
@@ -510,9 +511,10 @@ register_methods(JNIEnv *env, const char *classname, JNINativeMethod *methods, i
/* Library init */
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
mJavaVM = vm;
JNIEnv *env = NULL;
mJavaVM = vm;
if ((*mJavaVM)->GetEnv(mJavaVM, (void **)&env, JNI_VERSION_1_4) != JNI_OK) {
__android_log_print(ANDROID_LOG_ERROR, "SDL", "Failed to get JNI Env");
return JNI_VERSION_1_4;
@@ -582,6 +584,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");
@@ -612,6 +615,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
!midClipboardHasText ||
!midClipboardSetText ||
!midCreateCustomCursor ||
!midDestroyCustomCursor ||
!midGetContext ||
!midGetDisplayDPI ||
!midGetManifestEnvironmentVariables ||
@@ -1006,6 +1010,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();
@@ -1018,6 +1023,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);
}
@@ -1048,10 +1054,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);
@@ -2123,6 +2131,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)
{
@@ -2503,6 +2520,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)
{
@@ -2531,6 +2554,7 @@ SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled)
SDL_bool Android_JNI_RequestPermission(const char *permission)
{
JNIEnv *env = Android_JNI_GetEnv();
jstring jpermission;
const int requestCode = 1;
/* Wait for any pending request on another thread */
@@ -2539,7 +2563,7 @@ SDL_bool Android_JNI_RequestPermission(const char *permission)
}
SDL_AtomicSet(&bPermissionRequestPending, SDL_TRUE);
jstring jpermission = (*env)->NewStringUTF(env, permission);
jpermission = (*env)->NewStringUTF(env, permission);
(*env)->CallStaticVoidMethod(env, mActivityClass, midRequestPermission, jpermission, requestCode);
(*env)->DeleteLocalRef(env, jpermission);

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -118,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);

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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
@@ -22,6 +22,7 @@
#include "SDL_hints.h"
#include "SDL_dbus.h"
#include "SDL_atomic.h"
#include "../../stdlib/SDL_vacopy.h"
#if SDL_USE_LIBDBUS
/* we never link directly to libdbus. */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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