Browse Source

unique_ptr -> optional, and use std::vector<> for shared buffer in opusdecoder

pull/3317/head
lizzie 3 weeks ago
parent
commit
fe6d54a3f7
  1. 8
      src/audio_core/adsp/adsp.cpp
  2. 4
      src/audio_core/adsp/adsp.h
  3. 38
      src/audio_core/opus/decoder.cpp
  4. 3
      src/audio_core/opus/decoder.h
  5. 5
      src/common/wall_clock.cpp
  6. 4
      src/common/wall_clock.h
  7. 14
      src/core/core_timing.cpp
  8. 4
      src/core/core_timing.h
  9. 14
      src/core/hle/kernel/k_process.cpp
  10. 82
      src/core/hle/kernel/k_process.h

8
src/audio_core/adsp/adsp.cpp

@ -7,8 +7,8 @@
namespace AudioCore::ADSP {
ADSP::ADSP(Core::System& system, Sink::Sink& sink) {
audio_renderer = std::make_unique<AudioRenderer::AudioRenderer>(system, sink);
opus_decoder = std::make_unique<OpusDecoder::OpusDecoder>(system);
audio_renderer.emplace(system, sink);
opus_decoder.emplace(system);
opus_decoder->Send(Direction::DSP, OpusDecoder::Message::Start);
if (opus_decoder->Receive(Direction::Host) != OpusDecoder::Message::StartOK) {
LOG_ERROR(Service_Audio, "OpusDecoder failed to initialize.");
@ -17,11 +17,11 @@ ADSP::ADSP(Core::System& system, Sink::Sink& sink) {
}
AudioRenderer::AudioRenderer& ADSP::AudioRenderer() {
return *audio_renderer.get();
return *audio_renderer;
}
OpusDecoder::OpusDecoder& ADSP::OpusDecoder() {
return *opus_decoder.get();
return *opus_decoder;
}
} // namespace AudioCore::ADSP

4
src/audio_core/adsp/adsp.h

@ -45,8 +45,8 @@ public:
private:
/// AudioRenderer app
std::unique_ptr<AudioRenderer::AudioRenderer> audio_renderer{};
std::unique_ptr<OpusDecoder::OpusDecoder> opus_decoder{};
std::optional<AudioRenderer::AudioRenderer> audio_renderer{};
std::optional<OpusDecoder::OpusDecoder> opus_decoder{};
};
} // namespace ADSP

38
src/audio_core/opus/decoder.cpp

