Browse Source
[audio_core/dsp] nuke libopus, use ffmpeg for opus decoding
[audio_core/dsp] nuke libopus, use ffmpeg for opus decoding
Signed-off-by: lizzie <lizzie@eden-emu.dev>lizzie/nuke-opus-wawaw
18 changed files with 385 additions and 736 deletions
-
28.patch/opus/0001-disable-clang-runtime-neon.patch
-
153.patch/opus/0002-no-install.patch
-
15CMakeLists.txt
-
22CMakeModules/find/FindOpus.cmake
-
15cpmfile.json
-
2docs/Deps.md
-
7src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/LicensesFragment.kt
-
45src/android/app/src/main/res/values/strings.xml
-
2src/audio_core/CMakeLists.txt
-
132src/audio_core/adsp/apps/opus/opus_decode_object.cpp
-
39src/audio_core/adsp/apps/opus/opus_decode_object.h
-
371src/audio_core/adsp/apps/opus/opus_decoder.cpp
-
10src/audio_core/adsp/apps/opus/opus_decoder.h
-
129src/audio_core/adsp/apps/opus/opus_multistream_decode_object.cpp
-
40src/audio_core/adsp/apps/opus/opus_multistream_decode_object.h
-
32src/audio_core/adsp/apps/opus/opus_types.h
-
74src/audio_core/opus/hardware_opus.cpp
-
5src/audio_core/opus/hardware_opus.h
@ -1,28 +0,0 @@ |
|||
From cc15da16e533b2a801934eab2dfeaf3c3949a1dc Mon Sep 17 00:00:00 2001 |
|||
From: crueter <crueter@eden-emu.dev> |
|||
Date: Mon, 8 Sep 2025 12:28:55 -0400 |
|||
Subject: [PATCH] [cmake] disable NEON runtime check on clang-cl |
|||
|
|||
When enabling runtime NEON checking for clang-cl, the linker would error out with `undefined symbol: __emit`, since clang doesn't actually implement this instruction. Therefore it makes sense to disable the runtime check by default on this platform, until either this is fixed or a clang-cl compatible intrinsic check is added (I don't have enough knowledge of MSVC to do this) |
|||
---
|
|||
cmake/OpusConfig.cmake | 7 ++++++- |
|||
1 file changed, 6 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/cmake/OpusConfig.cmake b/cmake/OpusConfig.cmake
|
|||
index e9319fbad..d0f459e88 100644
|
|||
--- a/cmake/OpusConfig.cmake
|
|||
+++ b/cmake/OpusConfig.cmake
|
|||
@@ -71,7 +71,12 @@ elseif(OPUS_CPU_ARM AND NOT OPUS_DISABLE_INTRINSICS)
|
|||
opus_detect_neon(COMPILER_SUPPORT_NEON) |
|||
if(COMPILER_SUPPORT_NEON) |
|||
option(OPUS_USE_NEON "Option to enable NEON" ON) |
|||
- option(OPUS_MAY_HAVE_NEON "Does runtime check for neon support" ON)
|
|||
+ if (MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
|||
+ set(NEON_RUNTIME_CHECK_DEFAULT OFF)
|
|||
+ else()
|
|||
+ set(NEON_RUNTIME_CHECK_DEFAULT ON)
|
|||
+ endif()
|
|||
+ option(OPUS_MAY_HAVE_NEON "Does runtime check for neon support" ${NEON_RUNTIME_CHECK_DEFAULT})
|
|||
option(OPUS_PRESUME_NEON "Assume target CPU has NEON support" OFF) |
|||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") |
|||
set(OPUS_PRESUME_NEON ON) |
|||
@ -1,153 +0,0 @@ |
|||
From bf455b67b4eaa446ffae5d25410b141b7b1b1082 Mon Sep 17 00:00:00 2001 |
|||
From: crueter <crueter@eden-emu.dev> |
|||
Date: Mon, 8 Sep 2025 12:08:20 -0400 |
|||
Subject: [PATCH] [cmake] `OPUS_INSTALL` option; only default install if root |
|||
project |
|||
|
|||
Signed-off-by: crueter <crueter@eden-emu.dev> |
|||
---
|
|||
CMakeLists.txt | 112 ++++++++++++++++++++++++++++--------------------- |
|||
1 file changed, 64 insertions(+), 48 deletions(-) |
|||
|
|||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
|||
index fcf034b19..08b5e16f8 100644
|
|||
--- a/CMakeLists.txt
|
|||
+++ b/CMakeLists.txt
|
|||
@@ -4,6 +4,13 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
|||
include(OpusPackageVersion) |
|||
get_package_version(PACKAGE_VERSION PROJECT_VERSION) |
|||
|
|||
+# root project detection
|
|||
+if(DEFINED PROJECT_NAME)
|
|||
+ set(root_project OFF)
|
|||
+else()
|
|||
+ set(root_project ON)
|
|||
+endif()
|
|||
+
|
|||
project(Opus LANGUAGES C VERSION ${PROJECT_VERSION}) |
|||
|
|||
include(OpusFunctions) |
|||
@@ -83,12 +90,16 @@ set(OPUS_DNN_FLOAT_DEBUG_HELP_STR "Run DNN computations as float for debugging p
|
|||
option(OPUS_DNN_FLOAT_DEBUG ${OPUS_DNN_FLOAT_DEBUG_HELP_STR} OFF) |
|||
add_feature_info(OPUS_DNN_FLOAT_DEBUG OPUS_DNN_FLOAT_DEBUG ${OPUS_DNN_FLOAT_DEBUG_HELP_STR}) |
|||
|
|||
+set(OPUS_INSTALL_HELP_STR "Install Opus targets")
|
|||
+option(OPUS_INSTALL ${OPUS_INSTALL_HELP_STR} ${root_project})
|
|||
+add_feature_info(OPUS_INSTALL OPUS_INSTALL ${OPUS_INSTALL_HELP_STR})
|
|||
+
|
|||
set(OPUS_INSTALL_PKG_CONFIG_MODULE_HELP_STR "install pkg-config module.") |
|||
-option(OPUS_INSTALL_PKG_CONFIG_MODULE ${OPUS_INSTALL_PKG_CONFIG_MODULE_HELP_STR} ON)
|
|||
+option(OPUS_INSTALL_PKG_CONFIG_MODULE ${OPUS_INSTALL_PKG_CONFIG_MODULE_HELP_STR} ${OPUS_INSTALL})
|
|||
add_feature_info(OPUS_INSTALL_PKG_CONFIG_MODULE OPUS_INSTALL_PKG_CONFIG_MODULE ${OPUS_INSTALL_PKG_CONFIG_MODULE_HELP_STR}) |
|||
|
|||
set(OPUS_INSTALL_CMAKE_CONFIG_MODULE_HELP_STR "install CMake package config module.") |
|||
-option(OPUS_INSTALL_CMAKE_CONFIG_MODULE ${OPUS_INSTALL_CMAKE_CONFIG_MODULE_HELP_STR} ON)
|
|||
+option(OPUS_INSTALL_CMAKE_CONFIG_MODULE ${OPUS_INSTALL_CMAKE_CONFIG_MODULE_HELP_STR} ${OPUS_INSTALL})
|
|||
add_feature_info(OPUS_INSTALL_CMAKE_CONFIG_MODULE OPUS_INSTALL_CMAKE_CONFIG_MODULE ${OPUS_INSTALL_CMAKE_CONFIG_MODULE_HELP_STR}) |
|||
|
|||
set(OPUS_DRED_HELP_STR "enable DRED.") |
|||
@@ -613,53 +624,58 @@ if(OPUS_BUILD_FRAMEWORK)
|
|||
OUTPUT_NAME Opus) |
|||
endif() |
|||
|
|||
-install(TARGETS opus
|
|||
- EXPORT OpusTargets
|
|||
- ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|||
- LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|||
- RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
|||
- FRAMEWORK DESTINATION ${CMAKE_INSTALL_PREFIX}
|
|||
- PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/opus)
|
|||
-
|
|||
-if(OPUS_INSTALL_PKG_CONFIG_MODULE)
|
|||
- set(prefix ${CMAKE_INSTALL_PREFIX})
|
|||
- set(exec_prefix ${CMAKE_INSTALL_PREFIX})
|
|||
- set(libdir ${CMAKE_INSTALL_FULL_LIBDIR})
|
|||
- set(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR})
|
|||
- set(VERSION ${PACKAGE_VERSION})
|
|||
- if(HAVE_LIBM)
|
|||
- set(LIBM "-lm")
|
|||
+if (OPUS_INSTALL)
|
|||
+ install(TARGETS opus
|
|||
+ EXPORT OpusTargets
|
|||
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|||
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|||
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
|||
+ FRAMEWORK DESTINATION ${CMAKE_INSTALL_PREFIX}
|
|||
+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/opus)
|
|||
+
|
|||
+ if(OPUS_INSTALL_PKG_CONFIG_MODULE)
|
|||
+ set(prefix ${CMAKE_INSTALL_PREFIX})
|
|||
+ set(exec_prefix ${CMAKE_INSTALL_PREFIX})
|
|||
+ set(libdir ${CMAKE_INSTALL_FULL_LIBDIR})
|
|||
+ set(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR})
|
|||
+ set(VERSION ${PACKAGE_VERSION})
|
|||
+ if(HAVE_LIBM)
|
|||
+ set(LIBM "-lm")
|
|||
+ endif()
|
|||
+ configure_file(opus.pc.in opus.pc)
|
|||
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/opus.pc
|
|||
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
|||
+ endif()
|
|||
+
|
|||
+ if(OPUS_INSTALL_CMAKE_CONFIG_MODULE)
|
|||
+ set(CPACK_GENERATOR TGZ)
|
|||
+ include(CPack)
|
|||
+ set(CMAKE_INSTALL_PACKAGEDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
|
|||
+ install(EXPORT OpusTargets
|
|||
+ NAMESPACE Opus::
|
|||
+ DESTINATION ${CMAKE_INSTALL_PACKAGEDIR})
|
|||
+
|
|||
+ include(CMakePackageConfigHelpers)
|
|||
+
|
|||
+ set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR})
|
|||
+ configure_package_config_file(
|
|||
+ ${PROJECT_SOURCE_DIR}/cmake/OpusConfig.cmake.in
|
|||
+ OpusConfig.cmake
|
|||
+ INSTALL_DESTINATION
|
|||
+ ${CMAKE_INSTALL_PACKAGEDIR}
|
|||
+ PATH_VARS
|
|||
+ INCLUDE_INSTALL_DIR
|
|||
+ INSTALL_PREFIX
|
|||
+ ${CMAKE_INSTALL_PREFIX})
|
|||
+
|
|||
+ write_basic_package_version_file(OpusConfigVersion.cmake
|
|||
+ VERSION ${PROJECT_VERSION}
|
|||
+ COMPATIBILITY SameMajorVersion)
|
|||
+
|
|||
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/OpusConfig.cmake
|
|||
+ ${CMAKE_CURRENT_BINARY_DIR}/OpusConfigVersion.cmake
|
|||
+ DESTINATION ${CMAKE_INSTALL_PACKAGEDIR})
|
|||
endif() |
|||
- configure_file(opus.pc.in opus.pc)
|
|||
- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/opus.pc
|
|||
- DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
|||
-endif()
|
|||
-
|
|||
-if(OPUS_INSTALL_CMAKE_CONFIG_MODULE)
|
|||
- set(CPACK_GENERATOR TGZ)
|
|||
- include(CPack)
|
|||
- set(CMAKE_INSTALL_PACKAGEDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
|
|||
- install(EXPORT OpusTargets
|
|||
- NAMESPACE Opus::
|
|||
- DESTINATION ${CMAKE_INSTALL_PACKAGEDIR})
|
|||
-
|
|||
- include(CMakePackageConfigHelpers)
|
|||
-
|
|||
- set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR})
|
|||
- configure_package_config_file(${PROJECT_SOURCE_DIR}/cmake/OpusConfig.cmake.in
|
|||
- OpusConfig.cmake
|
|||
- INSTALL_DESTINATION
|
|||
- ${CMAKE_INSTALL_PACKAGEDIR}
|
|||
- PATH_VARS
|
|||
- INCLUDE_INSTALL_DIR
|
|||
- INSTALL_PREFIX
|
|||
- ${CMAKE_INSTALL_PREFIX})
|
|||
- write_basic_package_version_file(OpusConfigVersion.cmake
|
|||
- VERSION ${PROJECT_VERSION}
|
|||
- COMPATIBILITY SameMajorVersion)
|
|||
- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/OpusConfig.cmake
|
|||
- ${CMAKE_CURRENT_BINARY_DIR}/OpusConfigVersion.cmake
|
|||
- DESTINATION ${CMAKE_INSTALL_PACKAGEDIR})
|
|||
endif() |
|||
|
|||
if(OPUS_BUILD_PROGRAMS) |
|||
@ -1,22 +0,0 @@ |
|||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|||
# SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
# SPDX-FileCopyrightText: 2022 yuzu Emulator Project |
|||
# SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
find_package(PkgConfig QUIET) |
|||
pkg_search_module(OPUS QUIET IMPORTED_TARGET opus) |
|||
|
|||
include(FindPackageHandleStandardArgs) |
|||
find_package_handle_standard_args(Opus |
|||
REQUIRED_VARS OPUS_LINK_LIBRARIES |
|||
VERSION_VAR OPUS_VERSION |
|||
) |
|||
|
|||
if (PLATFORM_MSYS) |
|||
FixMsysPath(PkgConfig::OPUS) |
|||
endif() |
|||
|
|||
if (Opus_FOUND AND NOT TARGET Opus::opus) |
|||
add_library(Opus::opus ALIAS PkgConfig::OPUS) |
|||
endif() |
|||
@ -1,107 +1,71 @@ |
|||
// 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
|
|||
|
|||
extern "C" { |
|||
#include <libavcodec/avcodec.h>
|
|||
#include <libavcodec/codec.h>
|
|||
#include <libavcodec/packet.h>
|
|||
#include <libavutil/channel_layout.h>
|
|||
#include <libavutil/frame.h>
|
|||
} |
|||
#include "audio_core/adsp/apps/opus/opus_decode_object.h"
|
|||
#include "audio_core/adsp/apps/opus/opus_types.h"
|
|||
#include "common/assert.h"
|
|||
#include "core/hle/service/audio/errors.h"
|
|||
|
|||
namespace AudioCore::ADSP::OpusDecoder { |
|||
namespace { |
|||
bool IsValidChannelCount(u32 channel_count) { |
|||
return channel_count == 1 || channel_count == 2; |
|||
} |
|||
} // namespace
|
|||
|
|||
u32 OpusDecodeObject::GetWorkBufferSize(u32 channel_count) { |
|||
if (!IsValidChannelCount(channel_count)) { |
|||
return 0; |
|||
} |
|||
return static_cast<u32>(sizeof(OpusDecodeObject)) + opus_decoder_get_size(channel_count); |
|||
if (channel_count == 1 || channel_count == 2) |
|||
return u32(sizeof(OpusDecodeObject)) + 16 * channel_count; |
|||
return 0; |
|||
} |
|||
|
|||
OpusDecodeObject& OpusDecodeObject::Initialize(u64 buffer, u64 buffer2) { |
|||
auto* new_decoder = reinterpret_cast<OpusDecodeObject*>(buffer); |
|||
auto* comparison = reinterpret_cast<OpusDecodeObject*>(buffer2); |
|||
|
|||
if (new_decoder->magic == DecodeObjectMagic) { |
|||
if (!new_decoder->initialized || |
|||
(new_decoder->initialized && new_decoder->self == comparison)) { |
|||
new_decoder->state_valid = true; |
|||
} |
|||
} else { |
|||
new_decoder->initialized = false; |
|||
new_decoder->state_valid = true; |
|||
} |
|||
return *new_decoder; |
|||
Result OpusDecodeObject::InitializeDecoder(u32 sample_rate, u32 channel_count) { |
|||
if ((codec = avcodec_find_decoder(AV_CODEC_ID_OPUS)) == nullptr) |
|||
return Service::Audio::ResultLibOpusInvalidState; |
|||
if ((avctx = avcodec_alloc_context3(codec)) == nullptr) |
|||
return Service::Audio::ResultLibOpusInvalidState; |
|||
avctx->sample_rate = sample_rate; |
|||
av_channel_layout_default(&avctx->ch_layout, channel_count); |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
s32 OpusDecodeObject::InitializeDecoder(u32 sample_rate, u32 channel_count) { |
|||
if (!state_valid) { |
|||
return OPUS_INVALID_STATE; |
|||
} |
|||
|
|||
if (initialized) { |
|||
return OPUS_OK; |
|||
} |
|||
|
|||
// Unfortunately libopus does not expose the OpusDecoder struct publicly, so we can't include
|
|||
// it in this class. Nintendo does not allocate memory, which is why we have a workbuffer
|
|||
// provided.
|
|||
// We could use _create and have libopus allocate it for us, but then we have to separately
|
|||
// track which decoder is being used between this and multistream in order to call the correct
|
|||
// destroy from the host side.
|
|||
// This is a bit cringe, but is safe as these objects are only ever initialized inside the given
|
|||
// workbuffer, and GetWorkBufferSize will guarantee there's enough space to follow.
|
|||
decoder = (LibOpusDecoder*)(this + 1); |
|||
s32 ret = opus_decoder_init(decoder, sample_rate, channel_count); |
|||
if (ret == OPUS_OK) { |
|||
magic = DecodeObjectMagic; |
|||
initialized = true; |
|||
state_valid = true; |
|||
self = this; |
|||
final_range = 0; |
|||
} |
|||
return ret; |
|||
Result OpusDecodeObject::Shutdown() { |
|||
if (avctx) |
|||
avcodec_free_context(&avctx); |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
s32 OpusDecodeObject::Shutdown() { |
|||
if (!state_valid) { |
|||
return OPUS_INVALID_STATE; |
|||
} |
|||
|
|||
if (initialized) { |
|||
magic = 0x0; |
|||
initialized = false; |
|||
state_valid = false; |
|||
self = nullptr; |
|||
final_range = 0; |
|||
decoder = nullptr; |
|||
Result OpusDecodeObject::ResetDecoder() { |
|||
if (avctx) { |
|||
avcodec_flush_buffers(avctx); |
|||
return ResultSuccess; |
|||
} |
|||
return OPUS_OK; |
|||
} |
|||
|
|||
s32 OpusDecodeObject::ResetDecoder() { |
|||
return opus_decoder_ctl(decoder, OPUS_RESET_STATE); |
|||
return Service::Audio::ResultLibOpusInvalidState; |
|||
} |
|||
|
|||
s32 OpusDecodeObject::Decode(u32& out_sample_count, u64 output_data, u64 output_data_size, |
|||
u64 input_data, u64 input_data_size) { |
|||
ASSERT(initialized); |
|||
Result OpusDecodeObject::Decode(u32& out_sample_count, u64 output_data, u64 output_data_size, u64 input_data, u64 input_data_size) { |
|||
out_sample_count = 0; |
|||
|
|||
if (!state_valid) { |
|||
return OPUS_INVALID_STATE; |
|||
if (avctx) { |
|||
AVPacket* avpkt = av_packet_alloc(); |
|||
av_new_packet(avpkt, int(input_data_size)); |
|||
std::memcpy(avpkt->data, reinterpret_cast<const u8*>(input_data), input_data_size); |
|||
avcodec_send_packet(avctx, avpkt); |
|||
|
|||
AVFrame* frame = av_frame_alloc(); |
|||
avcodec_receive_frame(avctx, frame); |
|||
std::memcpy(reinterpret_cast<u16*>(output_data), frame->data, output_data_size); |
|||
av_frame_free(&frame); |
|||
av_packet_free(&avpkt); |
|||
|
|||
out_sample_count = frame->nb_samples; |
|||
return ResultSuccess; |
|||
} |
|||
|
|||
auto ret_code_or_samples = opus_decode( |
|||
decoder, reinterpret_cast<const u8*>(input_data), static_cast<opus_int32>(input_data_size), |
|||
reinterpret_cast<opus_int16*>(output_data), static_cast<opus_int32>(output_data_size), 0); |
|||
|
|||
if (ret_code_or_samples < OPUS_OK) { |
|||
return ret_code_or_samples; |
|||
} |
|||
|
|||
out_sample_count = ret_code_or_samples; |
|||
return opus_decoder_ctl(decoder, OPUS_GET_FINAL_RANGE_REQUEST, &final_range); |
|||
return Service::Audio::ResultLibOpusInvalidState; |
|||
} |
|||
|
|||
} // namespace AudioCore::ADSP::OpusDecoder
|
|||
@ -1,38 +1,31 @@ |
|||
// 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 <opus.h> |
|||
|
|||
#include "common/common_types.h" |
|||
#include "audio_core/adsp/apps/opus/opus_types.h" |
|||
#include "core/hle/result.h" |
|||
|
|||
struct AVCodec; |
|||
struct AVCodecContext; |
|||
|
|||
namespace AudioCore::ADSP::OpusDecoder { |
|||
using LibOpusDecoder = ::OpusDecoder; |
|||
static constexpr u32 DecodeObjectMagic = 0xDEADBEEF; |
|||
|
|||
class OpusDecodeObject { |
|||
public: |
|||
static u32 GetWorkBufferSize(u32 channel_count); |
|||
static OpusDecodeObject& Initialize(u64 buffer, u64 buffer2); |
|||
|
|||
s32 InitializeDecoder(u32 sample_rate, u32 channel_count); |
|||
s32 Shutdown(); |
|||
s32 ResetDecoder(); |
|||
s32 Decode(u32& out_sample_count, u64 output_data, u64 output_data_size, u64 input_data, |
|||
u64 input_data_size); |
|||
u32 GetFinalRange() const noexcept { |
|||
return final_range; |
|||
} |
|||
|
|||
private: |
|||
u32 magic; |
|||
bool initialized; |
|||
bool state_valid; |
|||
OpusDecodeObject* self; |
|||
u32 final_range; |
|||
LibOpusDecoder* decoder; |
|||
|
|||
Result InitializeDecoder(u32 sample_rate, u32 channel_count); |
|||
Result Shutdown(); |
|||
Result ResetDecoder(); |
|||
Result Decode(u32& out_sample_count, u64 output_data, u64 output_data_size, u64 input_data, u64 input_data_size); |
|||
|
|||
AVCodec const* codec = nullptr; |
|||
AVCodecContext* avctx = nullptr; |
|||
}; |
|||
static_assert(std::is_trivially_constructible_v<OpusDecodeObject>); |
|||
|
|||
} // namespace AudioCore::ADSP::OpusDecoder |
|||
@ -1,39 +1,31 @@ |
|||
// 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 <opus_multistream.h> |
|||
|
|||
#include "audio_core/adsp/apps/opus/opus_types.h" |
|||
#include "common/common_types.h" |
|||
#include "core/hle/result.h" |
|||
|
|||
struct AVCodec; |
|||
struct AVCodecContext; |
|||
|
|||
namespace AudioCore::ADSP::OpusDecoder { |
|||
using LibOpusMSDecoder = ::OpusMSDecoder; |
|||
static constexpr u32 DecodeMultiStreamObjectMagic = 0xDEADBEEF; |
|||
|
|||
class OpusMultiStreamDecodeObject { |
|||
public: |
|||
static u32 GetWorkBufferSize(u32 total_stream_count, u32 stereo_stream_count); |
|||
static OpusMultiStreamDecodeObject& Initialize(u64 buffer, u64 buffer2); |
|||
|
|||
s32 InitializeDecoder(u32 sample_rate, u32 total_stream_count, u32 channel_count, |
|||
u32 stereo_stream_count, u8* mappings); |
|||
s32 Shutdown(); |
|||
s32 ResetDecoder(); |
|||
s32 Decode(u32& out_sample_count, u64 output_data, u64 output_data_size, u64 input_data, |
|||
u64 input_data_size); |
|||
u32 GetFinalRange() const noexcept { |
|||
return final_range; |
|||
} |
|||
|
|||
private: |
|||
u32 magic; |
|||
bool initialized; |
|||
bool state_valid; |
|||
OpusMultiStreamDecodeObject* self; |
|||
u32 final_range; |
|||
LibOpusMSDecoder* decoder; |
|||
|
|||
Result InitializeDecoder(u32 sample_rate, u32 total_stream_count, u32 channel_count, u32 stereo_stream_count, u8* mappings); |
|||
Result Shutdown(); |
|||
Result ResetDecoder(); |
|||
Result Decode(u32& out_sample_count, u64 output_data, u64 output_data_size, u64 input_data, u64 input_data_size); |
|||
|
|||
AVCodec const* codec = nullptr; |
|||
AVCodecContext* avctx = nullptr; |
|||
}; |
|||
static_assert(std::is_trivially_constructible_v<OpusMultiStreamDecodeObject>); |
|||
|
|||
} // namespace AudioCore::ADSP::OpusDecoder |
|||
@ -0,0 +1,32 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_types.h" |
|||
|
|||
namespace AudioCore::ADSP { |
|||
|
|||
static constexpr u32 DECODE_OBJECT_MAGIC = 0xDEADBEEF; |
|||
struct LibOpusDecoder { |
|||
u32 magic; |
|||
bool initialized; |
|||
bool state_valid; |
|||
LibOpusDecoder* self; |
|||
u32 final_range; |
|||
void* decoder; |
|||
}; |
|||
static_assert(sizeof(LibOpusDecoder) == 32); |
|||
|
|||
static constexpr u32 DECODE_MULTISTREAM_OBJECT_MAGIC = 0xDEADBEEF; |
|||
struct LibOpusMultistreamDecoder { |
|||
u32 magic; |
|||
bool initialized; |
|||
bool state_valid; |
|||
LibOpusMultistreamDecoder* self; |
|||
u32 final_range; |
|||
void* decoder; |
|||
}; |
|||
static_assert(sizeof(LibOpusMultistreamDecoder) == 32); |
|||
|
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue