Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sdl3 audio #86

Merged
merged 3 commits into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,18 @@ else()
target_sources(mcpelauncher-client PRIVATE src/cpuid.cpp src/cpuid.h src/xbox_shutdown_patch.cpp src/xbox_shutdown_patch.h src/texel_aa_patch.cpp src/texel_aa_patch.h)
endif()

find_package(PulseAudio)
if(TARGET SDL3::SDL3)
target_sources(mcpelauncher-client PRIVATE src/jni/sdl3audio.cpp src/jni/sdl3audio.h)
target_link_libraries(mcpelauncher-client SDL3::SDL3)
target_compile_definitions(mcpelauncher-client PRIVATE HAVE_SDL3AUDIO)
else()
find_package(PulseAudio)

if (PULSEAUDIO_FOUND AND PULSEAUDIOSIMPLE_FOUND)
target_sources(mcpelauncher-client PRIVATE src/jni/pulseaudio.cpp src/jni/pulseaudio.h)
target_link_libraries(mcpelauncher-client ${PULSEAUDIO_LIBRARIES} ${PULSEAUDIOSIMPLE_LIBRARIES})
target_compile_definitions(mcpelauncher-client PRIVATE HAVE_PULSEAUDIO)
if (PULSEAUDIO_FOUND AND PULSEAUDIOSIMPLE_FOUND)
target_sources(mcpelauncher-client PRIVATE src/jni/pulseaudio.cpp src/jni/pulseaudio.h)
target_link_libraries(mcpelauncher-client ${PULSEAUDIO_LIBRARIES} ${PULSEAUDIOSIMPLE_LIBRARIES})
target_compile_definitions(mcpelauncher-client PRIVATE HAVE_PULSEAUDIO)
endif()
endif()

option(XAL_WEBVIEW_USE_CLI "use cli for login to xboxlive" OFF)
Expand Down
9 changes: 9 additions & 0 deletions src/fake_looper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,15 @@ void FakeLooper::attachInputQueue(int ident, ALooper_callbackFunc callback, void

int FakeLooper::pollAll(int timeoutMillis, int *outFd, int *outEvents, void **outData) {
associatedWindowCallbacks->startSendEvents();
if(textInput != jniSupport->getTextInputHandler().isEnabled()) {
textInput = jniSupport->getTextInputHandler().isEnabled();
if(textInput) {
associatedWindow->startTextInput();
} else {
associatedWindow->stopTextInput();
}
}

if(androidEvent) {
pollfd f;
f.fd = androidEvent.fd;
Expand Down
1 change: 1 addition & 0 deletions src/fake_looper.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class FakeLooper {
static JniSupport *jniSupport;
static thread_local std::unique_ptr<FakeLooper> currentLooper;
bool prepared = false;
bool textInput = false;

struct EventEntry {
int fd, ident, events;
Expand Down
5 changes: 4 additions & 1 deletion src/jni/jni_descriptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#ifdef HAVE_PULSEAUDIO
#include "pulseaudio.h"
#endif
#ifdef HAVE_SDL3AUDIO
#include "sdl3audio.h"
#endif
#include "java_types.h"
#include "accounts.h"
#include "ecdsa.h"
Expand Down Expand Up @@ -308,7 +311,7 @@ BEGIN_NATIVE_DESCRIPTOR(HTTPResponse){Function<&HTTPResponse::getStatus>{}, "get
{Constructor<HTTPRequest>{}},
END_NATIVE_DESCRIPTOR

#ifdef HAVE_PULSEAUDIO
#if defined(HAVE_PULSEAUDIO) || defined(HAVE_SDL3AUDIO)
BEGIN_NATIVE_DESCRIPTOR(AudioDevice){Constructor<AudioDevice>{}},
{Function<&AudioDevice::init>{}, "init"},
{Function<&AudioDevice::write>{}, "write"},
Expand Down
5 changes: 4 additions & 1 deletion src/jni/jni_support.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
#ifdef HAVE_PULSEAUDIO
#include "pulseaudio.h"
#endif
#ifdef HAVE_SDL3AUDIO
#include "sdl3audio.h"
#endif
#include "accounts.h"
#include "ecdsa.h"
#include "webview.h"
Expand Down Expand Up @@ -101,7 +104,7 @@ void JniSupport::registerJniClasses() {

vm.registerClass<PlayIntegrity>();

#ifdef HAVE_PULSEAUDIO
#if defined(HAVE_PULSEAUDIO) || defined(HAVE_SDL3AUDIO)
vm.registerClass<AudioDevice>();
#endif
}
Expand Down
45 changes: 45 additions & 0 deletions src/jni/sdl3audio.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "sdl3audio.h"
#include <game_window_manager.h>
#include <SDL3/SDL.h>
#include <thread>
AudioDevice::AudioDevice() {
s = nullptr;
SDL_Init(SDL_INIT_AUDIO);
}

AudioDevice::~AudioDevice() {
SDL_QuitSubSystem(SDL_INIT_AUDIO);
}

FakeJni::JBoolean AudioDevice::init(FakeJni::JInt channels, FakeJni::JInt samplerate, FakeJni::JInt c, FakeJni::JInt d) {
if(s != NULL) {
GameWindowManager::getManager()->getErrorHandler()->onError("sdl3audio failed", "sdl3audio already initialized");
}
SDL_AudioSpec spec;
spec.channels = channels;
spec.format = SDL_AUDIO_S16LE;
spec.freq = samplerate;
maxBufferLen = c * d * channels * 2;
s = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &spec, nullptr, nullptr);
if(s == NULL) {
auto errormsg = SDL_GetError();
GameWindowManager::getManager()->getErrorHandler()->onError("sdl3audio failed", std::string("sdl3audio SDL_OpenAudioDeviceStream failed, audio will be unavailable: ") + (errormsg ? errormsg : "No message from sdl3audio"));
return false;
}
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(s));
return true;
}

void AudioDevice::write(std::shared_ptr<FakeJni::JByteArray> data, FakeJni::JInt length) {
SDL_PutAudioStreamData(s, data->getArray(), length);
// SDL3 cannot set any max buf size and fmod doesn't feeding data with the correct rate without it
// appeared as silence and a queue overflow
while(SDL_GetAudioStreamQueued(s) > maxBufferLen) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}

void AudioDevice::close() {
SDL_DestroyAudioStream(s);
s = nullptr;
}
21 changes: 21 additions & 0 deletions src/jni/sdl3audio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include <fake-jni/fake-jni.h>
#include <SDL3/SDL.h>

class AudioDevice : public FakeJni::JObject {
SDL_AudioStream* s;
int maxBufferLen;

public:
DEFINE_CLASS_NAME("org/fmod/AudioDevice")

AudioDevice();
~AudioDevice();

FakeJni::JBoolean init(FakeJni::JInt channels, FakeJni::JInt samplerate, FakeJni::JInt c, FakeJni::JInt d);

void write(std::shared_ptr<FakeJni::JByteArray> data, FakeJni::JInt length);

void close();
};
Loading