@ -27,33 +27,31 @@ OpusDecoder::OpusDecoder(Core::System& system_, HardwareOpus& hardware_opus_)
OpusDecoder::~OpusDecoder() {
if (decode_object_initialized) {
hardware_opus.ShutdownDecodeObject(shared_buffer.get(), shared_buffer_size);
hardware_opus.ShutdownDecodeObject(shared_buffer.data(), shared_buffer.size());
}
}
Result OpusDecoder::Initialize(const OpusParametersEx& params,
Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) {
Result OpusDecoder::Initialize(const OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) {
auto frame_size{params.use_large_frame_size ? 5760 : 1920};
shared_buffer_size = transfer_memory_size;
shared_buffer = std::make_unique<u8[]>(shared_buffer_size);
shared_buffer.resize(transfer_memory_size);
shared_memory_mapped = true;
buffer_size =
Common::AlignUp((frame_size * params.channel_count) / (48'000 / params.sample_rate), 16);
out_data = {shared_buffer.get() + shared_buffer_size - buffer_size, buffer_size};
out_data = {shared_buffer.data() + shared_buffer.size() - buffer_size, buffer_size};
size_t in_data_size{0x600u};
in_data = {out_data.data() - in_data_size, in_data_size};
ON_RESULT_FAILURE {
if (shared_memory_mapped) {
shared_memory_mapped = false;
ASSERT(R_SUCCEEDED(hardware_opus.UnmapMemory(shared_buffer.get(), shared_buffer_size)));
ASSERT(R_SUCCEEDED(hardware_opus.UnmapMemory(shared_buffer.data(), shared_buffer.size())));
}
};
R_TRY(hardware_opus.InitializeDecodeObject(params.sample_rate, params.channel_count,
shared_buffer.get(), shared_buffer_size));
shared_buffer.data(), shared_buffer.size()));
sample_rate = params.sample_rate;
channel_count = params.channel_count;
@ -62,31 +60,29 @@ Result OpusDecoder::Initialize(const OpusParametersEx& params,
R_SUCCEED();
}
Result OpusDecoder::Initialize(const OpusMultiStreamParametersEx& params,
Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) {
Result OpusDecoder::Initialize(const OpusMultiStreamParametersEx& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) {
auto frame_size{params.use_large_frame_size ? 5760 : 1920};
shared_buffer_size = transfer_memory_size;
shared_buffer = std::make_unique<u8[]>(shared_buffer_size);
shared_buffer.resize(transfer_memory_size, 0);
shared_memory_mapped = true;
buffer_size =
Common::AlignUp((frame_size * params.channel_count) / (48'000 / params.sample_rate), 16);
out_data = {shared_buffer.get() + shared_buffer_size - buffer_size, buffer_size};
out_data = {shared_buffer.data() + shared_buffer.size() - buffer_size, buffer_size};
size_t in_data_size{Common::AlignUp(1500ull * params.total_stream_count, 64u)};
in_data = {out_data.data() - in_data_size, in_data_size};
ON_RESULT_FAILURE {
if (shared_memory_mapped) {
shared_memory_mapped = false;
ASSERT(R_SUCCEEDED(hardware_opus.UnmapMemory(shared_buffer.get(), shared_buffer_size)));
ASSERT(R_SUCCEEDED(hardware_opus.UnmapMemory(shared_buffer.data(), shared_buffer.size())));
}
};
R_TRY(hardware_opus.InitializeMultiStreamDecodeObject(
params.sample_rate, params.channel_count, params.total_stream_count,
params.stereo_stream_count, params.mappings.data(), shared_buffer.get(),
shared_buffer_size));
params.stereo_stream_count, params.mappings.data(), shared_buffer.data(),
shared_buffer.size()));
sample_rate = params.sample_rate;
channel_count = params.channel_count;
@ -113,7 +109,7 @@ Result OpusDecoder::DecodeInterleaved(u32* out_data_size, u64* out_time_taken,
ResultBufferTooSmall);
if (!shared_memory_mapped) {
R_TRY(hardware_opus.MapMemory(shared_buffer.get(), shared_buffer_size));
R_TRY(hardware_opus.MapMemory(shared_buffer.data(), shared_buffer.size()));
shared_memory_mapped = true;
}
@ -121,7 +117,7 @@ Result OpusDecoder::DecodeInterleaved(u32* out_data_size, u64* out_time_taken,
R_TRY(hardware_opus.DecodeInterleaved(out_samples, out_data.data(), out_data.size_bytes(),
channel_count, in_data.data(), header.size,
shared_buffer.get(), time_taken, reset));
shared_buffer.data(), time_taken, reset));
std::memcpy(output_data.data(), out_data.data(), out_samples * channel_count * sizeof(s16));
@ -136,7 +132,7 @@ Result OpusDecoder::DecodeInterleaved(u32* out_data_size, u64* out_time_taken,
Result OpusDecoder::SetContext([[maybe_unused]] std::span<const u8> context) {
R_SUCCEED_IF(shared_memory_mapped);
shared_memory_mapped = true;
R_RETURN(hardware_opus.MapMemory(shared_buffer.get(), shared_buffer_size));
R_RETURN(hardware_opus.MapMemory(shared_buffer.data(), shared_buffer.size()));
}
Result OpusDecoder::DecodeInterleavedForMultiStream(u32* out_data_size, u64* out_time_taken,
@ -159,7 +155,7 @@ Result OpusDecoder::DecodeInterleavedForMultiStream(u32* out_data_size, u64* out
ResultBufferTooSmall);
if (!shared_memory_mapped) {
R_TRY(hardware_opus.MapMemory(shared_buffer.get(), shared_buffer_size));
R_TRY(hardware_opus.MapMemory(shared_buffer.data(), shared_buffer.size()));
shared_memory_mapped = true;
}
@ -167,7 +163,7 @@ Result OpusDecoder::DecodeInterleavedForMultiStream(u32* out_data_size, u64* out
R_TRY(hardware_opus.DecodeInterleavedForMultiStream(
out_samples, out_data.data(), out_data.size_bytes(), channel_count, in_data.data(),
header.size, shared_buffer.get(), time_taken, reset));
header.size, shared_buffer.data(), time_taken, reset));
std::memcpy(output_data.data(), out_data.data(), out_samples * channel_count * sizeof(s16));

3
src/audio_core/opus/decoder.h

@ -36,8 +36,7 @@ public:
private:
Core::System& system;
HardwareOpus& hardware_opus;
std::unique_ptr<u8[]> shared_buffer{};
u64 shared_buffer_size;
std::vector<u8> shared_buffer{};
std::span<u8> in_data{};
std::span<u8> out_data{};
u64 buffer_size{};

5
src/common/wall_clock.cpp

@ -9,7 +9,6 @@
#include "common/x64/native_clock.h"
#include "common/x64/rdtsc.h"
#endif
#ifdef HAS_NCE
#include "common/arm64/native_clock.h"
#endif
@ -73,8 +72,4 @@ std::unique_ptr<WallClock> CreateOptimalClock() {
#endif
}
std::unique_ptr<WallClock> CreateStandardWallClock() {
return std::make_unique<StandardWallClock>();
}
} // namespace Common

4
src/common/wall_clock.h

@ -84,8 +84,6 @@ protected:
using CPUTickToGPUTickRatio = std::ratio<GPUTickFreq, CPUTickFreq>;
};
std::unique_ptr<WallClock> CreateOptimalClock();
std::unique_ptr<WallClock> CreateStandardWallClock();
[[nodiscard]] std::unique_ptr<WallClock> CreateOptimalClock();
} // namespace Common

14
src/core/core_timing.cpp

@ -53,13 +53,6 @@ CoreTiming::~CoreTiming() {
Reset();
}
void CoreTiming::ThreadEntry(CoreTiming& instance) {
Common::SetCurrentThreadName("HostTiming");
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
instance.on_thread_init();
instance.ThreadLoop();
}
void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
Reset();
on_thread_init = std::move(on_thread_init_);
@ -67,7 +60,12 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
shutting_down = false;
cpu_ticks = 0;
if (is_multicore) {
timer_thread = std::make_unique<std::jthread>(ThreadEntry, std::ref(*this));
timer_thread.emplace([](CoreTiming& instance) {
Common::SetCurrentThreadName("HostTiming");
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
instance.on_thread_init();
instance.ThreadLoop();
}, std::ref(*this));
}
}

