diff --git a/.gitmodules b/.gitmodules
index ca304b62..b5ae2016 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,3 +4,7 @@
[submodule "app/libraries/fmt"]
path = app/libraries/fmt
url = https://github.com/fmtlib/fmt
+[submodule "app/libraries/oboe"]
+ path = app/libraries/oboe
+ url = https://github.com/google/oboe
+ branch = 1.3-stable
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index c399eec8..04558c48 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -3,6 +3,7 @@
+
\ No newline at end of file
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index 7e2111e9..07170970 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -15,12 +15,16 @@ endif()
set(CMAKE_POLICY_DEFAULT_CMP0048 OLD)
add_subdirectory("libraries/tinyxml2")
add_subdirectory("libraries/fmt")
+add_subdirectory("libraries/oboe")
+include_directories (libraries/oboe/include)
set(CMAKE_POLICY_DEFAULT_CMP0048 NEW)
include_directories(${source_DIR}/skyline)
add_library(skyline SHARED
${source_DIR}/main.cpp
+ ${source_DIR}/skyline/audio.cpp
+ ${source_DIR}/skyline/audio/track.cpp
${source_DIR}/skyline/common.cpp
${source_DIR}/skyline/nce/guest.S
${source_DIR}/skyline/nce/guest.cpp
@@ -47,6 +51,7 @@ add_library(skyline SHARED
${source_DIR}/skyline/services/serviceman.cpp
${source_DIR}/skyline/services/sm/sm.cpp
${source_DIR}/skyline/services/fatal/fatal.cpp
+ ${source_DIR}/skyline/services/audout/audout.cpp
${source_DIR}/skyline/services/set/sys.cpp
${source_DIR}/skyline/services/apm/apm.cpp
${source_DIR}/skyline/services/am/applet.cpp
@@ -59,5 +64,5 @@ add_library(skyline SHARED
${source_DIR}/skyline/services/vi/vi_m.cpp
)
-target_link_libraries(skyline vulkan android fmt tinyxml2)
+target_link_libraries(skyline vulkan android fmt tinyxml2 oboe)
target_compile_options(skyline PRIVATE -Wno-c++17-extensions)
diff --git a/app/libraries/oboe b/app/libraries/oboe
new file mode 160000
index 00000000..56854b88
--- /dev/null
+++ b/app/libraries/oboe
@@ -0,0 +1 @@
+Subproject commit 56854b88dd54a8bf7c511800ecf9f991e02cf3de
diff --git a/app/src/main/cpp/skyline/audio.cpp b/app/src/main/cpp/skyline/audio.cpp
new file mode 100644
index 00000000..ee451f0c
--- /dev/null
+++ b/app/src/main/cpp/skyline/audio.cpp
@@ -0,0 +1,64 @@
+#include "audio.h"
+
+namespace skyline::audio {
+ Audio::Audio(const DeviceState &state) : state(state), oboe::AudioStreamCallback() {
+ oboe::AudioStreamBuilder builder;
+
+ builder.setChannelCount(constant::ChannelCount)
+ ->setSampleRate(constant::SampleRate)
+ ->setFormat(constant::PcmFormat)
+ ->setCallback(this)
+ ->openManagedStream(outputStream);
+
+ outputStream->requestStart();
+ }
+
+ std::shared_ptr Audio::OpenTrack(int channelCount, int sampleRate, const std::function &releaseCallback) {
+ std::shared_ptr track = std::make_shared(channelCount, sampleRate, releaseCallback);
+ audioTracks.push_back(track);
+
+ return track;
+ }
+
+ void Audio::CloseTrack(std::shared_ptr &track) {
+ audioTracks.erase(std::remove(audioTracks.begin(), audioTracks.end(), track), audioTracks.end());
+ track.reset();
+ }
+
+ oboe::DataCallbackResult Audio::onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames) {
+ i16 *destBuffer = static_cast(audioData);
+ int setIndex = 0;
+ size_t sampleI16Size = static_cast(numFrames) * audioStream->getChannelCount();
+
+ for (auto &track : audioTracks) {
+ if (track->playbackState == AudioOutState::Stopped)
+ continue;
+
+ track->bufferLock.lock();
+
+ std::queue &srcBuffer = track->sampleQueue;
+ size_t amount = std::min(srcBuffer.size(), sampleI16Size);
+
+ for (size_t i = 0; i < amount; i++) {
+ if (setIndex == i) {
+ destBuffer[i] = srcBuffer.front();
+ setIndex++;
+ } else {
+ destBuffer[i] += srcBuffer.front();
+ }
+
+ srcBuffer.pop();
+ }
+
+ track->sampleCounter += amount;
+ track->CheckReleasedBuffers();
+
+ track->bufferLock.unlock();
+ }
+
+ if (sampleI16Size > setIndex)
+ memset(destBuffer, 0, (sampleI16Size - setIndex) * 2);
+
+ return oboe::DataCallbackResult::Continue;
+ }
+}
diff --git a/app/src/main/cpp/skyline/audio.h b/app/src/main/cpp/skyline/audio.h
new file mode 100644
index 00000000..8b71a9bd
--- /dev/null
+++ b/app/src/main/cpp/skyline/audio.h
@@ -0,0 +1,46 @@
+#pragma once
+
+#include
+#include
+
+#include
+#include