aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/opus/decoder.cpp16
-rw-r--r--src/audio_core/opus/hardware_opus.cpp20
-rw-r--r--src/audio_core/opus/hardware_opus.h8
-rw-r--r--src/core/hle/service/audio/errors.h3
4 files changed, 46 insertions, 1 deletions
diff --git a/src/audio_core/opus/decoder.cpp b/src/audio_core/opus/decoder.cpp
index e3a8fe1bfa..1c13cb60e9 100644
--- a/src/audio_core/opus/decoder.cpp
+++ b/src/audio_core/opus/decoder.cpp
@@ -8,6 +8,7 @@
#include "audio_core/opus/hardware_opus.h"
#include "audio_core/opus/parameters.h"
#include "common/alignment.h"
+#include "common/scope_exit.h"
#include "common/swap.h"
#include "core/core.h"
@@ -28,10 +29,18 @@ OpusDecoder::OpusDecoder(Core::System& system_, HardwareOpus& hardware_opus_)
OpusDecoder::~OpusDecoder() {
if (decode_object_initialized) {
hardware_opus.ShutdownDecodeObject(shared_buffer.data(), shared_buffer.size());
+ hardware_opus.UnregisterDecoder(this);
}
}
Result OpusDecoder::Initialize(const OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) {
+ R_TRY(hardware_opus.RegisterDecoder(this));
+ SCOPE_EXIT {
+ if (!decode_object_initialized) {
+ hardware_opus.UnregisterDecoder(this);
+ }
+ };
+
auto frame_size{params.use_large_frame_size ? 5760 : 1920};
shared_buffer.resize(transfer_memory_size);
shared_memory_mapped = true;
@@ -61,6 +70,13 @@ Result OpusDecoder::Initialize(const OpusParametersEx& params, Kernel::KTransfer
}
Result OpusDecoder::Initialize(const OpusMultiStreamParametersEx& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) {
+ R_TRY(hardware_opus.RegisterDecoder(this));
+ SCOPE_EXIT {
+ if (!decode_object_initialized) {
+ hardware_opus.UnregisterDecoder(this);
+ }
+ };
+
auto frame_size{params.use_large_frame_size ? 5760 : 1920};
shared_buffer.resize(transfer_memory_size, 0);
shared_memory_mapped = true;
diff --git a/src/audio_core/opus/hardware_opus.cpp b/src/audio_core/opus/hardware_opus.cpp
index 0037a3e503..04591c10b6 100644
--- a/src/audio_core/opus/hardware_opus.cpp
+++ b/src/audio_core/opus/hardware_opus.cpp
@@ -4,6 +4,7 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include <algorithm>
#include <array>
#include "audio_core/audio_core.h"
@@ -45,6 +46,25 @@ HardwareOpus::HardwareOpus(Core::System& system_)
opus_decoder.SetSharedMemory(shared_memory);
}
+Result HardwareOpus::RegisterDecoder(OpusDecoder* decoder) {
+ std::scoped_lock l{mutex};
+ const auto slot = std::ranges::find(decoders, nullptr);
+ if (slot == decoders.end()) {
+ R_THROW(ResultOutOfOpusDecoders);
+ }
+ *slot = decoder;
+ R_SUCCEED();
+}
+
+void HardwareOpus::UnregisterDecoder(OpusDecoder* decoder) {
+ std::scoped_lock l{mutex};
+ const auto slot = std::ranges::find(decoders, decoder);
+ if (slot == decoders.end()) {
+ return;
+ }
+ *slot = nullptr;
+}
+
u32 HardwareOpus::GetWorkBufferSize(u32 channel) {
if (!opus_decoder.IsRunning()) {
return 0;
diff --git a/src/audio_core/opus/hardware_opus.h b/src/audio_core/opus/hardware_opus.h
index caa7468401..b6c7fbe6c8 100644
--- a/src/audio_core/opus/hardware_opus.h
+++ b/src/audio_core/opus/hardware_opus.h
@@ -1,8 +1,12 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
+#include <array>
#include <mutex>
#include <opus.h>
@@ -12,9 +16,12 @@
#include "core/hle/service/audio/errors.h"
namespace AudioCore::OpusDecoder {
+class OpusDecoder;
class HardwareOpus {
public:
HardwareOpus(Core::System& system);
+ Result RegisterDecoder(OpusDecoder* decoder);
+ void UnregisterDecoder(OpusDecoder* decoder);
u32 GetWorkBufferSize(u32 channel);
u32 GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count);
@@ -39,6 +46,7 @@ public:
private:
Core::System& system;
std::mutex mutex;
+ std::array<OpusDecoder*, 24> decoders{};
ADSP::OpusDecoder::OpusDecoder& opus_decoder;
ADSP::OpusDecoder::SharedMemory shared_memory;
};
diff --git a/src/core/hle/service/audio/errors.h b/src/core/hle/service/audio/errors.h
index 8062820de3..553b4ee360 100644
--- a/src/core/hle/service/audio/errors.h
+++ b/src/core/hle/service/audio/errors.h
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
@@ -33,6 +33,7 @@ constexpr Result ResultLibOpusInternalError{ErrorModule::HwOpus, 4};
constexpr Result ResultBufferTooSmall{ErrorModule::HwOpus, 3};
constexpr Result ResultLibOpusBadArg{ErrorModule::HwOpus, 2};
constexpr Result ResultInvalidOpusDSPReturnCode{ErrorModule::HwOpus, 259};
+constexpr Result ResultOutOfOpusDecoders{ErrorModule::HwOpus, 385};
constexpr Result ResultInvalidOpusSampleRate{ErrorModule::HwOpus, 1001};
constexpr Result ResultInvalidOpusChannelCount{ErrorModule::HwOpus, 1002};