From d34b399ba0b05768669b66540c30f088fd906786 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sat, 26 Dec 2020 23:20:13 +0100 Subject: [PATCH] Implement IUnitInfo::getProgramPitchName --- src/common/logging/vst3.cpp | 23 ++++++++++ src/common/logging/vst3.h | 3 ++ src/common/serialization/vst3.h | 3 +- .../serialization/vst3/plugin/unit-info.h | 42 ++++++++++++++++++- .../bridges/vst3-impls/plugin-proxy.cpp | 13 ++++-- src/wine-host/bridges/vst3.cpp | 12 ++++++ 6 files changed, 91 insertions(+), 5 deletions(-) diff --git a/src/common/logging/vst3.cpp b/src/common/logging/vst3.cpp index ffa03067..2fe0bb51 100644 --- a/src/common/logging/vst3.cpp +++ b/src/common/logging/vst3.cpp @@ -492,6 +492,17 @@ bool Vst3Logger::log_request(bool is_host_vst, }); } +bool Vst3Logger::log_request(bool is_host_vst, + const YaUnitInfo::GetProgramPitchName& request) { + return log_request_base(is_host_vst, [&](auto& message) { + message << request.instance_id + << ": IUnitInfo::getProgramPitchName(listId = " + << request.list_id + << ", programIndex = " << request.program_index + << ", midiPitch = " << request.midi_pitch << ", &name)"; + }); +} + bool Vst3Logger::log_request( bool is_host_vst, const YaAudioProcessor::SetBusArrangements& request) { @@ -938,6 +949,18 @@ void Vst3Logger::log_response( }); } +void Vst3Logger::log_response( + bool is_host_vst, + const YaUnitInfo::GetProgramPitchNameResponse& response) { + log_response_base(is_host_vst, [&](auto& message) { + message << response.result.string(); + if (response.result == Steinberg::kResultOk) { + message << ", \"" << VST3::StringConvert::convert(response.name) + << "\""; + } + }); +} + void Vst3Logger::log_response( bool is_host_vst, const YaAudioProcessor::GetBusArrangementResponse& response) { diff --git a/src/common/logging/vst3.h b/src/common/logging/vst3.h index ff0c9017..173b0b63 100644 --- a/src/common/logging/vst3.h +++ b/src/common/logging/vst3.h @@ -115,6 +115,7 @@ class Vst3Logger { bool log_request(bool is_host_vst, const YaUnitInfo::GetProgramName&); bool log_request(bool is_host_vst, const YaUnitInfo::GetProgramInfo&); bool log_request(bool is_host_vst, const YaUnitInfo::HasProgramPitchNames&); + bool log_request(bool is_host_vst, const YaUnitInfo::GetProgramPitchName&); bool log_request(bool is_host_vst, const YaAudioProcessor::SetBusArrangements&); @@ -175,6 +176,8 @@ class Vst3Logger { const YaUnitInfo::GetProgramNameResponse&); void log_response(bool is_host_vst, const YaUnitInfo::GetProgramInfoResponse&); + void log_response(bool is_host_vst, + const YaUnitInfo::GetProgramPitchNameResponse&); void log_response(bool is_host_vst, const YaAudioProcessor::GetBusArrangementResponse&); diff --git a/src/common/serialization/vst3.h b/src/common/serialization/vst3.h index aa2da1ad..d40757f3 100644 --- a/src/common/serialization/vst3.h +++ b/src/common/serialization/vst3.h @@ -106,7 +106,8 @@ using ControlRequest = std::variant; + YaUnitInfo::HasProgramPitchNames, + YaUnitInfo::GetProgramPitchName>; template void serialize(S& s, ControlRequest& payload) { diff --git a/src/common/serialization/vst3/plugin/unit-info.h b/src/common/serialization/vst3/plugin/unit-info.h index 9fb5dedb..48402fdd 100644 --- a/src/common/serialization/vst3/plugin/unit-info.h +++ b/src/common/serialization/vst3/plugin/unit-info.h @@ -212,7 +212,7 @@ class YaUnitInfo : public Steinberg::Vst::IUnitInfo { Steinberg::Vst::String128 name /*out*/) override = 0; /** - * The response code and returned name for a call to + * The response code and returned value for a call to * `IUnitInfo::getPrograminfo(list_id, program_index, attribute_name, * &attribute_value)`. */ @@ -279,6 +279,46 @@ class YaUnitInfo : public Steinberg::Vst::IUnitInfo { virtual tresult PLUGIN_API hasProgramPitchNames(Steinberg::Vst::ProgramListID listId, int32 programIndex) override = 0; + + /** + * The response code and returned name for a call to + * `IUnitInfo::getProgramPitchName(list_id, program_index, midi_pitch, + * &name)`. + */ + struct GetProgramPitchNameResponse { + UniversalTResult result; + std::u16string name; + + template + void serialize(S& s) { + s.object(result); + s.text2b(name, std::extent_v); + } + }; + + /** + * Message to pass through a call to + * `IUnitInfo::getProgramPitchName(list_id, program_index, midi_pitch, + * &name)` to the Wine plugin host. + */ + struct GetProgramPitchName { + using Response = GetProgramPitchNameResponse; + + native_size_t instance_id; + + Steinberg::Vst::ProgramListID list_id; + int32 program_index; + int16 midi_pitch; + + template + void serialize(S& s) { + s.value8b(instance_id); + s.value4b(list_id); + s.value4b(program_index); + s.value2b(midi_pitch); + } + }; + virtual tresult PLUGIN_API getProgramPitchName(Steinberg::Vst::ProgramListID listId, int32 programIndex, diff --git a/src/plugin/bridges/vst3-impls/plugin-proxy.cpp b/src/plugin/bridges/vst3-impls/plugin-proxy.cpp index 32d05195..db48af26 100644 --- a/src/plugin/bridges/vst3-impls/plugin-proxy.cpp +++ b/src/plugin/bridges/vst3-impls/plugin-proxy.cpp @@ -523,9 +523,16 @@ tresult PLUGIN_API Vst3PluginProxyImpl::getProgramPitchName( int32 programIndex, int16 midiPitch, Steinberg::Vst::String128 name /*out*/) { - // TODO: Implement - bridge.logger.log("TODO: IUnitInfo::getProgramPitchName()"); - return Steinberg::kNotImplemented; + const GetProgramPitchNameResponse response = bridge.send_message( + YaUnitInfo::GetProgramPitchName{.instance_id = instance_id(), + .list_id = listId, + .program_index = programIndex, + .midi_pitch = midiPitch}); + + std::copy(response.name.begin(), response.name.end(), name); + name[response.name.size()] = 0; + + return response.result; } Steinberg::Vst::UnitID PLUGIN_API Vst3PluginProxyImpl::getSelectedUnit() { diff --git a/src/wine-host/bridges/vst3.cpp b/src/wine-host/bridges/vst3.cpp index 86026b2e..bfd15565 100644 --- a/src/wine-host/bridges/vst3.cpp +++ b/src/wine-host/bridges/vst3.cpp @@ -627,6 +627,18 @@ void Vst3Bridge::run() { .unit_info->hasProgramPitchNames(request.list_id, request.program_index); }, + [&](const YaUnitInfo::GetProgramPitchName& request) + -> YaUnitInfo::GetProgramPitchName::Response { + Steinberg::Vst::String128 name{0}; + const tresult result = + object_instances[request.instance_id] + .unit_info->getProgramPitchName( + request.list_id, request.program_index, + request.midi_pitch, name); + + return YaUnitInfo::GetProgramPitchNameResponse{ + .result = result, .name = tchar_pointer_to_u16string(name)}; + }, }); }