mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	audio: split IHardwarweOpusDecoder, move IHardwareOpusDecoderManager
This commit is contained in:
		@@ -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.cpp
 | 
			
		||||
    hle/service/audio/final_output_recorder_manager.h
 | 
			
		||||
    hle/service/audio/hwopus.cpp
 | 
			
		||||
    hle/service/audio/hwopus.h
 | 
			
		||||
    hle/service/audio/hardware_opus_decoder_manager.cpp
 | 
			
		||||
    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.h
 | 
			
		||||
    hle/service/bcat/bcat.cpp
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
#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_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/service.h"
 | 
			
		||||
 | 
			
		||||
@@ -27,7 +27,8 @@ void LoopProcess(Core::System& system) {
 | 
			
		||||
                                         std::make_shared<IFinalOutputRecorderManager>(system));
 | 
			
		||||
    server_manager->RegisterNamedService("audren:u",
 | 
			
		||||
                                         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));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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 {
 | 
			
		||||
 | 
			
		||||
class HwOpus final : public ServiceFramework<HwOpus> {
 | 
			
		||||
class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> {
 | 
			
		||||
public:
 | 
			
		||||
    explicit HwOpus(Core::System& system_);
 | 
			
		||||
    ~HwOpus() override;
 | 
			
		||||
    explicit IHardwareOpusDecoderManager(Core::System& system_);
 | 
			
		||||
    ~IHardwareOpusDecoderManager() override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    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
 | 
			
		||||
		Reference in New Issue
	
	Block a user