4
src/core/core_timing.h

@ -140,8 +140,6 @@ public:
private:
struct Event;
static void ThreadEntry(CoreTiming& instance);
void ThreadLoop();
void Reset();
@ -164,7 +162,7 @@ private:
Common::Event pause_event{};
mutable std::mutex basic_lock;
std::mutex advance_lock;
std::unique_ptr<std::jthread> timer_thread;
std::optional<std::jthread> timer_thread;
std::atomic<bool> paused{};
std::atomic<bool> paused_set{};
std::atomic<bool> wait_set{};

14
src/core/hle/kernel/k_process.cpp

@ -1148,9 +1148,17 @@ Result KProcess::GetThreadList(s32* out_num_threads, KProcessAddress out_thread_
void KProcess::Switch(KProcess* cur_process, KProcess* next_process) {}
KProcess::KProcess(KernelCore& kernel)
: KAutoObjectWithSlabHeapAndContainer(kernel), m_page_table{kernel}, m_state_lock{kernel},
m_list_lock{kernel}, m_cond_var{kernel.System()}, m_address_arbiter{kernel.System()},
m_handle_table{kernel}, m_exclusive_monitor{}, m_memory{kernel.System()} {}
: KAutoObjectWithSlabHeapAndContainer(kernel)
, m_exclusive_monitor{}
, m_memory{kernel.System()}
, m_handle_table{kernel}
, m_page_table{kernel}
, m_state_lock{kernel}
, m_list_lock{kernel}
, m_cond_var{kernel.System()}
, m_address_arbiter{kernel.System()}
{}
KProcess::~KProcess() = default;
Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,

82
src/core/hle/kernel/k_process.h

@ -66,60 +66,55 @@ public:
private:
using SharedMemoryInfoList = Common::IntrusiveListBaseTraits<KSharedMemoryInfo>::ListType;
using TLPTree =
Common::IntrusiveRedBlackTreeBaseTraits<KThreadLocalPage>::TreeType<KThreadLocalPage>;
using TLPTree = Common::IntrusiveRedBlackTreeBaseTraits<KThreadLocalPage>::TreeType<KThreadLocalPage>;
using TLPIterator = TLPTree::iterator;
private:
std::array<std::unique_ptr<Core::ArmInterface>, Core::Hardware::NUM_CPU_CORES> m_arm_interfaces{};
std::array<KThread*, Core::Hardware::NUM_CPU_CORES> m_running_threads{};
std::array<u64, Core::Hardware::NUM_CPU_CORES> m_running_thread_idle_counts{};
std::array<u64, Core::Hardware::NUM_CPU_CORES> m_running_thread_switch_counts{};
std::array<KThread*, Core::Hardware::NUM_CPU_CORES> m_pinned_threads{};
std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS> m_watchpoints{};
std::map<KProcessAddress, u64> m_debug_page_refcounts{};
#ifdef HAS_NCE
std::unordered_map<u64, u64> m_post_handlers{};
#endif
std::unique_ptr<Core::ExclusiveMonitor> m_exclusive_monitor;
Core::Memory::Memory m_memory;
KCapabilities m_capabilities{};
KProcessAddress m_code_address{};
KHandleTable m_handle_table;
KProcessAddress m_plr_address{};
ThreadList m_thread_list{};
SharedMemoryInfoList m_shared_memory_list{};
KProcessPageTable m_page_table;
std::atomic<size_t> m_used_kernel_memory_size{};
TLPTree m_fully_used_tlp_tree{};
TLPTree m_partially_used_tlp_tree{};
s32 m_ideal_core_id{};
KResourceLimit* m_resource_limit{};
KSystemResource* m_system_resource{};
size_t m_memory_release_hint{};
State m_state{};
KLightLock m_state_lock;
KLightLock m_list_lock;
KConditionVariable m_cond_var;
KAddressArbiter m_address_arbiter;
std::array<u64, 4> m_entropy{};
bool m_is_signaled{};
bool m_is_initialized{};
u32 m_pointer_buffer_size = 0x8000; // Default pointer buffer size (can be game-specific later)
bool m_is_application{};
bool m_is_default_application_system_resource{};
bool m_is_hbl{};
std::array<char, 13> m_name{};
std::atomic<u16> m_num_running_threads{};
Svc::CreateProcessFlag m_flags{};
KMemoryManager::Pool m_memory_pool{};
s64 m_schedule_count{};
KCapabilities m_capabilities{};
u64 m_program_id{};
u64 m_process_id{};
KProcessAddress m_code_address{};
KResourceLimit* m_resource_limit{};
KSystemResource* m_system_resource{};
KThread* m_exception_thread{};
size_t m_code_size{};
size_t m_main_thread_stack_size{};
size_t m_max_process_memory{};
u32 m_version{};
KHandleTable m_handle_table;
KProcessAddress m_plr_address{};
KThread* m_exception_thread{};
ThreadList m_thread_list{};
SharedMemoryInfoList m_shared_memory_list{};
bool m_is_suspended{};
bool m_is_immortal{};
bool m_is_handle_table_initialized{};
std::array<std::unique_ptr<Core::ArmInterface>, Core::Hardware::NUM_CPU_CORES>
m_arm_interfaces{};
std::array<KThread*, Core::Hardware::NUM_CPU_CORES> m_running_threads{};
std::array<u64, Core::Hardware::NUM_CPU_CORES> m_running_thread_idle_counts{};
std::array<u64, Core::Hardware::NUM_CPU_CORES> m_running_thread_switch_counts{};
std::array<KThread*, Core::Hardware::NUM_CPU_CORES> m_pinned_threads{};
std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS> m_watchpoints{};
std::map<KProcessAddress, u64> m_debug_page_refcounts{};
size_t m_memory_release_hint{};
s64 m_schedule_count{};
u64 m_program_id{};
u64 m_process_id{};
std::atomic<s64> m_cpu_time{};
std::atomic<s64> m_num_process_switches{};
std::atomic<s64> m_num_thread_switches{};
@ -128,11 +123,20 @@ private:
std::atomic<s64> m_num_ipc_messages{};
std::atomic<s64> m_num_ipc_replies{};
std::atomic<s64> m_num_ipc_receives{};
#ifdef HAS_NCE
std::unordered_map<u64, u64> m_post_handlers{};
#endif
std::unique_ptr<Core::ExclusiveMonitor> m_exclusive_monitor;
Core::Memory::Memory m_memory;
s32 m_ideal_core_id{};
u32 m_version{};
std::atomic<u16> m_num_running_threads{};
bool m_is_signaled : 1 = false;
bool m_is_initialized : 1 = false;
bool m_is_application : 1 = false;
bool m_is_default_application_system_resource : 1 = false;
bool m_is_hbl : 1 = false;
bool m_is_suspended : 1 = false;
bool m_is_immortal : 1 = false;
bool m_is_handle_table_initialized : 1 = false;
private:
Result StartTermination();

Loading…
Cancel
Save