audio: split IHardwarweOpusDecoder, move IHardwareOpusDecoderManager
This commit is contained in:
parent
62083fcafd
commit
f65539504f
7 changed files with 556 additions and 509 deletions
|
@ -512,8 +512,10 @@ add_library(core STATIC
|
||||||
hle/service/audio/final_output_recorder_manager_for_applet.h
|
hle/service/audio/final_output_recorder_manager_for_applet.h
|
||||||
hle/service/audio/final_output_recorder_manager.cpp
|
hle/service/audio/final_output_recorder_manager.cpp
|
||||||
hle/service/audio/final_output_recorder_manager.h
|
hle/service/audio/final_output_recorder_manager.h
|
||||||
hle/service/audio/hwopus.cpp
|
hle/service/audio/hardware_opus_decoder_manager.cpp
|
||||||
hle/service/audio/hwopus.h
|
hle/service/audio/hardware_opus_decoder_manager.h
|
||||||
|
hle/service/audio/hardware_opus_decoder.cpp
|
||||||
|
hle/service/audio/hardware_opus_decoder.h
|
||||||
hle/service/bcat/backend/backend.cpp
|
hle/service/bcat/backend/backend.cpp
|
||||||
hle/service/bcat/backend/backend.h
|
hle/service/bcat/backend/backend.h
|
||||||
hle/service/bcat/bcat.cpp
|
hle/service/bcat/bcat.cpp
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "core/hle/service/audio/audio_renderer_manager.h"
|
#include "core/hle/service/audio/audio_renderer_manager.h"
|
||||||
#include "core/hle/service/audio/final_output_recorder_manager.h"
|
#include "core/hle/service/audio/final_output_recorder_manager.h"
|
||||||
#include "core/hle/service/audio/final_output_recorder_manager_for_applet.h"
|
#include "core/hle/service/audio/final_output_recorder_manager_for_applet.h"
|
||||||
#include "core/hle/service/audio/hwopus.h"
|
#include "core/hle/service/audio/hardware_opus_decoder_manager.h"
|
||||||
#include "core/hle/service/server_manager.h"
|
#include "core/hle/service/server_manager.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
|
@ -27,7 +27,8 @@ void LoopProcess(Core::System& system) {
|
||||||
std::make_shared<IFinalOutputRecorderManager>(system));
|
std::make_shared<IFinalOutputRecorderManager>(system));
|
||||||
server_manager->RegisterNamedService("audren:u",
|
server_manager->RegisterNamedService("audren:u",
|
||||||
std::make_shared<IAudioRendererManager>(system));
|
std::make_shared<IAudioRendererManager>(system));
|
||||||
server_manager->RegisterNamedService("hwopus", std::make_shared<HwOpus>(system));
|
server_manager->RegisterNamedService("hwopus",
|
||||||
|
std::make_shared<IHardwareOpusDecoderManager>(system));
|
||||||
ServerManager::RunServer(std::move(server_manager));
|
ServerManager::RunServer(std::move(server_manager));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
265
src/core/hle/service/audio/hardware_opus_decoder.cpp
Normal file
265
src/core/hle/service/audio/hardware_opus_decoder.cpp
Normal file
|
@ -0,0 +1,265 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/hle/service/audio/hardware_opus_decoder.h"
|
||||||
|
#include "core/hle/service/ipc_helpers.h"
|
||||||
|
|
||||||
|
namespace Service::Audio {
|
||||||
|
|
||||||
|
using namespace AudioCore::OpusDecoder;
|
||||||
|
|
||||||
|
IHardwareOpusDecoder::IHardwareOpusDecoder(Core::System& system_, HardwareOpus& hardware_opus)
|
||||||
|
: ServiceFramework{system_, "IHardwareOpusDecoder"},
|
||||||
|
impl{std::make_unique<AudioCore::OpusDecoder::OpusDecoder>(system_, hardware_opus)} {
|
||||||
|
// clang-format off
|
||||||
|
static const FunctionInfo functions[] = {
|
||||||
|
{0, &IHardwareOpusDecoder::DecodeInterleavedOld, "DecodeInterleavedOld"},
|
||||||
|
{1, &IHardwareOpusDecoder::SetContext, "SetContext"},
|
||||||
|
{2, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamOld, "DecodeInterleavedForMultiStreamOld"},
|
||||||
|
{3, &IHardwareOpusDecoder::SetContextForMultiStream, "SetContextForMultiStream"},
|
||||||
|
{4, &IHardwareOpusDecoder::DecodeInterleavedWithPerfOld, "DecodeInterleavedWithPerfOld"},
|
||||||
|
{5, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfOld, "DecodeInterleavedForMultiStreamWithPerfOld"},
|
||||||
|
{6, &IHardwareOpusDecoder::DecodeInterleavedWithPerfAndResetOld, "DecodeInterleavedWithPerfAndResetOld"},
|
||||||
|
{7, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfAndResetOld, "DecodeInterleavedForMultiStreamWithPerfAndResetOld"},
|
||||||
|
{8, &IHardwareOpusDecoder::DecodeInterleaved, "DecodeInterleaved"},
|
||||||
|
{9, &IHardwareOpusDecoder::DecodeInterleavedForMultiStream, "DecodeInterleavedForMultiStream"},
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
RegisterHandlers(functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
IHardwareOpusDecoder::~IHardwareOpusDecoder() = default;
|
||||||
|
|
||||||
|
Result IHardwareOpusDecoder::Initialize(OpusParametersEx& params,
|
||||||
|
Kernel::KTransferMemory* transfer_memory,
|
||||||
|
u64 transfer_memory_size) {
|
||||||
|
return impl->Initialize(params, transfer_memory, transfer_memory_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result IHardwareOpusDecoder::Initialize(OpusMultiStreamParametersEx& params,
|
||||||
|
Kernel::KTransferMemory* transfer_memory,
|
||||||
|
u64 transfer_memory_size) {
|
||||||
|
return impl->Initialize(params, transfer_memory, transfer_memory_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoder::DecodeInterleavedOld(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
auto input_data{ctx.ReadBuffer(0)};
|
||||||
|
output_data.resize_destructive(ctx.GetWriteBufferSize());
|
||||||
|
|
||||||
|
u32 size{};
|
||||||
|
u32 sample_count{};
|
||||||
|
auto result =
|
||||||
|
impl->DecodeInterleaved(&size, nullptr, &sample_count, input_data, output_data, false);
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {}", size, sample_count);
|
||||||
|
|
||||||
|
ctx.WriteBuffer(output_data);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.Push(size);
|
||||||
|
rb.Push(sample_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoder::SetContext(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio, "called");
|
||||||
|
|
||||||
|
auto input_data{ctx.ReadBuffer(0)};
|
||||||
|
auto result = impl->SetContext(input_data);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoder::DecodeInterleavedForMultiStreamOld(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
auto input_data{ctx.ReadBuffer(0)};
|
||||||
|
output_data.resize_destructive(ctx.GetWriteBufferSize());
|
||||||
|
|
||||||
|
u32 size{};
|
||||||
|
u32 sample_count{};
|
||||||
|
auto result = impl->DecodeInterleavedForMultiStream(&size, nullptr, &sample_count, input_data,
|
||||||
|
output_data, false);
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {}", size, sample_count);
|
||||||
|
|
||||||
|
ctx.WriteBuffer(output_data);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.Push(size);
|
||||||
|
rb.Push(sample_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoder::SetContextForMultiStream(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio, "called");
|
||||||
|
|
||||||
|
auto input_data{ctx.ReadBuffer(0)};
|
||||||
|
auto result = impl->SetContext(input_data);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoder::DecodeInterleavedWithPerfOld(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
auto input_data{ctx.ReadBuffer(0)};
|
||||||
|
output_data.resize_destructive(ctx.GetWriteBufferSize());
|
||||||
|
|
||||||
|
u32 size{};
|
||||||
|
u32 sample_count{};
|
||||||
|
u64 time_taken{};
|
||||||
|
auto result =
|
||||||
|
impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data, output_data, false);
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {} time taken {}", size,
|
||||||
|
sample_count, time_taken);
|
||||||
|
|
||||||
|
ctx.WriteBuffer(output_data);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 6};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.Push(size);
|
||||||
|
rb.Push(sample_count);
|
||||||
|
rb.Push(time_taken);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfOld(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
auto input_data{ctx.ReadBuffer(0)};
|
||||||
|
output_data.resize_destructive(ctx.GetWriteBufferSize());
|
||||||
|
|
||||||
|
u32 size{};
|
||||||
|
u32 sample_count{};
|
||||||
|
u64 time_taken{};
|
||||||
|
auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count,
|
||||||
|
input_data, output_data, false);
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {} time taken {}", size,
|
||||||
|
sample_count, time_taken);
|
||||||
|
|
||||||
|
ctx.WriteBuffer(output_data);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 6};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.Push(size);
|
||||||
|
rb.Push(sample_count);
|
||||||
|
rb.Push(time_taken);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoder::DecodeInterleavedWithPerfAndResetOld(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
auto reset{rp.Pop<bool>()};
|
||||||
|
|
||||||
|
auto input_data{ctx.ReadBuffer(0)};
|
||||||
|
output_data.resize_destructive(ctx.GetWriteBufferSize());
|
||||||
|
|
||||||
|
u32 size{};
|
||||||
|
u32 sample_count{};
|
||||||
|
u64 time_taken{};
|
||||||
|
auto result =
|
||||||
|
impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data, output_data, reset);
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", reset,
|
||||||
|
size, sample_count, time_taken);
|
||||||
|
|
||||||
|
ctx.WriteBuffer(output_data);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 6};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.Push(size);
|
||||||
|
rb.Push(sample_count);
|
||||||
|
rb.Push(time_taken);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfAndResetOld(
|
||||||
|
HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
auto reset{rp.Pop<bool>()};
|
||||||
|
|
||||||
|
auto input_data{ctx.ReadBuffer(0)};
|
||||||
|
output_data.resize_destructive(ctx.GetWriteBufferSize());
|
||||||
|
|
||||||
|
u32 size{};
|
||||||
|
u32 sample_count{};
|
||||||
|
u64 time_taken{};
|
||||||
|
auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count,
|
||||||
|
input_data, output_data, reset);
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", reset,
|
||||||
|
size, sample_count, time_taken);
|
||||||
|
|
||||||
|
ctx.WriteBuffer(output_data);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 6};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.Push(size);
|
||||||
|
rb.Push(sample_count);
|
||||||
|
rb.Push(time_taken);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoder::DecodeInterleaved(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
auto reset{rp.Pop<bool>()};
|
||||||
|
|
||||||
|
auto input_data{ctx.ReadBuffer(0)};
|
||||||
|
output_data.resize_destructive(ctx.GetWriteBufferSize());
|
||||||
|
|
||||||
|
u32 size{};
|
||||||
|
u32 sample_count{};
|
||||||
|
u64 time_taken{};
|
||||||
|
auto result =
|
||||||
|
impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data, output_data, reset);
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", reset,
|
||||||
|
size, sample_count, time_taken);
|
||||||
|
|
||||||
|
ctx.WriteBuffer(output_data);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 6};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.Push(size);
|
||||||
|
rb.Push(sample_count);
|
||||||
|
rb.Push(time_taken);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoder::DecodeInterleavedForMultiStream(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
auto reset{rp.Pop<bool>()};
|
||||||
|
|
||||||
|
auto input_data{ctx.ReadBuffer(0)};
|
||||||
|
output_data.resize_destructive(ctx.GetWriteBufferSize());
|
||||||
|
|
||||||
|
u32 size{};
|
||||||
|
u32 sample_count{};
|
||||||
|
u64 time_taken{};
|
||||||
|
auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count,
|
||||||
|
input_data, output_data, reset);
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}", reset,
|
||||||
|
size, sample_count, time_taken);
|
||||||
|
|
||||||
|
ctx.WriteBuffer(output_data);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 6};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.Push(size);
|
||||||
|
rb.Push(sample_count);
|
||||||
|
rb.Push(time_taken);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Service::Audio
|
38
src/core/hle/service/audio/hardware_opus_decoder.h
Normal file
38
src/core/hle/service/audio/hardware_opus_decoder.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "audio_core/opus/decoder.h"
|
||||||
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
|
namespace Service::Audio {
|
||||||
|
|
||||||
|
class IHardwareOpusDecoder final : public ServiceFramework<IHardwareOpusDecoder> {
|
||||||
|
public:
|
||||||
|
explicit IHardwareOpusDecoder(Core::System& system_,
|
||||||
|
AudioCore::OpusDecoder::HardwareOpus& hardware_opus);
|
||||||
|
~IHardwareOpusDecoder() override;
|
||||||
|
|
||||||
|
Result Initialize(AudioCore::OpusDecoder::OpusParametersEx& params,
|
||||||
|
Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size);
|
||||||
|
Result Initialize(AudioCore::OpusDecoder::OpusMultiStreamParametersEx& params,
|
||||||
|
Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DecodeInterleavedOld(HLERequestContext& ctx);
|
||||||
|
void SetContext(HLERequestContext& ctx);
|
||||||
|
void DecodeInterleavedForMultiStreamOld(HLERequestContext& ctx);
|
||||||
|
void SetContextForMultiStream(HLERequestContext& ctx);
|
||||||
|
void DecodeInterleavedWithPerfOld(HLERequestContext& ctx);
|
||||||
|
void DecodeInterleavedForMultiStreamWithPerfOld(HLERequestContext& ctx);
|
||||||
|
void DecodeInterleavedWithPerfAndResetOld(HLERequestContext& ctx);
|
||||||
|
void DecodeInterleavedForMultiStreamWithPerfAndResetOld(HLERequestContext& ctx);
|
||||||
|
void DecodeInterleaved(HLERequestContext& ctx);
|
||||||
|
void DecodeInterleavedForMultiStream(HLERequestContext& ctx);
|
||||||
|
|
||||||
|
std::unique_ptr<AudioCore::OpusDecoder::OpusDecoder> impl;
|
||||||
|
Common::ScratchBuffer<u8> output_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Service::Audio
|
243
src/core/hle/service/audio/hardware_opus_decoder_manager.cpp
Normal file
243
src/core/hle/service/audio/hardware_opus_decoder_manager.cpp
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/hle/service/audio/hardware_opus_decoder.h"
|
||||||
|
#include "core/hle/service/audio/hardware_opus_decoder_manager.h"
|
||||||
|
#include "core/hle/service/ipc_helpers.h"
|
||||||
|
|
||||||
|
namespace Service::Audio {
|
||||||
|
|
||||||
|
using namespace AudioCore::OpusDecoder;
|
||||||
|
|
||||||
|
void IHardwareOpusDecoderManager::OpenHardwareOpusDecoder(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
auto params = rp.PopRaw<OpusParameters>();
|
||||||
|
auto transfer_memory_size{rp.Pop<u32>()};
|
||||||
|
auto transfer_memory_handle{ctx.GetCopyHandle(0)};
|
||||||
|
auto transfer_memory{ctx.GetObjectFromHandle<Kernel::KTransferMemory>(transfer_memory_handle)};
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} transfer_memory_size 0x{:X}",
|
||||||
|
params.sample_rate, params.channel_count, transfer_memory_size);
|
||||||
|
|
||||||
|
auto decoder{std::make_shared<IHardwareOpusDecoder>(system, impl.GetHardwareOpus())};
|
||||||
|
|
||||||
|
OpusParametersEx ex{
|
||||||
|
.sample_rate = params.sample_rate,
|
||||||
|
.channel_count = params.channel_count,
|
||||||
|
.use_large_frame_size = false,
|
||||||
|
};
|
||||||
|
auto result = decoder->Initialize(ex, transfer_memory.GetPointerUnsafe(), transfer_memory_size);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.PushIpcInterface(decoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoderManager::GetWorkBufferSize(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
auto params = rp.PopRaw<OpusParameters>();
|
||||||
|
|
||||||
|
u64 size{};
|
||||||
|
auto result = impl.GetWorkBufferSize(params, size);
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} -- returned size 0x{:X}",
|
||||||
|
params.sample_rate, params.channel_count, size);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.Push(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStream(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
auto input{ctx.ReadBuffer()};
|
||||||
|
OpusMultiStreamParameters params;
|
||||||
|
std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParameters));
|
||||||
|
|
||||||
|
auto transfer_memory_size{rp.Pop<u32>()};
|
||||||
|
auto transfer_memory_handle{ctx.GetCopyHandle(0)};
|
||||||
|
auto transfer_memory{ctx.GetObjectFromHandle<Kernel::KTransferMemory>(transfer_memory_handle)};
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio,
|
||||||
|
"sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} "
|
||||||
|
"transfer_memory_size 0x{:X}",
|
||||||
|
params.sample_rate, params.channel_count, params.total_stream_count,
|
||||||
|
params.stereo_stream_count, transfer_memory_size);
|
||||||
|
|
||||||
|
auto decoder{std::make_shared<IHardwareOpusDecoder>(system, impl.GetHardwareOpus())};
|
||||||
|
|
||||||
|
OpusMultiStreamParametersEx ex{
|
||||||
|
.sample_rate = params.sample_rate,
|
||||||
|
.channel_count = params.channel_count,
|
||||||
|
.total_stream_count = params.total_stream_count,
|
||||||
|
.stereo_stream_count = params.stereo_stream_count,
|
||||||
|
.use_large_frame_size = false,
|
||||||
|
.mappings{},
|
||||||
|
};
|
||||||
|
std::memcpy(ex.mappings.data(), params.mappings.data(), sizeof(params.mappings));
|
||||||
|
auto result = decoder->Initialize(ex, transfer_memory.GetPointerUnsafe(), transfer_memory_size);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.PushIpcInterface(decoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStream(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
auto input{ctx.ReadBuffer()};
|
||||||
|
OpusMultiStreamParameters params;
|
||||||
|
std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParameters));
|
||||||
|
|
||||||
|
u64 size{};
|
||||||
|
auto result = impl.GetWorkBufferSizeForMultiStream(params, size);
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio, "size 0x{:X}", size);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.Push(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoderManager::OpenHardwareOpusDecoderEx(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
auto params = rp.PopRaw<OpusParametersEx>();
|
||||||
|
auto transfer_memory_size{rp.Pop<u32>()};
|
||||||
|
auto transfer_memory_handle{ctx.GetCopyHandle(0)};
|
||||||
|
auto transfer_memory{ctx.GetObjectFromHandle<Kernel::KTransferMemory>(transfer_memory_handle)};
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} transfer_memory_size 0x{:X}",
|
||||||
|
params.sample_rate, params.channel_count, transfer_memory_size);
|
||||||
|
|
||||||
|
auto decoder{std::make_shared<IHardwareOpusDecoder>(system, impl.GetHardwareOpus())};
|
||||||
|
|
||||||
|
auto result =
|
||||||
|
decoder->Initialize(params, transfer_memory.GetPointerUnsafe(), transfer_memory_size);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.PushIpcInterface(decoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoderManager::GetWorkBufferSizeEx(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
auto params = rp.PopRaw<OpusParametersEx>();
|
||||||
|
|
||||||
|
u64 size{};
|
||||||
|
auto result = impl.GetWorkBufferSizeEx(params, size);
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio, "size 0x{:X}", size);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.Push(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStreamEx(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
auto input{ctx.ReadBuffer()};
|
||||||
|
OpusMultiStreamParametersEx params;
|
||||||
|
std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParametersEx));
|
||||||
|
|
||||||
|
auto transfer_memory_size{rp.Pop<u32>()};
|
||||||
|
auto transfer_memory_handle{ctx.GetCopyHandle(0)};
|
||||||
|
auto transfer_memory{ctx.GetObjectFromHandle<Kernel::KTransferMemory>(transfer_memory_handle)};
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio,
|
||||||
|
"sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} "
|
||||||
|
"use_large_frame_size {}"
|
||||||
|
"transfer_memory_size 0x{:X}",
|
||||||
|
params.sample_rate, params.channel_count, params.total_stream_count,
|
||||||
|
params.stereo_stream_count, params.use_large_frame_size, transfer_memory_size);
|
||||||
|
|
||||||
|
auto decoder{std::make_shared<IHardwareOpusDecoder>(system, impl.GetHardwareOpus())};
|
||||||
|
|
||||||
|
auto result =
|
||||||
|
decoder->Initialize(params, transfer_memory.GetPointerUnsafe(), transfer_memory_size);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.PushIpcInterface(decoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamEx(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
auto input{ctx.ReadBuffer()};
|
||||||
|
OpusMultiStreamParametersEx params;
|
||||||
|
std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParametersEx));
|
||||||
|
|
||||||
|
u64 size{};
|
||||||
|
auto result = impl.GetWorkBufferSizeForMultiStreamEx(params, size);
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio,
|
||||||
|
"sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} "
|
||||||
|
"use_large_frame_size {} -- returned size 0x{:X}",
|
||||||
|
params.sample_rate, params.channel_count, params.total_stream_count,
|
||||||
|
params.stereo_stream_count, params.use_large_frame_size, size);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.Push(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoderManager::GetWorkBufferSizeExEx(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
auto params = rp.PopRaw<OpusParametersEx>();
|
||||||
|
|
||||||
|
u64 size{};
|
||||||
|
auto result = impl.GetWorkBufferSizeExEx(params, size);
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio, "size 0x{:X}", size);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.Push(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamExEx(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
auto input{ctx.ReadBuffer()};
|
||||||
|
OpusMultiStreamParametersEx params;
|
||||||
|
std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParametersEx));
|
||||||
|
|
||||||
|
u64 size{};
|
||||||
|
auto result = impl.GetWorkBufferSizeForMultiStreamExEx(params, size);
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_Audio, "size 0x{:X}", size);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
|
rb.Push(result);
|
||||||
|
rb.Push(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
IHardwareOpusDecoderManager::IHardwareOpusDecoderManager(Core::System& system_)
|
||||||
|
: ServiceFramework{system_, "hwopus"}, system{system_}, impl{system} {
|
||||||
|
static const FunctionInfo functions[] = {
|
||||||
|
{0, &IHardwareOpusDecoderManager::OpenHardwareOpusDecoder, "OpenHardwareOpusDecoder"},
|
||||||
|
{1, &IHardwareOpusDecoderManager::GetWorkBufferSize, "GetWorkBufferSize"},
|
||||||
|
{2, &IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStream,
|
||||||
|
"OpenOpusDecoderForMultiStream"},
|
||||||
|
{3, &IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStream,
|
||||||
|
"GetWorkBufferSizeForMultiStream"},
|
||||||
|
{4, &IHardwareOpusDecoderManager::OpenHardwareOpusDecoderEx, "OpenHardwareOpusDecoderEx"},
|
||||||
|
{5, &IHardwareOpusDecoderManager::GetWorkBufferSizeEx, "GetWorkBufferSizeEx"},
|
||||||
|
{6, &IHardwareOpusDecoderManager::OpenHardwareOpusDecoderForMultiStreamEx,
|
||||||
|
"OpenHardwareOpusDecoderForMultiStreamEx"},
|
||||||
|
{7, &IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamEx,
|
||||||
|
"GetWorkBufferSizeForMultiStreamEx"},
|
||||||
|
{8, &IHardwareOpusDecoderManager::GetWorkBufferSizeExEx, "GetWorkBufferSizeExEx"},
|
||||||
|
{9, &IHardwareOpusDecoderManager::GetWorkBufferSizeForMultiStreamExEx,
|
||||||
|
"GetWorkBufferSizeForMultiStreamExEx"},
|
||||||
|
};
|
||||||
|
RegisterHandlers(functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
IHardwareOpusDecoderManager::~IHardwareOpusDecoderManager() = default;
|
||||||
|
|
||||||
|
} // namespace Service::Audio
|
|
@ -12,10 +12,10 @@ class System;
|
||||||
|
|
||||||
namespace Service::Audio {
|
namespace Service::Audio {
|
||||||
|
|
||||||
class HwOpus final : public ServiceFramework<HwOpus> {
|
class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> {
|
||||||
public:
|
public:
|
||||||
explicit HwOpus(Core::System& system_);
|
explicit IHardwareOpusDecoderManager(Core::System& system_);
|
||||||
~HwOpus() override;
|
~IHardwareOpusDecoderManager() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OpenHardwareOpusDecoder(HLERequestContext& ctx);
|
void OpenHardwareOpusDecoder(HLERequestContext& ctx);
|
|
@ -1,502 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "audio_core/opus/decoder.h"
|
|
||||||
#include "audio_core/opus/parameters.h"
|
|
||||||
#include "common/assert.h"
|
|
||||||
#include "common/logging/log.h"
|
|
||||||
#include "common/scratch_buffer.h"
|
|
||||||
#include "core/core.h"
|
|
||||||
#include "core/hle/service/audio/hwopus.h"
|
|
||||||
#include "core/hle/service/ipc_helpers.h"
|
|
||||||
|
|
||||||
namespace Service::Audio {
|
|
||||||
using namespace AudioCore::OpusDecoder;
|
|
||||||
|
|
||||||
class IHardwareOpusDecoder final : public ServiceFramework<IHardwareOpusDecoder> {
|
|
||||||
public:
|
|
||||||
explicit IHardwareOpusDecoder(Core::System& system_, HardwareOpus& hardware_opus)
|
|
||||||
: ServiceFramework{system_, "IHardwareOpusDecoder"},
|
|
||||||
impl{std::make_unique<AudioCore::OpusDecoder::OpusDecoder>(system_, hardware_opus)} {
|
|
||||||
// clang-format off
|
|
||||||
static const FunctionInfo functions[] = {
|
|
||||||
{0, &IHardwareOpusDecoder::DecodeInterleavedOld, "DecodeInterleavedOld"},
|
|
||||||
{1, &IHardwareOpusDecoder::SetContext, "SetContext"},
|
|
||||||
{2, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamOld, "DecodeInterleavedForMultiStreamOld"},
|
|
||||||
{3, &IHardwareOpusDecoder::SetContextForMultiStream, "SetContextForMultiStream"},
|
|
||||||
{4, &IHardwareOpusDecoder::DecodeInterleavedWithPerfOld, "DecodeInterleavedWithPerfOld"},
|
|
||||||
{5, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfOld, "DecodeInterleavedForMultiStreamWithPerfOld"},
|
|
||||||
{6, &IHardwareOpusDecoder::DecodeInterleavedWithPerfAndResetOld, "DecodeInterleavedWithPerfAndResetOld"},
|
|
||||||
{7, &IHardwareOpusDecoder::DecodeInterleavedForMultiStreamWithPerfAndResetOld, "DecodeInterleavedForMultiStreamWithPerfAndResetOld"},
|
|
||||||
{8, &IHardwareOpusDecoder::DecodeInterleaved, "DecodeInterleaved"},
|
|
||||||
{9, &IHardwareOpusDecoder::DecodeInterleavedForMultiStream, "DecodeInterleavedForMultiStream"},
|
|
||||||
};
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result Initialize(OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory,
|
|
||||||
u64 transfer_memory_size) {
|
|
||||||
return impl->Initialize(params, transfer_memory, transfer_memory_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result Initialize(OpusMultiStreamParametersEx& params, Kernel::KTransferMemory* transfer_memory,
|
|
||||||
u64 transfer_memory_size) {
|
|
||||||
return impl->Initialize(params, transfer_memory, transfer_memory_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void DecodeInterleavedOld(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
auto input_data{ctx.ReadBuffer(0)};
|
|
||||||
output_data.resize_destructive(ctx.GetWriteBufferSize());
|
|
||||||
|
|
||||||
u32 size{};
|
|
||||||
u32 sample_count{};
|
|
||||||
auto result =
|
|
||||||
impl->DecodeInterleaved(&size, nullptr, &sample_count, input_data, output_data, false);
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {}", size, sample_count);
|
|
||||||
|
|
||||||
ctx.WriteBuffer(output_data);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.Push(size);
|
|
||||||
rb.Push(sample_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetContext(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "called");
|
|
||||||
|
|
||||||
auto input_data{ctx.ReadBuffer(0)};
|
|
||||||
auto result = impl->SetContext(input_data);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
|
||||||
rb.Push(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DecodeInterleavedForMultiStreamOld(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
auto input_data{ctx.ReadBuffer(0)};
|
|
||||||
output_data.resize_destructive(ctx.GetWriteBufferSize());
|
|
||||||
|
|
||||||
u32 size{};
|
|
||||||
u32 sample_count{};
|
|
||||||
auto result = impl->DecodeInterleavedForMultiStream(&size, nullptr, &sample_count,
|
|
||||||
input_data, output_data, false);
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {}", size, sample_count);
|
|
||||||
|
|
||||||
ctx.WriteBuffer(output_data);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.Push(size);
|
|
||||||
rb.Push(sample_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetContextForMultiStream(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "called");
|
|
||||||
|
|
||||||
auto input_data{ctx.ReadBuffer(0)};
|
|
||||||
auto result = impl->SetContext(input_data);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
|
||||||
rb.Push(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DecodeInterleavedWithPerfOld(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
auto input_data{ctx.ReadBuffer(0)};
|
|
||||||
output_data.resize_destructive(ctx.GetWriteBufferSize());
|
|
||||||
|
|
||||||
u32 size{};
|
|
||||||
u32 sample_count{};
|
|
||||||
u64 time_taken{};
|
|
||||||
auto result = impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data,
|
|
||||||
output_data, false);
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {} time taken {}", size,
|
|
||||||
sample_count, time_taken);
|
|
||||||
|
|
||||||
ctx.WriteBuffer(output_data);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 6};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.Push(size);
|
|
||||||
rb.Push(sample_count);
|
|
||||||
rb.Push(time_taken);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DecodeInterleavedForMultiStreamWithPerfOld(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
auto input_data{ctx.ReadBuffer(0)};
|
|
||||||
output_data.resize_destructive(ctx.GetWriteBufferSize());
|
|
||||||
|
|
||||||
u32 size{};
|
|
||||||
u32 sample_count{};
|
|
||||||
u64 time_taken{};
|
|
||||||
auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count,
|
|
||||||
input_data, output_data, false);
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "bytes read 0x{:X} samples generated {} time taken {}", size,
|
|
||||||
sample_count, time_taken);
|
|
||||||
|
|
||||||
ctx.WriteBuffer(output_data);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 6};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.Push(size);
|
|
||||||
rb.Push(sample_count);
|
|
||||||
rb.Push(time_taken);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DecodeInterleavedWithPerfAndResetOld(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
auto reset{rp.Pop<bool>()};
|
|
||||||
|
|
||||||
auto input_data{ctx.ReadBuffer(0)};
|
|
||||||
output_data.resize_destructive(ctx.GetWriteBufferSize());
|
|
||||||
|
|
||||||
u32 size{};
|
|
||||||
u32 sample_count{};
|
|
||||||
u64 time_taken{};
|
|
||||||
auto result = impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data,
|
|
||||||
output_data, reset);
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}",
|
|
||||||
reset, size, sample_count, time_taken);
|
|
||||||
|
|
||||||
ctx.WriteBuffer(output_data);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 6};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.Push(size);
|
|
||||||
rb.Push(sample_count);
|
|
||||||
rb.Push(time_taken);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DecodeInterleavedForMultiStreamWithPerfAndResetOld(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
auto reset{rp.Pop<bool>()};
|
|
||||||
|
|
||||||
auto input_data{ctx.ReadBuffer(0)};
|
|
||||||
output_data.resize_destructive(ctx.GetWriteBufferSize());
|
|
||||||
|
|
||||||
u32 size{};
|
|
||||||
u32 sample_count{};
|
|
||||||
u64 time_taken{};
|
|
||||||
auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count,
|
|
||||||
input_data, output_data, reset);
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}",
|
|
||||||
reset, size, sample_count, time_taken);
|
|
||||||
|
|
||||||
ctx.WriteBuffer(output_data);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 6};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.Push(size);
|
|
||||||
rb.Push(sample_count);
|
|
||||||
rb.Push(time_taken);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DecodeInterleaved(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
auto reset{rp.Pop<bool>()};
|
|
||||||
|
|
||||||
auto input_data{ctx.ReadBuffer(0)};
|
|
||||||
output_data.resize_destructive(ctx.GetWriteBufferSize());
|
|
||||||
|
|
||||||
u32 size{};
|
|
||||||
u32 sample_count{};
|
|
||||||
u64 time_taken{};
|
|
||||||
auto result = impl->DecodeInterleaved(&size, &time_taken, &sample_count, input_data,
|
|
||||||
output_data, reset);
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}",
|
|
||||||
reset, size, sample_count, time_taken);
|
|
||||||
|
|
||||||
ctx.WriteBuffer(output_data);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 6};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.Push(size);
|
|
||||||
rb.Push(sample_count);
|
|
||||||
rb.Push(time_taken);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DecodeInterleavedForMultiStream(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
auto reset{rp.Pop<bool>()};
|
|
||||||
|
|
||||||
auto input_data{ctx.ReadBuffer(0)};
|
|
||||||
output_data.resize_destructive(ctx.GetWriteBufferSize());
|
|
||||||
|
|
||||||
u32 size{};
|
|
||||||
u32 sample_count{};
|
|
||||||
u64 time_taken{};
|
|
||||||
auto result = impl->DecodeInterleavedForMultiStream(&size, &time_taken, &sample_count,
|
|
||||||
input_data, output_data, reset);
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "reset {} bytes read 0x{:X} samples generated {} time taken {}",
|
|
||||||
reset, size, sample_count, time_taken);
|
|
||||||
|
|
||||||
ctx.WriteBuffer(output_data);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 6};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.Push(size);
|
|
||||||
rb.Push(sample_count);
|
|
||||||
rb.Push(time_taken);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<AudioCore::OpusDecoder::OpusDecoder> impl;
|
|
||||||
Common::ScratchBuffer<u8> output_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
void HwOpus::OpenHardwareOpusDecoder(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
auto params = rp.PopRaw<OpusParameters>();
|
|
||||||
auto transfer_memory_size{rp.Pop<u32>()};
|
|
||||||
auto transfer_memory_handle{ctx.GetCopyHandle(0)};
|
|
||||||
auto transfer_memory{ctx.GetObjectFromHandle<Kernel::KTransferMemory>(transfer_memory_handle)};
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} transfer_memory_size 0x{:X}",
|
|
||||||
params.sample_rate, params.channel_count, transfer_memory_size);
|
|
||||||
|
|
||||||
auto decoder{std::make_shared<IHardwareOpusDecoder>(system, impl.GetHardwareOpus())};
|
|
||||||
|
|
||||||
OpusParametersEx ex{
|
|
||||||
.sample_rate = params.sample_rate,
|
|
||||||
.channel_count = params.channel_count,
|
|
||||||
.use_large_frame_size = false,
|
|
||||||
};
|
|
||||||
auto result = decoder->Initialize(ex, transfer_memory.GetPointerUnsafe(), transfer_memory_size);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.PushIpcInterface(decoder);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HwOpus::GetWorkBufferSize(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
auto params = rp.PopRaw<OpusParameters>();
|
|
||||||
|
|
||||||
u64 size{};
|
|
||||||
auto result = impl.GetWorkBufferSize(params, size);
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} -- returned size 0x{:X}",
|
|
||||||
params.sample_rate, params.channel_count, size);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.Push(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HwOpus::OpenHardwareOpusDecoderForMultiStream(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
auto input{ctx.ReadBuffer()};
|
|
||||||
OpusMultiStreamParameters params;
|
|
||||||
std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParameters));
|
|
||||||
|
|
||||||
auto transfer_memory_size{rp.Pop<u32>()};
|
|
||||||
auto transfer_memory_handle{ctx.GetCopyHandle(0)};
|
|
||||||
auto transfer_memory{ctx.GetObjectFromHandle<Kernel::KTransferMemory>(transfer_memory_handle)};
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio,
|
|
||||||
"sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} "
|
|
||||||
"transfer_memory_size 0x{:X}",
|
|
||||||
params.sample_rate, params.channel_count, params.total_stream_count,
|
|
||||||
params.stereo_stream_count, transfer_memory_size);
|
|
||||||
|
|
||||||
auto decoder{std::make_shared<IHardwareOpusDecoder>(system, impl.GetHardwareOpus())};
|
|
||||||
|
|
||||||
OpusMultiStreamParametersEx ex{
|
|
||||||
.sample_rate = params.sample_rate,
|
|
||||||
.channel_count = params.channel_count,
|
|
||||||
.total_stream_count = params.total_stream_count,
|
|
||||||
.stereo_stream_count = params.stereo_stream_count,
|
|
||||||
.use_large_frame_size = false,
|
|
||||||
.mappings{},
|
|
||||||
};
|
|
||||||
std::memcpy(ex.mappings.data(), params.mappings.data(), sizeof(params.mappings));
|
|
||||||
auto result = decoder->Initialize(ex, transfer_memory.GetPointerUnsafe(), transfer_memory_size);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.PushIpcInterface(decoder);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HwOpus::GetWorkBufferSizeForMultiStream(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
auto input{ctx.ReadBuffer()};
|
|
||||||
OpusMultiStreamParameters params;
|
|
||||||
std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParameters));
|
|
||||||
|
|
||||||
u64 size{};
|
|
||||||
auto result = impl.GetWorkBufferSizeForMultiStream(params, size);
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "size 0x{:X}", size);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.Push(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HwOpus::OpenHardwareOpusDecoderEx(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
auto params = rp.PopRaw<OpusParametersEx>();
|
|
||||||
auto transfer_memory_size{rp.Pop<u32>()};
|
|
||||||
auto transfer_memory_handle{ctx.GetCopyHandle(0)};
|
|
||||||
auto transfer_memory{ctx.GetObjectFromHandle<Kernel::KTransferMemory>(transfer_memory_handle)};
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "sample_rate {} channel_count {} transfer_memory_size 0x{:X}",
|
|
||||||
params.sample_rate, params.channel_count, transfer_memory_size);
|
|
||||||
|
|
||||||
auto decoder{std::make_shared<IHardwareOpusDecoder>(system, impl.GetHardwareOpus())};
|
|
||||||
|
|
||||||
auto result =
|
|
||||||
decoder->Initialize(params, transfer_memory.GetPointerUnsafe(), transfer_memory_size);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.PushIpcInterface(decoder);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HwOpus::GetWorkBufferSizeEx(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
auto params = rp.PopRaw<OpusParametersEx>();
|
|
||||||
|
|
||||||
u64 size{};
|
|
||||||
auto result = impl.GetWorkBufferSizeEx(params, size);
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "size 0x{:X}", size);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.Push(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HwOpus::OpenHardwareOpusDecoderForMultiStreamEx(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
auto input{ctx.ReadBuffer()};
|
|
||||||
OpusMultiStreamParametersEx params;
|
|
||||||
std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParametersEx));
|
|
||||||
|
|
||||||
auto transfer_memory_size{rp.Pop<u32>()};
|
|
||||||
auto transfer_memory_handle{ctx.GetCopyHandle(0)};
|
|
||||||
auto transfer_memory{ctx.GetObjectFromHandle<Kernel::KTransferMemory>(transfer_memory_handle)};
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio,
|
|
||||||
"sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} "
|
|
||||||
"use_large_frame_size {}"
|
|
||||||
"transfer_memory_size 0x{:X}",
|
|
||||||
params.sample_rate, params.channel_count, params.total_stream_count,
|
|
||||||
params.stereo_stream_count, params.use_large_frame_size, transfer_memory_size);
|
|
||||||
|
|
||||||
auto decoder{std::make_shared<IHardwareOpusDecoder>(system, impl.GetHardwareOpus())};
|
|
||||||
|
|
||||||
auto result =
|
|
||||||
decoder->Initialize(params, transfer_memory.GetPointerUnsafe(), transfer_memory_size);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.PushIpcInterface(decoder);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HwOpus::GetWorkBufferSizeForMultiStreamEx(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
auto input{ctx.ReadBuffer()};
|
|
||||||
OpusMultiStreamParametersEx params;
|
|
||||||
std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParametersEx));
|
|
||||||
|
|
||||||
u64 size{};
|
|
||||||
auto result = impl.GetWorkBufferSizeForMultiStreamEx(params, size);
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio,
|
|
||||||
"sample_rate {} channel_count {} total_stream_count {} stereo_stream_count {} "
|
|
||||||
"use_large_frame_size {} -- returned size 0x{:X}",
|
|
||||||
params.sample_rate, params.channel_count, params.total_stream_count,
|
|
||||||
params.stereo_stream_count, params.use_large_frame_size, size);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.Push(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HwOpus::GetWorkBufferSizeExEx(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
auto params = rp.PopRaw<OpusParametersEx>();
|
|
||||||
|
|
||||||
u64 size{};
|
|
||||||
auto result = impl.GetWorkBufferSizeExEx(params, size);
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "size 0x{:X}", size);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.Push(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HwOpus::GetWorkBufferSizeForMultiStreamExEx(HLERequestContext& ctx) {
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
auto input{ctx.ReadBuffer()};
|
|
||||||
OpusMultiStreamParametersEx params;
|
|
||||||
std::memcpy(¶ms, input.data(), sizeof(OpusMultiStreamParametersEx));
|
|
||||||
|
|
||||||
u64 size{};
|
|
||||||
auto result = impl.GetWorkBufferSizeForMultiStreamExEx(params, size);
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_Audio, "size 0x{:X}", size);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.Push(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
HwOpus::HwOpus(Core::System& system_)
|
|
||||||
: ServiceFramework{system_, "hwopus"}, system{system_}, impl{system} {
|
|
||||||
static const FunctionInfo functions[] = {
|
|
||||||
{0, &HwOpus::OpenHardwareOpusDecoder, "OpenHardwareOpusDecoder"},
|
|
||||||
{1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"},
|
|
||||||
{2, &HwOpus::OpenHardwareOpusDecoderForMultiStream, "OpenOpusDecoderForMultiStream"},
|
|
||||||
{3, &HwOpus::GetWorkBufferSizeForMultiStream, "GetWorkBufferSizeForMultiStream"},
|
|
||||||
{4, &HwOpus::OpenHardwareOpusDecoderEx, "OpenHardwareOpusDecoderEx"},
|
|
||||||
{5, &HwOpus::GetWorkBufferSizeEx, "GetWorkBufferSizeEx"},
|
|
||||||
{6, &HwOpus::OpenHardwareOpusDecoderForMultiStreamEx,
|
|
||||||
"OpenHardwareOpusDecoderForMultiStreamEx"},
|
|
||||||
{7, &HwOpus::GetWorkBufferSizeForMultiStreamEx, "GetWorkBufferSizeForMultiStreamEx"},
|
|
||||||
{8, &HwOpus::GetWorkBufferSizeExEx, "GetWorkBufferSizeExEx"},
|
|
||||||
{9, &HwOpus::GetWorkBufferSizeForMultiStreamExEx, "GetWorkBufferSizeForMultiStreamExEx"},
|
|
||||||
};
|
|
||||||
RegisterHandlers(functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
HwOpus::~HwOpus() = default;
|
|
||||||
|
|
||||||
} // namespace Service::Audio
|
|
Loading…
Reference in a new issue