7 changed files with 556 additions and 509 deletions
-
6src/core/CMakeLists.txt
-
5src/core/hle/service/audio/audio.cpp
-
265src/core/hle/service/audio/hardware_opus_decoder.cpp
-
38src/core/hle/service/audio/hardware_opus_decoder.h
-
243src/core/hle/service/audio/hardware_opus_decoder_manager.cpp
-
6src/core/hle/service/audio/hardware_opus_decoder_manager.h
-
502src/core/hle/service/audio/hwopus.cpp
@ -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
|
||||
@ -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 |
||||
@ -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
|
||||
@ -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
|
|
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue