update sdl Merge commit '644725478f4de0f074a6834e8423ac36dce3974f'
This commit is contained in:
54
external/sdl/SDL/test/CMakeLists.txt
vendored
54
external/sdl/SDL/test/CMakeLists.txt
vendored
@ -230,7 +230,31 @@ elseif(HAVE_X11)
|
||||
target_link_libraries(testnative PRIVATE X11)
|
||||
endif()
|
||||
|
||||
set(gamepad_images
|
||||
find_package(Python3)
|
||||
function(files2headers OUTPUT)
|
||||
set(xxd "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/xxd.py")
|
||||
set(inputs ${ARGN})
|
||||
set(outputs )
|
||||
foreach(input IN LISTS inputs)
|
||||
get_filename_component(file_we "${input}" NAME_WE)
|
||||
set(intermediate "${CMAKE_CURRENT_BINARY_DIR}/${file_we}.h")
|
||||
set(output "${CMAKE_CURRENT_SOURCE_DIR}/${file_we}.h")
|
||||
list(APPEND outputs "${output}")
|
||||
if(Python3_FOUND AND Python3_VERSION VERSION_GREATER_EQUAL "3.2")
|
||||
list(APPEND outputs "${intermediate}")
|
||||
# Don't add the 'output' header to the output, to avoid marking them as GENERATED
|
||||
# (generated files are removed when running the CLEAN target)
|
||||
add_custom_command(OUTPUT "${intermediate}"
|
||||
COMMAND Python3::Interpreter "${xxd}" -i "${CMAKE_CURRENT_SOURCE_DIR}/${input}" "-o" "${intermediate}"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${intermediate}" "${output}"
|
||||
DEPENDS "${xxd}" "${bmp}"
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
set(${OUTPUT} "${outputs}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
files2headers(gamepad_image_headers
|
||||
gamepad_axis_arrow.bmp
|
||||
gamepad_axis.bmp
|
||||
gamepad_back.bmp
|
||||
@ -249,24 +273,7 @@ set(gamepad_images
|
||||
gamepad_front.bmp
|
||||
gamepad_touchpad.bmp
|
||||
)
|
||||
set(gamepad_image_headers)
|
||||
find_package(Python3)
|
||||
if(Python3_FOUND AND Python3_VERSION VERSION_GREATER_EQUAL "3.2")
|
||||
set(xxd "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/xxd.py")
|
||||
foreach(bmp ${gamepad_images})
|
||||
get_filename_component(bmp_we "${bmp}" NAME_WE)
|
||||
set(intermediate "${CMAKE_CURRENT_BINARY_DIR}/${bmp_we}.h")
|
||||
set(final "${CMAKE_CURRENT_SOURCE_DIR}/${bmp_we}.h")
|
||||
# Don't add the 'final' headers to the output, to avoid marking them as GENERATED
|
||||
# (generated files are removed when running the CLEAN target)
|
||||
add_custom_command(OUTPUT "${intermediate}"
|
||||
COMMAND Python3::Interpreter "${xxd}" -i "${CMAKE_CURRENT_SOURCE_DIR}/${bmp}" "-o" "${intermediate}"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${intermediate}" "${final}"
|
||||
DEPENDS "${xxd}" "${bmp}"
|
||||
)
|
||||
list(APPEND gamepad_image_headers "${intermediate}" "${final}")
|
||||
endforeach()
|
||||
endif()
|
||||
files2headers(icon_bmp_header icon.bmp)
|
||||
|
||||
add_sdl_test_executable(testaudio NEEDS_RESOURCES TESTUTILS SOURCES testaudio.c)
|
||||
add_sdl_test_executable(testfile NONINTERACTIVE SOURCES testfile.c)
|
||||
@ -296,6 +303,9 @@ add_sdl_test_executable(testoverlay NEEDS_RESOURCES TESTUTILS SOURCES testoverla
|
||||
add_sdl_test_executable(testplatform NONINTERACTIVE SOURCES testplatform.c)
|
||||
add_sdl_test_executable(testpower NONINTERACTIVE SOURCES testpower.c)
|
||||
add_sdl_test_executable(testfilesystem NONINTERACTIVE SOURCES testfilesystem.c)
|
||||
if(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
add_sdl_test_executable(testfilesystem_pre SOURCES testfilesystem_pre.c NONINTERACTIVE NONINTERACTIVE_TIMEOUT 60)
|
||||
endif()
|
||||
add_sdl_test_executable(testrendertarget NEEDS_RESOURCES TESTUTILS SOURCES testrendertarget.c)
|
||||
add_sdl_test_executable(testscale NEEDS_RESOURCES TESTUTILS SOURCES testscale.c)
|
||||
add_sdl_test_executable(testsem NONINTERACTIVE NONINTERACTIVE_ARGS 10 NONINTERACTIVE_TIMEOUT 30 SOURCES testsem.c)
|
||||
@ -303,7 +313,7 @@ add_sdl_test_executable(testsensor SOURCES testsensor.c)
|
||||
add_sdl_test_executable(testshader NEEDS_RESOURCES TESTUTILS SOURCES testshader.c)
|
||||
add_sdl_test_executable(testshape NEEDS_RESOURCES SOURCES testshape.c)
|
||||
add_sdl_test_executable(testsprite NEEDS_RESOURCES TESTUTILS SOURCES testsprite.c)
|
||||
add_sdl_test_executable(testspriteminimal NEEDS_RESOURCES TESTUTILS SOURCES testspriteminimal.c)
|
||||
add_sdl_test_executable(testspriteminimal SOURCES testspriteminimal.c ${icon_bmp_header})
|
||||
add_sdl_test_executable(teststreaming NEEDS_RESOURCES TESTUTILS SOURCES teststreaming.c)
|
||||
add_sdl_test_executable(testtimer NONINTERACTIVE NONINTERACTIVE_TIMEOUT 60 SOURCES testtimer.c)
|
||||
add_sdl_test_executable(testurl SOURCES testurl.c)
|
||||
@ -504,6 +514,10 @@ foreach(TEST ${SDL_TEST_EXECUTABLES})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(TARGET testfilesystem_pre)
|
||||
set_property(TEST testfilesystem APPEND PROPERTY DEPENDS testfilesystem_pre)
|
||||
endif()
|
||||
|
||||
if(SDL_INSTALL_TESTS)
|
||||
if(RISCOS)
|
||||
install(
|
||||
|
68
external/sdl/SDL/test/checkkeys.c
vendored
68
external/sdl/SDL/test/checkkeys.c
vendored
@ -15,8 +15,6 @@
|
||||
pump the event loop and catch keystrokes.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
@ -25,22 +23,10 @@
|
||||
#include <SDL3/SDL_main.h>
|
||||
#include <SDL3/SDL_test.h>
|
||||
|
||||
static SDL_Window *window;
|
||||
static SDL_Renderer *renderer;
|
||||
static SDLTest_CommonState *state;
|
||||
static SDLTest_TextWindow *textwin;
|
||||
static int done;
|
||||
|
||||
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
|
||||
static void
|
||||
quit(int rc)
|
||||
{
|
||||
SDL_Quit();
|
||||
/* Let 'main()' return normally */
|
||||
if (rc != 0) {
|
||||
exit(rc);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_string(char **text, size_t *maxlen, const char *fmt, ...)
|
||||
{
|
||||
@ -171,6 +157,7 @@ PrintText(const char *eventtype, const char *text)
|
||||
static void loop(void)
|
||||
{
|
||||
SDL_Event event;
|
||||
int i;
|
||||
/* Check for events */
|
||||
/*SDL_WaitEvent(&event); emscripten does not like waiting*/
|
||||
|
||||
@ -234,11 +221,13 @@ static void loop(void)
|
||||
}
|
||||
}
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
||||
SDLTest_TextWindowDisplay(textwin, renderer);
|
||||
SDL_RenderPresent(renderer);
|
||||
for (i = 0; i < state->num_windows; i++) {
|
||||
SDL_SetRenderDrawColor(state->renderers[i], 0, 0, 0, 255);
|
||||
SDL_RenderClear(state->renderers[i]);
|
||||
SDL_SetRenderDrawColor(state->renderers[i], 255, 255, 255, 255);
|
||||
SDLTest_TextWindowDisplay(textwin, state->renderers[i]);
|
||||
SDL_RenderPresent(state->renderers[i]);
|
||||
}
|
||||
|
||||
/* Slow down framerate */
|
||||
SDL_Delay(100);
|
||||
@ -252,13 +241,14 @@ static void loop(void)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
SDLTest_CommonState *state;
|
||||
int w, h;
|
||||
|
||||
/* Initialize test framework */
|
||||
state = SDLTest_CommonCreateState(argv, 0);
|
||||
state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
|
||||
if (state == NULL) {
|
||||
return 1;
|
||||
}
|
||||
state->window_title = "CheckKeys Test";
|
||||
|
||||
/* Enable standard application logging */
|
||||
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
|
||||
@ -275,31 +265,22 @@ int main(int argc, char *argv[])
|
||||
SDL_SetHint(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, "1");
|
||||
|
||||
/* Initialize SDL */
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
if (!SDLTest_CommonInit(state)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set 640x480 video mode */
|
||||
window = SDL_CreateWindow("CheckKeys Test", 640, 480, 0);
|
||||
if (window == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create 640x480 window: %s\n",
|
||||
SDL_GetError());
|
||||
quit(2);
|
||||
}
|
||||
|
||||
renderer = SDL_CreateRenderer(window, NULL, 0);
|
||||
if (renderer == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n",
|
||||
SDL_GetError());
|
||||
quit(2);
|
||||
}
|
||||
|
||||
textwin = SDLTest_TextWindowCreate(0, 0, 640, 480);
|
||||
SDL_GetWindowSize(state->windows[0], &w, &h);
|
||||
textwin = SDLTest_TextWindowCreate(0.f, 0.f, (float)w, (float)h);
|
||||
|
||||
#ifdef __IOS__
|
||||
/* Creating the context creates the view, which we need to show keyboard */
|
||||
SDL_GL_CreateContext(window);
|
||||
{
|
||||
int i;
|
||||
/* Creating the context creates the view, which we need to show keyboard */
|
||||
for (i = 0; i < state->num_windows; i++) {
|
||||
SDL_GL_CreateContext(state->windows[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_StartTextInput();
|
||||
@ -319,7 +300,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_Quit();
|
||||
SDLTest_CommonDestroyState(state);
|
||||
SDLTest_TextWindowDestroy(textwin);
|
||||
SDLTest_CleanupTextDrawing();
|
||||
SDLTest_CommonQuit(state);
|
||||
return 0;
|
||||
}
|
||||
|
3
external/sdl/SDL/test/checkkeysthreads.c
vendored
3
external/sdl/SDL/test/checkkeysthreads.c
vendored
@ -303,6 +303,9 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
|
||||
SDL_WaitThread(thread, NULL);
|
||||
SDL_Quit();
|
||||
SDLTest_CommonDestroyState(state);
|
||||
|
34
external/sdl/SDL/test/emscripten/server.py
vendored
34
external/sdl/SDL/test/emscripten/server.py
vendored
@ -3,13 +3,15 @@
|
||||
# Based on http/server.py from Python
|
||||
|
||||
from argparse import ArgumentParser
|
||||
import contextlib
|
||||
from http.server import SimpleHTTPRequestHandler
|
||||
from http.server import ThreadingHTTPServer
|
||||
import socket
|
||||
from socketserver import TCPServer
|
||||
|
||||
|
||||
def serve_forever(port: int, ServerClass):
|
||||
handler = SimpleHTTPRequestHandler
|
||||
handler.extensions_map = {
|
||||
class MyHTTPRequestHandler(SimpleHTTPRequestHandler):
|
||||
extensions_map = {
|
||||
".manifest": "text/cache-manifest",
|
||||
".html": "text/html",
|
||||
".png": "image/png",
|
||||
@ -21,14 +23,25 @@ def serve_forever(port: int, ServerClass):
|
||||
"": "application/octet-stream",
|
||||
}
|
||||
|
||||
def end_headers(self):
|
||||
self.send_my_headers()
|
||||
SimpleHTTPRequestHandler.end_headers(self)
|
||||
|
||||
def send_my_headers(self):
|
||||
self.send_header("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||
self.send_header("Pragma", "no-cache")
|
||||
self.send_header("Expires", "0")
|
||||
|
||||
|
||||
def serve_forever(port: int, ServerClass):
|
||||
handler = MyHTTPRequestHandler
|
||||
|
||||
addr = ("0.0.0.0", port)
|
||||
HandlerClass = SimpleHTTPRequestHandler
|
||||
with ServerClass(addr, handler) as httpd:
|
||||
host, port = httpd.socket.getsockname()[:2]
|
||||
url_host = f"[{host}]" if ":" in host else host
|
||||
print(
|
||||
f"Serving HTTP on {host} port {port} (http://{url_host}:{port}/) ..."
|
||||
)
|
||||
print(f"Serving HTTP on {host} port {port} (http://{url_host}:{port}/) ...")
|
||||
try:
|
||||
httpd.serve_forever()
|
||||
except KeyboardInterrupt:
|
||||
@ -42,16 +55,11 @@ def main():
|
||||
parser.add_argument("-d", dest="directory", type=str, default=None)
|
||||
args = parser.parse_args()
|
||||
|
||||
import contextlib
|
||||
import http.server
|
||||
import socket
|
||||
|
||||
class DualStackServer(http.server.ThreadingHTTPServer):
|
||||
class DualStackServer(ThreadingHTTPServer):
|
||||
def server_bind(self):
|
||||
# suppress exception when protocol is IPv4
|
||||
with contextlib.suppress(Exception):
|
||||
self.socket.setsockopt(
|
||||
socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
|
||||
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
|
||||
return super().server_bind()
|
||||
|
||||
def finish_request(self, request, client_address):
|
||||
|
52
external/sdl/SDL/test/icon.h
vendored
Normal file
52
external/sdl/SDL/test/icon.h
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
unsigned char icon_bmp[] = {
|
||||
0x42, 0x4d, 0x42, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00,
|
||||
0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
|
||||
0x00, 0x00, 0x6d, 0x0b, 0x00, 0x00, 0x6d, 0x0b, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x22, 0x22, 0x22, 0x22,
|
||||
0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22,
|
||||
0x21, 0x11, 0x11, 0x12, 0x22, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x12, 0x21, 0x11, 0x11, 0x11, 0x11, 0x12, 0x21, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x11, 0x11, 0x11, 0x11, 0x11,
|
||||
0x11, 0x22, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x21, 0x11,
|
||||
0x22, 0x22, 0x22, 0x22, 0x11, 0x12, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
|
||||
0x22, 0x22, 0x22, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x22, 0x22,
|
||||
0x22, 0x21, 0x12, 0x22, 0x22, 0x22, 0x22, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x22, 0x22, 0x22, 0x22, 0x21, 0x12, 0x22, 0x22, 0x22, 0x22, 0x10,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
|
||||
0x22, 0x22, 0x22, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x22, 0x22,
|
||||
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x22, 0x22, 0x11, 0x11, 0x22, 0x22, 0x11, 0x11, 0x22, 0x22, 0x10,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x22, 0x11, 0x01, 0x22, 0x22, 0x11,
|
||||
0x01, 0x22, 0x22, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x22, 0x11,
|
||||
0x11, 0x22, 0x22, 0x11, 0x11, 0x22, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
|
||||
0x22, 0x22, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x22,
|
||||
0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x10, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x22, 0x22, 0x22, 0x22,
|
||||
0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x11, 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00
|
||||
};
|
||||
unsigned int icon_bmp_len = 578;
|
19
external/sdl/SDL/test/loopwave.c
vendored
19
external/sdl/SDL/test/loopwave.c
vendored
@ -31,15 +31,14 @@ static struct
|
||||
SDL_AudioSpec spec;
|
||||
Uint8 *sound; /* Pointer to wave data */
|
||||
Uint32 soundlen; /* Length of wave data */
|
||||
Uint32 soundpos;
|
||||
} wave;
|
||||
|
||||
static SDL_AudioDeviceID device;
|
||||
static SDL_AudioStream *stream;
|
||||
|
||||
static void fillerup(void)
|
||||
{
|
||||
if (SDL_GetAudioStreamAvailable(stream) < (int) ((wave.soundlen / 2))) {
|
||||
const int minimum = (wave.soundlen / SDL_AUDIO_FRAMESIZE(wave.spec)) / 2;
|
||||
if (SDL_GetAudioStreamQueued(stream) < minimum) {
|
||||
SDL_PutAudioStreamData(stream, wave.sound, wave.soundlen);
|
||||
}
|
||||
}
|
||||
@ -58,30 +57,22 @@ quit(int rc)
|
||||
static void
|
||||
close_audio(void)
|
||||
{
|
||||
if (device != 0) {
|
||||
if (stream) {
|
||||
SDL_DestroyAudioStream(stream);
|
||||
stream = NULL;
|
||||
SDL_CloseAudioDevice(device);
|
||||
device = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
open_audio(void)
|
||||
{
|
||||
device = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &wave.spec);
|
||||
if (!device) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError());
|
||||
SDL_free(wave.sound);
|
||||
quit(2);
|
||||
}
|
||||
stream = SDL_CreateAndBindAudioStream(device, &wave.spec);
|
||||
stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &wave.spec, NULL, NULL);
|
||||
if (!stream) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create audio stream: %s\n", SDL_GetError());
|
||||
SDL_CloseAudioDevice(device);
|
||||
SDL_free(wave.sound);
|
||||
quit(2);
|
||||
}
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream));
|
||||
}
|
||||
|
||||
|
||||
|
219
external/sdl/SDL/test/testaudio.c
vendored
219
external/sdl/SDL/test/testaudio.c
vendored
@ -10,6 +10,8 @@
|
||||
#include "testutils.h"
|
||||
|
||||
#define POOF_LIFETIME 250
|
||||
#define VISUALIZER_WIDTH 100
|
||||
#define VISUALIZER_HEIGHT 50
|
||||
|
||||
typedef struct Texture
|
||||
{
|
||||
@ -50,6 +52,15 @@ struct Thing
|
||||
SDL_bool iscapture;
|
||||
SDL_AudioSpec spec;
|
||||
Thing *physdev;
|
||||
SDL_bool visualizer_enabled;
|
||||
SDL_bool visualizer_updated;
|
||||
SDL_Texture *visualizer;
|
||||
SDL_Mutex *postmix_lock;
|
||||
float *postmix_buffer;
|
||||
int postmix_buflen;
|
||||
int postmix_allocated;
|
||||
SDL_AudioSpec postmix_spec;
|
||||
SDL_AtomicInt postmix_updated;
|
||||
} logdev;
|
||||
struct {
|
||||
SDL_AudioSpec spec;
|
||||
@ -98,6 +109,7 @@ static SDLTest_CommonState *state = NULL;
|
||||
static Thing *things = NULL;
|
||||
static char *current_titlebar = NULL;
|
||||
|
||||
static Thing *mouseover_thing = NULL;
|
||||
static Thing *droppable_highlighted_thing = NULL;
|
||||
static Thing *dragging_thing = NULL;
|
||||
static int dragging_button = -1;
|
||||
@ -110,10 +122,16 @@ static Texture *soundboard_texture = NULL;
|
||||
static Texture *soundboard_levels_texture = NULL;
|
||||
|
||||
static void DestroyTexture(Texture *tex);
|
||||
static void DestroyThing(Thing *thing);
|
||||
|
||||
|
||||
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
|
||||
static void Quit(int rc)
|
||||
{
|
||||
while (things != NULL) {
|
||||
DestroyThing(things); /* make sure all the audio devices are closed, etc. */
|
||||
}
|
||||
|
||||
DestroyTexture(physdev_texture);
|
||||
DestroyTexture(logdev_texture);
|
||||
DestroyTexture(audio_texture);
|
||||
@ -121,6 +139,7 @@ static void Quit(int rc)
|
||||
DestroyTexture(soundboard_texture);
|
||||
DestroyTexture(soundboard_levels_texture);
|
||||
SDLTest_CommonQuit(state);
|
||||
|
||||
/* Let 'main()' return normally */
|
||||
if (rc != 0) {
|
||||
exit(rc);
|
||||
@ -193,6 +212,8 @@ static Thing *UpdateMouseOver(const float x, const float y)
|
||||
thing = FindThingAtPoint(x, y);
|
||||
}
|
||||
|
||||
mouseover_thing = thing;
|
||||
|
||||
if (!thing) {
|
||||
SetDefaultTitleBar();
|
||||
} else if (thing->titlebar) {
|
||||
@ -202,7 +223,7 @@ static Thing *UpdateMouseOver(const float x, const float y)
|
||||
return thing;
|
||||
}
|
||||
|
||||
static Thing *CreateThing(ThingType what, float x, float y, float z, float w, float h, Texture *texture, char *titlebar)
|
||||
static Thing *CreateThing(ThingType what, float x, float y, float z, float w, float h, Texture *texture, const char *titlebar)
|
||||
{
|
||||
Thing *last = NULL;
|
||||
Thing *i;
|
||||
@ -232,7 +253,7 @@ static Thing *CreateThing(ThingType what, float x, float y, float z, float w, fl
|
||||
thing->scale = 1.0f;
|
||||
thing->createticks = SDL_GetTicks();
|
||||
thing->texture = texture;
|
||||
thing->titlebar = titlebar;
|
||||
thing->titlebar = titlebar ? xstrdup(titlebar) : NULL;
|
||||
|
||||
/* insert in list by Z order (furthest from the "camera" first, so they get drawn over; negative Z is not drawn at all). */
|
||||
if (things == NULL) {
|
||||
@ -272,21 +293,40 @@ static void DestroyThing(Thing *thing)
|
||||
return;
|
||||
}
|
||||
|
||||
if (mouseover_thing == thing) {
|
||||
mouseover_thing = NULL;
|
||||
}
|
||||
|
||||
if (droppable_highlighted_thing == thing) {
|
||||
droppable_highlighted_thing = NULL;
|
||||
}
|
||||
|
||||
if (dragging_thing == thing) {
|
||||
dragging_thing = NULL;
|
||||
}
|
||||
|
||||
switch (thing->what) {
|
||||
case THING_POOF: break;
|
||||
case THING_NULL: break;
|
||||
case THING_TRASHCAN: break;
|
||||
|
||||
case THING_LOGDEV:
|
||||
case THING_LOGDEV_CAPTURE:
|
||||
SDL_CloseAudioDevice(thing->data.logdev.devid);
|
||||
SDL_DestroyTexture(thing->data.logdev.visualizer);
|
||||
SDL_DestroyMutex(thing->data.logdev.postmix_lock);
|
||||
SDL_free(thing->data.logdev.postmix_buffer);
|
||||
break;
|
||||
|
||||
case THING_PHYSDEV:
|
||||
case THING_PHYSDEV_CAPTURE:
|
||||
SDL_free(thing->data.physdev.name);
|
||||
break;
|
||||
|
||||
case THING_WAV:
|
||||
SDL_free(thing->data.wav.buf);
|
||||
break;
|
||||
|
||||
case THING_STREAM:
|
||||
SDL_DestroyAudioStream(thing->data.stream.stream);
|
||||
break;
|
||||
@ -416,12 +456,12 @@ static const char *AudioFmtToString(const SDL_AudioFormat fmt)
|
||||
#define FMTCASE(x) case SDL_AUDIO_##x: return #x
|
||||
FMTCASE(U8);
|
||||
FMTCASE(S8);
|
||||
FMTCASE(S16LSB);
|
||||
FMTCASE(S16MSB);
|
||||
FMTCASE(S32LSB);
|
||||
FMTCASE(S32MSB);
|
||||
FMTCASE(F32LSB);
|
||||
FMTCASE(F32MSB);
|
||||
FMTCASE(S16LE);
|
||||
FMTCASE(S16BE);
|
||||
FMTCASE(S32LE);
|
||||
FMTCASE(S32BE);
|
||||
FMTCASE(F32LE);
|
||||
FMTCASE(F32BE);
|
||||
#undef FMTCASE
|
||||
}
|
||||
return "?";
|
||||
@ -513,7 +553,7 @@ static void StreamThing_ontick(Thing *thing, Uint64 now)
|
||||
if (!available || (SDL_GetAudioStreamFormat(thing->data.stream.stream, NULL, &spec) < 0)) {
|
||||
DestroyThingInPoof(thing);
|
||||
} else {
|
||||
const int ticksleft = (int) ((((Uint64) ((available / (SDL_AUDIO_BITSIZE(spec.format) / 8)) / spec.channels)) * 1000) / spec.freq);
|
||||
const int ticksleft = (int) ((((Uint64) (available / SDL_AUDIO_FRAMESIZE(spec))) * 1000) / spec.freq);
|
||||
const float pct = thing->data.stream.total_ticks ? (((float) (ticksleft)) / ((float) thing->data.stream.total_ticks)) : 0.0f;
|
||||
thing->progress = 1.0f - pct;
|
||||
}
|
||||
@ -553,7 +593,7 @@ static void StreamThing_ondrop(Thing *thing, int button, float x, float y)
|
||||
SDL_UnbindAudioStream(thing->data.stream.stream); /* unbind from current device */
|
||||
if (thing->line_connected_to->what == THING_LOGDEV_CAPTURE) {
|
||||
SDL_FlushAudioStream(thing->data.stream.stream);
|
||||
thing->data.stream.total_ticks = (int) (((((Uint64) (SDL_GetAudioStreamAvailable(thing->data.stream.stream) / (SDL_AUDIO_BITSIZE(spec->format) / 8))) / spec->channels) * 1000) / spec->freq);
|
||||
thing->data.stream.total_ticks = (int) ((((Uint64) (SDL_GetAudioStreamAvailable(thing->data.stream.stream) / SDL_AUDIO_FRAMESIZE(*spec))) * 1000) / spec->freq);
|
||||
}
|
||||
}
|
||||
|
||||
@ -590,13 +630,13 @@ static void StreamThing_ondraw(Thing *thing, SDL_Renderer *renderer)
|
||||
static Thing *CreateStreamThing(const SDL_AudioSpec *spec, const Uint8 *buf, const Uint32 buflen, const char *fname, const float x, const float y)
|
||||
{
|
||||
static const ThingType can_be_dropped_onto[] = { THING_TRASHCAN, THING_LOGDEV, THING_LOGDEV_CAPTURE, THING_NULL };
|
||||
Thing *thing = CreateThing(THING_STREAM, x, y, 0, -1, -1, soundboard_texture, fname ? xstrdup(fname) : NULL);
|
||||
Thing *thing = CreateThing(THING_STREAM, x, y, 0, -1, -1, soundboard_texture, fname);
|
||||
SDL_Log("Adding audio stream for %s", fname ? fname : "(null)");
|
||||
thing->data.stream.stream = SDL_CreateAudioStream(spec, spec);
|
||||
if (buf && buflen) {
|
||||
SDL_PutAudioStreamData(thing->data.stream.stream, buf, (int) buflen);
|
||||
SDL_FlushAudioStream(thing->data.stream.stream);
|
||||
thing->data.stream.total_ticks = (int) (((((Uint64) (SDL_GetAudioStreamAvailable(thing->data.stream.stream) / (SDL_AUDIO_BITSIZE(spec->format) / 8))) / spec->channels) * 1000) / spec->freq);
|
||||
thing->data.stream.total_ticks = (int) ((((Uint64) (SDL_GetAudioStreamAvailable(thing->data.stream.stream) / SDL_AUDIO_FRAMESIZE(*spec))) * 1000) / spec->freq);
|
||||
}
|
||||
thing->ontick = StreamThing_ontick;
|
||||
thing->ondrag = StreamThing_ondrag;
|
||||
@ -656,6 +696,7 @@ static Thing *LoadWavThing(const char *fname, float x, float y)
|
||||
|
||||
SDL_asprintf(&titlebar, "WAV file (\"%s\", %s, %s, %uHz)", nodirs, AudioFmtToString(spec.format), AudioChansToStr(spec.channels), (unsigned int) spec.freq);
|
||||
thing = CreateThing(THING_WAV, x - (audio_texture->w / 2), y - (audio_texture->h / 2), 5, -1, -1, audio_texture, titlebar);
|
||||
SDL_free(titlebar);
|
||||
SDL_memcpy(&thing->data.wav.spec, &spec, sizeof (SDL_AudioSpec));
|
||||
thing->data.wav.buf = buf;
|
||||
thing->data.wav.buflen = buflen;
|
||||
@ -726,8 +767,10 @@ static void DeviceThing_ondrag(Thing *thing, int button, float x, float y)
|
||||
static void SetLogicalDeviceTitlebar(Thing *thing)
|
||||
{
|
||||
SDL_AudioSpec *spec = &thing->data.logdev.spec;
|
||||
SDL_GetAudioDeviceFormat(thing->data.logdev.devid, spec);
|
||||
SDL_asprintf(&thing->titlebar, "Logical device #%u (%s, %s, %s, %uHz)", (unsigned int) thing->data.logdev.devid, thing->data.logdev.iscapture ? "CAPTURE" : "OUTPUT", AudioFmtToString(spec->format), AudioChansToStr(spec->channels), (unsigned int) spec->freq);
|
||||
int frames = 0;
|
||||
SDL_GetAudioDeviceFormat(thing->data.logdev.devid, spec, &frames);
|
||||
SDL_free(thing->titlebar);
|
||||
SDL_asprintf(&thing->titlebar, "Logical device #%u (%s, %s, %s, %uHz, %d frames)", (unsigned int) thing->data.logdev.devid, thing->data.logdev.iscapture ? "CAPTURE" : "OUTPUT", AudioFmtToString(spec->format), AudioChansToStr(spec->channels), (unsigned int) spec->freq, frames);
|
||||
}
|
||||
|
||||
static void LogicalDeviceThing_ondrop(Thing *thing, int button, float x, float y)
|
||||
@ -739,6 +782,135 @@ static void LogicalDeviceThing_ondrop(Thing *thing, int button, float x, float y
|
||||
}
|
||||
}
|
||||
|
||||
static void SDLCALL PostmixCallback(void *userdata, const SDL_AudioSpec *spec, float *buffer, int buflen)
|
||||
{
|
||||
Thing *thing = (Thing *) userdata;
|
||||
|
||||
SDL_LockMutex(thing->data.logdev.postmix_lock);
|
||||
|
||||
if (thing->data.logdev.postmix_allocated < buflen) {
|
||||
void *ptr = SDL_realloc(thing->data.logdev.postmix_buffer, buflen);
|
||||
if (!ptr) {
|
||||
SDL_UnlockMutex(thing->data.logdev.postmix_lock);
|
||||
return; /* oh well. */
|
||||
}
|
||||
thing->data.logdev.postmix_buffer = (float *) ptr;
|
||||
thing->data.logdev.postmix_allocated = buflen;
|
||||
}
|
||||
|
||||
SDL_copyp(&thing->data.logdev.postmix_spec, spec);
|
||||
SDL_memcpy(thing->data.logdev.postmix_buffer, buffer, buflen);
|
||||
thing->data.logdev.postmix_buflen = buflen;
|
||||
SDL_AtomicSet(&thing->data.logdev.postmix_updated, 1);
|
||||
|
||||
SDL_UnlockMutex(thing->data.logdev.postmix_lock);
|
||||
}
|
||||
|
||||
static void UpdateVisualizer(SDL_Renderer *renderer, SDL_Texture *visualizer, const int channels, const float *buffer, const int buflen)
|
||||
{
|
||||
static const SDL_Color channel_colors[8] = {
|
||||
{ 255, 255, 255, 255 },
|
||||
{ 255, 0, 0, 255 },
|
||||
{ 0, 255, 0, 255 },
|
||||
{ 0, 0, 255, 255 },
|
||||
{ 255, 255, 0, 255 },
|
||||
{ 0, 255, 255, 255 },
|
||||
{ 255, 0, 255, 255 },
|
||||
{ 127, 127, 127, 255 }
|
||||
};
|
||||
|
||||
SDL_SetRenderTarget(renderer, visualizer);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
if (buffer && buflen) {
|
||||
const int frames = (buflen / sizeof (float)) / channels;
|
||||
const int skip = frames / (VISUALIZER_WIDTH * 2);
|
||||
int i, j;
|
||||
|
||||
for (i = channels - 1; i >= 0; i--) {
|
||||
const SDL_Color *color = &channel_colors[i % SDL_arraysize(channel_colors)];
|
||||
SDL_FPoint points[VISUALIZER_WIDTH + 2];
|
||||
float prevx = 0.0f;
|
||||
int pointidx = 1;
|
||||
|
||||
points[0].x = 0.0f;
|
||||
points[0].y = VISUALIZER_HEIGHT * 0.5f;
|
||||
|
||||
for (j = 0; j < (SDL_arraysize(points)-1); j++) {
|
||||
const float val = buffer[((j * skip) * channels) + i];
|
||||
const float x = prevx + 2;
|
||||
const float y = (VISUALIZER_HEIGHT * 0.5f) - (VISUALIZER_HEIGHT * (val * 0.5f));
|
||||
SDL_assert(pointidx < SDL_arraysize(points));
|
||||
points[pointidx].x = x;
|
||||
points[pointidx].y = y;
|
||||
pointidx++;
|
||||
prevx = x;
|
||||
}
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, color->r, color->g, color->b, 255);
|
||||
SDL_RenderLines(renderer, points, pointidx);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_SetRenderTarget(renderer, NULL);
|
||||
}
|
||||
|
||||
static void LogicalDeviceThing_ontick(Thing *thing, Uint64 now)
|
||||
{
|
||||
const SDL_bool ismousedover = (thing == mouseover_thing) ? SDL_TRUE : SDL_FALSE;
|
||||
|
||||
if (!thing->data.logdev.visualizer || !thing->data.logdev.postmix_lock) { /* need these to work, skip if they failed. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (thing->data.logdev.visualizer_enabled != ismousedover) {
|
||||
thing->data.logdev.visualizer_enabled = ismousedover;
|
||||
if (!ismousedover) {
|
||||
SDL_SetAudioPostmixCallback(thing->data.logdev.devid, NULL, NULL);
|
||||
} else {
|
||||
if (thing->data.logdev.postmix_buffer) {
|
||||
SDL_memset(thing->data.logdev.postmix_buffer, '\0', thing->data.logdev.postmix_buflen);
|
||||
}
|
||||
SDL_AtomicSet(&thing->data.logdev.postmix_updated, 1); /* so this will at least clear the texture later. */
|
||||
SDL_SetAudioPostmixCallback(thing->data.logdev.devid, PostmixCallback, thing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void LogicalDeviceThing_ondraw(Thing *thing, SDL_Renderer *renderer)
|
||||
{
|
||||
if (thing->data.logdev.visualizer_enabled) {
|
||||
SDL_FRect dst;
|
||||
dst.w = thing->rect.w;
|
||||
dst.h = thing->rect.h;
|
||||
dst.x = thing->rect.x + ((thing->rect.w - dst.w) / 2);
|
||||
dst.y = thing->rect.y + ((thing->rect.h - dst.h) / 2);
|
||||
|
||||
if (SDL_AtomicGet(&thing->data.logdev.postmix_updated)) {
|
||||
float *buffer;
|
||||
int channels;
|
||||
int buflen;
|
||||
|
||||
SDL_LockMutex(thing->data.logdev.postmix_lock);
|
||||
channels = thing->data.logdev.postmix_spec.channels;
|
||||
buflen = thing->data.logdev.postmix_buflen;
|
||||
buffer = (float *) SDL_malloc(thing->data.logdev.postmix_buflen);
|
||||
if (buffer) {
|
||||
SDL_memcpy(buffer, thing->data.logdev.postmix_buffer, thing->data.logdev.postmix_buflen);
|
||||
SDL_AtomicSet(&thing->data.logdev.postmix_updated, 0);
|
||||
}
|
||||
SDL_UnlockMutex(thing->data.logdev.postmix_lock);
|
||||
|
||||
UpdateVisualizer(renderer, thing->data.logdev.visualizer, channels, buffer, buflen);
|
||||
SDL_free(buffer);
|
||||
}
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 30);
|
||||
SDL_RenderTexture(renderer, thing->data.logdev.visualizer, NULL, &dst);
|
||||
}
|
||||
}
|
||||
|
||||
static Thing *CreateLogicalDeviceThing(Thing *parent, const SDL_AudioDeviceID which, const float x, const float y)
|
||||
{
|
||||
static const ThingType can_be_dropped_onto[] = { THING_TRASHCAN, THING_NULL };
|
||||
@ -751,9 +923,16 @@ static Thing *CreateLogicalDeviceThing(Thing *parent, const SDL_AudioDeviceID wh
|
||||
thing->data.logdev.devid = which;
|
||||
thing->data.logdev.iscapture = iscapture;
|
||||
thing->data.logdev.physdev = physthing;
|
||||
thing->data.logdev.visualizer = SDL_CreateTexture(state->renderers[0], SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, VISUALIZER_WIDTH, VISUALIZER_HEIGHT);
|
||||
thing->data.logdev.postmix_lock = SDL_CreateMutex();
|
||||
if (thing->data.logdev.visualizer) {
|
||||
SDL_SetTextureBlendMode(thing->data.logdev.visualizer, SDL_BLENDMODE_BLEND);
|
||||
}
|
||||
thing->line_connected_to = physthing;
|
||||
thing->ontick = LogicalDeviceThing_ontick;
|
||||
thing->ondrag = DeviceThing_ondrag;
|
||||
thing->ondrop = LogicalDeviceThing_ondrop;
|
||||
thing->ondraw = LogicalDeviceThing_ondraw;
|
||||
thing->can_be_dropped_onto = can_be_dropped_onto;
|
||||
|
||||
SetLogicalDeviceTitlebar(thing);
|
||||
@ -762,14 +941,16 @@ static Thing *CreateLogicalDeviceThing(Thing *parent, const SDL_AudioDeviceID wh
|
||||
|
||||
static void SetPhysicalDeviceTitlebar(Thing *thing)
|
||||
{
|
||||
int frames = 0;
|
||||
SDL_AudioSpec *spec = &thing->data.physdev.spec;
|
||||
SDL_GetAudioDeviceFormat(thing->data.physdev.devid, spec);
|
||||
SDL_GetAudioDeviceFormat(thing->data.physdev.devid, spec, &frames);
|
||||
SDL_free(thing->titlebar);
|
||||
if (thing->data.physdev.devid == SDL_AUDIO_DEVICE_DEFAULT_CAPTURE) {
|
||||
SDL_asprintf(&thing->titlebar, "Default system device (CAPTURE, %s, %s, %uHz)", AudioFmtToString(spec->format), AudioChansToStr(spec->channels), (unsigned int) spec->freq);
|
||||
SDL_asprintf(&thing->titlebar, "Default system device (CAPTURE, %s, %s, %uHz, %d frames)", AudioFmtToString(spec->format), AudioChansToStr(spec->channels), (unsigned int) spec->freq, frames);
|
||||
} else if (thing->data.physdev.devid == SDL_AUDIO_DEVICE_DEFAULT_OUTPUT) {
|
||||
SDL_asprintf(&thing->titlebar, "Default system device (OUTPUT, %s, %s, %uHz)", AudioFmtToString(spec->format), AudioChansToStr(spec->channels), (unsigned int) spec->freq);
|
||||
SDL_asprintf(&thing->titlebar, "Default system device (OUTPUT, %s, %s, %uHz, %d frames)", AudioFmtToString(spec->format), AudioChansToStr(spec->channels), (unsigned int) spec->freq, frames);
|
||||
} else {
|
||||
SDL_asprintf(&thing->titlebar, "Physical device #%u (%s, \"%s\", %s, %s, %uHz)", (unsigned int) thing->data.physdev.devid, thing->data.physdev.iscapture ? "CAPTURE" : "OUTPUT", thing->data.physdev.name, AudioFmtToString(spec->format), AudioChansToStr(spec->channels), (unsigned int) spec->freq);
|
||||
SDL_asprintf(&thing->titlebar, "Physical device #%u (%s, \"%s\", %s, %s, %uHz, %d frames)", (unsigned int) thing->data.physdev.devid, thing->data.physdev.iscapture ? "CAPTURE" : "OUTPUT", thing->data.physdev.name, AudioFmtToString(spec->format), AudioChansToStr(spec->channels), (unsigned int) spec->freq, frames);
|
||||
}
|
||||
}
|
||||
|
||||
@ -965,7 +1146,7 @@ static void Loop(void)
|
||||
case SDL_EVENT_AUDIO_DEVICE_ADDED:
|
||||
CreatePhysicalDeviceThing(event.adevice.which, event.adevice.iscapture);
|
||||
break;
|
||||
|
||||
|
||||
case SDL_EVENT_AUDIO_DEVICE_REMOVED: {
|
||||
const SDL_AudioDeviceID which = event.adevice.which;
|
||||
Thing *i, *next;
|
||||
|
22
external/sdl/SDL/test/testaudiocapture.c
vendored
22
external/sdl/SDL/test/testaudiocapture.c
vendored
@ -28,8 +28,8 @@ static int done = 0;
|
||||
|
||||
static void loop(void)
|
||||
{
|
||||
const SDL_AudioDeviceID devid_in = SDL_GetAudioStreamBinding(stream_in);
|
||||
const SDL_AudioDeviceID devid_out = SDL_GetAudioStreamBinding(stream_out);
|
||||
const SDL_AudioDeviceID devid_in = SDL_GetAudioStreamDevice(stream_in);
|
||||
const SDL_AudioDeviceID devid_out = SDL_GetAudioStreamDevice(stream_out);
|
||||
SDL_bool please_quit = SDL_FALSE;
|
||||
SDL_Event e;
|
||||
|
||||
@ -54,7 +54,7 @@ static void loop(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (!SDL_IsAudioDevicePaused(devid_in)) {
|
||||
if (!SDL_AudioDevicePaused(devid_in)) {
|
||||
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
|
||||
} else {
|
||||
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
|
||||
@ -179,12 +179,16 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
SDL_PauseAudioDevice(device);
|
||||
SDL_GetAudioDeviceFormat(device, &outspec);
|
||||
stream_out = SDL_CreateAndBindAudioStream(device, &outspec);
|
||||
SDL_GetAudioDeviceFormat(device, &outspec, NULL);
|
||||
stream_out = SDL_CreateAudioStream(&outspec, &outspec);
|
||||
if (!stream_out) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create an audio stream for playback: %s!\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
exit(1);
|
||||
} else if (SDL_BindAudioStream(device, stream_out) == -1) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't bind an audio stream for playback: %s!\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
SDL_Log("Opening capture device %s%s%s...\n",
|
||||
@ -199,12 +203,16 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
SDL_PauseAudioDevice(device);
|
||||
SDL_GetAudioDeviceFormat(device, &inspec);
|
||||
stream_in = SDL_CreateAndBindAudioStream(device, &inspec);
|
||||
SDL_GetAudioDeviceFormat(device, &inspec, NULL);
|
||||
stream_in = SDL_CreateAudioStream(&inspec, &inspec);
|
||||
if (!stream_in) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create an audio stream for capture: %s!\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
exit(1);
|
||||
} else if (SDL_BindAudioStream(device, stream_in) == -1) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't bind an audio stream for capture: %s!\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
SDL_SetAudioStreamFormat(stream_in, NULL, &outspec); /* make sure we output at the playback format. */
|
||||
|
19
external/sdl/SDL/test/testaudiohotplug.c
vendored
19
external/sdl/SDL/test/testaudiohotplug.c
vendored
@ -69,7 +69,7 @@ static void iteration(void)
|
||||
done = 1;
|
||||
}
|
||||
} else if (e.type == SDL_EVENT_AUDIO_DEVICE_ADDED) {
|
||||
const SDL_AudioDeviceID which = (SDL_AudioDeviceID ) e.adevice.which;
|
||||
const SDL_AudioDeviceID which = (SDL_AudioDeviceID) e.adevice.which;
|
||||
const SDL_bool iscapture = e.adevice.iscapture ? SDL_TRUE : SDL_FALSE;
|
||||
char *name = SDL_GetAudioDeviceName(which);
|
||||
if (name != NULL) {
|
||||
@ -80,20 +80,15 @@ static void iteration(void)
|
||||
continue;
|
||||
}
|
||||
if (!iscapture) {
|
||||
dev = SDL_OpenAudioDevice(which, &spec);
|
||||
if (!dev) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open '%s': %s\n", name, SDL_GetError());
|
||||
SDL_AudioStream *stream = SDL_OpenAudioDeviceStream(which, &spec, NULL, NULL);
|
||||
if (!stream) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create/bind an audio stream to %u ('%s'): %s", (unsigned int) which, name, SDL_GetError());
|
||||
} else {
|
||||
SDL_AudioStream *stream;
|
||||
SDL_Log("Opened '%s' as %u\n", name, (unsigned int)dev);
|
||||
stream = SDL_CreateAndBindAudioStream(dev, &spec);
|
||||
if (!stream) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create/bind an audio stream to %u ('%s'): %s", (unsigned int) dev, name, SDL_GetError());
|
||||
SDL_CloseAudioDevice(dev);
|
||||
}
|
||||
SDL_Log("Opened '%s' as %u\n", name, (unsigned int) which);
|
||||
/* !!! FIXME: laziness, this used to loop the audio, but we'll just play it once for now on each connect. */
|
||||
SDL_PutAudioStreamData(stream, sound, soundlen);
|
||||
SDL_FlushAudioStream(stream);
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream));
|
||||
/* !!! FIXME: this is leaking the stream for now. We'll wire it up to a dictionary or whatever later. */
|
||||
}
|
||||
}
|
||||
@ -101,7 +96,7 @@ static void iteration(void)
|
||||
} else if (e.type == SDL_EVENT_AUDIO_DEVICE_REMOVED) {
|
||||
dev = (SDL_AudioDeviceID)e.adevice.which;
|
||||
SDL_Log("%s device %u removed.\n", devtypestr(e.adevice.iscapture), (unsigned int)dev);
|
||||
SDL_CloseAudioDevice(dev);
|
||||
/* !!! FIXME: we need to keep track of our streams and destroy them here. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
external/sdl/SDL/test/testaudioinfo.c
vendored
11
external/sdl/SDL/test/testaudioinfo.c
vendored
@ -19,6 +19,7 @@ print_devices(SDL_bool iscapture)
|
||||
SDL_AudioSpec spec;
|
||||
const char *typestr = ((iscapture) ? "capture" : "output");
|
||||
int n = 0;
|
||||
int frames;
|
||||
SDL_AudioDeviceID *devices = iscapture ? SDL_GetAudioCaptureDevices(&n) : SDL_GetAudioOutputDevices(&n);
|
||||
|
||||
if (devices == NULL) {
|
||||
@ -37,10 +38,11 @@ print_devices(SDL_bool iscapture)
|
||||
SDL_Log(" %d Error: %s\n", i, SDL_GetError());
|
||||
}
|
||||
|
||||
if (SDL_GetAudioDeviceFormat(devices[i], &spec) == 0) {
|
||||
if (SDL_GetAudioDeviceFormat(devices[i], &spec, &frames) == 0) {
|
||||
SDL_Log(" Sample Rate: %d\n", spec.freq);
|
||||
SDL_Log(" Channels: %d\n", spec.channels);
|
||||
SDL_Log(" SDL_AudioFormat: %X\n", spec.format);
|
||||
SDL_Log(" Buffer Size: %d frames\n", frames);
|
||||
}
|
||||
}
|
||||
SDL_Log("\n");
|
||||
@ -53,6 +55,7 @@ int main(int argc, char **argv)
|
||||
SDL_AudioSpec spec;
|
||||
int i;
|
||||
int n;
|
||||
int frames;
|
||||
SDLTest_CommonState *state;
|
||||
|
||||
/* Initialize test framework */
|
||||
@ -92,22 +95,24 @@ int main(int argc, char **argv)
|
||||
print_devices(SDL_FALSE);
|
||||
print_devices(SDL_TRUE);
|
||||
|
||||
if (SDL_GetAudioDeviceFormat(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &spec) < 0) {
|
||||
if (SDL_GetAudioDeviceFormat(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &spec, &frames) < 0) {
|
||||
SDL_Log("Error when calling SDL_GetAudioDeviceFormat(default output): %s\n", SDL_GetError());
|
||||
} else {
|
||||
SDL_Log("Default Output Device:\n");
|
||||
SDL_Log("Sample Rate: %d\n", spec.freq);
|
||||
SDL_Log("Channels: %d\n", spec.channels);
|
||||
SDL_Log("SDL_AudioFormat: %X\n", spec.format);
|
||||
SDL_Log("Buffer Size: %d frames\n", frames);
|
||||
}
|
||||
|
||||
if (SDL_GetAudioDeviceFormat(SDL_AUDIO_DEVICE_DEFAULT_CAPTURE, &spec) < 0) {
|
||||
if (SDL_GetAudioDeviceFormat(SDL_AUDIO_DEVICE_DEFAULT_CAPTURE, &spec, &frames) < 0) {
|
||||
SDL_Log("Error when calling SDL_GetAudioDeviceFormat(default capture): %s\n", SDL_GetError());
|
||||
} else {
|
||||
SDL_Log("Default Capture Device:\n");
|
||||
SDL_Log("Sample Rate: %d\n", spec.freq);
|
||||
SDL_Log("Channels: %d\n", spec.channels);
|
||||
SDL_Log("SDL_AudioFormat: %X\n", spec.format);
|
||||
SDL_Log("Buffer Size: %d frames\n", frames);
|
||||
}
|
||||
|
||||
SDL_Quit();
|
||||
|
@ -24,24 +24,198 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#define SLIDER_WIDTH_PERC 500.f / 600.f
|
||||
#define SLIDER_HEIGHT_PERC 100.f / 480.f
|
||||
#define SLIDER_HEIGHT_PERC 70.f / 480.f
|
||||
|
||||
static int done;
|
||||
static SDLTest_CommonState *state;
|
||||
|
||||
static int multiplier = 100;
|
||||
static SDL_FRect slider_area;
|
||||
static SDL_FRect slider_fill_area;
|
||||
static SDL_AudioSpec spec;
|
||||
static SDL_AudioStream *stream;
|
||||
static Uint8 *audio_buf = NULL;
|
||||
static Uint32 audio_len = 0;
|
||||
|
||||
static SDL_bool auto_loop = SDL_TRUE;
|
||||
static SDL_bool auto_flush = SDL_FALSE;
|
||||
|
||||
static Uint64 last_get_callback = 0;
|
||||
static int last_get_amount_additional = 0;
|
||||
static int last_get_amount_total = 0;
|
||||
|
||||
typedef struct Slider
|
||||
{
|
||||
SDL_FRect area;
|
||||
SDL_bool changed;
|
||||
char fmtlabel[64];
|
||||
float pos;
|
||||
int flags;
|
||||
float min;
|
||||
float mid;
|
||||
float max;
|
||||
float value;
|
||||
} Slider;
|
||||
|
||||
#define NUM_SLIDERS 3
|
||||
Slider sliders[NUM_SLIDERS];
|
||||
static int active_slider = -1;
|
||||
|
||||
static void init_slider(int index, const char* fmtlabel, int flags, float value, float min, float max)
|
||||
{
|
||||
Slider* slider = &sliders[index];
|
||||
|
||||
slider->area.x = state->window_w * (1.f - SLIDER_WIDTH_PERC) / 2;
|
||||
slider->area.y = state->window_h * (0.2f + (index * SLIDER_HEIGHT_PERC * 1.4f));
|
||||
slider->area.w = SLIDER_WIDTH_PERC * state->window_w;
|
||||
slider->area.h = SLIDER_HEIGHT_PERC * state->window_h;
|
||||
slider->changed = SDL_TRUE;
|
||||
SDL_strlcpy(slider->fmtlabel, fmtlabel, SDL_arraysize(slider->fmtlabel));
|
||||
slider->flags = flags;
|
||||
slider->min = min;
|
||||
slider->max = max;
|
||||
slider->value = value;
|
||||
|
||||
if (slider->flags & 1) {
|
||||
slider->pos = (value - slider->min + 0.5f) / (slider->max - slider->min + 1.0f);
|
||||
} else {
|
||||
slider->pos = 0.5f;
|
||||
slider->mid = value;
|
||||
}
|
||||
}
|
||||
|
||||
static float lerp(float v0, float v1, float t)
|
||||
{
|
||||
return (1 - t) * v0 + t * v1;
|
||||
}
|
||||
|
||||
static void draw_text(SDL_Renderer* renderer, int x, int y, const char* text)
|
||||
{
|
||||
SDL_SetRenderDrawColor(renderer, 0xFD, 0xF6, 0xE3, 0xFF);
|
||||
SDLTest_DrawString(renderer, (float) x, (float) y, text);
|
||||
}
|
||||
|
||||
static void draw_textf(SDL_Renderer* renderer, int x, int y, const char* fmt, ...)
|
||||
{
|
||||
char text[256];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
SDL_vsnprintf(text, SDL_arraysize(text), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
draw_text(renderer, x, y, text);
|
||||
}
|
||||
|
||||
static void queue_audio()
|
||||
{
|
||||
Uint8* new_data = NULL;
|
||||
int new_len = 0;
|
||||
int retval = 0;
|
||||
SDL_AudioSpec new_spec;
|
||||
|
||||
new_spec.format = spec.format;
|
||||
new_spec.channels = (int) sliders[2].value;
|
||||
new_spec.freq = (int) sliders[1].value;
|
||||
|
||||
SDL_Log("Converting audio from %i to %i", spec.freq, new_spec.freq);
|
||||
|
||||
retval = retval ? retval : SDL_ConvertAudioSamples(&spec, audio_buf, audio_len, &new_spec, &new_data, &new_len);
|
||||
retval = retval ? retval : SDL_SetAudioStreamFormat(stream, &new_spec, NULL);
|
||||
retval = retval ? retval : SDL_PutAudioStreamData(stream, new_data, new_len);
|
||||
|
||||
if (auto_flush) {
|
||||
retval = retval ? retval : SDL_FlushAudioStream(stream);
|
||||
}
|
||||
|
||||
SDL_free(new_data);
|
||||
|
||||
if (retval) {
|
||||
SDL_Log("Failed to queue audio: %s", SDL_GetError());
|
||||
} else {
|
||||
SDL_Log("Queued audio");
|
||||
}
|
||||
}
|
||||
|
||||
static void skip_audio(float amount)
|
||||
{
|
||||
float speed;
|
||||
SDL_AudioSpec dst_spec, new_spec;
|
||||
int num_frames;
|
||||
int retval = 0;
|
||||
void* buf = NULL;
|
||||
|
||||
SDL_LockAudioStream(stream);
|
||||
|
||||
speed = SDL_GetAudioStreamFrequencyRatio(stream);
|
||||
SDL_GetAudioStreamFormat(stream, NULL, &dst_spec);
|
||||
|
||||
/* Gimme that crunchy audio */
|
||||
new_spec.format = SDL_AUDIO_S8;
|
||||
new_spec.channels = 1;
|
||||
new_spec.freq = 4000;
|
||||
|
||||
SDL_SetAudioStreamFrequencyRatio(stream, 100.0f);
|
||||
SDL_SetAudioStreamFormat(stream, NULL, &new_spec);
|
||||
|
||||
num_frames = (int)(new_spec.freq * ((speed * amount) / 100.0f));
|
||||
buf = SDL_malloc(num_frames);
|
||||
|
||||
if (buf != NULL) {
|
||||
retval = SDL_GetAudioStreamData(stream, buf, num_frames);
|
||||
SDL_free(buf);
|
||||
}
|
||||
|
||||
SDL_SetAudioStreamFormat(stream, NULL, &dst_spec);
|
||||
SDL_SetAudioStreamFrequencyRatio(stream, speed);
|
||||
|
||||
SDL_UnlockAudioStream(stream);
|
||||
|
||||
if (retval >= 0) {
|
||||
SDL_Log("Skipped %.2f seconds", amount);
|
||||
} else {
|
||||
SDL_Log("Failed to skip: %s", SDL_GetError());
|
||||
}
|
||||
}
|
||||
|
||||
static const char *AudioFmtToString(const SDL_AudioFormat fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
#define FMTCASE(x) case SDL_AUDIO_##x: return #x
|
||||
FMTCASE(U8);
|
||||
FMTCASE(S8);
|
||||
FMTCASE(S16LE);
|
||||
FMTCASE(S16BE);
|
||||
FMTCASE(S32LE);
|
||||
FMTCASE(S32BE);
|
||||
FMTCASE(F32LE);
|
||||
FMTCASE(F32BE);
|
||||
#undef FMTCASE
|
||||
}
|
||||
return "?";
|
||||
}
|
||||
|
||||
static const char *AudioChansToStr(const int channels)
|
||||
{
|
||||
switch (channels) {
|
||||
case 1: return "Mono";
|
||||
case 2: return "Stereo";
|
||||
case 3: return "2.1";
|
||||
case 4: return "Quad";
|
||||
case 5: return "4.1";
|
||||
case 6: return "5.1";
|
||||
case 7: return "6.1";
|
||||
case 8: return "7.1";
|
||||
default: break;
|
||||
}
|
||||
return "?";
|
||||
}
|
||||
|
||||
static void loop(void)
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
SDL_Event e;
|
||||
int newmultiplier = multiplier;
|
||||
SDL_FPoint p;
|
||||
SDL_AudioSpec src_spec, dst_spec;
|
||||
int available_bytes = 0;
|
||||
float available_seconds = 0;
|
||||
|
||||
while (SDL_PollEvent(&e)) {
|
||||
SDLTest_CommonEvent(state, &e, &done);
|
||||
@ -50,63 +224,148 @@ static void loop(void)
|
||||
emscripten_cancel_main_loop();
|
||||
}
|
||||
#endif
|
||||
if (e.type == SDL_EVENT_MOUSE_MOTION) {
|
||||
if (e.motion.state & SDL_BUTTON_LMASK) {
|
||||
const SDL_FPoint p = { e.motion.x, e.motion.y };
|
||||
if (SDL_PointInRectFloat(&p, &slider_area)) {
|
||||
const float w = SDL_roundf(p.x - slider_area.x);
|
||||
slider_fill_area.w = w;
|
||||
newmultiplier = ((int) ((w / slider_area.w) * 800.0f)) - 400;
|
||||
if (e.type == SDL_EVENT_KEY_DOWN) {
|
||||
SDL_Keycode sym = e.key.keysym.sym;
|
||||
if (sym == SDLK_q) {
|
||||
if (SDL_AudioDevicePaused(state->audio_id)) {
|
||||
SDL_ResumeAudioDevice(state->audio_id);
|
||||
} else {
|
||||
SDL_PauseAudioDevice(state->audio_id);
|
||||
}
|
||||
} else if (sym == SDLK_w) {
|
||||
auto_loop = auto_loop ? SDL_FALSE : SDL_TRUE;
|
||||
} else if (sym == SDLK_e) {
|
||||
auto_flush = auto_flush ? SDL_FALSE : SDL_TRUE;
|
||||
} else if (sym == SDLK_a) {
|
||||
SDL_ClearAudioStream(stream);
|
||||
SDL_Log("Cleared audio stream");
|
||||
} else if (sym == SDLK_s) {
|
||||
queue_audio();
|
||||
} else if (sym == SDLK_d) {
|
||||
float amount = 1.0f;
|
||||
amount *= (e.key.keysym.mod & SDL_KMOD_CTRL) ? 10.0f : 1.0f;
|
||||
amount *= (e.key.keysym.mod & SDL_KMOD_SHIFT) ? 10.0f : 1.0f;
|
||||
skip_audio(amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (multiplier != newmultiplier) {
|
||||
SDL_AudioSpec newspec;
|
||||
char title[64];
|
||||
int newfreq = spec.freq;
|
||||
|
||||
multiplier = newmultiplier;
|
||||
if (multiplier == 0) {
|
||||
SDL_snprintf(title, sizeof (title), "Drag the slider: Normal speed");
|
||||
} else if (multiplier < 0) {
|
||||
SDL_snprintf(title, sizeof (title), "Drag the slider: %.2fx slow", (-multiplier / 100.0f) + 1.0f);
|
||||
} else {
|
||||
SDL_snprintf(title, sizeof (title), "Drag the slider: %.2fx fast", (multiplier / 100.0f) + 1.0f);
|
||||
if (SDL_GetMouseState(&p.x, &p.y) & SDL_BUTTON_LMASK) {
|
||||
if (active_slider == -1) {
|
||||
for (i = 0; i < NUM_SLIDERS; ++i) {
|
||||
if (SDL_PointInRectFloat(&p, &sliders[i].area)) {
|
||||
active_slider = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < state->num_windows; i++) {
|
||||
SDL_SetWindowTitle(state->windows[i], title);
|
||||
}
|
||||
|
||||
/* this math sucks, but whatever. */
|
||||
if (multiplier < 0) {
|
||||
newfreq = spec.freq + (int) ((spec.freq * (multiplier / 400.0f)) * 0.75f);
|
||||
} else if (multiplier > 0) {
|
||||
newfreq = spec.freq + (int) (spec.freq * (multiplier / 100.0f));
|
||||
}
|
||||
/* SDL_Log("newfreq=%d multiplier=%d\n", newfreq, multiplier); */
|
||||
SDL_memcpy(&newspec, &spec, sizeof (spec));
|
||||
newspec.freq = newfreq;
|
||||
SDL_SetAudioStreamFormat(stream, &newspec, NULL);
|
||||
} else {
|
||||
active_slider = -1;
|
||||
}
|
||||
|
||||
/* keep it looping. */
|
||||
if (SDL_GetAudioStreamAvailable(stream) < ((int) (audio_len / 2))) {
|
||||
SDL_PutAudioStreamData(stream, audio_buf, audio_len);
|
||||
if (active_slider != -1) {
|
||||
Slider* slider = &sliders[active_slider];
|
||||
|
||||
float value = (p.x - slider->area.x) / slider->area.w;
|
||||
value = SDL_clamp(value, 0.0f, 1.0f);
|
||||
slider->pos = value;
|
||||
|
||||
if (slider->flags & 1) {
|
||||
value = slider->min + (value * (slider->max - slider->min + 1.0f));
|
||||
value = SDL_clamp(value, slider->min, slider->max);
|
||||
} else {
|
||||
value = (value * 2.0f) - 1.0f;
|
||||
value = (value >= 0)
|
||||
? lerp(slider->mid, slider->max, value)
|
||||
: lerp(slider->mid, slider->min, -value);
|
||||
}
|
||||
|
||||
if (value != slider->value) {
|
||||
slider->value = value;
|
||||
slider->changed = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (sliders[0].changed) {
|
||||
sliders[0].changed = SDL_FALSE;
|
||||
SDL_SetAudioStreamFrequencyRatio(stream, sliders[0].value);
|
||||
}
|
||||
|
||||
if (SDL_GetAudioStreamFormat(stream, &src_spec, &dst_spec) == 0) {
|
||||
available_bytes = SDL_GetAudioStreamAvailable(stream);
|
||||
available_seconds = (float)available_bytes / (float)(SDL_AUDIO_FRAMESIZE(dst_spec) * dst_spec.freq);
|
||||
|
||||
/* keep it looping. */
|
||||
if (auto_loop && (available_seconds < 10.0f)) {
|
||||
queue_audio();
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < state->num_windows; i++) {
|
||||
SDL_SetRenderDrawColor(state->renderers[i], 0, 0, 255, 255);
|
||||
SDL_RenderClear(state->renderers[i]);
|
||||
SDL_SetRenderDrawColor(state->renderers[i], 0, 0, 0, 255);
|
||||
SDL_RenderFillRect(state->renderers[i], &slider_area);
|
||||
SDL_SetRenderDrawColor(state->renderers[i], 255, 0, 0, 255);
|
||||
SDL_RenderFillRect(state->renderers[i], &slider_fill_area);
|
||||
SDL_RenderPresent(state->renderers[i]);
|
||||
int draw_y = 0;
|
||||
SDL_Renderer* rend = state->renderers[i];
|
||||
|
||||
SDL_SetRenderDrawColor(rend, 0x00, 0x2B, 0x36, 0xFF);
|
||||
SDL_RenderClear(rend);
|
||||
|
||||
for (j = 0; j < NUM_SLIDERS; ++j) {
|
||||
Slider* slider = &sliders[j];
|
||||
SDL_FRect area;
|
||||
|
||||
SDL_copyp(&area, &slider->area);
|
||||
|
||||
SDL_SetRenderDrawColor(rend, 0x07, 0x36, 0x42, 0xFF);
|
||||
SDL_RenderFillRect(rend, &area);
|
||||
|
||||
area.w *= slider->pos;
|
||||
|
||||
SDL_SetRenderDrawColor(rend, 0x58, 0x6E, 0x75, 0xFF);
|
||||
SDL_RenderFillRect(rend, &area);
|
||||
|
||||
draw_textf(rend, (int)slider->area.x, (int)slider->area.y, slider->fmtlabel,
|
||||
(slider->flags & 2) ? ((float)(int)slider->value) : slider->value);
|
||||
}
|
||||
|
||||
draw_textf(rend, 0, draw_y, "%7s, Loop: %3s, Flush: %3s",
|
||||
SDL_AudioDevicePaused(state->audio_id) ? "Paused" : "Playing", auto_loop ? "On" : "Off", auto_flush ? "On" : "Off");
|
||||
draw_y += FONT_LINE_HEIGHT;
|
||||
|
||||
draw_textf(rend, 0, draw_y, "Available: %4.2f (%i bytes)", available_seconds, available_bytes);
|
||||
draw_y += FONT_LINE_HEIGHT;
|
||||
|
||||
SDL_LockAudioStream(stream);
|
||||
|
||||
draw_textf(rend, 0, draw_y, "Get Callback: %i/%i bytes, %2i ms ago",
|
||||
last_get_amount_additional, last_get_amount_total, (int)(SDL_GetTicks() - last_get_callback));
|
||||
draw_y += FONT_LINE_HEIGHT;
|
||||
|
||||
SDL_UnlockAudioStream(stream);
|
||||
|
||||
draw_y = state->window_h - FONT_LINE_HEIGHT * 3;
|
||||
|
||||
draw_textf(rend, 0, draw_y, "Wav: %6s/%6s/%i",
|
||||
AudioFmtToString(spec.format), AudioChansToStr(spec.channels), spec.freq);
|
||||
draw_y += FONT_LINE_HEIGHT;
|
||||
|
||||
draw_textf(rend, 0, draw_y, "Src: %6s/%6s/%i",
|
||||
AudioFmtToString(src_spec.format), AudioChansToStr(src_spec.channels), src_spec.freq);
|
||||
draw_y += FONT_LINE_HEIGHT;
|
||||
|
||||
draw_textf(rend, 0, draw_y, "Dst: %6s/%6s/%i",
|
||||
AudioFmtToString(dst_spec.format), AudioChansToStr(dst_spec.channels), dst_spec.freq);
|
||||
draw_y += FONT_LINE_HEIGHT;
|
||||
|
||||
SDL_RenderPresent(rend);
|
||||
}
|
||||
}
|
||||
|
||||
static void SDLCALL our_get_callback(void *userdata, SDL_AudioStream *strm, int additional_amount, int total_amount)
|
||||
{
|
||||
last_get_callback = SDL_GetTicks();
|
||||
last_get_amount_additional = additional_amount;
|
||||
last_get_amount_total = total_amount;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *filename = NULL;
|
||||
@ -142,20 +401,14 @@ int main(int argc, char *argv[])
|
||||
i += consumed;
|
||||
}
|
||||
|
||||
slider_area.x = state->window_w * (1.f - SLIDER_WIDTH_PERC) / 2;
|
||||
slider_area.y = state->window_h * (1.f - SLIDER_HEIGHT_PERC) / 2;
|
||||
slider_area.w = SLIDER_WIDTH_PERC * state->window_w;
|
||||
slider_area.h = SLIDER_HEIGHT_PERC * state->window_h;
|
||||
|
||||
slider_fill_area = slider_area;
|
||||
slider_fill_area.w /= 2;
|
||||
|
||||
/* Load the SDL library */
|
||||
if (!SDLTest_CommonInit(state)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
FONT_CHARACTER_SIZE = 16;
|
||||
|
||||
filename = GetResourceFilename(filename, "sample.wav");
|
||||
rc = SDL_LoadWAV(filename, &spec, &audio_buf, &audio_len);
|
||||
SDL_free(filename);
|
||||
@ -166,12 +419,17 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
init_slider(0, "Speed: %3.2fx", 0x0, 1.0f, 0.2f, 5.0f);
|
||||
init_slider(1, "Freq: %g", 0x2, (float)spec.freq, 4000.0f, 192000.0f);
|
||||
init_slider(2, "Channels: %g", 0x3, (float)spec.channels, 1.0f, 8.0f);
|
||||
|
||||
for (i = 0; i < state->num_windows; i++) {
|
||||
SDL_SetWindowTitle(state->windows[i], "Drag the slider: Normal speed");
|
||||
SDL_SetWindowTitle(state->windows[i], "Resampler Test");
|
||||
}
|
||||
|
||||
stream = SDL_CreateAudioStream(&spec, &spec);
|
||||
SDL_PutAudioStreamData(stream, audio_buf, audio_len);
|
||||
SDL_SetAudioStreamGetCallback(stream, our_get_callback, NULL);
|
||||
|
||||
SDL_BindAudioStream(state->audio_id, stream);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
@ -182,10 +440,10 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
#endif
|
||||
|
||||
SDLTest_CleanupTextDrawing();
|
||||
SDL_DestroyAudioStream(stream);
|
||||
SDL_free(audio_buf);
|
||||
SDLTest_CommonQuit(state);
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
448
external/sdl/SDL/test/testautomation_audio.c
vendored
448
external/sdl/SDL/test/testautomation_audio.c
vendored
@ -176,13 +176,13 @@ static int audio_initOpenCloseQuitAudio(void *arg)
|
||||
case 0:
|
||||
/* Set standard desired spec */
|
||||
desired.freq = 22050;
|
||||
desired.format = SDL_AUDIO_S16SYS;
|
||||
desired.format = SDL_AUDIO_S16;
|
||||
desired.channels = 2;
|
||||
|
||||
case 1:
|
||||
/* Set custom desired spec */
|
||||
desired.freq = 48000;
|
||||
desired.format = SDL_AUDIO_F32SYS;
|
||||
desired.format = SDL_AUDIO_F32;
|
||||
desired.channels = 2;
|
||||
break;
|
||||
}
|
||||
@ -261,14 +261,14 @@ static int audio_pauseUnpauseAudio(void *arg)
|
||||
case 0:
|
||||
/* Set standard desired spec */
|
||||
desired.freq = 22050;
|
||||
desired.format = SDL_AUDIO_S16SYS;
|
||||
desired.format = SDL_AUDIO_S16;
|
||||
desired.channels = 2;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* Set custom desired spec */
|
||||
desired.freq = 48000;
|
||||
desired.format = SDL_AUDIO_F32SYS;
|
||||
desired.format = SDL_AUDIO_F32;
|
||||
desired.channels = 2;
|
||||
break;
|
||||
}
|
||||
@ -441,18 +441,34 @@ static int audio_printCurrentAudioDriver(void *arg)
|
||||
}
|
||||
|
||||
/* Definition of all formats, channels, and frequencies used to test audio conversions */
|
||||
static SDL_AudioFormat g_audioFormats[] = { SDL_AUDIO_S8, SDL_AUDIO_U8, SDL_AUDIO_S16LSB, SDL_AUDIO_S16MSB, SDL_AUDIO_S16SYS, SDL_AUDIO_S16,
|
||||
SDL_AUDIO_S32LSB, SDL_AUDIO_S32MSB, SDL_AUDIO_S32SYS, SDL_AUDIO_S32,
|
||||
SDL_AUDIO_F32LSB, SDL_AUDIO_F32MSB, SDL_AUDIO_F32SYS, SDL_AUDIO_F32 };
|
||||
static const char *g_audioFormatsVerbose[] = { "SDL_AUDIO_S8", "SDL_AUDIO_U8", "SDL_AUDIO_S16LSB", "SDL_AUDIO_S16MSB", "SDL_AUDIO_S16SYS", "SDL_AUDIO_S16",
|
||||
"SDL_AUDIO_S32LSB", "SDL_AUDIO_S32MSB", "SDL_AUDIO_S32SYS", "SDL_AUDIO_S32",
|
||||
"SDL_AUDIO_F32LSB", "SDL_AUDIO_F32MSB", "SDL_AUDIO_F32SYS", "SDL_AUDIO_F32" };
|
||||
static SDL_AudioFormat g_audioFormats[] = {
|
||||
SDL_AUDIO_S8, SDL_AUDIO_U8,
|
||||
SDL_AUDIO_S16LE, SDL_AUDIO_S16BE,
|
||||
SDL_AUDIO_S32LE, SDL_AUDIO_S32BE,
|
||||
SDL_AUDIO_F32LE, SDL_AUDIO_F32BE
|
||||
};
|
||||
static const char *g_audioFormatsVerbose[] = {
|
||||
"SDL_AUDIO_S8", "SDL_AUDIO_U8",
|
||||
"SDL_AUDIO_S16LE", "SDL_AUDIO_S16BE",
|
||||
"SDL_AUDIO_S32LE", "SDL_AUDIO_S32BE",
|
||||
"SDL_AUDIO_F32LE", "SDL_AUDIO_F32BE"
|
||||
};
|
||||
static const int g_numAudioFormats = SDL_arraysize(g_audioFormats);
|
||||
static Uint8 g_audioChannels[] = { 1, 2, 4, 6 };
|
||||
static const int g_numAudioChannels = SDL_arraysize(g_audioChannels);
|
||||
static int g_audioFrequencies[] = { 11025, 22050, 44100, 48000 };
|
||||
static const int g_numAudioFrequencies = SDL_arraysize(g_audioFrequencies);
|
||||
|
||||
/* Verify the audio formats are laid out as expected */
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_AUDIO_U8_FORMAT, SDL_AUDIO_U8 == SDL_AUDIO_BITSIZE(8));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_AUDIO_S8_FORMAT, SDL_AUDIO_S8 == (SDL_AUDIO_BITSIZE(8) | SDL_AUDIO_MASK_SIGNED));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_AUDIO_S16LE_FORMAT, SDL_AUDIO_S16LE == (SDL_AUDIO_BITSIZE(16) | SDL_AUDIO_MASK_SIGNED));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_AUDIO_S16BE_FORMAT, SDL_AUDIO_S16BE == (SDL_AUDIO_S16LE | SDL_AUDIO_MASK_BIG_ENDIAN));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_AUDIO_S32LE_FORMAT, SDL_AUDIO_S32LE == (SDL_AUDIO_BITSIZE(32) | SDL_AUDIO_MASK_SIGNED));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_AUDIO_S32BE_FORMAT, SDL_AUDIO_S32BE == (SDL_AUDIO_S32LE | SDL_AUDIO_MASK_BIG_ENDIAN));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_AUDIO_F32LE_FORMAT, SDL_AUDIO_F32LE == (SDL_AUDIO_BITSIZE(32) | SDL_AUDIO_MASK_FLOAT | SDL_AUDIO_MASK_SIGNED));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_AUDIO_F32BE_FORMAT, SDL_AUDIO_F32BE == (SDL_AUDIO_F32LE | SDL_AUDIO_MASK_BIG_ENDIAN));
|
||||
|
||||
/**
|
||||
* \brief Builds various audio conversion structures
|
||||
*
|
||||
@ -466,7 +482,7 @@ static int audio_buildAudioStream(void *arg)
|
||||
int i, ii, j, jj, k, kk;
|
||||
|
||||
/* No conversion needed */
|
||||
spec1.format = SDL_AUDIO_S16LSB;
|
||||
spec1.format = SDL_AUDIO_S16LE;
|
||||
spec1.channels = 2;
|
||||
spec1.freq = 22050;
|
||||
stream = SDL_CreateAudioStream(&spec1, &spec1);
|
||||
@ -478,7 +494,7 @@ static int audio_buildAudioStream(void *arg)
|
||||
spec1.format = SDL_AUDIO_S8;
|
||||
spec1.channels = 1;
|
||||
spec1.freq = 22050;
|
||||
spec2.format = SDL_AUDIO_S16LSB;
|
||||
spec2.format = SDL_AUDIO_S16LE;
|
||||
spec2.channels = 2;
|
||||
spec2.freq = 44100;
|
||||
stream = SDL_CreateAudioStream(&spec1, &spec2);
|
||||
@ -533,7 +549,7 @@ static int audio_buildAudioStreamNegative(void *arg)
|
||||
spec1.format = SDL_AUDIO_S8;
|
||||
spec1.channels = 1;
|
||||
spec1.freq = 22050;
|
||||
spec2.format = SDL_AUDIO_S16LSB;
|
||||
spec2.format = SDL_AUDIO_S16LE;
|
||||
spec2.channels = 2;
|
||||
spec2.freq = 44100;
|
||||
|
||||
@ -546,7 +562,7 @@ static int audio_buildAudioStreamNegative(void *arg)
|
||||
spec1.format = SDL_AUDIO_S8;
|
||||
spec1.channels = 1;
|
||||
spec1.freq = 22050;
|
||||
spec2.format = SDL_AUDIO_S16LSB;
|
||||
spec2.format = SDL_AUDIO_S16LE;
|
||||
spec2.channels = 2;
|
||||
spec2.freq = 44100;
|
||||
|
||||
@ -692,54 +708,65 @@ static int audio_convertAudio(void *arg)
|
||||
} else {
|
||||
Uint8 *dst_buf = NULL, *src_buf = NULL;
|
||||
int dst_len = 0, src_len = 0, real_dst_len = 0;
|
||||
int l = 64;
|
||||
int src_samplesize, dst_samplesize;
|
||||
int l = 64, m;
|
||||
int src_framesize, dst_framesize;
|
||||
int src_silence, dst_silence;
|
||||
|
||||
src_samplesize = (SDL_AUDIO_BITSIZE(spec1.format) / 8) * spec1.channels;
|
||||
dst_samplesize = (SDL_AUDIO_BITSIZE(spec2.format) / 8) * spec2.channels;
|
||||
src_framesize = SDL_AUDIO_FRAMESIZE(spec1);
|
||||
dst_framesize = SDL_AUDIO_FRAMESIZE(spec2);
|
||||
|
||||
|
||||
/* Create some random data to convert */
|
||||
src_len = l * src_samplesize;
|
||||
src_len = l * src_framesize;
|
||||
SDLTest_Log("Creating dummy sample buffer of %i length (%i bytes)", l, src_len);
|
||||
src_buf = (Uint8 *)SDL_malloc(src_len);
|
||||
SDLTest_AssertCheck(dst_buf != NULL, "Check src data buffer to convert is not NULL");
|
||||
SDLTest_AssertCheck(src_buf != NULL, "Check src data buffer to convert is not NULL");
|
||||
if (src_buf == NULL) {
|
||||
return TEST_ABORTED;
|
||||
}
|
||||
|
||||
src_len = src_len & ~(src_samplesize - 1);
|
||||
dst_len = dst_samplesize * (src_len / src_samplesize);
|
||||
if (spec1.freq < spec2.freq) {
|
||||
const double mult = ((double)spec2.freq) / ((double)spec1.freq);
|
||||
dst_len *= (int) SDL_ceil(mult);
|
||||
}
|
||||
src_silence = SDL_GetSilenceValueForFormat(spec1.format);
|
||||
SDL_memset(src_buf, src_silence, src_len);
|
||||
|
||||
dst_len = dst_len & ~(dst_samplesize - 1);
|
||||
dst_buf = (Uint8 *)SDL_calloc(1, dst_len);
|
||||
dst_len = ((int)((((Sint64)l * spec2.freq) - 1) / spec1.freq) + 1) * dst_framesize;
|
||||
dst_buf = (Uint8 *)SDL_malloc(dst_len);
|
||||
SDLTest_AssertCheck(dst_buf != NULL, "Check dst data buffer to convert is not NULL");
|
||||
if (dst_buf == NULL) {
|
||||
return TEST_ABORTED;
|
||||
}
|
||||
|
||||
real_dst_len = SDL_GetAudioStreamAvailable(stream);
|
||||
SDLTest_AssertCheck(0 == real_dst_len, "Verify available (pre-put); expected: %i; got: %i", 0, real_dst_len);
|
||||
|
||||
/* Run the audio converter */
|
||||
if (SDL_PutAudioStreamData(stream, src_buf, src_len) < 0 ||
|
||||
SDL_FlushAudioStream(stream) < 0) {
|
||||
return TEST_ABORTED;
|
||||
}
|
||||
|
||||
real_dst_len = SDL_GetAudioStreamAvailable(stream);
|
||||
SDLTest_AssertCheck(dst_len == real_dst_len, "Verify available (post-put); expected: %i; got: %i", dst_len, real_dst_len);
|
||||
|
||||
real_dst_len = SDL_GetAudioStreamData(stream, dst_buf, dst_len);
|
||||
SDLTest_AssertCheck(real_dst_len > 0, "Verify result value; expected: > 0; got: %i", real_dst_len);
|
||||
if (real_dst_len < 0) {
|
||||
SDLTest_AssertCheck(dst_len == real_dst_len, "Verify result value; expected: %i; got: %i", dst_len, real_dst_len);
|
||||
if (dst_len != real_dst_len) {
|
||||
return TEST_ABORTED;
|
||||
}
|
||||
|
||||
real_dst_len = SDL_GetAudioStreamAvailable(stream);
|
||||
SDLTest_AssertCheck(0 == real_dst_len, "Verify available (post-get); expected: %i; got: %i", 0, real_dst_len);
|
||||
|
||||
dst_silence = SDL_GetSilenceValueForFormat(spec2.format);
|
||||
|
||||
for (m = 0; m < dst_len; ++m) {
|
||||
if (dst_buf[m] != dst_silence) {
|
||||
SDLTest_LogError("Output buffer is not silent");
|
||||
return TEST_ABORTED;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_DestroyAudioStream(stream);
|
||||
/* Free converted buffer */
|
||||
SDL_free(src_buf);
|
||||
SDL_free(dst_buf);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -794,24 +821,30 @@ static int audio_resampleLoss(void *arg)
|
||||
double signal_to_noise;
|
||||
double max_error;
|
||||
} test_specs[] = {
|
||||
{ 50, 440, 0, 44100, 48000, 60, 0.0025 },
|
||||
{ 50, 5000, SDL_PI_D / 2, 20000, 10000, 65, 0.0010 },
|
||||
{ 50, 440, 0, 44100, 48000, 80, 0.0009 },
|
||||
{ 50, 5000, SDL_PI_D / 2, 20000, 10000, 999, 0.0001 },
|
||||
{ 50, 440, 0, 22050, 96000, 79, 0.0120 },
|
||||
{ 50, 440, 0, 96000, 22050, 80, 0.0002 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
int spec_idx = 0;
|
||||
int min_channels = 1;
|
||||
int max_channels = 1 /*8*/;
|
||||
int num_channels = min_channels;
|
||||
|
||||
for (spec_idx = 0; test_specs[spec_idx].time > 0; ++spec_idx) {
|
||||
for (spec_idx = 0; test_specs[spec_idx].time > 0;) {
|
||||
const struct test_spec_t *spec = &test_specs[spec_idx];
|
||||
const int frames_in = spec->time * spec->rate_in;
|
||||
const int frames_target = spec->time * spec->rate_out;
|
||||
const int len_in = frames_in * (int)sizeof(float);
|
||||
const int len_target = frames_target * (int)sizeof(float);
|
||||
const int len_in = (frames_in * num_channels) * (int)sizeof(float);
|
||||
const int len_target = (frames_target * num_channels) * (int)sizeof(float);
|
||||
|
||||
SDL_AudioSpec tmpspec1, tmpspec2;
|
||||
Uint64 tick_beg = 0;
|
||||
Uint64 tick_end = 0;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int ret = 0;
|
||||
SDL_AudioStream *stream = NULL;
|
||||
float *buf_in = NULL;
|
||||
@ -826,10 +859,10 @@ static int audio_resampleLoss(void *arg)
|
||||
spec->time, spec->freq, spec->phase, spec->rate_in, spec->rate_out);
|
||||
|
||||
tmpspec1.format = SDL_AUDIO_F32;
|
||||
tmpspec1.channels = 1;
|
||||
tmpspec1.channels = num_channels;
|
||||
tmpspec1.freq = spec->rate_in;
|
||||
tmpspec2.format = SDL_AUDIO_F32;
|
||||
tmpspec2.channels = 1;
|
||||
tmpspec2.channels = num_channels;
|
||||
tmpspec2.freq = spec->rate_out;
|
||||
stream = SDL_CreateAudioStream(&tmpspec1, &tmpspec2);
|
||||
SDLTest_AssertPass("Call to SDL_CreateAudioStream(SDL_AUDIO_F32, 1, %i, SDL_AUDIO_F32, 1, %i)", spec->rate_in, spec->rate_out);
|
||||
@ -846,7 +879,10 @@ static int audio_resampleLoss(void *arg)
|
||||
}
|
||||
|
||||
for (i = 0; i < frames_in; ++i) {
|
||||
*(buf_in + i) = (float)sine_wave_sample(i, spec->rate_in, spec->freq, spec->phase);
|
||||
float f = (float)sine_wave_sample(i, spec->rate_in, spec->freq, spec->phase);
|
||||
for (j = 0; j < num_channels; ++j) {
|
||||
*(buf_in + (i * num_channels) + j) = f;
|
||||
}
|
||||
}
|
||||
|
||||
tick_beg = SDL_GetPerformanceCounter();
|
||||
@ -877,9 +913,7 @@ static int audio_resampleLoss(void *arg)
|
||||
|
||||
len_out = SDL_GetAudioStreamData(stream, buf_out, len_target);
|
||||
SDLTest_AssertPass("Call to SDL_GetAudioStreamData(stream, buf_out, %i)", len_target);
|
||||
/** !!! FIXME: SDL_AudioStream does not return output of the same length as
|
||||
** !!! FIXME: the input even if SDL_FlushAudioStream is called. */
|
||||
SDLTest_AssertCheck(len_out <= len_target, "Expected output length to be no larger than %i, got %i.",
|
||||
SDLTest_AssertCheck(len_out == len_target, "Expected output length to be no larger than %i, got %i.",
|
||||
len_target, len_out);
|
||||
SDL_DestroyAudioStream(stream);
|
||||
if (len_out > len_target) {
|
||||
@ -890,13 +924,15 @@ static int audio_resampleLoss(void *arg)
|
||||
tick_end = SDL_GetPerformanceCounter();
|
||||
SDLTest_Log("Resampling used %f seconds.", ((double)(tick_end - tick_beg)) / SDL_GetPerformanceFrequency());
|
||||
|
||||
for (i = 0; i < len_out / (int)sizeof(float); ++i) {
|
||||
const float output = *(buf_out + i);
|
||||
for (i = 0; i < frames_target; ++i) {
|
||||
const double target = sine_wave_sample(i, spec->rate_out, spec->freq, spec->phase);
|
||||
const double error = SDL_fabs(target - output);
|
||||
max_error = SDL_max(max_error, error);
|
||||
sum_squared_error += error * error;
|
||||
sum_squared_value += target * target;
|
||||
for (j = 0; j < num_channels; ++j) {
|
||||
const float output = *(buf_out + (i * num_channels) + j);
|
||||
const double error = SDL_fabs(target - output);
|
||||
max_error = SDL_max(max_error, error);
|
||||
sum_squared_error += error * error;
|
||||
sum_squared_value += target * target;
|
||||
}
|
||||
}
|
||||
SDL_free(buf_out);
|
||||
signal_to_noise = 10 * SDL_log10(sum_squared_value / sum_squared_error); /* decibel */
|
||||
@ -909,10 +945,303 @@ static int audio_resampleLoss(void *arg)
|
||||
signal_to_noise, spec->signal_to_noise);
|
||||
SDLTest_AssertCheck(max_error <= spec->max_error, "Maximum conversion error %f should be no more than %f.",
|
||||
max_error, spec->max_error);
|
||||
|
||||
if (++num_channels > max_channels) {
|
||||
num_channels = min_channels;
|
||||
++spec_idx;
|
||||
}
|
||||
}
|
||||
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check accuracy converting between audio formats.
|
||||
*
|
||||
* \sa SDL_ConvertAudioSamples
|
||||
*/
|
||||
static int audio_convertAccuracy(void *arg)
|
||||
{
|
||||
static SDL_AudioFormat formats[] = { SDL_AUDIO_S8, SDL_AUDIO_U8, SDL_AUDIO_S16, SDL_AUDIO_S32 };
|
||||
static const char* format_names[] = { "S8", "U8", "S16", "S32" };
|
||||
|
||||
int src_num = 65537 + 2048 + 48 + 256 + 100000;
|
||||
int src_len = src_num * sizeof(float);
|
||||
float* src_data = SDL_malloc(src_len);
|
||||
int i, j;
|
||||
|
||||
SDLTest_AssertCheck(src_data != NULL, "Expected source buffer to be created.");
|
||||
if (src_data == NULL) {
|
||||
return TEST_ABORTED;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
|
||||
/* Generate a uniform range of floats between [-1.0, 1.0] */
|
||||
for (i = 0; i < 65537; ++i) {
|
||||
src_data[j++] = ((float)i - 32768.0f) / 32768.0f;
|
||||
}
|
||||
|
||||
/* Generate floats close to 1.0 */
|
||||
const float max_val = 16777216.0f;
|
||||
|
||||
for (i = 0; i < 1024; ++i) {
|
||||
float f = (max_val + (float)(512 - i)) / max_val;
|
||||
src_data[j++] = f;
|
||||
src_data[j++] = -f;
|
||||
}
|
||||
|
||||
for (i = 0; i < 24; ++i) {
|
||||
float f = (max_val + (float)(3u << i)) / max_val;
|
||||
src_data[j++] = f;
|
||||
src_data[j++] = -f;
|
||||
}
|
||||
|
||||
/* Generate floats far outside the [-1.0, 1.0] range */
|
||||
for (i = 0; i < 128; ++i) {
|
||||
float f = 2.0f + (float) i;
|
||||
src_data[j++] = f;
|
||||
src_data[j++] = -f;
|
||||
}
|
||||
|
||||
/* Fill the rest with random floats between [-1.0, 1.0] */
|
||||
for (i = 0; i < 100000; ++i) {
|
||||
src_data[j++] = SDLTest_RandomSint32() / 2147483648.0f;
|
||||
}
|
||||
|
||||
/* Shuffle the data for good measure */
|
||||
for (i = src_num - 1; i > 0; --i) {
|
||||
float f = src_data[i];
|
||||
j = SDLTest_RandomIntegerInRange(0, i);
|
||||
src_data[i] = src_data[j];
|
||||
src_data[j] = f;
|
||||
}
|
||||
|
||||
for (i = 0; i < SDL_arraysize(formats); ++i) {
|
||||
SDL_AudioSpec src_spec, tmp_spec;
|
||||
Uint64 convert_begin, convert_end;
|
||||
Uint8 *tmp_data, *dst_data;
|
||||
int tmp_len, dst_len;
|
||||
int ret;
|
||||
|
||||
SDL_AudioFormat format = formats[i];
|
||||
const char* format_name = format_names[i];
|
||||
|
||||
/* Formats with > 23 bits can represent every value exactly */
|
||||
float min_delta = 1.0f;
|
||||
float max_delta = -1.0f;
|
||||
|
||||
/* Subtract 1 bit to account for sign */
|
||||
int bits = SDL_AUDIO_BITSIZE(format) - 1;
|
||||
float target_max_delta = (bits > 23) ? 0.0f : (1.0f / (float)(1 << bits));
|
||||
float target_min_delta = -target_max_delta;
|
||||
|
||||
src_spec.format = SDL_AUDIO_F32;
|
||||
src_spec.channels = 1;
|
||||
src_spec.freq = 44100;
|
||||
|
||||
tmp_spec.format = format;
|
||||
tmp_spec.channels = 1;
|
||||
tmp_spec.freq = 44100;
|
||||
|
||||
convert_begin = SDL_GetPerformanceCounter();
|
||||
|
||||
tmp_data = NULL;
|
||||
tmp_len = 0;
|
||||
ret = SDL_ConvertAudioSamples(&src_spec, (const Uint8*) src_data, src_len, &tmp_spec, &tmp_data, &tmp_len);
|
||||
SDLTest_AssertCheck(ret == 0, "Expected SDL_ConvertAudioSamples(F32->%s) to succeed", format_name);
|
||||
if (ret != 0) {
|
||||
SDL_free(src_data);
|
||||
return TEST_ABORTED;
|
||||
}
|
||||
|
||||
dst_data = NULL;
|
||||
dst_len = 0;
|
||||
ret = SDL_ConvertAudioSamples(&tmp_spec, tmp_data, tmp_len, &src_spec, &dst_data, &dst_len);
|
||||
SDLTest_AssertCheck(ret == 0, "Expected SDL_ConvertAudioSamples(%s->F32) to succeed", format_name);
|
||||
if (ret != 0) {
|
||||
SDL_free(tmp_data);
|
||||
SDL_free(src_data);
|
||||
return TEST_ABORTED;
|
||||
}
|
||||
|
||||
convert_end = SDL_GetPerformanceCounter();
|
||||
SDLTest_Log("Conversion via %s took %f seconds.", format_name, ((double)(convert_end - convert_begin)) / SDL_GetPerformanceFrequency());
|
||||
|
||||
SDL_free(tmp_data);
|
||||
|
||||
for (j = 0; j < src_num; ++j) {
|
||||
float x = src_data[j];
|
||||
float y = ((float*)dst_data)[j];
|
||||
float d = SDL_clamp(x, -1.0f, 1.0f) - y;
|
||||
|
||||
min_delta = SDL_min(min_delta, d);
|
||||
max_delta = SDL_max(max_delta, d);
|
||||
}
|
||||
|
||||
SDLTest_AssertCheck(min_delta >= target_min_delta, "%s has min delta of %+f, should be >= %+f", format_name, min_delta, target_min_delta);
|
||||
SDLTest_AssertCheck(max_delta <= target_max_delta, "%s has max delta of %+f, should be <= %+f", format_name, max_delta, target_max_delta);
|
||||
|
||||
SDL_free(dst_data);
|
||||
}
|
||||
|
||||
SDL_free(src_data);
|
||||
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check accuracy when switching between formats
|
||||
*
|
||||
* \sa SDL_SetAudioStreamFormat
|
||||
*/
|
||||
static int audio_formatChange(void *arg)
|
||||
{
|
||||
int i;
|
||||
SDL_AudioSpec spec1, spec2, spec3;
|
||||
int frames_1, frames_2, frames_3;
|
||||
int length_1, length_2, length_3;
|
||||
int retval = 0;
|
||||
int status = TEST_ABORTED;
|
||||
float* buffer_1 = NULL;
|
||||
float* buffer_2 = NULL;
|
||||
float* buffer_3 = NULL;
|
||||
SDL_AudioStream* stream = NULL;
|
||||
double max_error = 0;
|
||||
double sum_squared_error = 0;
|
||||
double sum_squared_value = 0;
|
||||
double signal_to_noise = 0;
|
||||
double target_max_error = 0.02;
|
||||
double target_signal_to_noise = 75.0;
|
||||
int sine_freq = 500;
|
||||
|
||||
spec1.format = SDL_AUDIO_F32;
|
||||
spec1.channels = 1;
|
||||
spec1.freq = 20000;
|
||||
|
||||
spec2.format = SDL_AUDIO_F32;
|
||||
spec2.channels = 1;
|
||||
spec2.freq = 40000;
|
||||
|
||||
spec3.format = SDL_AUDIO_F32;
|
||||
spec3.channels = 1;
|
||||
spec3.freq = 80000;
|
||||
|
||||
frames_1 = spec1.freq;
|
||||
frames_2 = spec2.freq;
|
||||
frames_3 = spec3.freq * 2;
|
||||
|
||||
length_1 = (int)(frames_1 * sizeof(*buffer_1));
|
||||
buffer_1 = (float*) SDL_malloc(length_1);
|
||||
if (!SDLTest_AssertCheck(buffer_1 != NULL, "Expected buffer_1 to be created.")) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
length_2 = (int)(frames_2 * sizeof(*buffer_2));
|
||||
buffer_2 = (float*) SDL_malloc(length_2);
|
||||
if (!SDLTest_AssertCheck(buffer_2 != NULL, "Expected buffer_2 to be created.")) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
length_3 = (int)(frames_3 * sizeof(*buffer_3));
|
||||
buffer_3 = (float*) SDL_malloc(length_3);
|
||||
if (!SDLTest_AssertCheck(buffer_3 != NULL, "Expected buffer_3 to be created.")) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < frames_1; ++i) {
|
||||
buffer_1[i] = (float) sine_wave_sample(i, spec1.freq, sine_freq, 0.0f);
|
||||
}
|
||||
|
||||
for (i = 0; i < frames_2; ++i) {
|
||||
buffer_2[i] = (float) sine_wave_sample(i, spec2.freq, sine_freq, 0.0f);
|
||||
}
|
||||
|
||||
stream = SDL_CreateAudioStream(NULL, NULL);
|
||||
if (!SDLTest_AssertCheck(stream != NULL, "Expected SDL_CreateAudioStream to succeed")) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
retval = SDL_SetAudioStreamFormat(stream, &spec1, &spec3);
|
||||
if (!SDLTest_AssertCheck(retval == 0, "Expected SDL_SetAudioStreamFormat(spec1, spec3) to succeed")) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
retval = SDL_GetAudioStreamAvailable(stream);
|
||||
if (!SDLTest_AssertCheck(retval == 0, "Expected SDL_GetAudioStreamAvailable return 0")) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
retval = SDL_PutAudioStreamData(stream, buffer_1, length_1);
|
||||
if (!SDLTest_AssertCheck(retval == 0, "Expected SDL_PutAudioStreamData(buffer_1) to succeed")) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
retval = SDL_FlushAudioStream(stream);
|
||||
if (!SDLTest_AssertCheck(retval == 0, "Expected SDL_FlushAudioStream to succeed")) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
retval = SDL_SetAudioStreamFormat(stream, &spec2, &spec3);
|
||||
if (!SDLTest_AssertCheck(retval == 0, "Expected SDL_SetAudioStreamFormat(spec2, spec3) to succeed")) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
retval = SDL_PutAudioStreamData(stream, buffer_2, length_2);
|
||||
if (!SDLTest_AssertCheck(retval == 0, "Expected SDL_PutAudioStreamData(buffer_1) to succeed")) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
retval = SDL_FlushAudioStream(stream);
|
||||
if (!SDLTest_AssertCheck(retval == 0, "Expected SDL_FlushAudioStream to succeed")) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
retval = SDL_GetAudioStreamAvailable(stream);
|
||||
if (!SDLTest_AssertCheck(retval == length_3, "Expected SDL_GetAudioStreamAvailable to return %i, got %i", length_3, retval)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
retval = SDL_GetAudioStreamData(stream, buffer_3, length_3);
|
||||
if (!SDLTest_AssertCheck(retval == length_3, "Expected SDL_GetAudioStreamData to return %i, got %i", length_3, retval)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
retval = SDL_GetAudioStreamAvailable(stream);
|
||||
if (!SDLTest_AssertCheck(retval == 0, "Expected SDL_GetAudioStreamAvailable to return 0")) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < frames_3; ++i) {
|
||||
const float output = buffer_3[i];
|
||||
const float target = (float) sine_wave_sample(i, spec3.freq, sine_freq, 0.0f);
|
||||
const double error = SDL_fabs(target - output);
|
||||
max_error = SDL_max(max_error, error);
|
||||
sum_squared_error += error * error;
|
||||
sum_squared_value += target * target;
|
||||
}
|
||||
|
||||
signal_to_noise = 10 * SDL_log10(sum_squared_value / sum_squared_error); /* decibel */
|
||||
SDLTest_AssertCheck(isfinite(sum_squared_value), "Sum of squared target should be finite.");
|
||||
SDLTest_AssertCheck(isfinite(sum_squared_error), "Sum of squared error should be finite.");
|
||||
/* Infinity is theoretically possible when there is very little to no noise */
|
||||
SDLTest_AssertCheck(!isnan(signal_to_noise), "Signal-to-noise ratio should not be NaN.");
|
||||
SDLTest_AssertCheck(isfinite(max_error), "Maximum conversion error should be finite.");
|
||||
SDLTest_AssertCheck(signal_to_noise >= target_signal_to_noise, "Conversion signal-to-noise ratio %f dB should be no less than %f dB.",
|
||||
signal_to_noise, target_signal_to_noise);
|
||||
SDLTest_AssertCheck(max_error <= target_max_error, "Maximum conversion error %f should be no more than %f.",
|
||||
max_error, target_max_error);
|
||||
|
||||
status = TEST_COMPLETED;
|
||||
|
||||
cleanup:
|
||||
SDL_free(buffer_1);
|
||||
SDL_free(buffer_2);
|
||||
SDL_free(buffer_3);
|
||||
SDL_DestroyAudioStream(stream);
|
||||
|
||||
return status;
|
||||
}
|
||||
/* ================= Test Case References ================== */
|
||||
|
||||
/* Audio test cases */
|
||||
@ -952,12 +1281,8 @@ static const SDLTest_TestCaseReference audioTest9 = {
|
||||
audio_lockUnlockOpenAudioDevice, "audio_lockUnlockOpenAudioDevice", "Locks and unlocks an open audio device.", TEST_ENABLED
|
||||
};
|
||||
|
||||
/* TODO: enable test when SDL_ConvertAudio segfaults on cygwin have been fixed.
|
||||
* TODO: re-check, since this was changer to AudioStream */
|
||||
/* For debugging, test case can be run manually using --filter audio_convertAudio */
|
||||
|
||||
static const SDLTest_TestCaseReference audioTest10 = {
|
||||
audio_convertAudio, "audio_convertAudio", "Convert audio using available formats.", TEST_DISABLED
|
||||
audio_convertAudio, "audio_convertAudio", "Convert audio using available formats.", TEST_ENABLED
|
||||
};
|
||||
|
||||
/* TODO: enable test when SDL_AudioDeviceConnected has been implemented. */
|
||||
@ -986,11 +1311,20 @@ static const SDLTest_TestCaseReference audioTest16 = {
|
||||
audio_resampleLoss, "audio_resampleLoss", "Check signal-to-noise ratio and maximum error of audio resampling.", TEST_ENABLED
|
||||
};
|
||||
|
||||
static const SDLTest_TestCaseReference audioTest17 = {
|
||||
audio_convertAccuracy, "audio_convertAccuracy", "Check accuracy converting between audio formats.", TEST_ENABLED
|
||||
};
|
||||
|
||||
static const SDLTest_TestCaseReference audioTest18 = {
|
||||
audio_formatChange, "audio_formatChange", "Check handling of format changes.", TEST_ENABLED
|
||||
};
|
||||
|
||||
/* Sequence of Audio test cases */
|
||||
static const SDLTest_TestCaseReference *audioTests[] = {
|
||||
&audioTest1, &audioTest2, &audioTest3, &audioTest4, &audioTest5, &audioTest6,
|
||||
&audioTest7, &audioTest8, &audioTest9, &audioTest10, &audioTest11,
|
||||
&audioTest12, &audioTest13, &audioTest14, &audioTest15, &audioTest16, NULL
|
||||
&audioTest12, &audioTest13, &audioTest14, &audioTest15, &audioTest16,
|
||||
&audioTest17, &audioTest18, NULL
|
||||
};
|
||||
|
||||
/* Audio test suite (global) */
|
||||
|
16
external/sdl/SDL/test/testautomation_pixels.c
vendored
16
external/sdl/SDL/test/testautomation_pixels.c
vendored
@ -122,7 +122,7 @@ static int pixels_allocFreeFormat(void *arg)
|
||||
|
||||
/* Blank/unknown format */
|
||||
format = 0;
|
||||
SDLTest_Log("RGB Format: %s (%" SDL_PRIu32 ")", unknownFormat, format);
|
||||
SDLTest_Log("Pixel Format: %s (%" SDL_PRIu32 ")", unknownFormat, format);
|
||||
|
||||
/* Allocate format */
|
||||
result = SDL_CreatePixelFormat(format);
|
||||
@ -143,7 +143,7 @@ static int pixels_allocFreeFormat(void *arg)
|
||||
/* RGB formats */
|
||||
for (i = 0; i < g_numAllFormats; i++) {
|
||||
format = g_AllFormats[i];
|
||||
SDLTest_Log("RGB Format: %s (%" SDL_PRIu32 ")", g_AllFormatsVerbose[i], format);
|
||||
SDLTest_Log("Pixel Format: %s (%" SDL_PRIu32 ")", g_AllFormatsVerbose[i], format);
|
||||
|
||||
/* Allocate format */
|
||||
result = SDL_CreatePixelFormat(format);
|
||||
@ -151,11 +151,13 @@ static int pixels_allocFreeFormat(void *arg)
|
||||
SDLTest_AssertCheck(result != NULL, "Verify result is not NULL");
|
||||
if (result != NULL) {
|
||||
SDLTest_AssertCheck(result->format == format, "Verify value of result.format; expected: %" SDL_PRIu32 ", got %" SDL_PRIu32, format, result->format);
|
||||
SDLTest_AssertCheck(result->BitsPerPixel > 0, "Verify value of result.BitsPerPixel; expected: >0, got %u", result->BitsPerPixel);
|
||||
SDLTest_AssertCheck(result->BytesPerPixel > 0, "Verify value of result.BytesPerPixel; expected: >0, got %u", result->BytesPerPixel);
|
||||
if (result->palette != NULL && !SDL_ISPIXELFORMAT_FOURCC(result->format)) {
|
||||
masks = result->Rmask | result->Gmask | result->Bmask | result->Amask;
|
||||
SDLTest_AssertCheck(masks > 0, "Verify value of result.[RGBA]mask combined; expected: >0, got %" SDL_PRIu32, masks);
|
||||
if (!SDL_ISPIXELFORMAT_FOURCC(format)) {
|
||||
SDLTest_AssertCheck(result->BitsPerPixel > 0, "Verify value of result.BitsPerPixel; expected: >0, got %u", result->BitsPerPixel);
|
||||
SDLTest_AssertCheck(result->BytesPerPixel > 0, "Verify value of result.BytesPerPixel; expected: >0, got %u", result->BytesPerPixel);
|
||||
if (!SDL_ISPIXELFORMAT_INDEXED(format)) {
|
||||
masks = result->Rmask | result->Gmask | result->Bmask | result->Amask;
|
||||
SDLTest_AssertCheck(masks > 0, "Verify value of result.[RGBA]mask combined; expected: >0, got %" SDL_PRIu32, masks);
|
||||
}
|
||||
}
|
||||
|
||||
/* Deallocate again */
|
||||
|
11
external/sdl/SDL/test/testcontroller.c
vendored
11
external/sdl/SDL/test/testcontroller.c
vendored
@ -2008,15 +2008,22 @@ int main(int argc, char *argv[])
|
||||
HandleGamepadRemoved(controllers[0].id);
|
||||
DelController(controllers[0].id);
|
||||
}
|
||||
SDL_free(controllers);
|
||||
SDL_free(controller_name);
|
||||
DestroyGamepadImage(image);
|
||||
DestroyGamepadDisplay(gamepad_elements);
|
||||
DestroyGamepadTypeDisplay(gamepad_type);
|
||||
DestroyJoystickDisplay(joystick_elements);
|
||||
DestroyGamepadButton(setup_mapping_button);
|
||||
DestroyGamepadButton(done_mapping_button);
|
||||
DestroyGamepadButton(cancel_button);
|
||||
DestroyGamepadButton(clear_button);
|
||||
DestroyGamepadButton(copy_button);
|
||||
DestroyGamepadButton(paste_button);
|
||||
SDLTest_CleanupTextDrawing();
|
||||
SDL_DestroyRenderer(screen);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD);
|
||||
SDL_Quit();
|
||||
SDLTest_CommonDestroyState(state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
27
external/sdl/SDL/test/testdropfile.c
vendored
27
external/sdl/SDL/test/testdropfile.c
vendored
@ -10,24 +10,11 @@
|
||||
freely.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <SDL3/SDL_test_common.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
static SDLTest_CommonState *state;
|
||||
|
||||
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
|
||||
static void
|
||||
quit(int rc)
|
||||
{
|
||||
SDLTest_CommonQuit(state);
|
||||
/* Let 'main()' return normally */
|
||||
if (rc != 0) {
|
||||
exit(rc);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i, done;
|
||||
@ -35,6 +22,7 @@ int main(int argc, char *argv[])
|
||||
SDL_bool is_hover = SDL_FALSE;
|
||||
float x = 0.0f, y = 0.0f;
|
||||
unsigned int windowID = 0;
|
||||
int return_code = -1;
|
||||
|
||||
/* Initialize test framework */
|
||||
state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
|
||||
@ -58,12 +46,14 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
if (consumed < 0) {
|
||||
SDLTest_CommonLogUsage(state, argv[0], NULL);
|
||||
quit(1);
|
||||
return_code = 1;
|
||||
goto quit;
|
||||
}
|
||||
i += consumed;
|
||||
}
|
||||
if (!SDLTest_CommonInit(state)) {
|
||||
quit(2);
|
||||
return_code = 1;
|
||||
goto quit;
|
||||
}
|
||||
|
||||
|
||||
@ -114,7 +104,8 @@ int main(int argc, char *argv[])
|
||||
SDL_Delay(16);
|
||||
}
|
||||
|
||||
quit(0);
|
||||
/* keep the compiler happy ... */
|
||||
return 0;
|
||||
return_code = 0;
|
||||
quit:
|
||||
SDLTest_CommonQuit(state);
|
||||
return return_code;
|
||||
}
|
||||
|
1
external/sdl/SDL/test/testfile.c
vendored
1
external/sdl/SDL/test/testfile.c
vendored
@ -369,6 +369,7 @@ int main(int argc, char *argv[])
|
||||
SDL_RWclose(rwops);
|
||||
SDL_Log("test5 OK\n");
|
||||
cleanup();
|
||||
SDL_Quit();
|
||||
SDLTest_CommonDestroyState(state);
|
||||
return 0; /* all ok */
|
||||
}
|
||||
|
33
external/sdl/SDL/test/testfilesystem_pre.c
vendored
Normal file
33
external/sdl/SDL/test/testfilesystem_pre.c
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely.
|
||||
*/
|
||||
/* Call SDL_GetPrefPath to warm the SHGetFolderPathW cache */
|
||||
|
||||
/**
|
||||
* We noticed frequent ci timeouts running testfilesystem on 32-bit Windows.
|
||||
* Internally, this functions calls Shell32.SHGetFolderPathW.
|
||||
*/
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Uint64 start;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
SDL_Init(0);
|
||||
start = SDL_GetTicks();
|
||||
SDL_GetPrefPath("libsdl", "test_filesystem");
|
||||
SDL_Log("SDL_GetPrefPath took %" SDL_PRIu64 "ms", SDL_GetTicks() - start);
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
}
|
37
external/sdl/SDL/test/testmultiaudio.c
vendored
37
external/sdl/SDL/test/testmultiaudio.c
vendored
@ -28,7 +28,6 @@ static Uint8 *sound = NULL; /* Pointer to wave data */
|
||||
static Uint32 soundlen = 0; /* Length of wave data */
|
||||
|
||||
/* these have to be in globals so the Emscripten port can see them in the mainloop. :/ */
|
||||
static SDL_AudioDeviceID device = 0;
|
||||
static SDL_AudioStream *stream = NULL;
|
||||
|
||||
|
||||
@ -37,7 +36,6 @@ static void loop(void)
|
||||
{
|
||||
if (SDL_GetAudioStreamAvailable(stream) == 0) {
|
||||
SDL_Log("done.");
|
||||
SDL_CloseAudioDevice(device);
|
||||
SDL_DestroyAudioStream(stream);
|
||||
SDL_free(sound);
|
||||
SDL_Quit();
|
||||
@ -65,13 +63,10 @@ test_multi_audio(SDL_AudioDeviceID *devices, int devcount)
|
||||
|
||||
SDL_Log("Playing on device #%d of %d: id=%u, name='%s'...", i, devcount, (unsigned int) devices[i], devname);
|
||||
|
||||
device = SDL_OpenAudioDevice(devices[i], &spec);
|
||||
if (device == 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device failed: %s", SDL_GetError());
|
||||
} else if ((stream = SDL_CreateAndBindAudioStream(device, &spec)) == NULL) { /* we can reuse these, but we'll just make one each time for now. */
|
||||
if ((stream = SDL_OpenAudioDeviceStream(devices[i], &spec, NULL, NULL)) == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Audio stream creation failed: %s", SDL_GetError());
|
||||
SDL_CloseAudioDevice(device);
|
||||
} else {
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream));
|
||||
SDL_PutAudioStreamData(stream, sound, soundlen);
|
||||
SDL_FlushAudioStream(stream);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
@ -87,7 +82,6 @@ test_multi_audio(SDL_AudioDeviceID *devices, int devcount)
|
||||
}
|
||||
#endif
|
||||
SDL_Log("done.");
|
||||
SDL_CloseAudioDevice(device);
|
||||
SDL_DestroyAudioStream(stream);
|
||||
}
|
||||
SDL_free(devname);
|
||||
@ -101,29 +95,19 @@ test_multi_audio(SDL_AudioDeviceID *devices, int devcount)
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!");
|
||||
} else {
|
||||
for (i = 0; i < devcount; i++) {
|
||||
char *devname = SDL_GetAudioDeviceName(devices[i]);
|
||||
device = SDL_OpenAudioDevice(devices[i], &spec);
|
||||
if (device == 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device %d of %d (id=%u, name='%s') failed: %s\n", i, devcount, (unsigned int) devices[i], devname, SDL_GetError());
|
||||
}
|
||||
SDL_free(devname);
|
||||
devices[i] = device; /* just replace the physical device ID with the newly-opened logical device ID. */
|
||||
if (device) {
|
||||
SDL_PauseAudioDevice(device); /* hold while we set up all the streams. */
|
||||
streams[i] = SDL_CreateAndBindAudioStream(device, &spec);
|
||||
if (streams[i] == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Audio stream creation failed for device %d of %d: %s", i, devcount, SDL_GetError());
|
||||
} else {
|
||||
SDL_PutAudioStreamData(streams[i], sound, soundlen);
|
||||
SDL_FlushAudioStream(streams[i]);
|
||||
}
|
||||
streams[i] = SDL_OpenAudioDeviceStream(devices[i], &spec, NULL, NULL);
|
||||
if (streams[i] == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Audio stream creation failed for device %d of %d: %s", i, devcount, SDL_GetError());
|
||||
} else {
|
||||
SDL_PutAudioStreamData(streams[i], sound, soundlen);
|
||||
SDL_FlushAudioStream(streams[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* try to start all the devices about the same time. SDL does not guarantee sync across physical devices. */
|
||||
for (i = 0; i < devcount; i++) {
|
||||
if (devices[i]) {
|
||||
SDL_ResumeAudioDevice(devices[i]);
|
||||
if (streams[i]) {
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(streams[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,7 +127,6 @@ test_multi_audio(SDL_AudioDeviceID *devices, int devcount)
|
||||
}
|
||||
|
||||
for (i = 0; i < devcount; i++) {
|
||||
SDL_CloseAudioDevice(devices[i]);
|
||||
SDL_DestroyAudioStream(streams[i]);
|
||||
}
|
||||
|
||||
|
6
external/sdl/SDL/test/testnative.c
vendored
6
external/sdl/SDL/test/testnative.c
vendored
@ -212,6 +212,12 @@ int main(int argc, char *argv[])
|
||||
MoveSprites(renderer, sprite);
|
||||
}
|
||||
|
||||
SDL_DestroyTexture(sprite);
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_free(positions);
|
||||
SDL_free(velocities);
|
||||
|
||||
quit(0);
|
||||
|
||||
return 0; /* to prevent compiler warning */
|
||||
|
9
external/sdl/SDL/test/testshape.c
vendored
9
external/sdl/SDL/test/testshape.c
vendored
@ -388,6 +388,15 @@ ret:
|
||||
/* Destroy the window. */
|
||||
SDL_DestroyWindow(window);
|
||||
|
||||
if (g_bitmap) {
|
||||
SDL_free(g_bitmap);
|
||||
g_bitmap = NULL;
|
||||
}
|
||||
if (g_shape_surface) {
|
||||
SDL_DestroySurface(g_shape_surface);
|
||||
g_shape_surface = NULL;
|
||||
}
|
||||
|
||||
SDL_Quit();
|
||||
SDLTest_CommonDestroyState(state);
|
||||
|
||||
|
55
external/sdl/SDL/test/testspriteminimal.c
vendored
55
external/sdl/SDL/test/testspriteminimal.c
vendored
@ -20,7 +20,8 @@
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
#include "testutils.h"
|
||||
|
||||
#include "icon.h"
|
||||
|
||||
#define WINDOW_WIDTH 640
|
||||
#define WINDOW_HEIGHT 480
|
||||
@ -35,15 +36,23 @@ static int sprite_w, sprite_h;
|
||||
static SDL_Renderer *renderer;
|
||||
static int done;
|
||||
|
||||
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
|
||||
static void
|
||||
quit(int rc)
|
||||
{
|
||||
SDL_Quit();
|
||||
/* Let 'main()' return normally */
|
||||
if (rc != 0) {
|
||||
exit(rc);
|
||||
static SDL_Texture *CreateTexture(SDL_Renderer *r, unsigned char *data, unsigned int len, int *w, int *h) {
|
||||
SDL_Texture *texture = NULL;
|
||||
SDL_Surface *surface;
|
||||
SDL_RWops *src = SDL_RWFromConstMem(data, len);
|
||||
if (src) {
|
||||
surface = SDL_LoadBMP_RW(src, SDL_TRUE);
|
||||
if (surface) {
|
||||
/* Treat white as transparent */
|
||||
SDL_SetSurfaceColorKey(surface, SDL_TRUE, SDL_MapRGB(surface->format, 255, 255, 255));
|
||||
|
||||
texture = SDL_CreateTextureFromSurface(r, surface);
|
||||
*w = surface->w;
|
||||
*h = surface->h;
|
||||
SDL_DestroySurface(surface);
|
||||
}
|
||||
}
|
||||
return texture;
|
||||
}
|
||||
|
||||
static void MoveSprites(void)
|
||||
@ -100,7 +109,8 @@ static void loop(void)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
SDL_Window *window;
|
||||
SDL_Window *window = NULL;
|
||||
int return_code = -1;
|
||||
int i;
|
||||
|
||||
/* Enable standard application logging */
|
||||
@ -108,17 +118,25 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (argc > 1) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "USAGE: %s\n", argv[0]);
|
||||
quit(1);
|
||||
return_code = 1;
|
||||
goto quit;
|
||||
}
|
||||
|
||||
if (SDL_CreateWindowAndRenderer(WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer) < 0) {
|
||||
quit(2);
|
||||
return_code = 2;
|
||||
goto quit;
|
||||
}
|
||||
|
||||
sprite = LoadTexture(renderer, "icon.bmp", SDL_TRUE, &sprite_w, &sprite_h);
|
||||
if (SDL_SetWindowTitle(window, argv[0]) < 0) {
|
||||
SDL_Log("SDL_SetWindowTitle: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
sprite = CreateTexture(renderer, icon_bmp, icon_bmp_len, &sprite_w, &sprite_h);
|
||||
|
||||
if (sprite == NULL) {
|
||||
quit(2);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture (%s)", SDL_GetError());
|
||||
return_code = 3;
|
||||
goto quit;
|
||||
}
|
||||
|
||||
/* Initialize the sprite positions */
|
||||
@ -146,7 +164,10 @@ int main(int argc, char *argv[])
|
||||
loop();
|
||||
}
|
||||
#endif
|
||||
quit(0);
|
||||
|
||||
return 0; /* to prevent compiler warning */
|
||||
return_code = 0;
|
||||
quit:
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
return return_code;
|
||||
}
|
||||
|
28
external/sdl/SDL/test/testsurround.c
vendored
28
external/sdl/SDL/test/testsurround.c
vendored
@ -96,7 +96,7 @@ static SDL_bool is_lfe_channel(int channel_index, int channel_count)
|
||||
return (channel_count == 3 && channel_index == 2) || (channel_count >= 6 && channel_index == 3);
|
||||
}
|
||||
|
||||
static void SDLCALL fill_buffer(SDL_AudioStream *stream, int len, void *unused)
|
||||
static void SDLCALL fill_buffer(void *userdata, SDL_AudioStream *stream, int len, int totallen)
|
||||
{
|
||||
const int samples = len / sizeof(Sint16);
|
||||
Sint16 *buffer = NULL;
|
||||
@ -193,12 +193,11 @@ int main(int argc, char *argv[])
|
||||
char *devname = SDL_GetAudioDeviceName(devices[i]);
|
||||
int j;
|
||||
SDL_AudioSpec spec;
|
||||
SDL_AudioDeviceID dev;
|
||||
|
||||
SDL_Log("Testing audio device: %s\n", devname);
|
||||
SDL_free(devname);
|
||||
|
||||
if (SDL_GetAudioDeviceFormat(devices[i], &spec) != 0) {
|
||||
if (SDL_GetAudioDeviceFormat(devices[i], &spec, NULL) != 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GetAudioDeviceFormat() failed: %s\n", SDL_GetError());
|
||||
continue;
|
||||
}
|
||||
@ -206,26 +205,18 @@ int main(int argc, char *argv[])
|
||||
SDL_Log(" (%d channels)\n", spec.channels);
|
||||
|
||||
spec.freq = SAMPLE_RATE_HZ;
|
||||
spec.format = SDL_AUDIO_S16SYS;
|
||||
|
||||
dev = SDL_OpenAudioDevice(devices[i], &spec);
|
||||
if (dev == 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_OpenAudioDevice() failed: %s\n", SDL_GetError());
|
||||
continue;
|
||||
}
|
||||
|
||||
stream = SDL_CreateAndBindAudioStream(dev, &spec);
|
||||
if (stream == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateAndBindAudioStream() failed: %s\n", SDL_GetError());
|
||||
SDL_CloseAudioDevice(dev);
|
||||
continue;
|
||||
}
|
||||
spec.format = SDL_AUDIO_S16;
|
||||
|
||||
/* These are used by the fill_buffer callback */
|
||||
total_channels = spec.channels;
|
||||
active_channel = 0;
|
||||
|
||||
SDL_SetAudioStreamGetCallback(stream, fill_buffer, NULL);
|
||||
stream = SDL_OpenAudioDeviceStream(devices[i], &spec, fill_buffer, NULL);
|
||||
if (stream == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_OpenAudioDeviceStream() failed: %s\n", SDL_GetError());
|
||||
continue;
|
||||
}
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream));
|
||||
|
||||
for (j = 0; j < total_channels; j++) {
|
||||
const int sine_freq = is_lfe_channel(j, total_channels) ? LFE_SINE_FREQ_HZ : SINE_FREQ_HZ;
|
||||
@ -240,7 +231,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
SDL_CloseAudioDevice(dev);
|
||||
SDL_DestroyAudioStream(stream);
|
||||
}
|
||||
|
||||
|
17
external/sdl/SDL/test/testwm.c
vendored
17
external/sdl/SDL/test/testwm.c
vendored
@ -10,8 +10,6 @@
|
||||
freely.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
@ -42,17 +40,6 @@ static SDL_Cursor *cursor = NULL;
|
||||
static SDL_bool relative_mode = SDL_FALSE;
|
||||
static const SDL_DisplayMode *highlighted_mode = NULL;
|
||||
|
||||
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
|
||||
static void
|
||||
quit(int rc)
|
||||
{
|
||||
SDLTest_CommonQuit(state);
|
||||
/* Let 'main()' return normally */
|
||||
if (rc != 0) {
|
||||
exit(rc);
|
||||
}
|
||||
}
|
||||
|
||||
/* Draws the modes menu, and stores the mode index under the mouse in highlighted_mode */
|
||||
static void
|
||||
draw_modes_menu(SDL_Window *window, SDL_Renderer *renderer, SDL_FRect viewport)
|
||||
@ -298,7 +285,7 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
SDL_DestroyCursor(cursor);
|
||||
|
||||
quit(0);
|
||||
/* keep the compiler happy ... */
|
||||
SDLTest_CleanupTextDrawing();
|
||||
SDLTest_CommonQuit(state);
|
||||
return 0;
|
||||
}
|
||||
|
11
external/sdl/SDL/test/testyuv.c
vendored
11
external/sdl/SDL/test/testyuv.c
vendored
@ -243,6 +243,7 @@ int main(int argc, char **argv)
|
||||
char *filename = NULL;
|
||||
SDL_Surface *original;
|
||||
SDL_Surface *converted;
|
||||
SDL_Surface *bmp;
|
||||
SDL_Window *window;
|
||||
SDL_Renderer *renderer;
|
||||
SDL_Texture *output[3];
|
||||
@ -368,7 +369,9 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
filename = GetResourceFilename(filename, "testyuv.bmp");
|
||||
original = SDL_ConvertSurfaceFormat(SDL_LoadBMP(filename), SDL_PIXELFORMAT_RGB24);
|
||||
bmp = SDL_LoadBMP(filename);
|
||||
original = SDL_ConvertSurfaceFormat(bmp, SDL_PIXELFORMAT_RGB24);
|
||||
SDL_DestroySurface(bmp);
|
||||
if (original == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError());
|
||||
return 3;
|
||||
@ -481,7 +484,13 @@ int main(int argc, char **argv)
|
||||
SDL_Delay(10);
|
||||
}
|
||||
}
|
||||
SDL_free(raw_yuv);
|
||||
SDL_free(filename);
|
||||
SDL_DestroySurface(original);
|
||||
SDL_DestroySurface(converted);
|
||||
SDLTest_CleanupTextDrawing();
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
SDLTest_CommonDestroyState(state);
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user