diff --git a/src/libs/ngs2.cpp b/src/libs/ngs2.cpp index 30f2651b6..a9e6c0884 100644 --- a/src/libs/ngs2.cpp +++ b/src/libs/ngs2.cpp @@ -2339,6 +2339,17 @@ int KYTY_SYSV_ABI Ngs2RackGetVoiceHandle(uintptr_t rack_handle, uint32_t voice_i return OK; } +// A patch to a rack handle connects to voice #0 of that rack. +static Ngs2VoiceInternal* Ngs2FindPatchDestination(uintptr_t handle) { + Common::LockGuard racks_lock(g_racks_mutex); + for (auto* rack = g_racks_list; rack != nullptr; rack = rack->next) { + if (reinterpret_cast(rack) == handle) { + return reinterpret_cast(rack + 1); + } + } + return reinterpret_cast(handle); +} + // NOLINTNEXTLINE(readability-function-cognitive-complexity) int KYTY_SYSV_ABI Ngs2VoiceControl(uintptr_t voice_handle, const Ngs2VoiceParamHeader* param_list) { PRINT_NAME(); @@ -2408,7 +2419,7 @@ int KYTY_SYSV_ABI Ngs2VoiceControl(uintptr_t voice_handle, const Ngs2VoiceParamH const auto* patch = reinterpret_cast(param); EXIT_NOT_IMPLEMENTED(patch->port >= voice->ports.size()); voice->ports[patch->port].dest = - reinterpret_cast(patch->dest_handle); + Ngs2FindPatchDestination(patch->dest_handle); voice->ports[patch->port].input = patch->dest_input_id; LOGF("\t connect->port = %u\n" "\t connect->dest_input_id = %u\n" diff --git a/tests/Ngs2SamplerTests.cpp b/tests/Ngs2SamplerTests.cpp index 85b4e22f0..e3cf79ad2 100644 --- a/tests/Ngs2SamplerTests.cpp +++ b/tests/Ngs2SamplerTests.cpp @@ -807,6 +807,21 @@ void TestPcm16RenderOutput() { "PCM16 output retained samples from the previous render"); } +void TestPatchToRackHandle() { + Ngs2Internal system; + Ngs2RackOptionUnion sampler_option {}, mastering_option {}; + Ngs2FillDefaultRackOption(0x1000, &sampler_option); + Ngs2FillDefaultRackOption(0x3000, &mastering_option); + sampler_option.common.max_voices = 1; + RenderRack sampler(system, 0x1000, sampler_option.common); + RenderRack master(system, 0x3000, mastering_option.common); + auto& source = sampler.Voice(); + Ngs2VoicePatchParam patch {{24, 0, 5}, 0, 0, master.handle}; + Check(Ngs2VoiceControl(reinterpret_cast(&source), &patch.header) == OK && + source.ports[0].dest == &master.Voice(), + "patch to a rack handle did not connect to its voice #0"); +} + void TestCustomMasteringChannelMixer() { Ngs2Internal system; system.option = Ngs2DefaultSystemOption(); @@ -1803,6 +1818,7 @@ int main() { TestAtrac9Vibration(); TestAtrac9Discrete(); TestPcm16RenderOutput(); + TestPatchToRackHandle(); TestCustomMasteringChannelMixer(); TestCustomVoiceStateCapacity(); TestSubmixerSetupAndRouting();