diff --git a/.gitmodules b/.gitmodules index 50a03d73..c66cca49 100644 --- a/.gitmodules +++ b/.gitmodules @@ -57,3 +57,9 @@ [submodule "app/libraries/thread-pool"] path = app/libraries/thread-pool url = https://github.com/bshoshany/thread-pool.git +[submodule "app/libraries/cubeb"] + path = app/libraries/cubeb + url = https://github.com/skyline-emu/cubeb +[submodule "app/libraries/audio-core"] + path = app/libraries/audio-core + url = https://github.com/skyline-emu/audio-core diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index ee279005..e5e2e782 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -51,10 +51,6 @@ add_subdirectory("libraries/fmt") add_subdirectory("libraries/tzcode") target_compile_options(tzcode PRIVATE -Wno-everything) -# Oboe -add_subdirectory("libraries/oboe") -include_directories(SYSTEM "libraries/oboe/include") - # LZ4 set(LZ4_BUILD_CLI OFF CACHE BOOL "Build LZ4 CLI" FORCE) set(LZ4_BUILD_LEGACY_LZ4C OFF CACHE BOOL "Build lz4c progam with legacy argument support" FORCE) @@ -95,6 +91,13 @@ include_directories(SYSTEM "libraries/opus/include") add_subdirectory("libraries/opus") target_compile_definitions(opus PRIVATE OPUS_WILL_BE_SLOW=1) # libopus will warn when built without optimizations +# Cubeb +set(USE_AAUDIO ON) +set(USE_SANITIZERS OFF) +set(BUNDLE_SPEEX ON) +add_subdirectory("libraries/cubeb") +include_directories(SYSTEM "libraries/cubeb/include") + # Perfetto SDK include_directories(SYSTEM "libraries/perfetto/sdk") add_library(perfetto STATIC libraries/perfetto/sdk/perfetto.cc) @@ -142,6 +145,11 @@ add_subdirectory("libraries/shader-compiler") target_include_directories(shader_recompiler PUBLIC "libraries/shader-compiler/include") target_link_libraries_system(shader_recompiler Boost::intrusive Boost::container range-v3) +# yuzu Audio Core +add_subdirectory("libraries/audio-core") +include_directories(SYSTEM "libraries/audio-core/include") +target_link_libraries_system(audio_core Boost::intrusive Boost::container range-v3) + # Skyline add_library(skyline SHARED ${source_DIR}/driver_jni.cpp @@ -168,9 +176,6 @@ add_library(skyline SHARED ${source_DIR}/skyline/kernel/types/KPrivateMemory.cpp ${source_DIR}/skyline/kernel/types/KSyncObject.cpp ${source_DIR}/skyline/audio.cpp - ${source_DIR}/skyline/audio/track.cpp - ${source_DIR}/skyline/audio/resampler.cpp - ${source_DIR}/skyline/audio/adpcm_decoder.cpp ${source_DIR}/skyline/gpu.cpp ${source_DIR}/skyline/gpu/trait_manager.cpp ${source_DIR}/skyline/gpu/memory_manager.cpp @@ -265,9 +270,7 @@ add_library(skyline SHARED ${source_DIR}/skyline/services/audio/IAudioOut.cpp ${source_DIR}/skyline/services/audio/IAudioDevice.cpp ${source_DIR}/skyline/services/audio/IAudioRendererManager.cpp - ${source_DIR}/skyline/services/audio/IAudioRenderer/IAudioRenderer.cpp - ${source_DIR}/skyline/services/audio/IAudioRenderer/voice.cpp - ${source_DIR}/skyline/services/audio/IAudioRenderer/memory_pool.cpp + ${source_DIR}/skyline/services/audio/IAudioRenderer.cpp ${source_DIR}/skyline/services/settings/ISettingsServer.cpp ${source_DIR}/skyline/services/settings/ISystemSettingsServer.cpp ${source_DIR}/skyline/services/apm/IManager.cpp @@ -397,5 +400,5 @@ target_include_directories(skyline PRIVATE ${source_DIR}/skyline) # target_precompile_headers(skyline PRIVATE ${source_DIR}/skyline/common.h) # PCH will currently break Intellisense target_compile_options(skyline PRIVATE -Wall -Wno-unknown-attributes -Wno-c++20-extensions -Wno-c++17-extensions -Wno-c99-designator -Wno-reorder -Wno-missing-braces -Wno-unused-variable -Wno-unused-private-field -Wno-dangling-else -Wconversion -fsigned-bitfields) -target_link_libraries(skyline PRIVATE shader_recompiler) -target_link_libraries_system(skyline android perfetto fmt lz4_static tzcode oboe vkma mbedcrypto opus Boost::intrusive Boost::container range-v3 adrenotools tsl::robin_map) +target_link_libraries(skyline PRIVATE shader_recompiler audio_core) +target_link_libraries_system(skyline android perfetto fmt lz4_static tzcode vkma mbedcrypto opus Boost::intrusive Boost::container range-v3 adrenotools tsl::robin_map) diff --git a/app/libraries/audio-core b/app/libraries/audio-core new file mode 160000 index 00000000..645cb10f --- /dev/null +++ b/app/libraries/audio-core @@ -0,0 +1 @@ +Subproject commit 645cb10fb1e73a0bdfc0d3693087201845f8195c diff --git a/app/libraries/cubeb b/app/libraries/cubeb new file mode 160000 index 00000000..2d93d734 --- /dev/null +++ b/app/libraries/cubeb @@ -0,0 +1 @@ +Subproject commit 2d93d734ecff78deb060abd727712bae8ab0489a diff --git a/app/src/main/cpp/skyline/audio.cpp b/app/src/main/cpp/skyline/audio.cpp index b8549e00..817b0602 100644 --- a/app/src/main/cpp/skyline/audio.cpp +++ b/app/src/main/cpp/skyline/audio.cpp @@ -1,80 +1,55 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/) +#include +#include +#include +#include +#include #include "audio.h" -namespace skyline::audio { - Audio::Audio(const DeviceState &state) : oboe::AudioStreamCallback() { - settings = std::shared_ptr{state.settings}; - - builder.setChannelCount(constant::StereoChannelCount); - builder.setSampleRate(constant::SampleRate); - builder.setFormat(constant::PcmFormat); - builder.setUsage(oboe::Usage::Game); - builder.setCallback(this); - builder.setSharingMode(oboe::SharingMode::Exclusive); - builder.setPerformanceMode(oboe::PerformanceMode::LowLatency); - - builder.openManagedStream(outputStream); - outputStream->requestStart(); +namespace AudioCore::Log { + void Debug(const std::string &message) { + skyline::Logger::Write(skyline::Logger::LogLevel::Debug, message); } - Audio::~Audio() { - outputStream->requestStop(); + void Info(const std::string &message) { + skyline::Logger::Write(skyline::Logger::LogLevel::Info, message); } - std::shared_ptr Audio::OpenTrack(u8 channelCount, u32 sampleRate, const std::function &releaseCallback) { - std::scoped_lock trackGuard{trackLock}; - - auto track{std::make_shared(channelCount, sampleRate, releaseCallback)}; - audioTracks.push_back(track); - - return track; + void Warn(const std::string &message) { + skyline::Logger::Write(skyline::Logger::LogLevel::Warn, message); } - void Audio::CloseTrack(std::shared_ptr &track) { - std::scoped_lock trackGuard{trackLock}; - - audioTracks.erase(std::remove(audioTracks.begin(), audioTracks.end(), track), audioTracks.end()); - } - - oboe::DataCallbackResult Audio::onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames) { - auto destBuffer{static_cast(audioData)}; - auto streamSamples{static_cast(numFrames) * static_cast(audioStream->getChannelCount())}; - size_t writtenSamples{}; - - { - std::scoped_lock trackGuard{trackLock}; - - for (auto &track : audioTracks) { - if (track->playbackState == AudioOutState::Stopped) - continue; - - std::scoped_lock bufferGuard{track->bufferLock}; - - if (!*settings->isAudioOutputDisabled) { - auto trackSamples{track->samples.Read(span(destBuffer, streamSamples), [](i16 *source, i16 *destination) { - *destination = Saturate(static_cast(*destination) + static_cast(*source)); - }, static_cast(writtenSamples))}; - - writtenSamples = std::max(trackSamples, writtenSamples); - - track->sampleCounter += trackSamples; - } else { - track->sampleCounter += streamSamples; - } - track->CheckReleasedBuffers(); - } - } - - if (streamSamples > writtenSamples) - memset(destBuffer + writtenSamples, 0, (streamSamples - writtenSamples) * sizeof(i16)); - - return oboe::DataCallbackResult::Continue; - } - - void Audio::onErrorAfterClose(oboe::AudioStream *audioStream, oboe::Result error) { - builder.openManagedStream(outputStream); - outputStream->requestStart(); + void Error(const std::string &message) { + skyline::Logger::Write(skyline::Logger::LogLevel::Error, message); + } +} + +namespace Core::Timing { + skyline::u64 GetClockTicks() { + return skyline::util::GetTimeTicks(); + } + + std::chrono::nanoseconds GetClockNs() { + return std::chrono::nanoseconds{skyline::util::GetTimeNs()}; + } +} + +namespace skyline::audio { + Audio::Audio(const DeviceState &state) + : audioOutManager{std::make_unique(audioSystem)}, + audioRendererManager{std::make_unique(audioSystem)} { + AudioCore::Settings::values.volume = *state.settings->isAudioOutputDisabled ? 0 : 200; + } + + Audio::~Audio() = default; + + void Audio::Pause() { + audioSystem.AudioCore().GetOutputSink().SetSystemVolume(0.0f); + } + + void Audio::Resume() { + audioSystem.AudioCore().GetOutputSink().SetSystemVolume(1.0f); } } diff --git a/app/src/main/cpp/skyline/audio.h b/app/src/main/cpp/skyline/audio.h index f2685743..3ecee568 100644 --- a/app/src/main/cpp/skyline/audio.h +++ b/app/src/main/cpp/skyline/audio.h @@ -3,61 +3,33 @@ #pragma once -#include -#include