From e548e594fa6f35320955777b7b50b9fc0fa40bc2 Mon Sep 17 00:00:00 2001 From: Aryan Sharma Date: Fri, 9 Oct 2026 11:22:04 +0530 Subject: [PATCH] test(audioout): check pad ports in the main mix without a pad device With SDL's disk driver no pad audio device is open, so AudioOut2MixPorts runs with no pad output. A vibration port and a mono pad speaker port are pushed together: only the speaker's data reaches the main mix, and a vibration port alone leaves it silent. --- .../tests/AudioOut2PortLayouts.cpp | 48 +++++++++++++++---- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/core/libs/prx/libSceAudioOut/tests/AudioOut2PortLayouts.cpp b/core/libs/prx/libSceAudioOut/tests/AudioOut2PortLayouts.cpp index 56648e1b0..bf6c33e17 100644 --- a/core/libs/prx/libSceAudioOut/tests/AudioOut2PortLayouts.cpp +++ b/core/libs/prx/libSceAudioOut/tests/AudioOut2PortLayouts.cpp @@ -37,6 +37,8 @@ namespace { constexpr std::uint32_t grain = 256; constexpr std::uint32_t frequency = 48000; constexpr std::uint16_t portTypeMain = 0; +constexpr std::uint16_t portTypePadSpeaker = 0x3; +constexpr std::uint16_t portTypePadVibration = 0x6; constexpr std::uint32_t attributeData = 0; constexpr std::uint32_t attributeVolume = 1; constexpr std::uint32_t formatFloat = 0; @@ -73,9 +75,9 @@ AudioOut2ContextHandle CreateContext() { return context; } -int CreatePort(AudioOut2ContextHandle context, std::uint32_t format, AudioOut2PortHandle* port) { +int CreatePort(AudioOut2ContextHandle context, std::uint32_t format, AudioOut2PortHandle* port, std::uint16_t type = portTypeMain) { AudioOut2PortParam params{}; - params.port_type = portTypeMain; + params.port_type = type; params.data_format = format; params.sampling_freq = frequency; return sceAudioOut2PortCreate(context, ¶ms, port); @@ -91,20 +93,31 @@ void SetVolume(AudioOut2PortHandle port, const std::vector& volume) { Require(sceAudioOut2PortSetAttributes(port, &attribute, 1) == 0); } -std::vector Play(std::uint32_t format, const void* data, const std::vector& volume) { +struct PortData { + std::uint16_t type; + std::uint32_t format; + const void* data; + std::vector volume; +}; + +std::vector Play(const std::vector& inputs) { const auto path = std::filesystem::temp_directory_path() / ("anyps5_audio_out2_port_layouts-" + std::to_string(std::random_device{}()) + ".raw"); std::filesystem::remove(path); SetEnvironment("SDL_DISKAUDIOFILE", path.string()); const auto context = CreateContext(); - AudioOut2PortHandle port = 0; - Require(CreatePort(context, format, &port) == 0); - SetVolume(port, volume); - SetData(port, data); + std::vector ports; + for (const auto& input : inputs) { + AudioOut2PortHandle port = 0; + Require(CreatePort(context, input.format, &port, input.type) == 0); + SetVolume(port, input.volume); + SetData(port, input.data); + ports.push_back(port); + } Require(sceAudioOut2ContextPush(context, 1) == 0); - SetData(port, nullptr); + for (const auto port : ports) SetData(port, nullptr); for (std::uint32_t push = 0; push < silentGrains; push++) Require(sceAudioOut2ContextPush(context, 1) == 0); - Require(sceAudioOut2PortDestroy(port) == 0); + for (const auto port : ports) Require(sceAudioOut2PortDestroy(port) == 0); Require(sceAudioOut2ContextDestroy(context) == 0); std::ifstream file(path, std::ios::binary); @@ -121,6 +134,10 @@ std::vector Play(std::uint32_t format, const void* data, const std::vecto return {samples + first, samples + last}; } +std::vector Play(std::uint32_t format, const void* data, const std::vector& volume) { + return Play({{portTypeMain, format, data, volume}}); +} + float Sample(std::uint32_t channel, std::uint32_t frame) { const float sign = frame % 2 == 0 ? 1.0f : -1.0f; return sign * 0.01f * static_cast(channel + 1) * static_cast(1 + frame % 5); @@ -204,6 +221,18 @@ void TestDroppedLfe() { RequireFold(Play(Format(surround714.channels, formatFloat), data.data(), volume), surround714, expected, volume, 1.0f); } +void TestPadPortsWithoutPadDevice() { + const auto speaker = FloatGrain(mono.channels); + std::vector vibration(static_cast(grain) * stereo.channels, 0.75f); + const std::vector unity{1.0f, 1.0f}; + const auto played = Play({ + {portTypePadVibration, Format(stereo.channels, formatFloat), vibration.data(), unity}, + {portTypePadSpeaker, Format(mono.channels, formatFloat), speaker.data(), {1.0f}}, + }); + RequireFold(played, mono, speaker, {1.0f}, 1.0f); + Require(Play({{portTypePadVibration, Format(stereo.channels, formatFloat), vibration.data(), unity}}).empty()); +} + void TestMeasuredMainPortFormats() { struct Case { std::uint32_t format; @@ -270,6 +299,7 @@ int main() { } TestHeightChannels(); TestDroppedLfe(); + TestPadPortsWithoutPadDevice(); TestMeasuredMainPortFormats(); return 0; }