diff --git a/meson.build b/meson.build index d8c0fbb8..7e514e0b 100644 --- a/meson.build +++ b/meson.build @@ -79,6 +79,7 @@ vst3_plugin_sources = [ 'src/common/logging/vst3.cpp', 'src/common/serialization/vst3/base.cpp', 'src/common/serialization/vst3/component.cpp', + 'src/common/serialization/vst3/event-list.cpp', 'src/common/serialization/vst3/host-application.cpp', 'src/common/serialization/vst3/param-value-queue.cpp', 'src/common/serialization/vst3/parameter-changes.cpp', @@ -116,6 +117,7 @@ if with_vst3 'src/common/logging/vst3.cpp', 'src/common/serialization/vst3/base.cpp', 'src/common/serialization/vst3/component.cpp', + 'src/common/serialization/vst3/event-list.cpp', 'src/common/serialization/vst3/host-application.cpp', 'src/common/serialization/vst3/param-value-queue.cpp', 'src/common/serialization/vst3/parameter-changes.cpp', diff --git a/src/common/serialization/vst3/base.cpp b/src/common/serialization/vst3/base.cpp index 31b00998..d8f21041 100644 --- a/src/common/serialization/vst3/base.cpp +++ b/src/common/serialization/vst3/base.cpp @@ -19,7 +19,7 @@ #include "base.h" -std::u16string tchar_string_to_u16string(const Steinberg::Vst::TChar* string) { +std::u16string tchar_pointer_to_u16string(const Steinberg::Vst::TChar* string) { #ifdef __WINE__ // This is great, thanks Steinberg static_assert(sizeof(Steinberg::Vst::TChar) == sizeof(char16_t)); @@ -29,6 +29,26 @@ std::u16string tchar_string_to_u16string(const Steinberg::Vst::TChar* string) { #endif } +std::u16string tchar_pointer_to_u16string(const Steinberg::Vst::TChar* string, + uint32 length) { +#ifdef __WINE__ + static_assert(sizeof(Steinberg::Vst::TChar) == sizeof(char16_t)); + return std::u16string(reinterpret_cast(string), length); +#else + return std::u16string(static_cast(string), length); +#endif +} + +const Steinberg::Vst::TChar* u16string_to_tchar_pointer( + const std::u16string& string) { +#ifdef __WINE__ + static_assert(sizeof(Steinberg::Vst::TChar) == sizeof(char16_t)); + return reinterpret_cast(string.c_str()); +#else + return static_cast(string.c_str()); +#endif +} + UniversalTResult::UniversalTResult() : universal_result(Value::kResultFalse) {} UniversalTResult::UniversalTResult(tresult native_result) diff --git a/src/common/serialization/vst3/base.h b/src/common/serialization/vst3/base.h index 5a1b12d0..97504639 100644 --- a/src/common/serialization/vst3/base.h +++ b/src/common/serialization/vst3/base.h @@ -29,8 +29,8 @@ // we'll need for all of our interfaces using Steinberg::TBool, Steinberg::int8, Steinberg::int16, Steinberg::int32, - Steinberg::int64, Steinberg::uint8, Steinberg::uint32, Steinberg::uint64, - Steinberg::tresult; + Steinberg::int64, Steinberg::uint8, Steinberg::uint16, Steinberg::uint32, + Steinberg::uint64, Steinberg::tresult; /** * Both `TUID` (`int8_t[16]`) and `FIDString` (`char*`) are hard to work with @@ -57,7 +57,21 @@ constexpr size_t max_vector_stream_size = 50 << 20; * Convert a UTF-16 C-style string to an `std::u16string`. Who event invented * UTF-16? */ -std::u16string tchar_string_to_u16string(const Steinberg::Vst::TChar* string); +std::u16string tchar_pointer_to_u16string(const Steinberg::Vst::TChar* string); + +/** + * Same as the above, but with a fixed string length. + * + * @overload + */ +std::u16string tchar_pointer_to_u16string(const Steinberg::Vst::TChar* string, + uint32 length); + +/** + * Convert an `std::u16string` back to a null terminated `TChar*` string. + */ +const Steinberg::Vst::TChar* u16string_to_tchar_pointer( + const std::u16string& string); /** * Empty struct for when we have send a response to some operation without any diff --git a/src/common/serialization/vst3/event-list.cpp b/src/common/serialization/vst3/event-list.cpp new file mode 100644 index 00000000..58359588 --- /dev/null +++ b/src/common/serialization/vst3/event-list.cpp @@ -0,0 +1,72 @@ +// yabridge: a Wine VST bridge +// Copyright (C) 2020 Robbert van der Helm +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "event-list.h" + +YaDataEvent::YaDataEvent() {} + +YaDataEvent::YaDataEvent(const Steinberg::Vst::DataEvent& event) + : type(event.type), buffer(event.bytes, event.bytes + event.size) {} + +Steinberg::Vst::DataEvent YaDataEvent::get() const { + return Steinberg::Vst::DataEvent{.size = static_cast(buffer.size()), + .type = type, + .bytes = buffer.data()}; +} + +YaNoteExpressionTextEvent::YaNoteExpressionTextEvent() {} + +YaNoteExpressionTextEvent::YaNoteExpressionTextEvent( + const Steinberg::Vst::NoteExpressionTextEvent& event) + : type_id(event.typeId), + note_id(event.noteId), + text(tchar_pointer_to_u16string(event.text, event.textLen)) {} + +Steinberg::Vst::NoteExpressionTextEvent YaNoteExpressionTextEvent::get() const { + return Steinberg::Vst::NoteExpressionTextEvent{ + .typeId = type_id, + .noteId = note_id, + .textLen = static_cast(text.size()), + .text = u16string_to_tchar_pointer(text)}; +} + +YaChordEvent::YaChordEvent() {} + +YaChordEvent::YaChordEvent(const Steinberg::Vst::ChordEvent& event) + : root(event.root), + bass_note(event.bassNote), + text(tchar_pointer_to_u16string(event.text, event.textLen)) {} + +Steinberg::Vst::ChordEvent YaChordEvent::get() const { + return Steinberg::Vst::ChordEvent{ + .root = root, + .bassNote = bass_note, + .textLen = static_cast(text.size()), + .text = u16string_to_tchar_pointer(text)}; +} + +YaScaleEvent::YaScaleEvent() {} + +YaScaleEvent::YaScaleEvent(const Steinberg::Vst::ScaleEvent& event) + : root(event.root), + text(tchar_pointer_to_u16string(event.text, event.textLen)) {} + +Steinberg::Vst::ScaleEvent YaScaleEvent::get() const { + return Steinberg::Vst::ScaleEvent{ + .root = root, + .textLen = static_cast(text.size()), + .text = u16string_to_tchar_pointer(text)}; +} diff --git a/src/common/serialization/vst3/event-list.h b/src/common/serialization/vst3/event-list.h index ac3e93d7..21bba146 100644 --- a/src/common/serialization/vst3/event-list.h +++ b/src/common/serialization/vst3/event-list.h @@ -45,12 +45,12 @@ struct YaDataEvent { Steinberg::Vst::DataEvent get() const; uint32 type; - std::vector data; + std::vector buffer; template void serialize(S& s) { s.value4b(type); - s.container1b(data, 1 << 16); + s.container1b(buffer, 1 << 16); } }; diff --git a/src/common/serialization/vst3/host-application.cpp b/src/common/serialization/vst3/host-application.cpp index 00c2e637..044f4d7a 100644 --- a/src/common/serialization/vst3/host-application.cpp +++ b/src/common/serialization/vst3/host-application.cpp @@ -24,7 +24,7 @@ YaHostApplication::ConstructArgs::ConstructArgs( : component_instance_id(component_instance_id) { Steinberg::Vst::String128 name_array; if (context->getName(name_array) == Steinberg::kResultOk) { - name = tchar_string_to_u16string(name_array); + name = tchar_pointer_to_u16string(name_array); } }