diff options
Diffstat (limited to 'src/core/hle/service/audio')
-rw-r--r-- | src/core/hle/service/audio/audin_u.cpp | 4 | ||||
-rw-r--r-- | src/core/hle/service/audio/audout_u.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/service/audio/audren_u.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/service/audio/audren_u.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/audio/hwopus.cpp | 55 | ||||
-rw-r--r-- | src/core/hle/service/audio/hwopus.h | 6 |
6 files changed, 62 insertions, 9 deletions
diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp index 526a39130..56fee4591 100644 --- a/src/core/hle/service/audio/audin_u.cpp +++ b/src/core/hle/service/audio/audin_u.cpp @@ -220,7 +220,7 @@ AudInU::AudInU(Core::System& system_) AudInU::~AudInU() = default; void AudInU::ListAudioIns(HLERequestContext& ctx) { - using namespace AudioCore::AudioRenderer; + using namespace AudioCore::Renderer; LOG_DEBUG(Service_Audio, "called"); @@ -240,7 +240,7 @@ void AudInU::ListAudioIns(HLERequestContext& ctx) { } void AudInU::ListAudioInsAutoFiltered(HLERequestContext& ctx) { - using namespace AudioCore::AudioRenderer; + using namespace AudioCore::Renderer; LOG_DEBUG(Service_Audio, "called"); diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 23f84a29f..ca683d72c 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -228,7 +228,7 @@ AudOutU::AudOutU(Core::System& system_) AudOutU::~AudOutU() = default; void AudOutU::ListAudioOuts(HLERequestContext& ctx) { - using namespace AudioCore::AudioRenderer; + using namespace AudioCore::Renderer; std::scoped_lock l{impl->mutex}; diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index b723b65c8..2f09cade5 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -26,7 +26,7 @@ #include "core/hle/service/ipc_helpers.h" #include "core/memory.h" -using namespace AudioCore::AudioRenderer; +using namespace AudioCore::Renderer; namespace Service::Audio { diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h index d8e9c8719..3d7993a16 100644 --- a/src/core/hle/service/audio/audren_u.h +++ b/src/core/hle/service/audio/audren_u.h @@ -28,7 +28,7 @@ private: void GetAudioDeviceServiceWithRevisionInfo(HLERequestContext& ctx); KernelHelpers::ServiceContext service_context; - std::unique_ptr<AudioCore::AudioRenderer::Manager> impl; + std::unique_ptr<AudioCore::Renderer::Manager> impl; u32 num_audio_devices{0}; }; diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp index fa77007f3..1557e6088 100644 --- a/src/core/hle/service/audio/hwopus.cpp +++ b/src/core/hle/service/audio/hwopus.cpp @@ -174,7 +174,7 @@ public: {6, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleavedWithPerfAndResetOld"}, {7, nullptr, "DecodeInterleavedForMultiStreamWithPerfAndResetOld"}, {8, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleaved"}, - {9, nullptr, "DecodeInterleavedForMultiStream"}, + {9, &IHardwareOpusDecoderManager::DecodeInterleavedForMultiStream, "DecodeInterleavedForMultiStream"}, }; // clang-format on @@ -206,6 +206,16 @@ private: decoder_state.DecodeInterleaved(ctx, OpusDecoderState::PerfTime::Enabled, extra_behavior); } + void DecodeInterleavedForMultiStream(HLERequestContext& ctx) { + LOG_DEBUG(Audio, "called"); + + IPC::RequestParser rp{ctx}; + const auto extra_behavior = rp.Pop<bool>() ? OpusDecoderState::ExtraBehavior::ResetContext + : OpusDecoderState::ExtraBehavior::None; + + decoder_state.DecodeInterleaved(ctx, OpusDecoderState::PerfTime::Enabled, extra_behavior); + } + OpusDecoderState decoder_state; }; @@ -257,6 +267,10 @@ void HwOpus::GetWorkBufferSizeEx(HLERequestContext& ctx) { GetWorkBufferSize(ctx); } +void HwOpus::GetWorkBufferSizeExEx(HLERequestContext& ctx) { + GetWorkBufferSizeEx(ctx); +} + void HwOpus::GetWorkBufferSizeForMultiStreamEx(HLERequestContext& ctx) { OpusMultiStreamParametersEx param; std::memcpy(¶m, ctx.ReadBuffer().data(), ctx.GetReadBufferSize()); @@ -354,6 +368,40 @@ void HwOpus::OpenHardwareOpusDecoderEx(HLERequestContext& ctx) { system, OpusDecoderState{std::move(decoder), sample_rate, channel_count}); } +void HwOpus::OpenHardwareOpusDecoderForMultiStreamEx(HLERequestContext& ctx) { + OpusMultiStreamParametersEx params; + std::memcpy(¶ms, ctx.ReadBuffer().data(), ctx.GetReadBufferSize()); + + const auto& sample_rate = params.sample_rate; + const auto& channel_count = params.channel_count; + + LOG_INFO( + Audio, + "called with sample_rate={}, channel_count={}, number_streams={}, number_stereo_streams={}", + sample_rate, channel_count, params.number_streams, params.number_stereo_streams); + + ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 || + sample_rate == 12000 || sample_rate == 8000, + "Invalid sample rate"); + + int error = 0; + OpusDecoderPtr decoder{opus_multistream_decoder_create( + sample_rate, static_cast<int>(channel_count), params.number_streams, + params.number_stereo_streams, params.channel_mappings.data(), &error)}; + if (error != OPUS_OK || decoder == nullptr) { + LOG_ERROR(Audio, "Failed to create Opus decoder (error={}).", error); + IPC::ResponseBuilder rb{ctx, 2}; + // TODO(ogniK): Use correct error code + rb.Push(ResultUnknown); + return; + } + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface<IHardwareOpusDecoderManager>( + system, OpusDecoderState{std::move(decoder), sample_rate, channel_count}); +} + HwOpus::HwOpus(Core::System& system_) : ServiceFramework{system_, "hwopus"} { static const FunctionInfo functions[] = { {0, &HwOpus::OpenHardwareOpusDecoder, "OpenHardwareOpusDecoder"}, @@ -362,9 +410,10 @@ HwOpus::HwOpus(Core::System& system_) : ServiceFramework{system_, "hwopus"} { {3, nullptr, "GetWorkBufferSizeForMultiStream"}, {4, &HwOpus::OpenHardwareOpusDecoderEx, "OpenHardwareOpusDecoderEx"}, {5, &HwOpus::GetWorkBufferSizeEx, "GetWorkBufferSizeEx"}, - {6, nullptr, "OpenHardwareOpusDecoderForMultiStreamEx"}, + {6, &HwOpus::OpenHardwareOpusDecoderForMultiStreamEx, + "OpenHardwareOpusDecoderForMultiStreamEx"}, {7, &HwOpus::GetWorkBufferSizeForMultiStreamEx, "GetWorkBufferSizeForMultiStreamEx"}, - {8, nullptr, "GetWorkBufferSizeExEx"}, + {8, &HwOpus::GetWorkBufferSizeExEx, "GetWorkBufferSizeExEx"}, {9, nullptr, "GetWorkBufferSizeForMultiStreamExEx"}, }; RegisterHandlers(functions); diff --git a/src/core/hle/service/audio/hwopus.h b/src/core/hle/service/audio/hwopus.h index ece65c02c..90867bf74 100644 --- a/src/core/hle/service/audio/hwopus.h +++ b/src/core/hle/service/audio/hwopus.h @@ -18,8 +18,10 @@ struct OpusMultiStreamParametersEx { u32 number_stereo_streams; u32 use_large_frame_size; u32 padding; - std::array<u32, 64> channel_mappings; + std::array<u8, 0x100> channel_mappings; }; +static_assert(sizeof(OpusMultiStreamParametersEx) == 0x118, + "OpusMultiStreamParametersEx has incorrect size"); class HwOpus final : public ServiceFramework<HwOpus> { public: @@ -29,8 +31,10 @@ public: private: void OpenHardwareOpusDecoder(HLERequestContext& ctx); void OpenHardwareOpusDecoderEx(HLERequestContext& ctx); + void OpenHardwareOpusDecoderForMultiStreamEx(HLERequestContext& ctx); void GetWorkBufferSize(HLERequestContext& ctx); void GetWorkBufferSizeEx(HLERequestContext& ctx); + void GetWorkBufferSizeExEx(HLERequestContext& ctx); void GetWorkBufferSizeForMultiStreamEx(HLERequestContext& ctx); }; |