Compare commits

..

1 Commits

Author SHA1 Message Date
xbzk f744bcf9e1 [opus] proper limit and error of opus decoder instances 2026-09-09 23:28:23 -03:00
17 changed files with 75 additions and 107 deletions
+16
View File
@@ -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;
+20
View File
@@ -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;
+5
View File
@@ -3,6 +3,7 @@
#pragma once
#include <array>
#include <mutex>
#include <opus.h>
@@ -12,9 +13,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 +43,7 @@ public:
private:
Core::System& system;
std::mutex mutex;
std::array<OpusDecoder*, 24> decoders{};
ADSP::OpusDecoder::OpusDecoder& opus_decoder;
ADSP::OpusDecoder::SharedMemory shared_memory;
};
@@ -40,14 +40,10 @@ VirtualDir SystemVersion() {
VirtualFile file = std::make_shared<VectorVfsFile>(file_data, "file");
// the "/digest"
if (HLE::ApiVersion::VERSION_DIGEST[0] == '\0') {
return std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{file}, std::vector<VirtualDir>{}, "data");
} else {
std::vector<u8> digest_data(sizeof(HLE::ApiVersion::VERSION_DIGEST));
std::memcpy(digest_data.data(), HLE::ApiVersion::VERSION_DIGEST, sizeof(HLE::ApiVersion::VERSION_DIGEST));
VirtualFile digest_file = std::make_shared<VectorVfsFile>(digest_data, "digest");
return std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{file, digest_file}, std::vector<VirtualDir>{}, "data");
}
std::vector<u8> digest_data(sizeof(HLE::ApiVersion::VERSION_DIGEST));
std::memcpy(digest_data.data(), HLE::ApiVersion::VERSION_DIGEST, sizeof(HLE::ApiVersion::VERSION_DIGEST));
VirtualFile digest_file = std::make_shared<VectorVfsFile>(digest_data, "digest");
return std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{file, digest_file}, std::vector<VirtualDir>{}, "data");
}
} // namespace FileSys::SystemArchive
+8 -9
View File
@@ -16,8 +16,8 @@ namespace HLE::ApiVersion {
// Horizon OS version constants.
constexpr u8 HOS_VERSION_MAJOR = 23;
constexpr u8 HOS_VERSION_MINOR = 0;
constexpr u8 HOS_VERSION_MAJOR = 22;
constexpr u8 HOS_VERSION_MINOR = 5;
constexpr u8 HOS_VERSION_MICRO = 0;
// NintendoSDK version constants.
@@ -25,16 +25,15 @@ constexpr u8 SDK_REVISION_MAJOR = 1;
constexpr u8 SDK_REVISION_MINOR = 0;
constexpr char PLATFORM_STRING[0x20] = "NX";
constexpr char VERSION_HASH[0x40] = "c2663accb7490a6ccfe9bc4dfd120ca215490525";
constexpr char DISPLAY_VERSION[0x18] = "23.0.0";
constexpr char DISPLAY_TITLE[0x80] = "NintendoSDK Firmware for NX 23.0.0-4.0";
// Leave empty when there's no digest (N/A)
constexpr char VERSION_DIGEST[0x40] = "";
constexpr char VERSION_HASH[0x40] = "ae93061abbc7791fcf8d2f7e7b7b2d62163af697";
constexpr char DISPLAY_VERSION[0x18] = "22.5.0";
constexpr char DISPLAY_TITLE[0x80] = "NintendoSDK Firmware for NX 22.5.0-1.0 ";
constexpr char VERSION_DIGEST[0x40] = "CusHY#00160500#WxlZDREksAFSi6bQJEV6nm6-cHLg2jikdYRVN3bwqyE=";
// Atmosphere version constants.
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MAJOR = 1;
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MINOR = 12;
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MICRO = 0;
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MINOR = 11;
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MICRO = 2;
constexpr u32 AtmosphereTargetFirmwareWithRevision(u8 major, u8 minor, u8 micro, u8 rev) {
return u32{major} << 24 | u32{minor} << 16 | u32{micro} << 8 | u32{rev};
-7
View File
@@ -210,13 +210,6 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
*result = system.Kernel().CurrentScheduler()->GetIdleThread()->GetCpuTime();
R_SUCCEED();
}
case InfoType::Unknown37:
case InfoType::Unknown38: {
LOG_WARNING(Kernel_SVC, "(STUBBED) called, info_id={:#x}, info_sub_id={:#x}, handle={:#08x}",
info_id, info_sub_id, handle);
*result = 0;
R_SUCCEED();
}
case InfoType::MesosphereMeta: {
enum MesosphereMetaInfo : u64 {
KernelVersion = 0,
+1 -6
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
@@ -158,11 +158,6 @@ enum class InfoType : u32 {
IoRegionHint = 27,
AliasRegionExtraSize = 28,
TransferMemoryHint = 34,
Unknown37 = 37,
Unknown38 = 38,
MesosphereMeta = 65000,
MesosphereCurrentProcess = 65001,
};
@@ -16,7 +16,6 @@
#include "core/hle/service/cmif_serialization.h"
#include "core/loader/loader.h"
#include "core/launch_timestamp_cache.h"
#include "core/hle/api_version.h"
namespace Service::AM {
@@ -88,7 +87,7 @@ Result IApplicationCreator::CreateSystemApplication(
std::vector<u8> control;
std::unique_ptr<Loader::AppLoader> loader;
auto process = CreateProcess(system, application_id, 1, HLE::ApiVersion::HOS_VERSION_MAJOR);
auto process = CreateProcess(system, application_id, 1, 22);
R_UNLESS(process != nullptr, ResultUnknown);
const auto applet = std::make_shared<Applet>(system, std::move(process), true);
@@ -13,8 +13,6 @@
#include "core/hle/service/am/process_creation.h"
#include "core/hle/service/am/service/library_applet_accessor.h"
#include "core/hle/service/am/service/library_applet_creator.h"
#include "core/hle/api_version.h"
#include "core/hle/service/am/service/storage.h"
#include "core/hle/service/am/window_system.h"
#include "core/hle/service/cmif_serialization.h"
@@ -110,7 +108,20 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
return {};
}
auto process = CreateProcess(system, program_id, 1, HLE::ApiVersion::HOS_VERSION_MAJOR);
// TODO: enable other versions of applets
enum : u8 {
Firmware1400 = 14,
Firmware1500 = 15,
Firmware1600 = 16,
Firmware1700 = 17,
Firmware1800 = 18,
Firmware1900 = 19,
Firmware2000 = 20,
Firmware2100 = 21,
Firmware2200 = 22,
};
auto process = CreateProcess(system, program_id, Firmware1400, Firmware2200);
if (process) {
const auto applet = std::make_shared<Applet>(system, std::move(process), false);
applet->program_id = program_id;
@@ -71,7 +71,6 @@ ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet>
{120, D<&ISelfController::SaveCurrentScreenshot>, "SaveCurrentScreenshot"},
{130, D<&ISelfController::SetRecordVolumeMuted>, "SetRecordVolumeMuted"},
{230, D<&ISelfController::Unknown230>, "Unknown230"},
{240, D<&ISelfController::Unknown240>, "Unknown240"},
{1000, nullptr, "GetDebugStorageChannel"},
};
// clang-format on
@@ -423,10 +422,4 @@ Result ISelfController::Unknown230(u32 in_val, Out<u16> out_val) {
R_SUCCEED();
}
Result ISelfController::Unknown240(u32 in_val) {
LOG_WARNING(Service_AM, "(STUBBED) called, in_val={}", in_val);
R_SUCCEED();
}
} // namespace Service::AM
@@ -68,7 +68,6 @@ private:
Result SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option);
Result SetRecordVolumeMuted(bool muted);
Result Unknown230(u32 in_val, Out<u16> out_val);
Result Unknown240(u32 in_val);
Kernel::KProcess* const m_process;
const std::shared_ptr<Applet> m_applet;
+1
View File
@@ -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};
@@ -54,7 +54,7 @@ FSP_SRV::FSP_SRV(Core::System& system_)
static const FunctionInfo functions[] = {
{0, nullptr, "OpenFileSystem"},
{1, D<&FSP_SRV::SetCurrentProcess>, "SetCurrentProcess"},
{2, D<&FSP_SRV::OpenDataFileSystemByCurrentProcess>, "OpenDataFileSystemByCurrentProcess"},
{2, nullptr, "OpenDataFileSystemByCurrentProcess"},
{7, D<&FSP_SRV::OpenFileSystemWithPatch>, "OpenFileSystemWithPatch"},
{8, nullptr, "OpenFileSystemWithId"},
{9, nullptr, "OpenDataFileSystemByApplicationId"},
@@ -118,7 +118,6 @@ FSP_SRV::FSP_SRV(Core::System& system_)
{204, nullptr, "OpenDataFileSystemByProgramIndex"},
{205, D<&FSP_SRV::OpenDataStorageWithProgramIndex>, "OpenDataStorageWithProgramIndex"},
{206, nullptr, "OpenDataStorageByPath"},
{210, D<&FSP_SRV::SetCurrentProcess>, "SetCurrentProcess"},
{400, nullptr, "OpenDeviceOperator"},
{500, nullptr, "OpenSdCardDetectionEventNotifier"},
{501, nullptr, "OpenGameCardDetectionEventNotifier"},
@@ -461,31 +460,6 @@ Result FSP_SRV::OpenSaveDataTransferProhibiter(
R_SUCCEED();
}
Result FSP_SRV::OpenDataFileSystemByCurrentProcess(OutInterface<IFileSystem> out_interface) {
LOG_DEBUG(Service_FS, "called");
if (!romfs) {
auto current_romfs = romfs_controller->OpenRomFSCurrentProcess();
if (!current_romfs) {
LOG_CRITICAL(Service_FS, "No file system interface available!");
R_RETURN(ResultUnknown);
}
romfs = current_romfs;
}
auto extracted_romfs = FileSys::ExtractRomFS(romfs);
if (!extracted_romfs) {
LOG_CRITICAL(Service_FS, "Failed to extract RomFS for the current process!");
R_RETURN(ResultUnknown);
}
*out_interface = std::make_shared<IFileSystem>(
system, extracted_romfs, SizeGetter::FromStorageId(fsc, FileSys::StorageId::NandUser));
R_SUCCEED();
}
Result FSP_SRV::OpenDataStorageByCurrentProcess(OutInterface<IStorage> out_interface) {
LOG_DEBUG(Service_FS, "called");
@@ -51,7 +51,6 @@ public:
private:
Result SetCurrentProcess(ClientProcessId pid);
Result OpenDataFileSystemByCurrentProcess(OutInterface<IFileSystem> out_interface);
Result OpenFileSystemWithPatch(OutInterface<IFileSystem> out_interface,
FileSystemProxyType type, u64 open_program_id);
Result OpenSdCardFileSystem(OutInterface<IFileSystem> out_interface);
@@ -4,8 +4,6 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <chrono>
#include "core/core.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
@@ -96,7 +94,6 @@ IParentalControlService::IParentalControlService(Core::System& system_, Capabili
{1457, D<&IParentalControlService::GetPlayTimerEventToRequestSuspension>, "GetPlayTimerEventToRequestSuspension"},
{1458, D<&IParentalControlService::IsPlayTimerAlarmDisabled>, "IsPlayTimerAlarmDisabled"},
{1459, D<&IParentalControlService::GetPlayTimerRemainingTimeDisplayInfo>, "GetPlayTimerRemainingTimeDisplayInfo"},
{1460, D<&IParentalControlService::Unknown1460>, "Unknown1460"},
{1471, nullptr, "NotifyWrongPinCodeInputManyTimes"},
{1472, nullptr, "CancelNetworkRequest"},
{1473, D<&IParentalControlService::GetUnlinkedEvent>, "GetUnlinkedEvent"},
@@ -443,15 +440,8 @@ Result IParentalControlService::IsPlayTimerAlarmDisabled(Out<bool> out_play_time
R_SUCCEED();
}
Result IParentalControlService::GetPlayTimerRemainingTimeDisplayInfo(Out<PlayTimerRemainingTimeDisplayInfo> out_display_info) {
LOG_DEBUG(Service_PCTL, "called");
*out_display_info = {.state = PlayTimerDisplayState::NotConfigured};
R_SUCCEED();
}
Result IParentalControlService::Unknown1460(u8 in_unk, Out<PlayTimerRemainingTimeDisplayInfo> out_display_info) {
LOG_DEBUG(Service_PCTL, "called, in_unk={}", in_unk);
*out_display_info = {.state = PlayTimerDisplayState::NotConfigured};
Result IParentalControlService::GetPlayTimerRemainingTimeDisplayInfo(/* Out 0x18 */) {
LOG_INFO(Service_PCTL, "called");
R_SUCCEED();
}
@@ -55,8 +55,7 @@ private:
Result GetPlayTimerSettingsOld(Out<PlayTimerSettingsOld> out_play_timer_settings);
Result GetPlayTimerEventToRequestSuspension(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result IsPlayTimerAlarmDisabled(Out<bool> out_play_timer_alarm_disabled);
Result GetPlayTimerRemainingTimeDisplayInfo(Out<PlayTimerRemainingTimeDisplayInfo> out_display_info);
Result Unknown1460(u8 in_unk, Out<PlayTimerRemainingTimeDisplayInfo> out_display_info);
Result GetPlayTimerRemainingTimeDisplayInfo();
Result GetUnlinkedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetStereoVisionRestriction(Out<bool> out_stereo_vision_restriction);
Result SetStereoVisionRestriction(bool stereo_vision_restriction);
+1 -22
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
@@ -49,25 +49,4 @@ struct PlayTimerSettings {
};
static_assert(sizeof(PlayTimerSettings) == 0x44, "PlayTimerSettings has incorrect size.");
enum class PlayTimerDisplayState : u8 {
TimesUp = 0,
BedtimeAlarm = 1,
RemainingTime = 2,
Unknown3 = 3,
Unknown4 = 4,
Unknown5 = 5,
TimerDisabled = 6,
NotConfigured = 7,
};
// This is nn::pctl::PlayTimerRemainingTimeDisplayInfo
struct PlayTimerRemainingTimeDisplayInfo {
PlayTimerDisplayState state;
INSERT_PADDING_BYTES(0x7);
u64 unknown_08;
u64 remaining_time;
};
static_assert(sizeof(PlayTimerRemainingTimeDisplayInfo) == 0x18,
"PlayTimerRemainingTimeDisplayInfo has incorrect size.");
} // namespace Service::PCTL