From f6e5951ebfc40bdf9c413d5a731a6e27f55f2317 Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Wed, 14 Mar 2018 14:16:52 +0100 Subject: [PATCH] SWITCH: add audio support --- CMakeLists.switch | 3 +- configure.ac | 2 - src/audio/SDL_audio.c | 3 + src/audio/SDL_sysaudio.h | 1 + src/audio/switch/SDL_switchaudio.c | 148 +++++++++++++++++++++++++++++ src/audio/switch/SDL_switchaudio.h | 40 ++++++++ src/audio/switch/dummy.c | 0 7 files changed, 193 insertions(+), 4 deletions(-) create mode 100644 src/audio/switch/SDL_switchaudio.c create mode 100644 src/audio/switch/SDL_switchaudio.h delete mode 100644 src/audio/switch/dummy.c diff --git a/CMakeLists.switch b/CMakeLists.switch index 95fa700f2..eaf670550 100644 --- a/CMakeLists.switch +++ b/CMakeLists.switch @@ -25,8 +25,7 @@ set(SRC_DIRS src src/atomic src/audio - #src/audio/switch - src/audio/dummy + src/audio/switch src/cpuinfo src/events src/file diff --git a/configure.ac b/configure.ac index ed7be4f05..715e48e76 100644 --- a/configure.ac +++ b/configure.ac @@ -4235,8 +4235,6 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau EXTRA_CFLAGS="$EXTRA_CFLAGS -isystem${DEVKITPRO}/libnx/include -I${DEVKITPRO}/portlibs/switch/include -D__SWITCH__=1" EXTRA_CFLAGS="$EXTRA_CFLAGS -g -O2 -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIC -ftls-model=local-exec" CheckDeclarationAfterStatement - CheckDiskAudio - CheckDummyAudio # Set up files for the video library if test x$enable_video = xyes; then diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 16d29f9f2..f433959ce 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -101,6 +101,9 @@ static const AudioBootStrap *const bootstrap[] = { #if SDL_AUDIO_DRIVER_EMSCRIPTEN &EMSCRIPTENAUDIO_bootstrap, #endif +#if SDL_AUDIO_DRIVER_SWITCH + &SWITCHAUDIO_bootstrap, +#endif #if SDL_AUDIO_DRIVER_JACK &JACK_bootstrap, #endif diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h index 350a6d0a0..05fd4af6b 100644 --- a/src/audio/SDL_sysaudio.h +++ b/src/audio/SDL_sysaudio.h @@ -208,6 +208,7 @@ extern AudioBootStrap ANDROIDAUDIO_bootstrap; extern AudioBootStrap PSPAUDIO_bootstrap; extern AudioBootStrap EMSCRIPTENAUDIO_bootstrap; extern AudioBootStrap OS2AUDIO_bootstrap; +extern AudioBootStrap SWITCHAUDIO_bootstrap; #endif /* SDL_sysaudio_h_ */ diff --git a/src/audio/switch/SDL_switchaudio.c b/src/audio/switch/SDL_switchaudio.c new file mode 100644 index 000000000..00e1ea53e --- /dev/null +++ b/src/audio/switch/SDL_switchaudio.c @@ -0,0 +1,148 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_AUDIO_DRIVER_SWITCH + +#include +#include +#include +#include + +#include "SDL_audio.h" +#include "../SDL_audio_c.h" +#include "../SDL_audiodev_c.h" + +#include "SDL_switchaudio.h" + +static int +SWITCHAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +{ + Result res = audoutInitialize(); + if (res != 0) { + return SDL_SetError("audoutInitialize failed (0x%x)", res); + } + + res = audoutStartAudioOut(); + if (res != 0) { + audoutExit(); + return SDL_SetError("audoutStartAudioOut failed (0x%x)", res); + } + + this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc(sizeof(*this->hidden)); + if (this->hidden == NULL) { + return SDL_OutOfMemory(); + } + SDL_zerop(this->hidden); + + switch (this->spec.format & 0xff) { + case 8: + case 16: + this->spec.format = AUDIO_S16LSB; + break; + default: + return SDL_SetError("Unsupported audio format"); + } + + this->spec.freq = 48000; + this->spec.channels = 2; + + SDL_CalculateAudioSpec(&this->spec); + + for (int i = 0; i < 2; i++) { + u32 size = (u32) (this->spec.size + 0xfff) & ~0xfff; + this->hidden->buffer[i] = memalign(0x1000, size); + memset(this->hidden->buffer[i], 0, size); + this->hidden->source_buffer[i].next = NULL; + this->hidden->source_buffer[i].buffer = this->hidden->buffer[i]; + this->hidden->source_buffer[i].buffer_size = + (u64) this->spec.size / this->spec.channels / 2; + this->hidden->source_buffer[i].data_size = (u64) this->spec.size; + this->hidden->source_buffer[i].data_offset = (u64) 0; + audoutAppendAudioOutBuffer(&this->hidden->source_buffer[i]); + } + + return 0; +} + +static void +SWITCHAUDIO_PlayDevice(_THIS) +{ + audoutAppendAudioOutBuffer(this->hidden->released_buffer); +} + +static void +SWITCHAUDIO_WaitDevice(_THIS) +{ + +} + +static Uint8 +*SWITCHAUDIO_GetDeviceBuf(_THIS) +{ + audoutWaitPlayFinish(&this->hidden->released_buffer, + &this->hidden->released_count, U64_MAX); + + return this->hidden->released_buffer->buffer; +} + +static void +SWITCHAUDIO_CloseDevice(_THIS) +{ + if (this->hidden->buffer[0]) { + free(this->hidden->buffer[0]); + } + if (this->hidden->buffer[1]) { + free(this->hidden->buffer[1]); + } + + audoutStopAudioOut(); + audoutExit(); + + SDL_free(this->hidden); +} + +static void +SWITCHAUDIO_ThreadInit(_THIS) +{ + +} + +static int +SWITCHAUDIO_Init(SDL_AudioDriverImpl *impl) +{ + impl->OpenDevice = SWITCHAUDIO_OpenDevice; + impl->PlayDevice = SWITCHAUDIO_PlayDevice; + impl->WaitDevice = SWITCHAUDIO_WaitDevice; + impl->GetDeviceBuf = SWITCHAUDIO_GetDeviceBuf; + impl->CloseDevice = SWITCHAUDIO_CloseDevice; + impl->ThreadInit = SWITCHAUDIO_ThreadInit; + + impl->OnlyHasDefaultOutputDevice = 1; + + return 1; +} + +AudioBootStrap SWITCHAUDIO_bootstrap = { + "switch", "Nintendo Switch audio driver", SWITCHAUDIO_Init, 0 +}; + +#endif /* SDL_AUDIO_DRIVER_SWITCH */ diff --git a/src/audio/switch/SDL_switchaudio.h b/src/audio/switch/SDL_switchaudio.h new file mode 100644 index 000000000..aeada608a --- /dev/null +++ b/src/audio/switch/SDL_switchaudio.h @@ -0,0 +1,40 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_switchaudio_h_ +#define SDL_switchaudio_h_ + +#include +#include "../SDL_sysaudio.h" + +/* Hidden "this" pointer for the audio functions */ +#define _THIS SDL_AudioDevice *this + +struct SDL_PrivateAudioData +{ + void *buffer[2]; + AudioOutBuffer source_buffer[2]; + AudioOutBuffer *released_buffer; + u32 released_count; + +}; + +#endif /* SDL_switchaudio_h_ */ diff --git a/src/audio/switch/dummy.c b/src/audio/switch/dummy.c deleted file mode 100644 index e69de29bb..000000000