mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-11 06:17:41 +00:00
00a1c392e7
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions). - [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md) - [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability. ------------------- This is intended to fix Hades II save loading issue. By analyzing panic dump it was found out that the error code was 0x160A. By decoding firmware it was found that error comes from 'nn::codec::InitializeHardwareOpusDecoder'. Further decoding revealed that SDK tries to allocate multiple opus instances, up to the fw limit of 24 instances, and when it receives return error ResultOutOfOpusDecoders (385), a software fallback is gracefully used. Implementing the limitation and the limit reached error code return makes saves load properly, multiple times in a row in both windows and android. I still wonder why the game allocates too many parallel instances, but the current implementation is a real fw compliant solution, and whether the 24+ is real or some leak may be investigated later, or not. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4384 Reviewed-by: lizzie <lizzie@eden-emu.dev> Reviewed-by: MaranBr <maranbr@eden-emu.dev>
54 lines
2.3 KiB
C++
54 lines
2.3 KiB
C++
// 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>
|
|
|
|
#include "audio_core/adsp/apps/opus/opus_decoder.h"
|
|
#include "audio_core/adsp/apps/opus/shared_memory.h"
|
|
#include "audio_core/adsp/mailbox.h"
|
|
#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);
|
|
|
|
Result InitializeDecodeObject(u32 sample_rate, u32 channel_count, void* buffer,
|
|
u64 buffer_size);
|
|
Result InitializeMultiStreamDecodeObject(u32 sample_rate, u32 channel_count,
|
|
u32 totaL_stream_count, u32 stereo_stream_count,
|
|
const void* mappings, void* buffer, u64 buffer_size);
|
|
Result ShutdownDecodeObject(void* buffer, u64 buffer_size);
|
|
Result ShutdownMultiStreamDecodeObject(void* buffer, u64 buffer_size);
|
|
Result DecodeInterleaved(u32& out_sample_count, void* output_data, u64 output_data_size,
|
|
u32 channel_count, void* input_data, u64 input_data_size, void* buffer,
|
|
u64& out_time_taken, bool reset);
|
|
Result DecodeInterleavedForMultiStream(u32& out_sample_count, void* output_data,
|
|
u64 output_data_size, u32 channel_count,
|
|
void* input_data, u64 input_data_size, void* buffer,
|
|
u64& out_time_taken, bool reset);
|
|
Result MapMemory(void* buffer, u64 buffer_size);
|
|
Result UnmapMemory(void* buffer, u64 buffer_size);
|
|
|
|
private:
|
|
Core::System& system;
|
|
std::mutex mutex;
|
|
std::array<OpusDecoder*, 24> decoders{};
|
|
ADSP::OpusDecoder::OpusDecoder& opus_decoder;
|
|
ADSP::OpusDecoder::SharedMemory shared_memory;
|
|
};
|
|
} // namespace AudioCore::OpusDecoder
|