├── .clang-format ├── .clang-tidy ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ ├── feature_request.yml │ └── setup_help.yml └── workflows │ └── build.yml ├── .gitignore ├── CHANGELOG.md ├── COPYING ├── README.md ├── ROADMAP.md ├── cross-wine.conf ├── docs └── architecture.md ├── meson.build ├── meson_options.txt ├── screenshot.png ├── src ├── chainloader │ ├── clap-chainloader.cpp │ ├── meson.build │ ├── utils.cpp │ ├── utils.h │ ├── vst2-chainloader.cpp │ └── vst3-chainloader.cpp ├── common │ ├── audio-shm.cpp │ ├── audio-shm.h │ ├── bitsery │ │ ├── ext │ │ │ ├── ghc-path.h │ │ │ ├── in-place-optional.h │ │ │ ├── in-place-variant.h │ │ │ ├── message-reference.h │ │ │ └── native-pointer.h │ │ └── traits │ │ │ └── small-vector.h │ ├── communication │ │ ├── clap.h │ │ ├── common.cpp │ │ ├── common.h │ │ ├── vst2.cpp │ │ ├── vst2.h │ │ └── vst3.h │ ├── config │ │ ├── config.h.in │ │ ├── meson.build │ │ └── version.h.in │ ├── configuration.cpp │ ├── configuration.h │ ├── linking.cpp │ ├── linking.h │ ├── logging │ │ ├── clap.cpp │ │ ├── clap.h │ │ ├── common.cpp │ │ ├── common.h │ │ ├── vst2.cpp │ │ ├── vst2.h │ │ ├── vst3.cpp │ │ └── vst3.h │ ├── mutual-recursion.h │ ├── notifications.cpp │ ├── notifications.h │ ├── plugins.cpp │ ├── plugins.h │ ├── process.cpp │ ├── process.h │ ├── serialization │ │ ├── clap.h │ │ ├── clap │ │ │ ├── README.md │ │ │ ├── audio-buffer.h │ │ │ ├── events.cpp │ │ │ ├── events.h │ │ │ ├── ext │ │ │ │ ├── audio-ports-config.cpp │ │ │ │ ├── audio-ports-config.h │ │ │ │ ├── audio-ports.cpp │ │ │ │ ├── audio-ports.h │ │ │ │ ├── gui.h │ │ │ │ ├── latency.h │ │ │ │ ├── log.h │ │ │ │ ├── note-name.cpp │ │ │ │ ├── note-name.h │ │ │ │ ├── note-ports.cpp │ │ │ │ ├── note-ports.h │ │ │ │ ├── params.cpp │ │ │ │ ├── params.h │ │ │ │ ├── render.h │ │ │ │ ├── state.h │ │ │ │ ├── tail.h │ │ │ │ └── voice-info.h │ │ │ ├── factory │ │ │ │ └── plugin-factory.h │ │ │ ├── host.cpp │ │ │ ├── host.h │ │ │ ├── plugin.cpp │ │ │ ├── plugin.h │ │ │ ├── process.cpp │ │ │ ├── process.h │ │ │ ├── stream.cpp │ │ │ ├── stream.h │ │ │ └── version.h │ │ ├── common.h │ │ ├── vst2.cpp │ │ ├── vst2.h │ │ ├── vst3-impls │ │ │ └── context-menu-target.h │ │ ├── vst3.h │ │ └── vst3 │ │ │ ├── README.md │ │ │ ├── attribute-list.cpp │ │ │ ├── attribute-list.h │ │ │ ├── base.cpp │ │ │ ├── base.h │ │ │ ├── bstream.cpp │ │ │ ├── bstream.h │ │ │ ├── component-handler-proxy.cpp │ │ │ ├── component-handler-proxy.h │ │ │ ├── component-handler │ │ │ ├── component-handler-2.cpp │ │ │ ├── component-handler-2.h │ │ │ ├── component-handler-3.cpp │ │ │ ├── component-handler-3.h │ │ │ ├── component-handler-bus-activation.cpp │ │ │ ├── component-handler-bus-activation.h │ │ │ ├── component-handler.cpp │ │ │ ├── component-handler.h │ │ │ ├── progress.cpp │ │ │ ├── progress.h │ │ │ ├── unit-handler-2.cpp │ │ │ ├── unit-handler-2.h │ │ │ ├── unit-handler.cpp │ │ │ └── unit-handler.h │ │ │ ├── connection-point-proxy.cpp │ │ │ ├── connection-point-proxy.h │ │ │ ├── context-menu-proxy.cpp │ │ │ ├── context-menu-proxy.h │ │ │ ├── context-menu-target.cpp │ │ │ ├── context-menu-target.h │ │ │ ├── context-menu │ │ │ ├── context-menu.cpp │ │ │ └── context-menu.h │ │ │ ├── event-list.cpp │ │ │ ├── event-list.h │ │ │ ├── host-context-proxy.cpp │ │ │ ├── host-context-proxy.h │ │ │ ├── host-context │ │ │ ├── host-application.cpp │ │ │ ├── host-application.h │ │ │ ├── plug-interface-support.cpp │ │ │ └── plug-interface-support.h │ │ │ ├── message.cpp │ │ │ ├── message.h │ │ │ ├── param-value-queue.cpp │ │ │ ├── param-value-queue.h │ │ │ ├── parameter-changes.cpp │ │ │ ├── parameter-changes.h │ │ │ ├── physical-ui-map-list.cpp │ │ │ ├── physical-ui-map-list.h │ │ │ ├── plug-frame-proxy.cpp │ │ │ ├── plug-frame-proxy.h │ │ │ ├── plug-frame │ │ │ ├── plug-frame.cpp │ │ │ └── plug-frame.h │ │ │ ├── plug-view-proxy.cpp │ │ │ ├── plug-view-proxy.h │ │ │ ├── plug-view │ │ │ ├── parameter-finder.cpp │ │ │ ├── parameter-finder.h │ │ │ ├── plug-view-content-scale-support.cpp │ │ │ ├── plug-view-content-scale-support.h │ │ │ ├── plug-view.cpp │ │ │ └── plug-view.h │ │ │ ├── plugin-factory-proxy.cpp │ │ │ ├── plugin-factory-proxy.h │ │ │ ├── plugin-factory │ │ │ ├── plugin-factory.cpp │ │ │ └── plugin-factory.h │ │ │ ├── plugin-proxy.cpp │ │ │ ├── plugin-proxy.h │ │ │ ├── plugin │ │ │ ├── audio-presentation-latency.cpp │ │ │ ├── audio-presentation-latency.h │ │ │ ├── audio-processor.cpp │ │ │ ├── audio-processor.h │ │ │ ├── automation-state.cpp │ │ │ ├── automation-state.h │ │ │ ├── component.cpp │ │ │ ├── component.h │ │ │ ├── connection-point.cpp │ │ │ ├── connection-point.h │ │ │ ├── edit-controller-2.cpp │ │ │ ├── edit-controller-2.h │ │ │ ├── edit-controller-host-editing.cpp │ │ │ ├── edit-controller-host-editing.h │ │ │ ├── edit-controller.cpp │ │ │ ├── edit-controller.h │ │ │ ├── info-listener.cpp │ │ │ ├── info-listener.h │ │ │ ├── keyswitch-controller.cpp │ │ │ ├── keyswitch-controller.h │ │ │ ├── midi-learn.cpp │ │ │ ├── midi-learn.h │ │ │ ├── midi-mapping.cpp │ │ │ ├── midi-mapping.h │ │ │ ├── note-expression-controller.cpp │ │ │ ├── note-expression-controller.h │ │ │ ├── note-expression-physical-ui-mapping.cpp │ │ │ ├── note-expression-physical-ui-mapping.h │ │ │ ├── parameter-function-name.cpp │ │ │ ├── parameter-function-name.h │ │ │ ├── plugin-base.cpp │ │ │ ├── plugin-base.h │ │ │ ├── prefetchable-support.cpp │ │ │ ├── prefetchable-support.h │ │ │ ├── process-context-requirements.cpp │ │ │ ├── process-context-requirements.h │ │ │ ├── program-list-data.cpp │ │ │ ├── program-list-data.h │ │ │ ├── unit-data.cpp │ │ │ ├── unit-data.h │ │ │ ├── unit-info.cpp │ │ │ ├── unit-info.h │ │ │ ├── xml-representation-controller.cpp │ │ │ └── xml-representation-controller.h │ │ │ ├── process-data.cpp │ │ │ └── process-data.h │ ├── toml++.h │ ├── utils.cpp │ ├── utils.h │ ├── vst24.h │ └── vst3 │ │ └── meson.build ├── include │ ├── llvm │ │ ├── small-vector.cpp │ │ └── small-vector.h │ ├── rigtorp │ │ └── MPMCQueue.h │ └── vestige │ │ └── aeffectx.h ├── plugin │ ├── bridges │ │ ├── clap-impls │ │ │ ├── plugin-factory-proxy.cpp │ │ │ ├── plugin-factory-proxy.h │ │ │ ├── plugin-proxy.cpp │ │ │ └── plugin-proxy.h │ │ ├── clap.cpp │ │ ├── clap.h │ │ ├── common.h │ │ ├── vst2.cpp │ │ ├── vst2.h │ │ ├── vst3-impls │ │ │ ├── plug-view-proxy.cpp │ │ │ ├── plug-view-proxy.h │ │ │ ├── plugin-factory-proxy.cpp │ │ │ ├── plugin-factory-proxy.h │ │ │ ├── plugin-proxy.cpp │ │ │ └── plugin-proxy.h │ │ ├── vst3.cpp │ │ └── vst3.h │ ├── clap-plugin.cpp │ ├── host-process.cpp │ ├── host-process.h │ ├── meson.build │ ├── utils.cpp │ ├── utils.h │ ├── vst2-plugin.cpp │ └── vst3-plugin.cpp └── wine-host │ ├── bridges │ ├── clap-impls │ │ ├── host-proxy.cpp │ │ └── host-proxy.h │ ├── clap.cpp │ ├── clap.h │ ├── common.cpp │ ├── common.h │ ├── group.cpp │ ├── group.h │ ├── vst2.cpp │ ├── vst2.h │ ├── vst3-impls │ │ ├── component-handler-proxy.cpp │ │ ├── component-handler-proxy.h │ │ ├── connection-point-proxy.cpp │ │ ├── connection-point-proxy.h │ │ ├── context-menu-proxy.cpp │ │ ├── context-menu-proxy.h │ │ ├── host-context-proxy.cpp │ │ ├── host-context-proxy.h │ │ ├── plug-frame-proxy.cpp │ │ └── plug-frame-proxy.h │ ├── vst3.cpp │ └── vst3.h │ ├── editor.cpp │ ├── editor.h │ ├── host.cpp │ ├── meson.build │ ├── use-linux-asio.h │ ├── utils.cpp │ ├── utils.h │ ├── xdnd-proxy.cpp │ └── xdnd-proxy.h ├── subprojects ├── .gitignore ├── asio.wrap ├── bitsery.wrap ├── clap.wrap ├── function2.wrap ├── ghc_filesystem.wrap ├── packagefiles │ ├── asio │ │ └── meson.build │ ├── bitsery │ │ └── meson.build │ ├── clap │ │ └── meson.build │ ├── function2 │ │ └── meson.build │ └── ghc_filesystem │ │ └── meson.build ├── tomlplusplus.wrap └── vst3.wrap └── tools ├── migration ├── README.md ├── migrate-ardour.py ├── migrate-bitwig.py ├── migrate-reaper.py └── migrate-renoise.py ├── patch-vst3-sdk.sh ├── run-clang-tidy.sh ├── vst3-sdk-patches ├── vst3-sdk-patch-3.7.1.diff ├── vst3-sdk-patch-3.7.2.diff ├── vst3-sdk-patch-3.7.3.diff ├── vst3-sdk-patch-3.7.4.diff ├── vst3-sdk-patch-3.7.5.diff └── vst3-sdk-patch-3.7.7.diff └── yabridgectl ├── .gitignore ├── .rustfmt.toml ├── Cargo.lock ├── Cargo.toml ├── README.md └── src ├── actions.rs ├── actions └── blacklist.rs ├── config.rs ├── files.rs ├── main.rs ├── symbols.rs ├── util.rs └── vst3_moduleinfo.rs /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Chromium 2 | IndentWidth: 4 3 | Standard: Cpp11 4 | 5 | # Don't reflow nested comments 6 | CommentPragmas: '^ *//' 7 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | # Use `tools/run-clang-tidy.sh` to run clang-tidy with the correct config 2 | Checks: 'bugprone-*,concurrency-*,clang-analyzer-*,-clang-diagnostic-missing-braces' 3 | InheritParentConfig: false 4 | FormatStyle: file 5 | HeaderFilterRegex: '' 6 | WarningsAsErrors: '' 7 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: robbert-vdh 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: ["https://paypal.me/robbertvdh"] 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Discord 4 | about: Support and announcements for yabridge as well as general discussion about plugins and Wine 5 | url: https://discord.gg/pyNeweqadf 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: I wish yabridge did this 3 | body: 4 | - type: textarea 5 | id: description 6 | attributes: 7 | label: Feature description 8 | placeholder: >- 9 | What should yabridge be doing that it currently doesn't? 10 | - type: textarea 11 | id: other-information 12 | attributes: 13 | label: Anything else? 14 | placeholder: If there's anything else you'd like to add, then you can do so here. 15 | validations: 16 | required: false 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build*/ 2 | -------------------------------------------------------------------------------- /ROADMAP.md: -------------------------------------------------------------------------------- 1 | # Roadmap 2 | 3 | Yabridge's VST2 and VST3 bridging are feature complete and should work great, 4 | but there are still some other features that may be worth implementing. This 5 | page lists some of those. 6 | 7 | # Short-ish term 8 | 9 | - [ARA](https://www.celemony.com/en/service1/about-celemony/technologies) 10 | support for VST3 plugins. The ARA SDK has recently been [open 11 | source](https://github.com/Celemony/ARA_SDK), so we can now finally start 12 | working on this. 13 | 14 | # Longer term 15 | 16 | - An easier [updater](https://github.com/robbert-vdh/yabridge/issues/51) through 17 | a new `yabridgectl update` command for distros that don't package yabridge. 18 | 19 | # Somewhere in the future, possibly 20 | 21 | - CLAP audio thread pool support. Implementing this efficiently is less than 22 | trivial, and there are currently no plugins that can benefit from it. 23 | - REAPER's vendor specific [VST2.4](https://www.reaper.fm/sdk/vst/vst_ext.php) 24 | and 25 | [VST3](https://github.com/justinfrankel/reaper-sdk/blob/main/sdk/reaper_vst3_interfaces.h) 26 | extensions. 27 | - [Presonus' extensions](https://presonussoftware.com/en_US/developer) to the 28 | VST3 interfaces. All of these extensions have been superseded by official VST3 29 | interfaces in later versions of the VST3 SDK, so it's unlikely that there are 30 | many plugins that still rely on these older extensions. 31 | -------------------------------------------------------------------------------- /cross-wine.conf: -------------------------------------------------------------------------------- 1 | [binaries] 2 | c = 'winegcc' 3 | cpp = 'wineg++' 4 | ar = 'ar' 5 | strip = 'strip' 6 | # Needs to be specified explicitely for Fedora 32 7 | pkgconfig = 'pkg-config' 8 | # Useful for packaging so Meson can resolve dependencies without a pkg-config 9 | # file from the repositories 10 | cmake = 'cmake' 11 | 12 | [properties] 13 | needs_exe_wrapper = true 14 | 15 | [built-in options] 16 | # Instead of specifying the target architecture below, we'll do this directly in 17 | # the meson.build file. By setting the `-m64` flags there (or `-m32`), we can 18 | # build both the regular 64-bit version of the host application and the 32-bit 19 | # bit bridge in the same build. This ensures that the plugin and both host 20 | # applications are always in sync. This might not be needed anymore once Meson 21 | # cross compiling to multiple targets at once. 22 | # https://github.com/mesonbuild/meson/issues/5125 23 | cpp_link_args = ['-mwindows'] 24 | 25 | # For instance, this should be in the 64-bit only cross-file 26 | # c_args = ['-m64'] 27 | # cpp_args = ['-m64'] 28 | # cpp_link_args = ['-m64', '-mwindows'] 29 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option( 2 | 'bitbridge', 3 | type : 'boolean', 4 | value : false, 5 | description : 'Build a 32-bit host application for hosting 32-bit plugins. See the readme for full instructions on how to use this.' 6 | ) 7 | 8 | option( 9 | 'clap', 10 | type : 'boolean', 11 | value : true, 12 | description : 'Whether to build the CLAP version of yabridge.' 13 | ) 14 | 15 | option( 16 | 'vst3', 17 | type : 'boolean', 18 | value : true, 19 | description : 'Whether to build the VST3 version of yabridge.' 20 | ) 21 | 22 | option( 23 | 'winedbg', 24 | type : 'boolean', 25 | value : false, 26 | description : 'Whether to run the Wine plugin host with GDB attached. Might not always be reliable.' 27 | ) 28 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robbert-vdh/yabridge/918d24a16e8eda9ac2eac692704770dfed96f6ee/screenshot.png -------------------------------------------------------------------------------- /src/chainloader/meson.build: -------------------------------------------------------------------------------- 1 | # Like for the other libraries, the actual `shared_library()` call is in the 2 | # main `meson.build` file so everything gets bundled to a single directory. 3 | 4 | chainloader_deps = [ 5 | configuration_dep, 6 | 7 | dbus_dep, 8 | dl_dep, 9 | ghc_filesystem_dep, 10 | rt_dep, 11 | ] 12 | 13 | if with_clap 14 | clap_chainloader_deps = chainloader_deps + [clap_dep] 15 | endif 16 | 17 | vst2_chainloader_sources = files( 18 | '../common/logging/common.cpp', 19 | '../common/linking.cpp', 20 | '../common/notifications.cpp', 21 | '../common/process.cpp', 22 | '../common/utils.cpp', 23 | 'utils.cpp', 24 | 'vst2-chainloader.cpp', 25 | ) 26 | 27 | if with_clap 28 | clap_chainloader_sources = files( 29 | '../common/logging/common.cpp', 30 | '../common/linking.cpp', 31 | '../common/notifications.cpp', 32 | '../common/process.cpp', 33 | '../common/utils.cpp', 34 | 'utils.cpp', 35 | 'clap-chainloader.cpp', 36 | ) 37 | endif 38 | 39 | if with_vst3 40 | vst3_chainloader_sources = files( 41 | '../common/logging/common.cpp', 42 | '../common/linking.cpp', 43 | '../common/notifications.cpp', 44 | '../common/process.cpp', 45 | '../common/utils.cpp', 46 | 'utils.cpp', 47 | 'vst3-chainloader.cpp', 48 | ) 49 | endif 50 | -------------------------------------------------------------------------------- /src/chainloader/utils.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | /** 22 | * Finds the matching `libyabridge-*.so` for this chainloader. Returns the 23 | * handle if it is found. Otherwise, we'll log an error and show a desktop 24 | * notification, and this function returns a null pointer. The pointer may be 25 | * `dlclose()`'d when it's no longer needed. This search works in the following 26 | * order: 27 | * 28 | * - First we'll try to locate `yabridge-host.exe` using the same method used by 29 | * the yabridge plugin bridges themselves. We'll search in `$PATH`, followed 30 | * by `${XDG_DATA_HOME:-$HOME/.local/share}/yabridge`. If that file exists and 31 | * the target plugin library exists right next to it, then we'll use that. 32 | * - For compatibility with 32-bit only builds of yabridge, we'll repeat this 33 | * process for `yabridge-host-32.exe`. 34 | * - When those don't exist, we'll try to `dlopen()` the file directly. This 35 | * will use the correct path for the system. 36 | * - If we still can't find the file, we'll do one last scan through common lib 37 | * directories in case `ldconfig` was not set up correctly. 38 | */ 39 | void* find_plugin_library(const std::string& name); 40 | 41 | /** 42 | * Log a message when a `dlsym()` call fails and show a corresponding desktop 43 | * notification. Used as part of the `LOAD_FUNCTION` macros. 44 | */ 45 | void log_failing_dlsym(const std::string& library_name, 46 | const char* function_name); 47 | -------------------------------------------------------------------------------- /src/common/bitsery/ext/ghc-path.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | namespace bitsery { 25 | namespace ext { 26 | 27 | /** 28 | * An adapter for serializing and deserializing filesystem paths since they're 29 | * not mutable. 30 | */ 31 | class GhcPath { 32 | public: 33 | template 34 | void serialize(Ser& ser, const ghc::filesystem::path& path, Fnc&&) const { 35 | auto path_str = path.string(); 36 | ser.text1b(path_str, 4096); 37 | } 38 | 39 | template 40 | void deserialize(Des& des, ghc::filesystem::path& path, Fnc&&) const { 41 | ghc::filesystem::path::string_type path_str{}; 42 | des.text1b(path_str, 4096); 43 | path = path_str; 44 | } 45 | }; 46 | 47 | } // namespace ext 48 | 49 | namespace traits { 50 | 51 | template <> 52 | struct ExtensionTraits { 53 | using TValue = void; 54 | static constexpr bool SupportValueOverload = false; 55 | static constexpr bool SupportObjectOverload = true; 56 | static constexpr bool SupportLambdaOverload = false; 57 | }; 58 | 59 | } // namespace traits 60 | } // namespace bitsery 61 | -------------------------------------------------------------------------------- /src/common/bitsery/ext/in-place-optional.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | namespace bitsery { 22 | namespace ext { 23 | 24 | /** 25 | * A temporary replacement for `bitsery::ext::InPlaceOptional` to avoid 26 | * reinitializing the object we're deserializing into if it already holds a 27 | * value. This follows the same idea as our `InPLaceVariant`. 28 | * 29 | * This is copied almost verbatim from `bitsery::ext::InPlaceOptional` (we can't 30 | * access the private member, so we couldn't override just the deserialization 31 | * method). 32 | */ 33 | class InPlaceOptional { 34 | public: 35 | /** 36 | * Works with std::optional types 37 | * @param alignBeforeData only makes sense when bit-packing enabled, by 38 | * default aligns after writing/reading bool state of optional 39 | */ 40 | explicit InPlaceOptional(bool alignBeforeData = true) 41 | : _alignBeforeData{alignBeforeData} {} 42 | 43 | template 44 | void serialize(Ser& ser, const std::optional& obj, Fnc&& fnc) const { 45 | ser.boolValue(static_cast(obj)); 46 | if (_alignBeforeData) 47 | ser.adapter().align(); 48 | if (obj) 49 | fnc(ser, const_cast(*obj)); 50 | } 51 | 52 | template 53 | void deserialize(Des& des, std::optional& obj, Fnc&& fnc) const { 54 | bool exists{}; 55 | des.boolValue(exists); 56 | if (_alignBeforeData) 57 | des.adapter().align(); 58 | if (exists) { 59 | // Reinitializing nontrivial types may be expensive 60 | // especially when they reference heap data, so if `obj` 61 | // already holds a value then we'll deserialize into the 62 | // existing object 63 | if constexpr (!std::is_trivial_v) { 64 | if (obj) { 65 | fnc(des, *obj); 66 | return; 67 | } 68 | } 69 | 70 | obj = ::bitsery::Access::create(); 71 | fnc(des, *obj); 72 | } else { 73 | obj = std::nullopt; 74 | } 75 | } 76 | 77 | private: 78 | bool _alignBeforeData; 79 | }; 80 | } // namespace ext 81 | 82 | namespace traits { 83 | template 84 | struct ExtensionTraits> { 85 | using TValue = T; 86 | static constexpr bool SupportValueOverload = true; 87 | static constexpr bool SupportObjectOverload = true; 88 | static constexpr bool SupportLambdaOverload = true; 89 | }; 90 | } // namespace traits 91 | } // namespace bitsery 92 | -------------------------------------------------------------------------------- /src/common/bitsery/ext/native-pointer.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include "../../serialization/common.h" 25 | 26 | namespace bitsery { 27 | namespace ext { 28 | 29 | /** 30 | * An adapter for serializing and deserializing native pointer types. This makes 31 | * it possible to serialize `void*` fields in CLAP structs as a `native_size_t` 32 | * without having to modify the struct. Used in the CLAP event serialization. 33 | */ 34 | class NativePointer { 35 | public: 36 | template 37 | void serialize(Ser& ser, const void* const& pointer, Fnc&&) const { 38 | const auto native_pointer = 39 | static_cast(reinterpret_cast(pointer)); 40 | ser.value8b(native_pointer); 41 | } 42 | 43 | template 44 | void deserialize(Des& des, void*& pointer, Fnc&&) const { 45 | native_size_t native_pointer; 46 | des.value8b(native_pointer); 47 | pointer = reinterpret_cast(static_cast(native_pointer)); 48 | } 49 | }; 50 | 51 | } // namespace ext 52 | 53 | namespace traits { 54 | 55 | template <> 56 | struct ExtensionTraits { 57 | using TValue = void; 58 | static constexpr bool SupportValueOverload = false; 59 | static constexpr bool SupportObjectOverload = true; 60 | static constexpr bool SupportLambdaOverload = false; 61 | }; 62 | 63 | } // namespace traits 64 | } // namespace bitsery 65 | -------------------------------------------------------------------------------- /src/common/bitsery/traits/small-vector.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | namespace bitsery { 23 | namespace traits { 24 | 25 | template 26 | struct ContainerTraits> 27 | : public StdContainer, true, true> { 28 | // The small vector implementation needs to be contiguous for this to work 29 | }; 30 | 31 | template 32 | struct BufferAdapterTraits> 33 | : public StdContainerForBufferAdapter> {}; 34 | 35 | // And the same extensions again for the type erased version 36 | 37 | template 38 | struct ContainerTraits> 39 | : public StdContainer, true, true> {}; 40 | 41 | template 42 | struct BufferAdapterTraits> 43 | : public StdContainerForBufferAdapter> {}; 44 | 45 | } // namespace traits 46 | } // namespace bitsery 47 | -------------------------------------------------------------------------------- /src/common/communication/common.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "common.h" 18 | 19 | #include 20 | #include 21 | 22 | #include "../utils.h" 23 | 24 | namespace fs = ghc::filesystem; 25 | 26 | /** 27 | * Used for generating random identifiers. 28 | */ 29 | constexpr char alphanumeric_characters[] = 30 | "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 31 | 32 | ghc::filesystem::path generate_endpoint_base(const std::string& plugin_name) { 33 | fs::path temp_directory = get_temporary_directory(); 34 | 35 | std::random_device random_device; 36 | std::mt19937 rng(random_device()); 37 | fs::path candidate_endpoint; 38 | do { 39 | std::string random_id; 40 | std::sample( 41 | alphanumeric_characters, 42 | alphanumeric_characters + strlen(alphanumeric_characters) - 1, 43 | std::back_inserter(random_id), 8, rng); 44 | 45 | // We'll get rid of the file descriptors immediately after accepting the 46 | // sockets, so putting them inside of a subdirectory would only leave 47 | // behind an empty directory 48 | std::ostringstream socket_name; 49 | socket_name << "yabridge-" << plugin_name << "-" << random_id; 50 | 51 | candidate_endpoint = temp_directory / socket_name.str(); 52 | } while (fs::exists(candidate_endpoint)); 53 | 54 | return candidate_endpoint; 55 | } 56 | -------------------------------------------------------------------------------- /src/common/communication/vst2.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "vst2.h" 18 | 19 | Vst2Event::Payload DefaultDataConverter::read_data(const int /*opcode*/, 20 | const int /*index*/, 21 | const intptr_t /*value*/, 22 | const void* data) const { 23 | if (!data) { 24 | return nullptr; 25 | } 26 | 27 | // This is a simple fallback that will work in almost every case. Because 28 | // some plugins don't zero out their string buffers when sending host 29 | // callbacks, we will explicitely list all callbacks that expect a string in 30 | // `DispatchDataConverter` and `HostCallbackDataConverter`. 31 | const char* str = static_cast(data); 32 | if (str[0] != 0) { 33 | return std::string(str); 34 | } else { 35 | return WantsString{}; 36 | } 37 | } 38 | 39 | std::optional DefaultDataConverter::read_value( 40 | const int /*opcode*/, 41 | const intptr_t /*value*/) const { 42 | return std::nullopt; 43 | } 44 | 45 | void DefaultDataConverter::write_data(const int /*opcode*/, 46 | void* data, 47 | const Vst2EventResult& response) const { 48 | // The default behavior is to handle this as a null terminated C-style 49 | // string 50 | std::visit(overload{[&](const auto&) {}, 51 | [&](const std::string& s) { 52 | char* output = static_cast(data); 53 | 54 | // We use std::string for easy transport but in 55 | // practice we're always writing null terminated 56 | // C-style strings 57 | std::copy(s.begin(), s.end(), output); 58 | output[s.size()] = 0; 59 | }}, 60 | response.payload); 61 | } 62 | 63 | void DefaultDataConverter::write_value( 64 | const int /*opcode*/, 65 | intptr_t /*value*/, 66 | const Vst2EventResult& /*response*/) const {} 67 | 68 | intptr_t DefaultDataConverter::return_value(const int /*opcode*/, 69 | const intptr_t original) const { 70 | return original; 71 | } 72 | 73 | Vst2EventResult DefaultDataConverter::send_event( 74 | asio::local::stream_protocol::socket& socket, 75 | const Vst2Event& event, 76 | SerializationBufferBase& buffer) const { 77 | write_object(socket, event, buffer); 78 | return read_object(socket, buffer); 79 | } 80 | -------------------------------------------------------------------------------- /src/common/config/config.h.in: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | /** 20 | * The name of yabridge's CLAP library, e.g. `libyabridge-clap.so`. 21 | */ 22 | constexpr char yabridge_clap_plugin_name[] = "@clap_plugin_name@"; 23 | 24 | /** 25 | * The name of yabridge's VST2 library, e.g. `libyabridge-vst2.so`. 26 | */ 27 | constexpr char yabridge_vst2_plugin_name[] = "@vst2_plugin_name@"; 28 | 29 | /** 30 | * The name of yabridge's VST3 library, e.g. `libyabridge-vst3.so`. 31 | */ 32 | constexpr char yabridge_vst3_plugin_name[] = "@vst3_plugin_name@"; 33 | 34 | /** 35 | * The name of the Wine plugin host application, e.g. `yabridge-host.exe` for 36 | * the regular 64-bit build. 37 | */ 38 | constexpr char yabridge_host_name[] = "@host_binary_64bit@"; 39 | 40 | /** 41 | * The name of the 32-bit Wine plugin host application, e.g. 42 | * `yabridge-host-32.exe`.` This is used as a bitbridge to be able to load 43 | * legacy 32-bit only Windows plugins from a 64-bit Linux host. 44 | */ 45 | constexpr char yabridge_host_name_32bit[] = "@host_binary_32bit@"; 46 | -------------------------------------------------------------------------------- /src/common/config/meson.build: -------------------------------------------------------------------------------- 1 | # Contains constants determined while configuring the build. As an alternative 2 | # to preprocessor macros. 3 | config_header = configure_file( 4 | input : 'config.h.in', 5 | output : 'config.h', 6 | configuration : configuration_data( 7 | { 8 | 'clap_plugin_name': 'lib' + clap_plugin_name + '.so', 9 | 'vst2_plugin_name': 'lib' + vst2_plugin_name + '.so', 10 | 'vst3_plugin_name': 'lib' + vst3_plugin_name + '.so', 11 | 'host_binary_32bit': host_name_32bit + '.exe', 12 | 'host_binary_64bit': host_name_64bit + '.exe', 13 | } 14 | ) 15 | ) 16 | 17 | # Generate a file containing the last annotated git tag, the amount of commits 18 | # since then, and the hash of the last commit 19 | # NOTE: We explicitly specify the git directory to be relative to the main 20 | # `meson.build` file. Otherwise git will search up the file tree, which 21 | # might cause `git describe` to be run in an unrelated repository when 22 | # building from a tarball that's been extracted inside of a git 23 | # directory, like when building the `yabridge` AUR package. In that case 24 | # `vcs_tag()` should always fall back to the Meson project version. 25 | version_header = vcs_tag( 26 | command : ['git', '--git-dir=' + (meson.project_source_root() / '.git'), 'describe', '--always'], 27 | input : 'version.h.in', 28 | output : 'version.h', 29 | replace_string : '@VCS_VERSION@' 30 | ) 31 | 32 | configuration_dep = declare_dependency( 33 | include_directories : include_directories('.'), 34 | sources : [config_header, version_header], 35 | ) 36 | -------------------------------------------------------------------------------- /src/common/config/version.h.in: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | /** 20 | * Will be replaced with the output of `git describe` by Meson. Contains the 21 | * latest annotated tag and possibly also the amount of commits and the hash of 22 | * the last commit. 23 | */ 24 | constexpr char yabridge_git_version[] = "@VCS_VERSION@"; 25 | -------------------------------------------------------------------------------- /src/common/linking.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "linking.h" 18 | 19 | #include 20 | 21 | #include 22 | 23 | namespace fs = ghc::filesystem; 24 | 25 | fs::path get_this_file_location() { 26 | // We'll try to find the library this function was defined in. When called 27 | // from a copy of `libyabridge-*.so` this will return that library. Because 28 | // the chainloader libraries load the plugin libraries from fixed locations, 29 | // the plugin libraries cannot use this function directly when using the 30 | // chainloaders. 31 | 32 | // On success this returns a non-zero value, just to keep you on your toes 33 | Dl_info info; 34 | assert(dladdr(reinterpret_cast(get_this_file_location), &info) != 0); 35 | assert(info.dli_fname); 36 | 37 | std::string this_file(info.dli_fname); 38 | 39 | // HACK: Not sure why, but `boost::dll::this_line_location()` used to return 40 | // a path starting with a double slash on some systems. I've seen this 41 | // happen on both Ubuntu 18.04 and 20.04, but not on Arch based 42 | // distros. Under Linux a path starting with two slashes is treated 43 | // the same as a path starting with only a single slash, but Wine will 44 | // refuse to load any files when the path starts with two slashes. The 45 | // easiest way to work around this if this happens is to just add 46 | // another leading slash and then normalize the path, since three or 47 | // more slashes will be coerced into a single slash. We no longer use 48 | // Boost.Dll, but unless this was an obscure Boost.Filesystem bug it 49 | // sounds more likely that it was caused by some `ld.so` setting. 50 | // Unless we can really figure out what was causing this, it seems 51 | // best to still account for it 52 | if (this_file.starts_with("//")) { 53 | const size_t path_start_pos = this_file.find_first_not_of('/'); 54 | if (path_start_pos != std::string::npos) { 55 | // FIXME: This results in a spurious compiler warning if you inline 56 | // `path_start`: 57 | // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105329 58 | const std::string path_start = this_file.substr(path_start_pos); 59 | this_file = "/" + path_start; 60 | } 61 | } 62 | 63 | return this_file; 64 | } 65 | -------------------------------------------------------------------------------- /src/common/linking.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | // This header is completely standalone so the chainloading libraries can 20 | // retrieve their file path without pulling in a lot of additional dependencies 21 | 22 | #include 23 | 24 | /** 25 | * Return a path to this `.so` file. This can be used to find out from where 26 | * this copy of `libyabridge-{clap,vst2,vst3}.so` or 27 | * `libyabridge-chainloader-*.so` was loaded so we can search for a matching 28 | * Windows plugin library. When the chainloaders are used, this path should be 29 | * passed to the chainloaded plugin library using the provided exported 30 | * functions since they can't detect the path themselves. 31 | */ 32 | ghc::filesystem::path get_this_file_location(); 33 | -------------------------------------------------------------------------------- /src/common/notifications.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | // This header is used by the plugins and the chainloaders to send desktop 20 | // notifications when something goes wrong 21 | 22 | #include 23 | #include 24 | 25 | /** 26 | * Send a desktop notification using the D-Bus notifications protocol 27 | * (). 28 | * Used for diagnostics when a plugin fails to load since the user may not be 29 | * checking the output in a terminal. 30 | * 31 | * @param title The title (or technically, summary) of the notification. 32 | * @param body The message to display. This can contain line feeds, and it any 33 | * HTML tags and XML escape sequences will be automatically escaped. The 34 | * message can also be empty. 35 | * @param origin If this is set to the current plugin's path, then the 36 | * notification will append a 'Source: ' hyperlink to the body so the 37 | * user can more easily navigate to the plugin's path. 38 | * 39 | * @return Whether the notification was sent. This will be false if 40 | * `libdbus-1.so` is not available. 41 | */ 42 | bool send_notification(const std::string& title, 43 | const std::string body, 44 | std::optional origin); 45 | -------------------------------------------------------------------------------- /src/common/plugins.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | // Utilities and tags for plugin types and architectures 22 | 23 | /** 24 | * A tag to differentiate between 32 and 64-bit `.dll` files, used to determine 25 | * which host application to use. 26 | */ 27 | enum class LibArchitecture { dll_32, dll_64 }; 28 | 29 | /** 30 | * A tag to differentiate between different plugin types. 31 | * `plugin_type_to_string()` and `plugin_type_from_string()` can be used to 32 | * convert these values to and from strings. The string form is used as a 33 | * command line argument for the individual Wine host applications, and the enum 34 | * form is passed directly in `HostRequest`. 35 | * 36 | * The `unkonwn` tag is not used directly, but in the event that we do call 37 | * `plugin_type_from_string()` with some invalid value we can use it to 38 | * gracefully show an error message without resorting to exceptions. 39 | */ 40 | enum class PluginType { clap, vst2, vst3, unknown }; 41 | 42 | template 43 | void serialize(S& s, PluginType& plugin_type) { 44 | s.value4b(plugin_type); 45 | } 46 | 47 | /** 48 | * Determine the architecture of a `.dll` file based on the file header. 49 | * 50 | * See https://docs.microsoft.com/en-us/windows/win32/debug/pe-format for more 51 | * information on the PE32 format. 52 | * 53 | * @param path The path to the .dll file we're going to check. 54 | * 55 | * @return The detected architecture. 56 | * @throw std::runtime_error If the file is not a .dll file. 57 | */ 58 | LibArchitecture find_dll_architecture(const ghc::filesystem::path&); 59 | 60 | PluginType plugin_type_from_string(const std::string& plugin_type) noexcept; 61 | std::string plugin_type_to_string(const PluginType& plugin_type); 62 | -------------------------------------------------------------------------------- /src/common/serialization/clap/audio-buffer.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more destates. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | // Serialization messages for `clap/audio-buffer.h` 22 | 23 | namespace clap { 24 | namespace audio_buffer { 25 | 26 | /** 27 | * Metadata used to encode whether an audio port/buffer carries 32-=bit or 28 | * 64-bit audio data. This needs to be stored separately because CLAP uses 29 | * whether or not one of the two pointers is null to indicate the type of data 30 | * stored in the audio buffer. 31 | */ 32 | enum class AudioBufferType : uint8_t { 33 | Float32, 34 | Double64, 35 | }; 36 | 37 | } // namespace audio_buffer 38 | } // namespace clap 39 | 40 | template 41 | void serialize(S& s, clap_audio_buffer_t& buffer) { 42 | // These need to be set later using the shared memory object and depending 43 | // on the `AudioBufferType`. We'll zero them out so default initialized 44 | // objects created by bitsery won't contain uninitialized memory. 45 | buffer.data32 = nullptr; 46 | buffer.data64 = nullptr; 47 | s.value4b(buffer.channel_count); 48 | s.value4b(buffer.latency); 49 | s.value8b(buffer.constant_mask); 50 | } 51 | -------------------------------------------------------------------------------- /src/common/serialization/clap/ext/audio-ports-config.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "audio-ports-config.h" 18 | 19 | #include "../../../utils.h" 20 | 21 | namespace clap { 22 | namespace ext { 23 | namespace audio_ports_config { 24 | 25 | AudioPortsConfig::AudioPortsConfig(const clap_audio_ports_config_t& original) 26 | : id(original.id), 27 | name(original.name), 28 | input_port_count(original.input_port_count), 29 | output_port_count(original.output_port_count), 30 | has_main_input(original.has_main_input), 31 | main_input_channel_count(original.main_input_channel_count), 32 | main_input_port_type(clap::ext::audio_ports::parse_audio_port_type( 33 | original.main_input_port_type)), 34 | has_main_output(original.has_main_output), 35 | main_output_channel_count(original.main_output_channel_count), 36 | main_output_port_type(clap::ext::audio_ports::parse_audio_port_type( 37 | original.main_output_port_type)) {} 38 | 39 | void AudioPortsConfig::reconstruct(clap_audio_ports_config_t& config) const { 40 | config = clap_audio_ports_config_t{}; 41 | config.id = id; 42 | strlcpy_buffer(config.name, name); 43 | config.input_port_count = input_port_count; 44 | config.output_port_count = output_port_count; 45 | config.has_main_input = has_main_input; 46 | config.main_input_channel_count = main_input_channel_count; 47 | config.main_input_port_type = 48 | clap::ext::audio_ports::audio_port_type_to_string(main_input_port_type); 49 | config.has_main_output = has_main_output; 50 | config.main_output_channel_count = main_output_channel_count; 51 | config.main_output_port_type = 52 | clap::ext::audio_ports::audio_port_type_to_string( 53 | main_output_port_type); 54 | } 55 | 56 | } // namespace audio_ports_config 57 | } // namespace ext 58 | } // namespace clap 59 | -------------------------------------------------------------------------------- /src/common/serialization/clap/ext/audio-ports.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "audio-ports.h" 18 | 19 | #include "../../../utils.h" 20 | 21 | namespace clap { 22 | namespace ext { 23 | namespace audio_ports { 24 | 25 | AudioPortType parse_audio_port_type(const char* port_type) { 26 | if (!port_type) { 27 | return AudioPortType::Unknown; 28 | } 29 | 30 | if (strcmp(port_type, CLAP_PORT_MONO) == 0) { 31 | return AudioPortType::Mono; 32 | } else if (strcmp(port_type, CLAP_PORT_STEREO) == 0) { 33 | return AudioPortType::Stereo; 34 | } else { 35 | return AudioPortType::Unknown; 36 | } 37 | } 38 | 39 | const char* audio_port_type_to_string(AudioPortType port_type) { 40 | switch (port_type) { 41 | case AudioPortType::Mono: 42 | return CLAP_PORT_MONO; 43 | break; 44 | case AudioPortType::Stereo: 45 | return CLAP_PORT_STEREO; 46 | break; 47 | default: 48 | return nullptr; 49 | break; 50 | } 51 | } 52 | 53 | AudioPortInfo::AudioPortInfo(const clap_audio_port_info_t& original) 54 | : id(original.id), 55 | name(original.name), 56 | flags(original.flags), 57 | channel_count(original.channel_count), 58 | port_type(parse_audio_port_type(original.port_type)), 59 | in_place_pair(original.in_place_pair) {} 60 | 61 | void AudioPortInfo::reconstruct(clap_audio_port_info_t& port_info) const { 62 | port_info = clap_audio_port_info_t{}; 63 | port_info.id = id; 64 | strlcpy_buffer(port_info.name, name); 65 | port_info.flags = flags; 66 | port_info.channel_count = channel_count; 67 | port_info.port_type = audio_port_type_to_string(port_type); 68 | port_info.in_place_pair = in_place_pair; 69 | } 70 | 71 | } // namespace audio_ports 72 | } // namespace ext 73 | } // namespace clap 74 | -------------------------------------------------------------------------------- /src/common/serialization/clap/ext/latency.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more delatencys. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include "../../common.h" 22 | 23 | // Serialization messages for `clap/ext/latency.h` 24 | 25 | namespace clap { 26 | namespace ext { 27 | namespace latency { 28 | 29 | namespace plugin { 30 | 31 | /** 32 | * Message struct for `clap_plugin_latency::get()`. 33 | */ 34 | struct Get { 35 | using Response = PrimitiveResponse; 36 | 37 | native_size_t instance_id; 38 | 39 | template 40 | void serialize(S& s) { 41 | s.value8b(instance_id); 42 | } 43 | }; 44 | 45 | } // namespace plugin 46 | 47 | namespace host { 48 | 49 | /** 50 | * Message struct for `clap_host_latency::changed()`. 51 | */ 52 | struct Changed { 53 | using Response = Ack; 54 | 55 | native_size_t owner_instance_id; 56 | 57 | template 58 | void serialize(S& s) { 59 | s.value8b(owner_instance_id); 60 | } 61 | }; 62 | 63 | } // namespace host 64 | 65 | } // namespace latency 66 | } // namespace ext 67 | } // namespace clap 68 | -------------------------------------------------------------------------------- /src/common/serialization/clap/ext/log.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more delogs. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "../../common.h" 24 | 25 | // Serialization messages for `clap/ext/log.h` 26 | 27 | namespace clap { 28 | namespace ext { 29 | namespace log { 30 | 31 | namespace host { 32 | 33 | /** 34 | * Message struct for `clap_host_log::log()`. 35 | */ 36 | struct Log { 37 | using Response = Ack; 38 | 39 | native_size_t owner_instance_id; 40 | 41 | clap_log_severity severity; 42 | std::string msg; 43 | 44 | template 45 | void serialize(S& s) { 46 | s.value8b(owner_instance_id); 47 | s.value4b(severity); 48 | s.text1b(msg, 1 << 16); 49 | } 50 | }; 51 | 52 | } // namespace host 53 | 54 | } // namespace log 55 | } // namespace ext 56 | } // namespace clap 57 | -------------------------------------------------------------------------------- /src/common/serialization/clap/ext/note-name.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "note-name.h" 18 | 19 | #include "../../../utils.h" 20 | 21 | namespace clap { 22 | namespace ext { 23 | namespace note_name { 24 | 25 | NoteName::NoteName(const clap_note_name_t& original) 26 | : name(original.name), 27 | port(original.port), 28 | key(original.key), 29 | channel(original.channel) {} 30 | 31 | void NoteName::reconstruct(clap_note_name_t& note_name) const { 32 | note_name = clap_note_name_t{}; 33 | strlcpy_buffer(note_name.name, name); 34 | note_name.port = port; 35 | note_name.key = key; 36 | note_name.channel = channel; 37 | } 38 | 39 | } // namespace note_name 40 | } // namespace ext 41 | } // namespace clap 42 | -------------------------------------------------------------------------------- /src/common/serialization/clap/ext/note-ports.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "note-ports.h" 18 | 19 | #include "../../../utils.h" 20 | 21 | namespace clap { 22 | namespace ext { 23 | namespace note_ports { 24 | 25 | NotePortInfo::NotePortInfo(const clap_note_port_info_t& original) 26 | : id(original.id), 27 | supported_dialects(original.supported_dialects), 28 | preferred_dialect(original.preferred_dialect), 29 | name(original.name) {} 30 | 31 | void NotePortInfo::reconstruct(clap_note_port_info_t& port_info) const { 32 | port_info = clap_note_port_info_t{}; 33 | port_info.id = id; 34 | port_info.supported_dialects = supported_dialects; 35 | port_info.preferred_dialect = preferred_dialect; 36 | strlcpy_buffer(port_info.name, name); 37 | } 38 | 39 | } // namespace note_ports 40 | } // namespace ext 41 | } // namespace clap 42 | -------------------------------------------------------------------------------- /src/common/serialization/clap/ext/params.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "params.h" 18 | 19 | #include "../../../utils.h" 20 | 21 | namespace clap { 22 | namespace ext { 23 | namespace params { 24 | 25 | ParamInfo::ParamInfo(const clap_param_info_t& original) 26 | : id(original.id), 27 | flags(original.flags), 28 | cookie(reinterpret_cast(original.cookie)), 29 | name(original.name), 30 | module(original.module), 31 | min_value(original.min_value), 32 | max_value(original.max_value), 33 | default_value(original.default_value) {} 34 | 35 | void ParamInfo::reconstruct(clap_param_info_t& port_info) const { 36 | port_info = clap_param_info_t{}; 37 | port_info.id = id; 38 | port_info.flags = flags; 39 | port_info.cookie = reinterpret_cast(static_cast(cookie)); 40 | strlcpy_buffer(port_info.name, name); 41 | strlcpy_buffer(port_info.module, module); 42 | port_info.min_value = min_value; 43 | port_info.max_value = max_value; 44 | port_info.default_value = default_value; 45 | } 46 | 47 | } // namespace params 48 | } // namespace ext 49 | } // namespace clap 50 | -------------------------------------------------------------------------------- /src/common/serialization/clap/ext/render.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include "../../common.h" 22 | 23 | // Serialization messages for `clap/ext/render.h` 24 | 25 | namespace clap { 26 | namespace ext { 27 | namespace render { 28 | 29 | namespace plugin { 30 | 31 | /** 32 | * Message struct for `clap_plugin_render::has_hard_realtime_requirement()`. 33 | */ 34 | struct HasHardRealtimeRequirement { 35 | using Response = PrimitiveResponse; 36 | 37 | native_size_t instance_id; 38 | 39 | template 40 | void serialize(S& s) { 41 | s.value8b(instance_id); 42 | } 43 | }; 44 | 45 | /** 46 | * Message struct for `clap_plugin_render::set()`. 47 | */ 48 | struct Set { 49 | using Response = PrimitiveResponse; 50 | 51 | native_size_t instance_id; 52 | 53 | clap_plugin_render_mode mode; 54 | 55 | template 56 | void serialize(S& s) { 57 | s.value8b(instance_id); 58 | s.value4b(mode); 59 | } 60 | }; 61 | 62 | } // namespace plugin 63 | 64 | } // namespace render 65 | } // namespace ext 66 | } // namespace clap 67 | -------------------------------------------------------------------------------- /src/common/serialization/clap/ext/state.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more destates. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include "../../common.h" 22 | #include "../stream.h" 23 | 24 | // Serialization messages for `clap/ext/state.h` 25 | 26 | namespace clap { 27 | namespace ext { 28 | namespace state { 29 | 30 | namespace plugin { 31 | 32 | /** 33 | * The response to the `clap::ext::state::plugin::Save` message defined below. 34 | */ 35 | struct SaveResponse { 36 | std::optional result; 37 | 38 | template 39 | void serialize(S& s) { 40 | s.ext(result, bitsery::ext::InPlaceOptional()); 41 | } 42 | }; 43 | 44 | /** 45 | * Message struct for `clap_plugin_state::save()`. 46 | */ 47 | struct Save { 48 | using Response = SaveResponse; 49 | 50 | native_size_t instance_id; 51 | 52 | template 53 | void serialize(S& s) { 54 | s.value8b(instance_id); 55 | } 56 | }; 57 | 58 | /** 59 | * Message struct for `clap_plugin_state::load()`. 60 | */ 61 | struct Load { 62 | using Response = PrimitiveResponse; 63 | 64 | native_size_t instance_id; 65 | clap::stream::Stream stream; 66 | 67 | template 68 | void serialize(S& s) { 69 | s.value8b(instance_id); 70 | s.object(stream); 71 | } 72 | }; 73 | 74 | } // namespace plugin 75 | 76 | namespace host { 77 | 78 | /** 79 | * Message struct for `clap_host_state::mark_dirty()`. 80 | */ 81 | struct MarkDirty { 82 | using Response = Ack; 83 | 84 | native_size_t owner_instance_id; 85 | 86 | template 87 | void serialize(S& s) { 88 | s.value8b(owner_instance_id); 89 | } 90 | }; 91 | 92 | } // namespace host 93 | 94 | } // namespace state 95 | } // namespace ext 96 | } // namespace clap 97 | -------------------------------------------------------------------------------- /src/common/serialization/clap/ext/tail.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include "../../common.h" 22 | 23 | // Serialization messages for `clap/ext/tail.h` 24 | 25 | namespace clap { 26 | namespace ext { 27 | namespace tail { 28 | 29 | namespace plugin { 30 | 31 | /** 32 | * Message struct for `clap_plugin_tail::get()`. 33 | */ 34 | struct Get { 35 | using Response = PrimitiveResponse; 36 | 37 | native_size_t instance_id; 38 | 39 | template 40 | void serialize(S& s) { 41 | s.value8b(instance_id); 42 | } 43 | }; 44 | 45 | } // namespace plugin 46 | 47 | namespace host { 48 | 49 | /** 50 | * Message struct for `clap_host_tail::changed()`. 51 | */ 52 | struct Changed { 53 | using Response = Ack; 54 | 55 | native_size_t owner_instance_id; 56 | 57 | template 58 | void serialize(S& s) { 59 | s.value8b(owner_instance_id); 60 | } 61 | }; 62 | 63 | } // namespace host 64 | 65 | } // namespace tail 66 | } // namespace ext 67 | } // namespace clap 68 | -------------------------------------------------------------------------------- /src/common/serialization/clap/ext/voice-info.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include "../../common.h" 22 | 23 | // Serialization messages for `clap/ext/voice-info.h` 24 | 25 | namespace clap { 26 | namespace ext { 27 | namespace voice_info { 28 | 29 | namespace plugin { 30 | 31 | /** 32 | * The response to the `clap::ext::voice_info::plugin::Get` message defined 33 | * below. 34 | */ 35 | struct GetResponse { 36 | std::optional result; 37 | 38 | template 39 | void serialize(S& s) { 40 | s.ext(result, bitsery::ext::InPlaceOptional()); 41 | } 42 | }; 43 | 44 | /** 45 | * Message struct for `clap_plugin_voice_info::get()`. 46 | */ 47 | struct Get { 48 | using Response = GetResponse; 49 | 50 | native_size_t instance_id; 51 | 52 | template 53 | void serialize(S& s) { 54 | s.value8b(instance_id); 55 | } 56 | }; 57 | 58 | } // namespace plugin 59 | 60 | namespace host { 61 | 62 | /** 63 | * Message struct for `clap_host_voice_info::changed()`. 64 | */ 65 | struct Changed { 66 | using Response = Ack; 67 | 68 | native_size_t owner_instance_id; 69 | 70 | template 71 | void serialize(S& s) { 72 | s.value8b(owner_instance_id); 73 | } 74 | }; 75 | 76 | } // namespace host 77 | 78 | } // namespace voice_info 79 | } // namespace ext 80 | } // namespace clap 81 | 82 | template 83 | void serialize(S& s, clap_voice_info_t& info) { 84 | s.value4b(info.voice_count); 85 | s.value4b(info.voice_capacity); 86 | s.value8b(info.flags); 87 | } 88 | -------------------------------------------------------------------------------- /src/common/serialization/clap/host.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "host.h" 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | namespace clap { 32 | namespace host { 33 | 34 | Host::Host(const clap_host_t& original) 35 | : clap_version(original.clap_version), 36 | name((assert(original.name), original.name)), 37 | vendor(original.vendor ? std::optional(original.vendor) : std::nullopt), 38 | url(original.url ? std::optional(original.url) : std::nullopt), 39 | version((assert(original.version), original.version)) {} 40 | 41 | std::array, 11> SupportedHostExtensions::list() 42 | const noexcept { 43 | return {std::pair(supports_audio_ports, CLAP_EXT_AUDIO_PORTS), 44 | std::pair(supports_audio_ports_config, CLAP_EXT_AUDIO_PORTS_CONFIG), 45 | std::pair(supports_gui, CLAP_EXT_GUI), 46 | std::pair(supports_latency, CLAP_EXT_LATENCY), 47 | std::pair(supports_log, CLAP_EXT_LOG), 48 | std::pair(supports_note_name, CLAP_EXT_NOTE_NAME), 49 | std::pair(supports_note_ports, CLAP_EXT_NOTE_PORTS), 50 | std::pair(supports_params, CLAP_EXT_PARAMS), 51 | std::pair(supports_state, CLAP_EXT_STATE), 52 | std::pair(supports_tail, CLAP_EXT_TAIL), 53 | std::pair(supports_voice_info, CLAP_EXT_VOICE_INFO)}; 54 | } 55 | 56 | } // namespace host 57 | } // namespace clap 58 | -------------------------------------------------------------------------------- /src/common/serialization/clap/stream.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more destates. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | // Serialization messages for `clap/stream.h` 25 | 26 | namespace clap { 27 | namespace stream { 28 | 29 | /** 30 | * A serialization wrapper around streams that can be used as both a 31 | * `clap_istream_t` and a `clap_ostream_t`. 32 | */ 33 | class Stream { 34 | public: 35 | /** 36 | * Create an empty stream that can be written to by the plugin using 37 | * `ostream()`, and then written back to the host using 38 | * `write_to_ostream()`. 39 | */ 40 | Stream(); 41 | 42 | /** 43 | * Read a `clap_istream_t` from the host to a buffer. The results are 44 | * written to a buffer that can be serialized and send to the other side. 45 | */ 46 | Stream(const clap_istream_t& original); 47 | 48 | /** 49 | * The buffer's size in bytes, used for logging. 50 | */ 51 | inline size_t size() const noexcept { return buffer_.size(); } 52 | 53 | /** 54 | * Get a `clap_ostream_t` for this buffer that the plugin can write to. This 55 | * is only valid as long as this object is not moved. 56 | */ 57 | const clap_ostream_t* ostream(); 58 | /** 59 | * Get a `clap_istream_t` for this buffer that the plugin can read the 60 | * buffer from. This is only valid as long as this object is not moved. 61 | */ 62 | const clap_istream_t* istream(); 63 | 64 | /** 65 | * Write the entire buffer to a host provided `clap_ostream_t`. 66 | */ 67 | void write_to_stream(const clap_ostream_t& original) const; 68 | 69 | template 70 | void serialize(S& s) { 71 | s.container1b(buffer_, 50 << 20); 72 | } 73 | 74 | protected: 75 | static int64_t CLAP_ABI ostream_write(const struct clap_ostream* stream, 76 | const void* buffer, 77 | uint64_t size); 78 | 79 | static int64_t CLAP_ABI istream_read(const struct clap_istream* stream, 80 | void* buffer, 81 | uint64_t size); 82 | 83 | private: 84 | std::vector buffer_; 85 | 86 | /** 87 | * The current position in the buffer used in `istream_read()`. 88 | */ 89 | size_t read_pos_ = 0; 90 | 91 | // These are populated in the `ostream()` and `istream()` methods 92 | clap_ostream_t ostream_vtable_{}; 93 | clap_istream_t istream_vtable_{}; 94 | }; 95 | 96 | } // namespace stream 97 | } // namespace clap 98 | -------------------------------------------------------------------------------- /src/common/serialization/clap/version.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include 22 | 23 | /** 24 | * Return the minimum of the given CLAP version and the CLAP version currently 25 | * supported by the SDK. 26 | */ 27 | inline clap_version_t clamp_clap_version(clap_version_t version) { 28 | if (CLAP_VERSION_MAJOR < version.major || 29 | (version.major == CLAP_VERSION_MAJOR && 30 | (CLAP_VERSION_MINOR < version.minor || 31 | (version.minor == CLAP_VERSION_MINOR && 32 | CLAP_VERSION_REVISION < version.revision)))) { 33 | return CLAP_VERSION; 34 | } else { 35 | return version; 36 | } 37 | } 38 | 39 | template 40 | void serialize(S& s, clap_version_t& version) { 41 | s.value4b(version.major); 42 | s.value4b(version.minor); 43 | s.value4b(version.revision); 44 | } 45 | -------------------------------------------------------------------------------- /src/common/serialization/vst3-impls/context-menu-target.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include "../vst3/context-menu-target.h" 20 | 21 | /** 22 | * This implementation used to live in `src/plugin/bridges/vst3-impls`, but 23 | * since plugins can also call context menu items added by the host this is 24 | * needed on both sides. 25 | * 26 | * NOTE: Bitwig does not actually set the tags here, so host menu items need to 27 | * be identified through their item ID, not through the tag. 28 | */ 29 | template 30 | class YaContextMenuTargetImpl : public YaContextMenuTarget { 31 | public: 32 | YaContextMenuTargetImpl(Bridge& bridge, ConstructArgs&& args) noexcept 33 | : YaContextMenuTarget(std::move(args)), bridge_(bridge) {} 34 | 35 | /** 36 | * We'll override the query interface to log queries for interfaces we do 37 | * not (yet) support. 38 | */ 39 | tresult PLUGIN_API queryInterface(const Steinberg::TUID _iid, 40 | void** obj) override { 41 | const tresult result = YaContextMenuTarget::queryInterface(_iid, obj); 42 | bridge_.logger_.log_query_interface( 43 | "In IContextMenuTarget::queryInterface()", result, 44 | Steinberg::FUID::fromTUID(_iid)); 45 | 46 | return result; 47 | } 48 | 49 | // From `IContextMenuTarget` 50 | tresult PLUGIN_API executeMenuItem(int32 tag) override { 51 | // NOTE: This requires mutual recursion, because REAPER will call 52 | // `getState()` whle the context menu is open, and `getState()` 53 | // also has to be handled from the GUI thread 54 | return bridge_.send_mutually_recursive_message( 55 | YaContextMenuTarget::ExecuteMenuItem{ 56 | .owner_instance_id = owner_instance_id(), 57 | .context_menu_id = context_menu_id(), 58 | .item_id = item_id(), 59 | .target_tag = target_tag(), 60 | .tag = tag}); 61 | } 62 | 63 | private: 64 | Bridge& bridge_; 65 | }; 66 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/component-handler/component-handler-2.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "component-handler-2.h" 18 | 19 | YaComponentHandler2::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaComponentHandler2::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported( 24 | Steinberg::FUnknownPtr(object)) {} 25 | 26 | YaComponentHandler2::YaComponentHandler2(ConstructArgs&& args) noexcept 27 | : arguments_(std::move(args)) {} 28 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/component-handler/component-handler-3.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "component-handler-3.h" 18 | 19 | YaComponentHandler3::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaComponentHandler3::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported( 24 | Steinberg::FUnknownPtr(object)) {} 25 | 26 | YaComponentHandler3::YaComponentHandler3(ConstructArgs&& args) noexcept 27 | : arguments_(std::move(args)) {} 28 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/component-handler/component-handler-bus-activation.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "component-handler-bus-activation.h" 18 | 19 | YaComponentHandlerBusActivation::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaComponentHandlerBusActivation::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr< 24 | Steinberg::Vst::IComponentHandlerBusActivation>(object)) {} 25 | 26 | YaComponentHandlerBusActivation::YaComponentHandlerBusActivation( 27 | ConstructArgs&& args) noexcept 28 | : arguments_(std::move(args)) {} 29 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/component-handler/component-handler.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "component-handler.h" 18 | 19 | YaComponentHandler::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaComponentHandler::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported( 24 | Steinberg::FUnknownPtr(object)) {} 25 | 26 | YaComponentHandler::YaComponentHandler(ConstructArgs&& args) noexcept 27 | : arguments(std::move(args)) {} 28 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/component-handler/progress.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "progress.h" 18 | 19 | YaProgress::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaProgress::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr(object)) {} 24 | 25 | YaProgress::YaProgress(ConstructArgs&& args) noexcept 26 | : arguments_(std::move(args)) {} 27 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/component-handler/unit-handler-2.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "unit-handler-2.h" 18 | 19 | YaUnitHandler2::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaUnitHandler2::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr(object)) { 24 | } 25 | 26 | YaUnitHandler2::YaUnitHandler2(ConstructArgs&& args) noexcept 27 | : arguments_(std::move(args)) {} 28 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/component-handler/unit-handler-2.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include "../../common.h" 22 | #include "../base.h" 23 | 24 | #pragma GCC diagnostic push 25 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 26 | 27 | /** 28 | * Wraps around `IUnitHandler2` for serialization purposes. This is instantiated 29 | * as part of `Vst3ComponentHandlerProxy`. 30 | */ 31 | class YaUnitHandler2 : public Steinberg::Vst::IUnitHandler2 { 32 | public: 33 | /** 34 | * These are the arguments for creating a `YaUnitHandler2`. 35 | */ 36 | struct ConstructArgs { 37 | ConstructArgs() noexcept; 38 | 39 | /** 40 | * Check whether an existing implementation implements `IUnitHandler2` 41 | * and read arguments from it. 42 | */ 43 | ConstructArgs(Steinberg::IPtr object) noexcept; 44 | 45 | /** 46 | * Whether the object supported this interface. 47 | */ 48 | bool supported; 49 | 50 | template 51 | void serialize(S& s) { 52 | s.value1b(supported); 53 | } 54 | }; 55 | 56 | /** 57 | * Instantiate this instance with arguments read from another interface 58 | * implementation. 59 | */ 60 | YaUnitHandler2(ConstructArgs&& args) noexcept; 61 | 62 | virtual ~YaUnitHandler2() noexcept = default; 63 | 64 | inline bool supported() const noexcept { return arguments_.supported; } 65 | 66 | /** 67 | * Message to pass through a call to 68 | * `IUnitHandler2::notifyUnitByBusChange()` to the unit handler provided by 69 | * the host. 70 | */ 71 | struct NotifyUnitByBusChange { 72 | using Response = UniversalTResult; 73 | 74 | native_size_t owner_instance_id; 75 | 76 | template 77 | void serialize(S& s) { 78 | s.value8b(owner_instance_id); 79 | } 80 | }; 81 | 82 | virtual tresult PLUGIN_API notifyUnitByBusChange() override = 0; 83 | 84 | protected: 85 | ConstructArgs arguments_; 86 | }; 87 | 88 | #pragma GCC diagnostic pop 89 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/component-handler/unit-handler.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "unit-handler.h" 18 | 19 | YaUnitHandler::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaUnitHandler::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr(object)) {} 24 | 25 | YaUnitHandler::YaUnitHandler(ConstructArgs&& args) noexcept 26 | : arguments_(std::move(args)) {} 27 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/connection-point-proxy.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "connection-point-proxy.h" 18 | 19 | Vst3ConnectionPointProxy::Vst3ConnectionPointProxy( 20 | ConstructArgs&& args) noexcept 21 | : YaConnectionPoint(std::move(args.connection_point_args)), 22 | arguments_(std::move(args)){FUNKNOWN_CTOR} 23 | 24 | Vst3ConnectionPointProxy::~Vst3ConnectionPointProxy() noexcept { 25 | FUNKNOWN_DTOR} 26 | #pragma GCC diagnostic push 27 | #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" 28 | IMPLEMENT_REFCOUNT(Vst3ConnectionPointProxy) 29 | #pragma GCC diagnostic pop 30 | 31 | tresult PLUGIN_API Vst3ConnectionPointProxy::queryInterface( 32 | Steinberg::FIDString _iid, 33 | void** obj) { 34 | if (YaConnectionPoint::supported()) { 35 | QUERY_INTERFACE(_iid, obj, Steinberg::FUnknown::iid, 36 | Steinberg::Vst::IConnectionPoint) 37 | QUERY_INTERFACE(_iid, obj, Steinberg::Vst::IConnectionPoint::iid, 38 | Steinberg::Vst::IConnectionPoint) 39 | } 40 | 41 | *obj = nullptr; 42 | return Steinberg::kNoInterface; 43 | } 44 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/connection-point-proxy.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include "../common.h" 20 | #include "plugin/connection-point.h" 21 | 22 | #pragma GCC diagnostic push 23 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 24 | 25 | /** 26 | * This is only needed to...proxy a connection point proxy. Most hosts will 27 | * connect a plugin's processor and controller directly using 28 | * `IConnectionPoint::connect()`. But some hosts, like Ardour, will place a 29 | * proxy object between them that forwards calls to 30 | * `IConnectionPoint::notify()`. When objects are connected directly by the host 31 | * we can also connect them directly in the Wine plugin host, but when the host 32 | * uses proxies we'll also have to go through that proxy. The purpose of this 33 | * class is to provide a proxy for such a connection proxy. So when the plugin 34 | * calls `notify()` on an object of this class, then we will forward that call 35 | * to the `IConnectionPoint` proxy provided by the host, which will then in turn 36 | * call `IConnectionPoint::notify()` on the other object and we'll then forward 37 | * that message again to them Wine plugin host. 38 | */ 39 | class Vst3ConnectionPointProxy : public YaConnectionPoint { 40 | public: 41 | // We had to define this in `YaConnectionPoint` to work around circular 42 | // includes 43 | using ConstructArgs = 44 | YaConnectionPoint::Vst3ConnectionPointProxyConstructArgs; 45 | 46 | /** 47 | * Instantiate this instance with arguments read from an actual 48 | * `IConnectionPoint` object/proxy. 49 | * 50 | * @note This object will be created as part of handling 51 | * `IConnectionPoint::connect()` if the connection is indirect. 52 | */ 53 | Vst3ConnectionPointProxy(ConstructArgs&& args) noexcept; 54 | 55 | /** 56 | * This object will be destroyed again during 57 | * `IConnectionPoint::disconnect()`. 58 | */ 59 | virtual ~Vst3ConnectionPointProxy() noexcept; 60 | 61 | DECLARE_FUNKNOWN_METHODS 62 | 63 | /** 64 | * Get the instance ID of the owner of this object. 65 | */ 66 | inline size_t owner_instance_id() const noexcept { 67 | return arguments_.owner_instance_id; 68 | } 69 | 70 | private: 71 | ConstructArgs arguments_; 72 | }; 73 | 74 | #pragma GCC diagnostic pop 75 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/context-menu-proxy.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "context-menu-proxy.h" 18 | 19 | Vst3ContextMenuProxy::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | Vst3ContextMenuProxy::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object, 23 | size_t owner_instance_id, 24 | size_t context_menu_id) 25 | : owner_instance_id(owner_instance_id), 26 | context_menu_id(context_menu_id), 27 | context_menu_args(object) {} 28 | 29 | Vst3ContextMenuProxy::Vst3ContextMenuProxy(ConstructArgs&& args) noexcept 30 | : YaContextMenu(std::move(args.context_menu_args)), 31 | arguments_(std::move(args)){FUNKNOWN_CTOR} 32 | 33 | Vst3ContextMenuProxy::~Vst3ContextMenuProxy() noexcept {FUNKNOWN_DTOR} 34 | #pragma GCC diagnostic push 35 | #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" 36 | IMPLEMENT_REFCOUNT(Vst3ContextMenuProxy) 37 | #pragma GCC diagnostic pop 38 | 39 | tresult PLUGIN_API Vst3ContextMenuProxy::queryInterface( 40 | Steinberg::FIDString _iid, 41 | void** obj) { 42 | if (YaContextMenu::supported()) { 43 | QUERY_INTERFACE(_iid, obj, Steinberg::FUnknown::iid, 44 | Steinberg::Vst::IContextMenu) 45 | QUERY_INTERFACE(_iid, obj, Steinberg::Vst::IContextMenu::iid, 46 | Steinberg::Vst::IContextMenu) 47 | } 48 | 49 | *obj = nullptr; 50 | return Steinberg::kNoInterface; 51 | } 52 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/context-menu-target.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "context-menu-target.h" 18 | 19 | YaContextMenuTarget::YaContextMenuTarget(ConstructArgs&& args) noexcept 20 | : arguments_(std::move(args)){FUNKNOWN_CTOR} 21 | 22 | YaContextMenuTarget::~YaContextMenuTarget() noexcept {FUNKNOWN_DTOR} 23 | 24 | #pragma GCC diagnostic push 25 | #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" 26 | IMPLEMENT_FUNKNOWN_METHODS(YaContextMenuTarget, 27 | Steinberg::Vst::IContextMenuTarget, 28 | Steinberg::Vst::IContextMenuTarget::iid) 29 | #pragma GCC diagnostic pop 30 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/context-menu/context-menu.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "context-menu.h" 18 | 19 | YaContextMenu::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaContextMenu::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr(object)) { 24 | Steinberg::FUnknownPtr context_menu(object); 25 | if (context_menu) { 26 | // Can't trust plugins to check for null pointers, so we'll just always 27 | // pass something 28 | Steinberg::Vst::IContextMenuTarget* dummyTarget = nullptr; 29 | 30 | // Prepopulate the context menu with these targets 31 | // NOTE: Bitwig does not actually set the tags here, so host menu items 32 | // need to be identified through their item ID, not through the 33 | // tag 34 | items.resize(context_menu->getItemCount()); 35 | for (size_t i = 0; i < items.size(); i++) { 36 | context_menu->getItem(static_cast(i), items[i], 37 | &dummyTarget); 38 | } 39 | } 40 | } 41 | 42 | YaContextMenu::YaContextMenu(ConstructArgs&& args) noexcept 43 | : arguments_(std::move(args)) {} 44 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/host-context-proxy.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "host-context-proxy.h" 18 | 19 | Vst3HostContextProxy::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | Vst3HostContextProxy::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object, 23 | std::optional owner_instance_id) noexcept 24 | : owner_instance_id(owner_instance_id), 25 | host_application_args(object), 26 | plug_interface_support_args(object) {} 27 | 28 | Vst3HostContextProxy::Vst3HostContextProxy(ConstructArgs&& args) noexcept 29 | : YaHostApplication(std::move(args.host_application_args)), 30 | YaPlugInterfaceSupport(std::move(args.plug_interface_support_args)), 31 | arguments_(std::move(args)){FUNKNOWN_CTOR} 32 | 33 | Vst3HostContextProxy::~Vst3HostContextProxy() noexcept {FUNKNOWN_DTOR} 34 | #pragma GCC diagnostic push 35 | #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" 36 | IMPLEMENT_REFCOUNT(Vst3HostContextProxy) 37 | #pragma GCC diagnostic pop 38 | 39 | tresult PLUGIN_API Vst3HostContextProxy::queryInterface( 40 | Steinberg::FIDString _iid, 41 | void** obj) { 42 | if (YaHostApplication::supported()) { 43 | QUERY_INTERFACE(_iid, obj, Steinberg::FUnknown::iid, 44 | Steinberg::Vst::IHostApplication) 45 | QUERY_INTERFACE(_iid, obj, Steinberg::Vst::IHostApplication::iid, 46 | Steinberg::Vst::IHostApplication) 47 | } 48 | if (YaPlugInterfaceSupport::supported()) { 49 | QUERY_INTERFACE(_iid, obj, Steinberg::Vst::IPlugInterfaceSupport::iid, 50 | Steinberg::Vst::IPlugInterfaceSupport) 51 | } 52 | 53 | *obj = nullptr; 54 | return Steinberg::kNoInterface; 55 | } 56 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/host-context/host-application.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "host-application.h" 18 | 19 | YaHostApplication::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaHostApplication::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported( 24 | Steinberg::FUnknownPtr(object)) {} 25 | 26 | YaHostApplication::YaHostApplication(ConstructArgs&& args) noexcept 27 | : arguments_(std::move(args)) {} 28 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/host-context/plug-interface-support.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "plug-interface-support.h" 18 | 19 | YaPlugInterfaceSupport::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaPlugInterfaceSupport::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr( 24 | object)) {} 25 | 26 | YaPlugInterfaceSupport::YaPlugInterfaceSupport(ConstructArgs&& args) noexcept 27 | : arguments_(std::move(args)) {} 28 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/message.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "message.h" 18 | 19 | YaMessagePtr::YaMessagePtr() noexcept {FUNKNOWN_CTOR} 20 | 21 | YaMessagePtr::YaMessagePtr(IMessage& message) 22 | : message_id_(message.getMessageID() 23 | ? std::make_optional(message.getMessageID()) 24 | : std::nullopt), 25 | original_message_ptr_(static_cast( 26 | reinterpret_cast(&message))){FUNKNOWN_CTOR} 27 | 28 | YaMessagePtr::~YaMessagePtr() noexcept {FUNKNOWN_DTOR} 29 | #pragma GCC diagnostic push 30 | #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" 31 | IMPLEMENT_FUNKNOWN_METHODS(YaMessagePtr, 32 | Steinberg::Vst::IMessage, 33 | Steinberg::Vst::IMessage::iid) 34 | #pragma GCC diagnostic pop 35 | 36 | Steinberg::Vst::IMessage 37 | * YaMessagePtr::get_original() const noexcept { 38 | // See the docstrings on `YaMessage` and `YaMessagePtr` 39 | return reinterpret_cast( 40 | static_cast(original_message_ptr_)); 41 | } 42 | 43 | Steinberg::FIDString PLUGIN_API YaMessagePtr::getMessageID() { 44 | if (message_id_) { 45 | return message_id_->c_str(); 46 | } else { 47 | return nullptr; 48 | } 49 | } 50 | 51 | void PLUGIN_API YaMessagePtr::setMessageID(Steinberg::FIDString id /*in*/) { 52 | if (id) { 53 | message_id_ = id; 54 | } else { 55 | message_id_.reset(); 56 | } 57 | } 58 | 59 | Steinberg::Vst::IAttributeList* PLUGIN_API YaMessagePtr::getAttributes() { 60 | return &attribute_list_; 61 | } 62 | 63 | YaMessage::YaMessage() noexcept {FUNKNOWN_CTOR} 64 | 65 | YaMessage::~YaMessage() noexcept {FUNKNOWN_DTOR} 66 | #pragma GCC diagnostic push 67 | #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" 68 | IMPLEMENT_FUNKNOWN_METHODS(YaMessage, 69 | Steinberg::Vst::IMessage, 70 | Steinberg::Vst::IMessage::iid) 71 | #pragma GCC diagnostic pop 72 | 73 | Steinberg::FIDString PLUGIN_API YaMessage::getMessageID() { 74 | if (message_id_) { 75 | return message_id_->c_str(); 76 | } else { 77 | return nullptr; 78 | } 79 | } 80 | 81 | void PLUGIN_API YaMessage::setMessageID(Steinberg::FIDString id /*in*/) { 82 | if (id) { 83 | message_id_ = id; 84 | } else { 85 | message_id_.reset(); 86 | } 87 | } 88 | 89 | Steinberg::Vst::IAttributeList* PLUGIN_API YaMessage::getAttributes() { 90 | return &attribute_list_; 91 | } 92 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/parameter-changes.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "parameter-changes.h" 18 | 19 | YaParameterChanges::YaParameterChanges() noexcept {FUNKNOWN_CTOR} 20 | 21 | YaParameterChanges::~YaParameterChanges() noexcept { 22 | FUNKNOWN_DTOR 23 | } 24 | 25 | void YaParameterChanges::clear() noexcept { 26 | queues_.clear(); 27 | } 28 | 29 | void YaParameterChanges::repopulate( 30 | Steinberg::Vst::IParameterChanges& original_queues) { 31 | // Copy over all parameter change queues 32 | const size_t num_queues = original_queues.getParameterCount(); 33 | queues_.resize(num_queues); 34 | for (size_t i = 0; i < num_queues; i++) { 35 | queues_[i].repopulate( 36 | *original_queues.getParameterData(static_cast(i))); 37 | } 38 | } 39 | 40 | #pragma GCC diagnostic push 41 | #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" 42 | IMPLEMENT_FUNKNOWN_METHODS(YaParameterChanges, 43 | Steinberg::Vst::IParameterChanges, 44 | Steinberg::Vst::IParameterChanges::iid) 45 | #pragma GCC diagnostic pop 46 | 47 | size_t YaParameterChanges::num_parameters() const { 48 | return queues_.size(); 49 | } 50 | 51 | void YaParameterChanges::write_back_outputs( 52 | Steinberg::Vst::IParameterChanges& output_queues) const { 53 | for (auto& queue : queues_) { 54 | // We don't need this, but the SDK requires us to need this 55 | int32 output_queue_index; 56 | if (Steinberg::Vst::IParamValueQueue* output_queue = 57 | output_queues.addParameterData(queue.parameter_id_, 58 | output_queue_index)) { 59 | queue.write_back_outputs(*output_queue); 60 | } 61 | } 62 | } 63 | 64 | int32 PLUGIN_API YaParameterChanges::getParameterCount() { 65 | return static_cast(queues_.size()); 66 | } 67 | 68 | Steinberg::Vst::IParamValueQueue* PLUGIN_API 69 | YaParameterChanges::getParameterData(int32 index) { 70 | if (index < static_cast(queues_.size())) { 71 | return &queues_[index]; 72 | } else { 73 | return nullptr; 74 | } 75 | } 76 | 77 | Steinberg::Vst::IParamValueQueue* PLUGIN_API 78 | YaParameterChanges::addParameterData(const Steinberg::Vst::ParamID& id, 79 | int32& index /*out*/) { 80 | index = static_cast(queues_.size()); 81 | 82 | // Tiny hack, resizing avoids calling the constructor the second time we 83 | // resize the vector to the same size 84 | queues_.resize(queues_.size() + 1); 85 | queues_[index].clear_for_parameter(id); 86 | 87 | return &queues_[index]; 88 | } 89 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/parameter-changes.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | #include "../../bitsery/traits/small-vector.h" 23 | #include "base.h" 24 | #include "param-value-queue.h" 25 | 26 | #pragma GCC diagnostic push 27 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 28 | 29 | /** 30 | * Wraps around `IParameterChanges` for serialization purposes. Used in 31 | * `YaProcessData`. 32 | */ 33 | class YaParameterChanges : public Steinberg::Vst::IParameterChanges { 34 | public: 35 | /** 36 | * We only provide a default constructor here, because we need to fill the 37 | * existing object with new data every processing cycle to avoid 38 | * reallocating a new object every time. 39 | */ 40 | YaParameterChanges() noexcept; 41 | 42 | virtual ~YaParameterChanges() noexcept; 43 | 44 | /** 45 | * Remove all parameter changes. Used when a null pointer gets passed to the 46 | * input parameters field, and so the plugin can output its own parameter 47 | * changes. 48 | */ 49 | void clear() noexcept; 50 | 51 | /** 52 | * Read data from an `IParameterChanges` object into this existing object. 53 | */ 54 | void repopulate(Steinberg::Vst::IParameterChanges& original_queues); 55 | 56 | DECLARE_FUNKNOWN_METHODS 57 | 58 | /** 59 | * Return the number of parameter we have parameter change queues for. Used 60 | * in debug logs. 61 | */ 62 | size_t num_parameters() const; 63 | 64 | /** 65 | * Write these changes back to an output parameter changes queue on the 66 | * `ProcessData` object provided by the host. 67 | */ 68 | void write_back_outputs( 69 | Steinberg::Vst::IParameterChanges& output_queues) const; 70 | 71 | // From `IParameterChanges` 72 | int32 PLUGIN_API getParameterCount() override; 73 | Steinberg::Vst::IParamValueQueue* PLUGIN_API 74 | getParameterData(int32 index) override; 75 | Steinberg::Vst::IParamValueQueue* PLUGIN_API 76 | addParameterData(const Steinberg::Vst::ParamID& id, 77 | int32& index /*out*/) override; 78 | 79 | template 80 | void serialize(S& s) { 81 | s.container(queues_, 1 << 16); 82 | } 83 | 84 | private: 85 | /** 86 | * The parameter value changes queues. 87 | */ 88 | llvm::SmallVector queues_; 89 | }; 90 | 91 | #pragma GCC diagnostic pop 92 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/physical-ui-map-list.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "physical-ui-map-list.h" 18 | 19 | #include 20 | 21 | YaPhysicalUIMapList::YaPhysicalUIMapList() noexcept {} 22 | 23 | YaPhysicalUIMapList::YaPhysicalUIMapList( 24 | const Steinberg::Vst::PhysicalUIMapList& list) noexcept 25 | : maps_(list.map, list.map + list.count) {} 26 | 27 | Steinberg::Vst::PhysicalUIMapList YaPhysicalUIMapList::get() noexcept { 28 | return Steinberg::Vst::PhysicalUIMapList{ 29 | .count = static_cast(maps_.size()), 30 | .map = maps_.data()}; 31 | } 32 | 33 | void YaPhysicalUIMapList::write_back( 34 | Steinberg::Vst::PhysicalUIMapList& list) const { 35 | assert(list.count == maps_.size()); 36 | 37 | // Write the note expression IDs as updated by the plugin (if the plugin 38 | // updated them) back to the original list we've read from 39 | for (Steinberg::uint32 i = 0; i < list.count; i++) { 40 | list.map[i].noteExpressionTypeID = maps_[i].noteExpressionTypeID; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/physical-ui-map-list.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include 22 | 23 | /** 24 | * Serialization wrapper around `PhysicalUIMapList` that allows loading such a 25 | * list and writing the changes made by the plugin back to the original list. 26 | * The host provides a list with the `physicalUITypeID` field set for each 27 | * mapping, and the plugin then sets the `noteExpressionTypeID` to one of its 28 | * note expression of it can handle it. 29 | */ 30 | class YaPhysicalUIMapList { 31 | public: 32 | YaPhysicalUIMapList() noexcept; 33 | 34 | /** 35 | * Copy the data from a `PhysicalUIMapList` so it can be serialized. 36 | */ 37 | YaPhysicalUIMapList(const Steinberg::Vst::PhysicalUIMapList& list) noexcept; 38 | 39 | /** 40 | * Reconstruct the original `PhysicalUIMapList` object passed to the 41 | * constructor and return it. This is used to handle 42 | * `INoteExpressionPhysicalUIMapping::getPhysicalUIMapping()` on the Wine 43 | * plugin host side. The returned object is valid as long as this object is 44 | * alive. 45 | */ 46 | Steinberg::Vst::PhysicalUIMapList get() noexcept; 47 | 48 | /** 49 | * Write the `noteExpressionTypeID` values stored in `maps` back to the 50 | * original physical UI mapping list we copied `maps` from. 51 | */ 52 | void write_back(Steinberg::Vst::PhysicalUIMapList& list) const; 53 | 54 | template 55 | void serialize(S& s) { 56 | s.container(maps_, 1 << 31); 57 | } 58 | 59 | std::vector maps_; 60 | }; 61 | 62 | namespace Steinberg { 63 | namespace Vst { 64 | template 65 | void serialize(S& s, PhysicalUIMap map) { 66 | s.value4b(map.physicalUITypeID); 67 | s.value4b(map.noteExpressionTypeID); 68 | } 69 | } // namespace Vst 70 | } // namespace Steinberg 71 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plug-frame-proxy.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "plug-frame-proxy.h" 18 | 19 | Vst3PlugFrameProxy::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | Vst3PlugFrameProxy::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object, 23 | size_t owner_instance_id) noexcept 24 | : owner_instance_id(owner_instance_id), plug_frame_args(object) {} 25 | 26 | Vst3PlugFrameProxy::Vst3PlugFrameProxy(ConstructArgs&& args) noexcept 27 | : YaPlugFrame(std::move(args.plug_frame_args)), 28 | arguments_(std::move(args)){FUNKNOWN_CTOR} 29 | 30 | Vst3PlugFrameProxy::~Vst3PlugFrameProxy() noexcept {FUNKNOWN_DTOR} 31 | #pragma GCC diagnostic push 32 | #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" 33 | IMPLEMENT_REFCOUNT(Vst3PlugFrameProxy) 34 | #pragma GCC diagnostic pop 35 | 36 | tresult PLUGIN_API Vst3PlugFrameProxy::queryInterface( 37 | Steinberg::FIDString _iid, 38 | void** obj) { 39 | if (YaPlugFrame::supported()) { 40 | QUERY_INTERFACE(_iid, obj, Steinberg::FUnknown::iid, 41 | Steinberg::IPlugFrame) 42 | QUERY_INTERFACE(_iid, obj, Steinberg::IPlugFrame::iid, 43 | Steinberg::IPlugFrame) 44 | } 45 | 46 | *obj = nullptr; 47 | return Steinberg::kNoInterface; 48 | } 49 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plug-frame/plug-frame.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "plug-frame.h" 18 | 19 | YaPlugFrame::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaPlugFrame::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr(object)) {} 24 | 25 | YaPlugFrame::YaPlugFrame(ConstructArgs&& args) noexcept 26 | : arguments_(std::move(args)) {} 27 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plug-frame/plug-frame.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include "../../common.h" 22 | #include "../base.h" 23 | 24 | #pragma GCC diagnostic push 25 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 26 | 27 | /** 28 | * Wraps around `IPlugFrame` for serialization purposes. This is instantiated as 29 | * part of `Vst3PlugFrameProxy`. 30 | */ 31 | class YaPlugFrame : public Steinberg::IPlugFrame { 32 | public: 33 | /** 34 | * These are the arguments for creating a `YaPlugFrame`. 35 | */ 36 | struct ConstructArgs { 37 | ConstructArgs() noexcept; 38 | 39 | /** 40 | * Check whether an existing implementation implements `IPlugFrame` and 41 | * read arguments from it. 42 | */ 43 | ConstructArgs(Steinberg::IPtr object) noexcept; 44 | 45 | /** 46 | * Whether the object supported this interface. 47 | */ 48 | bool supported; 49 | 50 | template 51 | void serialize(S& s) { 52 | s.value1b(supported); 53 | } 54 | }; 55 | 56 | /** 57 | * Instantiate this instance with arguments read from another interface 58 | * implementation. 59 | */ 60 | YaPlugFrame(ConstructArgs&& args) noexcept; 61 | 62 | virtual ~YaPlugFrame() noexcept = default; 63 | 64 | inline bool supported() const noexcept { return arguments_.supported; } 65 | 66 | /** 67 | * Message to pass through a call to `IPlugFrame::resizeView(, 68 | * new_size)` to the `IPlugView` object provided by the host. 69 | * 70 | * XXX: Since we don't support multiple `IPlugView`s right now (as it's not 71 | * used the SDK's current version), we'll just assume that `view` is 72 | * the view stored in `Vst3PluginProxyImpl::plug_view` 73 | */ 74 | struct ResizeView { 75 | using Response = UniversalTResult; 76 | 77 | native_size_t owner_instance_id; 78 | 79 | Steinberg::ViewRect new_size; 80 | 81 | template 82 | void serialize(S& s) { 83 | s.value8b(owner_instance_id); 84 | s.object(new_size); 85 | } 86 | }; 87 | 88 | virtual tresult PLUGIN_API 89 | resizeView(Steinberg::IPlugView* view, 90 | Steinberg::ViewRect* newSize) override = 0; 91 | 92 | protected: 93 | ConstructArgs arguments_; 94 | }; 95 | 96 | #pragma GCC diagnostic pop 97 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plug-view-proxy.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "plug-view-proxy.h" 18 | 19 | Vst3PlugViewProxy::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | Vst3PlugViewProxy::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object, 23 | size_t owner_instance_id) noexcept 24 | : owner_instance_id(owner_instance_id), 25 | plug_view_args(object), 26 | parameter_finder_args(object), 27 | plug_view_content_scale_support_args(object) {} 28 | 29 | Vst3PlugViewProxy::Vst3PlugViewProxy(ConstructArgs&& args) noexcept 30 | : YaPlugView(std::move(args.plug_view_args)), 31 | YaParameterFinder(std::move(args.parameter_finder_args)), 32 | YaPlugViewContentScaleSupport( 33 | std::move(args.plug_view_content_scale_support_args)), 34 | arguments_(std::move(args)){FUNKNOWN_CTOR} 35 | 36 | Vst3PlugViewProxy::~Vst3PlugViewProxy() noexcept {FUNKNOWN_DTOR} 37 | #pragma GCC diagnostic push 38 | #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" 39 | IMPLEMENT_REFCOUNT(Vst3PlugViewProxy) 40 | #pragma GCC diagnostic pop 41 | 42 | tresult PLUGIN_API Vst3PlugViewProxy::queryInterface( 43 | Steinberg::FIDString _iid, 44 | void** obj) { 45 | if (YaPlugView::supported()) { 46 | QUERY_INTERFACE(_iid, obj, Steinberg::FUnknown::iid, 47 | Steinberg::IPlugView) 48 | QUERY_INTERFACE(_iid, obj, Steinberg::IPlugView::iid, 49 | Steinberg::IPlugView) 50 | } 51 | if (YaParameterFinder::supported()) { 52 | QUERY_INTERFACE(_iid, obj, Steinberg::Vst::IParameterFinder::iid, 53 | Steinberg::Vst::IParameterFinder) 54 | } 55 | if (YaPlugViewContentScaleSupport::supported()) { 56 | QUERY_INTERFACE(_iid, obj, Steinberg::IPlugViewContentScaleSupport::iid, 57 | Steinberg::IPlugViewContentScaleSupport) 58 | } 59 | 60 | *obj = nullptr; 61 | return Steinberg::kNoInterface; 62 | } 63 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plug-view/parameter-finder.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "parameter-finder.h" 18 | 19 | YaParameterFinder::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaParameterFinder::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported( 24 | Steinberg::FUnknownPtr(object)) {} 25 | 26 | YaParameterFinder::YaParameterFinder(ConstructArgs&& args) noexcept 27 | : arguments_(std::move(args)) {} 28 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plug-view/plug-view-content-scale-support.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "plug-view-content-scale-support.h" 18 | 19 | YaPlugViewContentScaleSupport::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaPlugViewContentScaleSupport::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr( 24 | object)) {} 25 | 26 | YaPlugViewContentScaleSupport::YaPlugViewContentScaleSupport( 27 | ConstructArgs&& args) noexcept 28 | : arguments_(std::move(args)) {} 29 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plug-view/plug-view-content-scale-support.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include "../../common.h" 22 | #include "../base.h" 23 | 24 | #pragma GCC diagnostic push 25 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 26 | 27 | /** 28 | * Wraps around `IPlugViewContentScaleSupport` for serialization purposes. This 29 | * is instantiated as part of `Vst3PlugViewProxy`. 30 | */ 31 | class YaPlugViewContentScaleSupport 32 | : public Steinberg::IPlugViewContentScaleSupport { 33 | public: 34 | /** 35 | * These are the arguments for creating a `YaPlugViewContentScaleSupport`. 36 | */ 37 | struct ConstructArgs { 38 | ConstructArgs() noexcept; 39 | 40 | /** 41 | * Check whether an existing implementation implements 42 | * `IPlugViewContentScaleSupport` and read arguments from it. 43 | */ 44 | ConstructArgs(Steinberg::IPtr object) noexcept; 45 | 46 | /** 47 | * Whether the object supported this interface. 48 | */ 49 | bool supported; 50 | 51 | template 52 | void serialize(S& s) { 53 | s.value1b(supported); 54 | } 55 | }; 56 | 57 | /** 58 | * Instantiate this instance with arguments read from another interface 59 | * implementation. 60 | */ 61 | YaPlugViewContentScaleSupport(ConstructArgs&& args) noexcept; 62 | 63 | virtual ~YaPlugViewContentScaleSupport() noexcept = default; 64 | 65 | inline bool supported() const noexcept { return arguments_.supported; } 66 | 67 | /** 68 | * Message to pass through a call to 69 | * `IPlugViewContentScaleSupport::setContentScaleFactor(factor)` to the Wine 70 | * plugin host. 71 | */ 72 | struct SetContentScaleFactor { 73 | using Response = UniversalTResult; 74 | 75 | native_size_t owner_instance_id; 76 | 77 | ScaleFactor factor; 78 | 79 | template 80 | void serialize(S& s) { 81 | s.value8b(owner_instance_id); 82 | s.value4b(factor); 83 | } 84 | }; 85 | 86 | virtual tresult PLUGIN_API 87 | setContentScaleFactor(ScaleFactor factor) override = 0; 88 | 89 | protected: 90 | ConstructArgs arguments_; 91 | }; 92 | 93 | #pragma GCC diagnostic pop 94 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plug-view/plug-view.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "plug-view.h" 18 | 19 | YaPlugView::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaPlugView::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr(object)) {} 24 | 25 | YaPlugView::YaPlugView(ConstructArgs&& args) noexcept 26 | : arguments_(std::move(args)) {} 27 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin-factory-proxy.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "plugin-factory-proxy.h" 18 | 19 | Vst3PluginFactoryProxy::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | Vst3PluginFactoryProxy::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : plugin_factory_args(object) {} 24 | 25 | Vst3PluginFactoryProxy::Vst3PluginFactoryProxy(ConstructArgs&& args) noexcept 26 | : YaPluginFactory3(std::move(args.plugin_factory_args)), 27 | arguments_(std::move(args)){FUNKNOWN_CTOR} 28 | 29 | // clang-format just doesn't understand these macros, I guess 30 | Vst3PluginFactoryProxy::~Vst3PluginFactoryProxy() noexcept {FUNKNOWN_DTOR} 31 | #pragma GCC diagnostic push 32 | #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" 33 | IMPLEMENT_REFCOUNT(Vst3PluginFactoryProxy) 34 | #pragma GCC diagnostic pop 35 | 36 | tresult PLUGIN_API Vst3PluginFactoryProxy::queryInterface( 37 | Steinberg::FIDString _iid, 38 | void** obj) { 39 | if (YaPluginFactory3::supports_plugin_factory()) { 40 | QUERY_INTERFACE(_iid, obj, Steinberg::FUnknown::iid, 41 | Steinberg::IPluginFactory) 42 | QUERY_INTERFACE(_iid, obj, Steinberg::IPluginFactory::iid, 43 | Steinberg::IPluginFactory) 44 | } 45 | if (YaPluginFactory3::supports_plugin_factory_2()) { 46 | QUERY_INTERFACE(_iid, obj, Steinberg::IPluginFactory2::iid, 47 | Steinberg::IPluginFactory2) 48 | } 49 | if (YaPluginFactory3::supports_plugin_factory_3()) { 50 | QUERY_INTERFACE(_iid, obj, Steinberg::IPluginFactory3::iid, 51 | Steinberg::IPluginFactory3) 52 | } 53 | 54 | *obj = nullptr; 55 | return Steinberg::kNoInterface; 56 | } 57 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin-factory-proxy.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include "../common.h" 20 | #include "plugin-factory/plugin-factory.h" 21 | 22 | #pragma GCC diagnostic push 23 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 24 | 25 | /** 26 | * An abstract class that `IPluginFactory`, and optionally also 27 | * `IPluginFactory2` and `IPluginFactory3` depending on what the Windows VST3 28 | * plugin's plugin factory supports. All information is read once the Wine 29 | * plugin host side, so the only callbacks that we'll make from here are to 30 | * create new objects and to set a host context for the factory (if the host and 31 | * the plugin supports that). 32 | */ 33 | class Vst3PluginFactoryProxy : public YaPluginFactory3 { 34 | public: 35 | /** 36 | * These are the arguments for constructing a `Vst3PluginFactoryProxyImpl`. 37 | */ 38 | struct ConstructArgs { 39 | ConstructArgs() noexcept; 40 | 41 | /** 42 | * Read from an existing object. We will try to mimic this object, so 43 | * we'll support any interfaces this object also supports. 44 | */ 45 | ConstructArgs(Steinberg::IPtr object) noexcept; 46 | 47 | YaPluginFactory3::ConstructArgs plugin_factory_args; 48 | 49 | template 50 | void serialize(S& s) { 51 | s.object(plugin_factory_args); 52 | } 53 | }; 54 | 55 | /** 56 | * Message to request the Windows VST3 plugin's plugin factory information 57 | * from the Wine plugin host. 58 | */ 59 | struct Construct { 60 | using Response = ConstructArgs; 61 | 62 | template 63 | void serialize(S&) {} 64 | }; 65 | 66 | /** 67 | * Instantiate this instance with arguments read from an actual plugin 68 | * factory. The is done once during startup and the plugin factory gets 69 | * reused for the lifetime of the module. 70 | */ 71 | Vst3PluginFactoryProxy(ConstructArgs&& args) noexcept; 72 | 73 | /** 74 | * We do not need special handling here since the Window VST3 plugin's 75 | * plugin factory will also be destroyed when we terminate the Wine plugin 76 | * host or unload the plugin there. 77 | */ 78 | virtual ~Vst3PluginFactoryProxy() noexcept; 79 | 80 | DECLARE_FUNKNOWN_METHODS 81 | 82 | private: 83 | ConstructArgs arguments_; 84 | }; 85 | 86 | #pragma GCC diagnostic pop 87 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/audio-presentation-latency.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "audio-presentation-latency.h" 18 | 19 | YaAudioPresentationLatency::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaAudioPresentationLatency::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported( 24 | Steinberg::FUnknownPtr( 25 | object)) {} 26 | 27 | YaAudioPresentationLatency::YaAudioPresentationLatency( 28 | ConstructArgs&& args) noexcept 29 | : arguments_(std::move(args)) {} 30 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/audio-processor.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "audio-processor.h" 18 | 19 | YaAudioProcessor::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaAudioProcessor::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported( 24 | Steinberg::FUnknownPtr(object)) {} 25 | 26 | YaAudioProcessor::YaAudioProcessor(ConstructArgs&& args) noexcept 27 | : arguments_(std::move(args)) {} 28 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/automation-state.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "automation-state.h" 18 | 19 | YaAutomationState::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaAutomationState::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported( 24 | Steinberg::FUnknownPtr(object)) {} 25 | 26 | YaAutomationState::YaAutomationState(ConstructArgs&& args) noexcept 27 | : arguments_(std::move(args)) {} 28 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/automation-state.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | // Great! They forgot an include in `ivstautomationstate.h` 20 | #include 21 | 22 | #include 23 | 24 | #include "../../common.h" 25 | #include "../base.h" 26 | 27 | #pragma GCC diagnostic push 28 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 29 | 30 | /** 31 | * Wraps around `IAutomationState` for serialization purposes. This is 32 | * instantiated as part of `Vst3PluginProxy`. 33 | */ 34 | class YaAutomationState : public Steinberg::Vst::IAutomationState { 35 | public: 36 | /** 37 | * These are the arguments for creating a `YaAutomationState`. 38 | */ 39 | struct ConstructArgs { 40 | ConstructArgs() noexcept; 41 | 42 | /** 43 | * Check whether an existing implementation implements 44 | * `IAutomationState` and read arguments from it. 45 | */ 46 | ConstructArgs(Steinberg::IPtr object) noexcept; 47 | 48 | /** 49 | * Whether the object supported this interface. 50 | */ 51 | bool supported; 52 | 53 | template 54 | void serialize(S& s) { 55 | s.value1b(supported); 56 | } 57 | }; 58 | 59 | /** 60 | * Instantiate this instance with arguments read from another interface 61 | * implementation. 62 | */ 63 | YaAutomationState(ConstructArgs&& args) noexcept; 64 | 65 | virtual ~YaAutomationState() noexcept = default; 66 | 67 | inline bool supported() const noexcept { return arguments_.supported; } 68 | 69 | /** 70 | * Message to pass through a call to 71 | * `IAutomationState::setAutomationState(state)` to the Wine plugin host. 72 | */ 73 | struct SetAutomationState { 74 | using Response = UniversalTResult; 75 | 76 | native_size_t instance_id; 77 | 78 | int32 state; 79 | 80 | template 81 | void serialize(S& s) { 82 | s.value8b(instance_id); 83 | s.value4b(state); 84 | } 85 | }; 86 | 87 | virtual tresult PLUGIN_API setAutomationState(int32 state) override = 0; 88 | 89 | protected: 90 | ConstructArgs arguments_; 91 | }; 92 | 93 | #pragma GCC diagnostic pop 94 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/component.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "component.h" 18 | 19 | YaComponent::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaComponent::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr(object)) {} 24 | 25 | YaComponent::YaComponent(ConstructArgs&& args) noexcept 26 | : arguments_(std::move(args)) {} 27 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/connection-point.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "connection-point.h" 18 | 19 | YaConnectionPoint::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaConnectionPoint::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported( 24 | Steinberg::FUnknownPtr(object)) {} 25 | 26 | YaConnectionPoint::Vst3ConnectionPointProxyConstructArgs:: 27 | Vst3ConnectionPointProxyConstructArgs() noexcept {} 28 | 29 | YaConnectionPoint::Vst3ConnectionPointProxyConstructArgs:: 30 | Vst3ConnectionPointProxyConstructArgs( 31 | Steinberg::IPtr object, 32 | size_t owner_instance_id) noexcept 33 | : owner_instance_id(owner_instance_id), connection_point_args(object) {} 34 | 35 | YaConnectionPoint::YaConnectionPoint(ConstructArgs&& args) noexcept 36 | : arguments_(std::move(args)) {} 37 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/edit-controller-2.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "edit-controller-2.h" 18 | 19 | YaEditController2::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaEditController2::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported( 24 | Steinberg::FUnknownPtr(object)) {} 25 | 26 | YaEditController2::YaEditController2(ConstructArgs&& args) noexcept 27 | : arguments_(std::move(args)) {} 28 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/edit-controller-host-editing.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "edit-controller-host-editing.h" 18 | 19 | YaEditControllerHostEditing::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaEditControllerHostEditing::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported( 24 | Steinberg::FUnknownPtr( 25 | object)) {} 26 | 27 | YaEditControllerHostEditing::YaEditControllerHostEditing( 28 | ConstructArgs&& args) noexcept 29 | : arguments_(std::move(args)) {} 30 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/edit-controller.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "edit-controller.h" 18 | 19 | YaEditController::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaEditController::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported( 24 | Steinberg::FUnknownPtr(object)) {} 25 | 26 | YaEditController::YaEditController(ConstructArgs&& args) noexcept 27 | : arguments_(std::move(args)) {} 28 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/info-listener.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "info-listener.h" 18 | 19 | YaInfoListener::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaInfoListener::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported( 24 | Steinberg::FUnknownPtr( 25 | object)) {} 26 | 27 | YaInfoListener::YaInfoListener(ConstructArgs&& args) noexcept 28 | : arguments_(std::move(args)) {} 29 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/info-listener.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include "../../common.h" 22 | #include "../attribute-list.h" 23 | #include "../base.h" 24 | 25 | #pragma GCC diagnostic push 26 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 27 | 28 | /** 29 | * Wraps around `IInfoListener` for serialization purposes. This is instantiated 30 | * as part of `Vst3PluginProxy`. 31 | */ 32 | class YaInfoListener : public Steinberg::Vst::ChannelContext::IInfoListener { 33 | public: 34 | /** 35 | * These are the arguments for creating a `YaInfoListener`. 36 | */ 37 | struct ConstructArgs { 38 | ConstructArgs() noexcept; 39 | 40 | /** 41 | * Check whether an existing implementation implements `IInfoListener` 42 | * and read arguments from it. 43 | */ 44 | ConstructArgs(Steinberg::IPtr object) noexcept; 45 | 46 | /** 47 | * Whether the object supported this interface. 48 | */ 49 | bool supported; 50 | 51 | template 52 | void serialize(S& s) { 53 | s.value1b(supported); 54 | } 55 | }; 56 | 57 | /** 58 | * Instantiate this instance with arguments read from another interface 59 | * implementation. 60 | */ 61 | YaInfoListener(ConstructArgs&& args) noexcept; 62 | 63 | virtual ~YaInfoListener() noexcept = default; 64 | 65 | inline bool supported() const noexcept { return arguments_.supported; } 66 | 67 | /** 68 | * Message to pass through a call to 69 | * `IInfoListeener::setChannelContextInfos(list)` to the Wine plugin host. 70 | */ 71 | struct SetChannelContextInfos { 72 | using Response = UniversalTResult; 73 | 74 | native_size_t instance_id; 75 | 76 | /** 77 | * The passed channel context attributes, read using 78 | * `YaAttributeList::read_channel_context()`. 79 | */ 80 | YaAttributeList list; 81 | 82 | template 83 | void serialize(S& s) { 84 | s.value8b(instance_id); 85 | s.object(list); 86 | } 87 | }; 88 | 89 | virtual tresult PLUGIN_API 90 | setChannelContextInfos(Steinberg::Vst::IAttributeList* list) override = 0; 91 | 92 | protected: 93 | ConstructArgs arguments_; 94 | }; 95 | 96 | #pragma GCC diagnostic pop 97 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/keyswitch-controller.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "keyswitch-controller.h" 18 | 19 | YaKeyswitchController::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaKeyswitchController::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr( 24 | object)) {} 25 | 26 | YaKeyswitchController::YaKeyswitchController(ConstructArgs&& args) noexcept 27 | : arguments_(std::move(args)) {} 28 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/midi-learn.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "midi-learn.h" 18 | 19 | YaMidiLearn::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaMidiLearn::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr(object)) {} 24 | 25 | YaMidiLearn::YaMidiLearn(ConstructArgs&& args) noexcept 26 | : arguments_(std::move(args)) {} 27 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/midi-learn.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include "../../common.h" 22 | #include "../base.h" 23 | 24 | #pragma GCC diagnostic push 25 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 26 | 27 | /** 28 | * Wraps around `IMidiLearn` for serialization purposes. This is instantiated as 29 | * part of `Vst3PluginProxy`. 30 | */ 31 | class YaMidiLearn : public Steinberg::Vst::IMidiLearn { 32 | public: 33 | /** 34 | * These are the arguments for creating a `YaMidiLearn`. 35 | */ 36 | struct ConstructArgs { 37 | ConstructArgs() noexcept; 38 | 39 | /** 40 | * Check whether an existing implementation implements `IMidiLearn` 41 | * and read arguments from it. 42 | */ 43 | ConstructArgs(Steinberg::IPtr object) noexcept; 44 | 45 | /** 46 | * Whether the object supported this interface. 47 | */ 48 | bool supported; 49 | 50 | template 51 | void serialize(S& s) { 52 | s.value1b(supported); 53 | } 54 | }; 55 | 56 | /** 57 | * Instantiate this instance with arguments read from another interface 58 | * implementation. 59 | */ 60 | YaMidiLearn(ConstructArgs&& args) noexcept; 61 | 62 | virtual ~YaMidiLearn() noexcept = default; 63 | 64 | inline bool supported() const noexcept { return arguments_.supported; } 65 | 66 | /** 67 | * Message to pass through a call to 68 | * `IMidiLearn::onLiveMIDIControllerInput(bus_index, channel, midi_cc)` to 69 | * the Wine plugin host. 70 | */ 71 | struct OnLiveMIDIControllerInput { 72 | using Response = UniversalTResult; 73 | 74 | native_size_t instance_id; 75 | 76 | int32 bus_index; 77 | int16 channel; 78 | Steinberg::Vst::CtrlNumber midi_cc; 79 | 80 | template 81 | void serialize(S& s) { 82 | s.value8b(instance_id); 83 | s.value4b(bus_index); 84 | s.value2b(channel); 85 | s.value2b(midi_cc); 86 | } 87 | }; 88 | 89 | virtual tresult PLUGIN_API 90 | onLiveMIDIControllerInput(int32 busIndex, 91 | int16 channel, 92 | Steinberg::Vst::CtrlNumber midiCC) override = 0; 93 | 94 | protected: 95 | ConstructArgs arguments_; 96 | }; 97 | 98 | #pragma GCC diagnostic pop 99 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/midi-mapping.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "midi-mapping.h" 18 | 19 | YaMidiMapping::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaMidiMapping::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr(object)) {} 24 | 25 | YaMidiMapping::YaMidiMapping(ConstructArgs&& args) noexcept 26 | : arguments_(std::move(args)) {} 27 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/note-expression-controller.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "note-expression-controller.h" 18 | 19 | YaNoteExpressionController::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaNoteExpressionController::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported( 24 | Steinberg::FUnknownPtr( 25 | object)) {} 26 | 27 | YaNoteExpressionController::YaNoteExpressionController( 28 | ConstructArgs&& args) noexcept 29 | : arguments_(std::move(args)) {} 30 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/note-expression-physical-ui-mapping.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "note-expression-physical-ui-mapping.h" 18 | 19 | YaNoteExpressionPhysicalUIMapping::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaNoteExpressionPhysicalUIMapping::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr< 24 | Steinberg::Vst::INoteExpressionPhysicalUIMapping>(object)) {} 25 | 26 | YaNoteExpressionPhysicalUIMapping::YaNoteExpressionPhysicalUIMapping( 27 | ConstructArgs&& args) noexcept 28 | : arguments_(std::move(args)) {} 29 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/parameter-function-name.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "parameter-function-name.h" 18 | 19 | YaParameterFunctionName::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaParameterFunctionName::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr( 24 | object)) {} 25 | 26 | YaParameterFunctionName::YaParameterFunctionName(ConstructArgs&& args) noexcept 27 | : arguments_(std::move(args)) {} 28 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/plugin-base.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "plugin-base.h" 18 | 19 | YaPluginBase::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaPluginBase::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr(object)) {} 24 | 25 | YaPluginBase::YaPluginBase(ConstructArgs&& args) noexcept 26 | : arguments_(std::move(args)) {} 27 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/plugin-base.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include "../../common.h" 22 | #include "../base.h" 23 | #include "../host-context-proxy.h" 24 | 25 | #pragma GCC diagnostic push 26 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 27 | 28 | /** 29 | * Wraps around `IPluginBase` for serialization purposes. Both components and 30 | * edit controllers inherit from this. This is instantiated as part of 31 | * `Vst3PluginProxy`. 32 | */ 33 | class YaPluginBase : public Steinberg::IPluginBase { 34 | public: 35 | /** 36 | * These are the arguments for creating a `YaPluginBase`. 37 | */ 38 | struct ConstructArgs { 39 | ConstructArgs() noexcept; 40 | 41 | /** 42 | * Check whether an existing implementation implements `IPluginBase` and 43 | * read arguments from it. 44 | */ 45 | ConstructArgs(Steinberg::IPtr object) noexcept; 46 | 47 | /** 48 | * Whether the object supported this interface. 49 | */ 50 | bool supported; 51 | 52 | template 53 | void serialize(S& s) { 54 | s.value1b(supported); 55 | } 56 | }; 57 | 58 | /** 59 | * Instantiate this instance with arguments read from another interface 60 | * implementation. 61 | */ 62 | YaPluginBase(ConstructArgs&& args) noexcept; 63 | 64 | virtual ~YaPluginBase() noexcept = default; 65 | 66 | inline bool supported() const noexcept { return arguments_.supported; } 67 | 68 | // The request and response for `IPluginBase::initialize()` is defined 69 | // within `Vst3PluginProxy` because it (thanks to Waves) requires all 70 | // supported interfaces to be queried again 71 | virtual tresult PLUGIN_API initialize(FUnknown* context) override = 0; 72 | 73 | /** 74 | * Message to pass through a call to `IPluginBase::terminate()` to the Wine 75 | * plugin host. 76 | */ 77 | struct Terminate { 78 | using Response = UniversalTResult; 79 | 80 | native_size_t instance_id; 81 | 82 | template 83 | void serialize(S& s) { 84 | s.value8b(instance_id); 85 | } 86 | }; 87 | 88 | virtual tresult PLUGIN_API terminate() override = 0; 89 | 90 | protected: 91 | ConstructArgs arguments_; 92 | }; 93 | 94 | #pragma GCC diagnostic pop 95 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/prefetchable-support.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "prefetchable-support.h" 18 | 19 | YaPrefetchableSupport::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaPrefetchableSupport::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr( 24 | object)) {} 25 | 26 | YaPrefetchableSupport::YaPrefetchableSupport(ConstructArgs&& args) noexcept 27 | : arguments_(std::move(args)) {} 28 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/process-context-requirements.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "process-context-requirements.h" 18 | 19 | YaProcessContextRequirements::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaProcessContextRequirements::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported( 24 | Steinberg::FUnknownPtr( 25 | object)) {} 26 | 27 | YaProcessContextRequirements::YaProcessContextRequirements( 28 | ConstructArgs&& args) noexcept 29 | : arguments_(std::move(args)) {} 30 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/process-context-requirements.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include "../../common.h" 22 | #include "../base.h" 23 | #include "../host-context-proxy.h" 24 | 25 | #pragma GCC diagnostic push 26 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 27 | 28 | /** 29 | * Wraps around `IProcessContextRequirements` for serialization purposes. Both 30 | * components and edit controllers inherit from this. This is instantiated as 31 | * part of `Vst3PluginProxy`. 32 | */ 33 | class YaProcessContextRequirements 34 | : public Steinberg::Vst::IProcessContextRequirements { 35 | public: 36 | /** 37 | * These are the arguments for creating a `YaProcessContextRequirements`. 38 | */ 39 | struct ConstructArgs { 40 | ConstructArgs() noexcept; 41 | 42 | /** 43 | * Check whether an existing implementation implements 44 | * `IProcessContextRequirements` and read arguments from it. 45 | */ 46 | ConstructArgs(Steinberg::IPtr object) noexcept; 47 | 48 | /** 49 | * Whether the object supported this interface. 50 | */ 51 | bool supported; 52 | 53 | template 54 | void serialize(S& s) { 55 | s.value1b(supported); 56 | } 57 | }; 58 | 59 | /** 60 | * Instantiate this instance with arguments read from another interface 61 | * implementation. 62 | */ 63 | YaProcessContextRequirements(ConstructArgs&& args) noexcept; 64 | 65 | virtual ~YaProcessContextRequirements() noexcept = default; 66 | 67 | inline bool supported() const noexcept { return arguments_.supported; } 68 | 69 | /** 70 | * Message to pass through a call to 71 | * `IProcessContextRequirements::getProcessContextRequirements()` to the 72 | * Wine plugin host. 73 | */ 74 | struct GetProcessContextRequirements { 75 | using Response = PrimitiveResponse; 76 | 77 | native_size_t instance_id; 78 | 79 | template 80 | void serialize(S& s) { 81 | s.value8b(instance_id); 82 | } 83 | }; 84 | 85 | virtual uint32 PLUGIN_API getProcessContextRequirements() override = 0; 86 | 87 | protected: 88 | ConstructArgs arguments_; 89 | }; 90 | 91 | #pragma GCC diagnostic pop 92 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/program-list-data.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "program-list-data.h" 18 | 19 | YaProgramListData::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaProgramListData::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported( 24 | Steinberg::FUnknownPtr(object)) {} 25 | 26 | YaProgramListData::YaProgramListData(ConstructArgs&& args) noexcept 27 | : arguments_(std::move(args)) {} 28 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/unit-data.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "unit-data.h" 18 | 19 | YaUnitData::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaUnitData::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr(object)) {} 24 | 25 | YaUnitData::YaUnitData(ConstructArgs&& args) noexcept 26 | : arguments_(std::move(args)) {} 27 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/unit-info.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "unit-info.h" 18 | 19 | YaUnitInfo::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaUnitInfo::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported(Steinberg::FUnknownPtr(object)) {} 24 | 25 | YaUnitInfo::YaUnitInfo(ConstructArgs&& args) noexcept 26 | : arguments_(std::move(args)) {} 27 | -------------------------------------------------------------------------------- /src/common/serialization/vst3/plugin/xml-representation-controller.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "xml-representation-controller.h" 18 | 19 | YaXmlRepresentationController::ConstructArgs::ConstructArgs() noexcept {} 20 | 21 | YaXmlRepresentationController::ConstructArgs::ConstructArgs( 22 | Steinberg::IPtr object) noexcept 23 | : supported( 24 | Steinberg::FUnknownPtr( 25 | object)) {} 26 | 27 | YaXmlRepresentationController::YaXmlRepresentationController( 28 | ConstructArgs&& args) noexcept 29 | : arguments_(std::move(args)) {} 30 | -------------------------------------------------------------------------------- /src/common/toml++.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | // Helper header for including toml++ in a way that works on both native Linux 18 | // as well as with Winelib compilation 19 | 20 | // By default tomlplusplus is no longer headers when using the package config 21 | // file. We don't want to link against third party shared libraries in yabridge. 22 | #ifdef TOML_SHARED_LIB 23 | 24 | #undef TOML_SHARED_LIB 25 | #undef TOML_HEADER_ONLY 26 | #define TOML_HEADER_ONLY 1 27 | 28 | #endif 29 | 30 | // tomlplusplus recently got some Windows fixes, but they cause compilation 31 | // errors and we don't need them so we'll just disable them outright. Disabling 32 | // `TOML_ENABLE_WINDOWS_COMPAT` is no longer enough, and you can't disable 33 | // `TOML_WINDOWS` directly. This is the same trick used in `use-asio-linux.h`. 34 | #pragma push_macro("WIN32") 35 | #pragma push_macro("_WIN32") 36 | #pragma push_macro("__WIN32__") 37 | #pragma push_macro("__NT__") 38 | #pragma push_macro("__CYGWIN__") 39 | #undef WIN32 40 | #undef _WIN32 41 | #undef __WIN32__ 42 | #undef __NT__ 43 | #undef __CYGWIN__ 44 | 45 | #include 46 | 47 | #pragma pop_macro("WIN32") 48 | #pragma pop_macro("_WIN32") 49 | #pragma pop_macro("__WIN32__") 50 | #pragma pop_macro("__NT__") 51 | #pragma pop_macro("__CYGWIN__") 52 | -------------------------------------------------------------------------------- /src/plugin/bridges/clap-impls/plugin-factory-proxy.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "../../common/serialization/clap/plugin.h" 24 | 25 | // Forward declaration to avoid circular includes 26 | class ClapPluginBridge; 27 | 28 | /** 29 | * A proxy for a plugin's `clap_plugin_factory`. 30 | */ 31 | class clap_plugin_factory_proxy { 32 | public: 33 | /** 34 | * The vtable for `clap_plugin_factory`, requires that this object is never 35 | * moved or copied. This is positioned at the start of the struct so we can 36 | * cast between them (with only a bit of UB). 37 | * 38 | * NOTE: CLAP does not provide a user pointer field for this vtable like it 39 | * does with other types because it expects the factory to be a 40 | * statically initialized singleton. That's why we need to do this 41 | * cast instead. 42 | */ 43 | const clap_plugin_factory_t plugin_factory_vtable; 44 | 45 | /** 46 | * Construct the plugin factory proxy based on the plugin descriptors 47 | * retrieved from a `clap::factory::plugin_factory::ListReponse`. 48 | */ 49 | clap_plugin_factory_proxy( 50 | ClapPluginBridge& bridge, 51 | std::vector descriptors); 52 | 53 | clap_plugin_factory_proxy(const clap_plugin_factory_proxy&) = delete; 54 | clap_plugin_factory_proxy& operator=(const clap_plugin_factory_proxy&) = 55 | delete; 56 | clap_plugin_factory_proxy(clap_plugin_factory_proxy&&) = delete; 57 | clap_plugin_factory_proxy& operator=(clap_plugin_factory_proxy&&) = delete; 58 | 59 | static uint32_t CLAP_ABI 60 | plugin_factory_get_plugin_count(const struct clap_plugin_factory* factory); 61 | static const clap_plugin_descriptor_t* CLAP_ABI 62 | plugin_factory_get_plugin_descriptor( 63 | const struct clap_plugin_factory* factory, 64 | uint32_t index); 65 | static const clap_plugin_t* CLAP_ABI 66 | plugin_factory_create_plugin(const struct clap_plugin_factory* factory, 67 | const clap_host_t* host, 68 | const char* plugin_id); 69 | 70 | private: 71 | ClapPluginBridge& bridge_; 72 | 73 | std::vector descriptors_; 74 | }; 75 | -------------------------------------------------------------------------------- /src/plugin/bridges/vst3-impls/plugin-factory-proxy.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include "../../../common/serialization/vst3/plugin-factory-proxy.h" 20 | 21 | // We need an `IPtr` in `Vst3PluginBridge`, so we 22 | // need to declare this slightly differently to avoid circular includes. 23 | class Vst3PluginBridge; 24 | 25 | class Vst3PluginFactoryProxyImpl : public Vst3PluginFactoryProxy { 26 | public: 27 | Vst3PluginFactoryProxyImpl( 28 | Vst3PluginBridge& bridge, 29 | Vst3PluginFactoryProxy::ConstructArgs&& args) noexcept; 30 | 31 | /** 32 | * We'll override the query interface to log queries for interfaces we do 33 | * not (yet) support. 34 | */ 35 | tresult PLUGIN_API queryInterface(const Steinberg::TUID _iid, 36 | void** obj) override; 37 | 38 | tresult PLUGIN_API createInstance(Steinberg::FIDString cid, 39 | Steinberg::FIDString _iid, 40 | void** obj) override; 41 | tresult PLUGIN_API setHostContext(Steinberg::FUnknown* context) override; 42 | 43 | // The following pointers are cast from `host_context` if 44 | // `IPluginFactory3::setHostContext()` has been called 45 | 46 | Steinberg::FUnknownPtr host_application_; 47 | Steinberg::FUnknownPtr 48 | plug_interface_support_; 49 | 50 | private: 51 | Vst3PluginBridge& bridge_; 52 | 53 | /** 54 | * An host context if we get passed one through 55 | * `IPluginFactory3::setHostContext()`. 56 | */ 57 | Steinberg::IPtr host_context_; 58 | }; 59 | -------------------------------------------------------------------------------- /src/wine-host/bridges/vst3-impls/connection-point-proxy.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "connection-point-proxy.h" 18 | 19 | #include 20 | 21 | Vst3ConnectionPointProxyImpl::Vst3ConnectionPointProxyImpl( 22 | Vst3Bridge& bridge, 23 | Vst3ConnectionPointProxy::ConstructArgs&& args) noexcept 24 | : Vst3ConnectionPointProxy(std::move(args)), bridge_(bridge) {} 25 | 26 | tresult PLUGIN_API 27 | Vst3ConnectionPointProxyImpl::queryInterface(const Steinberg::TUID _iid, 28 | void** obj) { 29 | const tresult result = Vst3ConnectionPointProxy::queryInterface(_iid, obj); 30 | bridge_.logger_.log_query_interface("In IConnectionPoint::queryInterface()", 31 | result, 32 | Steinberg::FUID::fromTUID(_iid)); 33 | 34 | return result; 35 | } 36 | 37 | tresult PLUGIN_API 38 | Vst3ConnectionPointProxyImpl::connect(IConnectionPoint* /*other*/) { 39 | std::cerr << "WARNING: The plugin called IConnectionPoint::connect(), this " 40 | "should not happen" 41 | << std::endl; 42 | return Steinberg::kNotImplemented; 43 | } 44 | 45 | tresult PLUGIN_API 46 | Vst3ConnectionPointProxyImpl::disconnect(IConnectionPoint* /*other*/) { 47 | std::cerr << "WARNING: The plugin called IConnectionPoint::disconnect(), " 48 | "this should not happen" 49 | << std::endl; 50 | return Steinberg::kNotImplemented; 51 | } 52 | 53 | tresult PLUGIN_API 54 | Vst3ConnectionPointProxyImpl::notify(Steinberg::Vst::IMessage* message) { 55 | if (message) { 56 | // FabFilter plugins require this to be done from the GUI thread so we 57 | // need to use our mutual recursion mechanism. Luckily only Ardour uses 58 | // connection proxies, so if this ends up breaking something it will 59 | // only affect Ardour. 60 | return bridge_.send_mutually_recursive_message( 61 | YaConnectionPoint::Notify{.instance_id = owner_instance_id(), 62 | .message_ptr = YaMessagePtr(*message)}); 63 | } else { 64 | std::cerr << "WARNING: Null pointer passed to " 65 | "'IConnectionPoint::notify()', ignoring" 66 | << std::endl; 67 | return Steinberg::kInvalidArgument; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/wine-host/bridges/vst3-impls/connection-point-proxy.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include "../vst3.h" 20 | 21 | class Vst3ConnectionPointProxyImpl : public Vst3ConnectionPointProxy { 22 | public: 23 | Vst3ConnectionPointProxyImpl( 24 | Vst3Bridge& bridge, 25 | Vst3ConnectionPointProxy::ConstructArgs&& args) noexcept; 26 | 27 | /** 28 | * We'll override the query interface to log queries for interfaces we do 29 | * not (yet) support. 30 | */ 31 | tresult PLUGIN_API queryInterface(const Steinberg::TUID _iid, 32 | void** obj) override; 33 | 34 | // From `IConnectionPoint` 35 | tresult PLUGIN_API connect(IConnectionPoint* other) override; 36 | tresult PLUGIN_API disconnect(IConnectionPoint* other) override; 37 | tresult PLUGIN_API notify(Steinberg::Vst::IMessage* message) override; 38 | 39 | private: 40 | Vst3Bridge& bridge_; 41 | }; 42 | -------------------------------------------------------------------------------- /src/wine-host/bridges/vst3-impls/host-context-proxy.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include "../vst3.h" 20 | 21 | class Vst3HostContextProxyImpl : public Vst3HostContextProxy { 22 | public: 23 | Vst3HostContextProxyImpl( 24 | Vst3Bridge& bridge, 25 | Vst3HostContextProxy::ConstructArgs&& args) noexcept; 26 | 27 | /** 28 | * We'll override the query interface to log queries for interfaces we do 29 | * not (yet) support. 30 | */ 31 | tresult PLUGIN_API queryInterface(const Steinberg::TUID _iid, 32 | void** obj) override; 33 | 34 | // From `IHostApplication` 35 | tresult PLUGIN_API getName(Steinberg::Vst::String128 name) override; 36 | tresult PLUGIN_API createInstance(Steinberg::TUID cid, 37 | Steinberg::TUID _iid, 38 | void** obj) override; 39 | 40 | // From `IPlugInterfaceSupport` 41 | tresult PLUGIN_API 42 | isPlugInterfaceSupported(const Steinberg::TUID _iid) override; 43 | 44 | private: 45 | Vst3Bridge& bridge_; 46 | }; 47 | -------------------------------------------------------------------------------- /src/wine-host/bridges/vst3-impls/plug-frame-proxy.cpp: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #include "plug-frame-proxy.h" 18 | 19 | #include 20 | 21 | Vst3PlugFrameProxyImpl::Vst3PlugFrameProxyImpl( 22 | Vst3Bridge& bridge, 23 | Vst3PlugFrameProxy::ConstructArgs&& args) noexcept 24 | : Vst3PlugFrameProxy(std::move(args)), bridge_(bridge) { 25 | // The lifecycle of this object is managed together with that of the plugin 26 | // object instance this host context got passed to 27 | } 28 | 29 | tresult PLUGIN_API 30 | Vst3PlugFrameProxyImpl::queryInterface(const Steinberg::TUID _iid, void** obj) { 31 | const tresult result = Vst3PlugFrameProxy::queryInterface(_iid, obj); 32 | bridge_.logger_.log_query_interface("In IPlugFrame::queryInterface()", 33 | result, 34 | Steinberg::FUID::fromTUID(_iid)); 35 | 36 | return result; 37 | } 38 | 39 | tresult PLUGIN_API 40 | Vst3PlugFrameProxyImpl::resizeView(Steinberg::IPlugView* /*view*/, 41 | Steinberg::ViewRect* newSize) { 42 | if (newSize) { 43 | // XXX: Since VST3 currently only support a single view type we'll 44 | // assume `view` is the `IPlugView*` returned by the last call to 45 | // `IEditController::createView()` 46 | 47 | // Resize the editor wrapper window in advance. We will do another 48 | // resize automatically on `IPlugView::onSize()`, but this should make 49 | // resizes look a bit smoother. 50 | bridge_.resize_editor(owner_instance_id(), *newSize); 51 | 52 | // We have to use this special sending function here so we can handle 53 | // calls to `IPlugView::onSize()` from this same thread (the UI thread). 54 | // See the docstring for more information. 55 | return bridge_.send_mutually_recursive_message(YaPlugFrame::ResizeView{ 56 | .owner_instance_id = owner_instance_id(), .new_size = *newSize}); 57 | } else { 58 | std::cerr 59 | << "WARNING: Null pointer passed to 'IPlugFrame::resizeView()'" 60 | << std::endl; 61 | return Steinberg::kInvalidArgument; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/wine-host/bridges/vst3-impls/plug-frame-proxy.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | #include "../vst3.h" 20 | 21 | class Vst3PlugFrameProxyImpl : public Vst3PlugFrameProxy { 22 | public: 23 | Vst3PlugFrameProxyImpl(Vst3Bridge& bridge, 24 | Vst3PlugFrameProxy::ConstructArgs&& args) noexcept; 25 | 26 | /** 27 | * We'll override the query interface to log queries for interfaces we do 28 | * not (yet) support. 29 | */ 30 | tresult PLUGIN_API queryInterface(const Steinberg::TUID _iid, 31 | void** obj) override; 32 | 33 | // From `IPlugFrame` 34 | tresult PLUGIN_API resizeView(Steinberg::IPlugView* view, 35 | Steinberg::ViewRect* newSize) override; 36 | 37 | private: 38 | Vst3Bridge& bridge_; 39 | }; 40 | -------------------------------------------------------------------------------- /src/wine-host/use-linux-asio.h: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | #pragma once 18 | 19 | // Libraries like (Boost.)Asio think we're compiling on Windows or using a MSVC 20 | // toolchain. This will cause them to make incorrect assumptions which platform 21 | // specific features are available. The only way around this I could think of 22 | // was to just temporarily undefine the macros these libraries use to detect 23 | // it's running under a WIN32 environment. If anyone knows a better way to do 24 | // this, please let me know! 25 | 26 | #pragma push_macro("WIN32") 27 | #pragma push_macro("_WIN32") 28 | #pragma push_macro("__WIN32__") 29 | #pragma push_macro("_WIN64") 30 | 31 | #undef WIN32 32 | #undef _WIN32 33 | #undef __WIN32__ 34 | #undef _WIN64 35 | 36 | // This would be the minimal include needed to get Asio to work. The commented 37 | // out includes are the actual header that would cause compile errors if not 38 | // included here, but including headers from the detail directory directly 39 | // didn't sound like a great idea. 40 | 41 | #include 42 | // #include 43 | 44 | #pragma pop_macro("WIN32") 45 | #pragma pop_macro("_WIN32") 46 | #pragma pop_macro("__WIN32__") 47 | #pragma pop_macro("_WIN64") 48 | -------------------------------------------------------------------------------- /subprojects/.gitignore: -------------------------------------------------------------------------------- 1 | /*/* 2 | 3 | # The above pattern doesn't match submodules 4 | /asio 5 | /bitsery 6 | /clap 7 | /function2 8 | /ghc_filesystem 9 | /tomlplusplus 10 | /vst3 11 | 12 | # And we obviously don't want to ignore our overlays 13 | !/packagefiles/asio 14 | !/packagefiles/bitsery 15 | !/packagefiles/clap 16 | !/packagefiles/function2 17 | !/packagefiles/ghc_filesystem 18 | !/function2-patch/* 19 | -------------------------------------------------------------------------------- /subprojects/asio.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/chriskohlhoff/asio.git 3 | # This is tag asio-1-34-2 4 | revision = ed6aa8a13d51dfc6c00ae453fc9fb7df5d6ea963 5 | depth = 1 6 | patch_directory = asio 7 | 8 | [provide] 9 | asio = asio_dep 10 | -------------------------------------------------------------------------------- /subprojects/bitsery.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/fraillt/bitsery.git 3 | # This is tag v5.2.3 4 | revision = d1a47e06e2104b195a19c73b61f1d5c1dceaa228 5 | depth = 1 6 | patch_directory = bitsery 7 | 8 | [provide] 9 | bitsery = bitsery_dep 10 | -------------------------------------------------------------------------------- /subprojects/clap.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/free-audio/clap.git 3 | # This is tag 1.1.9 4 | revision = 094bb76c85366a13cc6c49292226d8608d6ae50c 5 | depth = 1 6 | patch_directory = clap 7 | 8 | [provide] 9 | clap = clap_dep 10 | -------------------------------------------------------------------------------- /subprojects/function2.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/Naios/function2.git 3 | # Tag 4.2.3 4 | revision = 9e303865d14f1204f09379e37bbeb30c4375139a 5 | depth = 1 6 | patch_directory = function2 7 | 8 | [provide] 9 | function2 = function2_dep 10 | -------------------------------------------------------------------------------- /subprojects/ghc_filesystem.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/gulrak/filesystem.git 3 | # This is tag v1.5.14 4 | revision = 8a2edd6d92ed820521d42c94d179462bf06b5ed3 5 | depth = 1 6 | patch_directory = ghc_filesystem 7 | 8 | [provide] 9 | ghc_filesystem = ghc_filesystem_dep 10 | -------------------------------------------------------------------------------- /subprojects/packagefiles/asio/meson.build: -------------------------------------------------------------------------------- 1 | project('asio', 'cpp', version : '1.28.2') 2 | 3 | asio_dep = declare_dependency(include_directories : include_directories('asio/include')) 4 | -------------------------------------------------------------------------------- /subprojects/packagefiles/bitsery/meson.build: -------------------------------------------------------------------------------- 1 | project('bitsery', 'cpp', version : '5.2.3') 2 | 3 | bitsery_dep = declare_dependency(include_directories : include_directories('include')) 4 | -------------------------------------------------------------------------------- /subprojects/packagefiles/clap/meson.build: -------------------------------------------------------------------------------- 1 | project('clap', 'cpp', version : '1.1.9') 2 | 3 | clap_dep = declare_dependency(include_directories : include_directories('include')) 4 | -------------------------------------------------------------------------------- /subprojects/packagefiles/function2/meson.build: -------------------------------------------------------------------------------- 1 | project('function2', 'cpp', version : '4.2.3') 2 | 3 | function2_dep = declare_dependency(include_directories : include_directories('include')) 4 | -------------------------------------------------------------------------------- /subprojects/packagefiles/ghc_filesystem/meson.build: -------------------------------------------------------------------------------- 1 | project('ghc_filesystem', 'cpp', version : '1.5.14') 2 | 3 | ghc_filesystem_dep = declare_dependency(include_directories : include_directories('include')) 4 | -------------------------------------------------------------------------------- /subprojects/tomlplusplus.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/marzer/tomlplusplus.git 3 | # Tag v3.4.0 4 | revision = 30172438cee64926dc41fdd9c11fb3ba5b2ba9de 5 | depth = 1 6 | 7 | [provide] 8 | tomlplusplus = tomlplusplus_dep 9 | -------------------------------------------------------------------------------- /subprojects/vst3.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/robbert-vdh/vst3sdk.git 3 | # This is VST3 SDK v3.7.7_build_19 with the documentation and VSTGUI submodules 4 | # removed and a dummy `meson.build` file that just lists all source files 5 | revision = v3.7.7_build_19-patched 6 | clone-recursive = true 7 | depth = 1 8 | -------------------------------------------------------------------------------- /tools/migration/README.md: -------------------------------------------------------------------------------- 1 | # VST3 plugin class ID migration 2 | 3 | As someone pointed out, the development version of yabridge's VST3 support was 4 | not compatible with projects containing VST3 plugins saved on Windows. As it 5 | turned out, the class IDs VST3 plugins use to identify themselves with have a 6 | different format on Windows than they do on Linux. As of commit 7 | [1b804bd5ea4485cb204e40d476ef54801b1ecb38](https://github.com/robbert-vdh/yabridge/commit/1b804bd5ea4485cb204e40d476ef54801b1ecb38) 8 | yabridge converts between those formats for cross-platform compatibilty, but 9 | this does mean that containing VST3 plugins running through yabridge saved 10 | before that commit will no longer be compatible. As a temporary migration path, 11 | there are a few scripts here that you can use to convert old project files to 12 | the new format. 13 | 14 | These scripts won't overwrite any existing files, but remember to always make 15 | more backups than you really need! 16 | 17 | To use these, download the migration scripts for the DAWs you need to migrate an 18 | old project file for and run them. You'll get on screen instructions with what 19 | to do after that. 20 | 21 | ## Ardour 22 | 23 | ```shell 24 | # First download the script 25 | curl -o migrate-ardour.py https://raw.githubusercontent.com/robbert-vdh/yabridge/master/tools/migration/migrate-ardour.py 26 | chmod +x migrate-ardour.py 27 | 28 | # And then run it on any old .ardour files, the script will guide you through the 29 | # migration process 30 | ./migrate-ardour.py /path/to/some/project/project.ardour 31 | ``` 32 | 33 | ## Bitwig Studio 34 | 35 | ```shell 36 | # First download the script 37 | curl -o migrate-bitwig.py https://raw.githubusercontent.com/robbert-vdh/yabridge/master/tools/migration/migrate-bitwig.py 38 | chmod +x migrate-bitwig.py 39 | 40 | # And then run it on any old .bwproject files, the script will guide you through 41 | # the migration process 42 | ./migrate-bitwig.py /path/to/some/project/project.bwproject 43 | ``` 44 | 45 | ## REAPER 46 | 47 | ```shell 48 | # First download the script 49 | curl -o migrate-reaper.py https://raw.githubusercontent.com/robbert-vdh/yabridge/master/tools/migration/migrate-reaper.py 50 | chmod +x migrate-reaper.py 51 | 52 | # And then run it on any old .RPP files, the script will guide you through the 53 | # migration process 54 | ./migrate-reaper.py /path/to/some/project.RPP 55 | ``` 56 | 57 | ## Renoise 58 | 59 | ```shell 60 | # First download the script 61 | curl -o migrate-renoise.py https://raw.githubusercontent.com/robbert-vdh/yabridge/master/tools/migration/migrate-renoise.py 62 | chmod +x migrate-renoise.py 63 | 64 | # And then run it on any old .xrns files, the script will guide you through the 65 | # migration process 66 | ./migrate-renoise.py /path/to/some/project.xrns 67 | ``` 68 | -------------------------------------------------------------------------------- /tools/patch-vst3-sdk.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Patch the VST3 SDK and replace all MSVC-isms so it can be compiled with 4 | # winegcc. We do it this way instead of modifying the SDK directly so we don't 5 | # have to fork multiple repositories and keep them up to date. 6 | # If anyone knows a better way to get the SDK to compile with Win32 supports 7 | # under winegcc without having to modify it then please let me know, because I'd 8 | # rather not have to do this. 9 | # 10 | # Usage: 11 | # patch-vst3-sdk.sh [sdk_version] 12 | 13 | set -euo pipefail 14 | 15 | sdk_directory=$1 16 | version=${2:-} 17 | if [[ ! -d $sdk_directory ]]; then 18 | echo >&2 "Usage:" 19 | echo >&2 "patch-vst3-sdk.sh [sdk_version]" 20 | echo >&2 21 | echo >&2 "The version is parsed from the from the CMakeLists.txt file if omitted." 22 | exit 1 23 | fi 24 | 25 | if [[ -z $version ]]; then 26 | # `-z` is a quick way to search across multiple lines in case they format 27 | # future versions differently, and the combination of `-n`, `p`, and replacing 28 | # everything before and after the version causes this to print nothing if the 29 | # replacement didn't succeed 30 | version=$(sed -zn 's/.*project(vstsdk\s*VERSION \([0-9.]\+\).*/\1/ p' "$sdk_directory/CMakeLists.txt") 31 | fi 32 | 33 | if [[ -z $version ]]; then 34 | echo >&2 "Could not parse the VST3 SDK version from '$sdk_directory/CMakeLists.txt'" 35 | exit 1 36 | fi 37 | 38 | patch_file=$(dirname "$0")/vst3-sdk-patches/vst3-sdk-patch-$version.diff 39 | if [[ ! -f $patch_file ]]; then 40 | echo >&2 "The patch file for this SDK version ('$patch_file') does not yet exist" 41 | exit 1 42 | fi 43 | 44 | # Patch either automatically reverses already applied patches, or throws errors 45 | # when the patch has already been applied and you tell it to not reverse 46 | # patches. So we'll check whether the patch has already been applied first. 47 | if ! patch -d "$sdk_directory" -p1 -f --dry-run --reverse <"$patch_file" >/dev/null 2>&1; then 48 | patch -d "$sdk_directory" -p1 -f --forward <"$patch_file" 49 | echo -e "\nSuccessfully patched '$sdk_directory' for Winelib compatibility" 50 | else 51 | # Meson requires this program to output something, or else it will error out 52 | # when trying to encode the empty output 53 | echo "'$sdk_directory' has already been patched for Winelib compatibility, ignoring..." 54 | fi 55 | -------------------------------------------------------------------------------- /tools/run-clang-tidy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Run clang-tidy on our code, with the correct compiler options set (since it 4 | # doesn't seem to extract those from the compilation database) 5 | 6 | set -euo pipefail 7 | 8 | # This is the repository's root 9 | cd "$(dirname "$0")/.." 10 | 11 | shopt -s globstar nocaseglob 12 | parallel clang-tidy --use-color --extra-arg='-m64' --extra-arg='-std=c++2a' \ 13 | ::: src/plugin/**/*.cpp src/common/**/*.cpp 14 | parallel clang-tidy --use-color --extra-arg='-m64' --extra-arg='-std=c++2a' \ 15 | --extra-arg='-DWIN32' --extra-arg='-D_WIN32' --extra-arg='-D__WIN32__' --extra-arg='-D_WIN64' \ 16 | --extra-arg='-isystem/usr/include/wine/windows' \ 17 | ::: src/wine-host/**/*.cpp src/common/**/*.cpp 18 | -------------------------------------------------------------------------------- /tools/yabridgectl/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | -------------------------------------------------------------------------------- /tools/yabridgectl/.rustfmt.toml: -------------------------------------------------------------------------------- 1 | format_strings = true 2 | -------------------------------------------------------------------------------- /tools/yabridgectl/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "yabridgectl" 3 | # This version is linked to yabridge's version for clarity's sake and because 4 | # there's not a lot going on here 5 | version = "5.1.1" 6 | authors = ["Robbert van der Helm "] 7 | edition = "2021" 8 | description = "Utility for setting up and managing yabridge" 9 | repository = "https://github.com/robbert-vdh/yabridge" 10 | license = "GPL-3.0-or-later" 11 | 12 | [dependencies] 13 | anyhow = "1.0.52" 14 | clap = { version = "4.3.21", features = ["cargo", "derive", "wrap_help"] } 15 | colored = "2.0.0" 16 | is_executable = "1.0.1" 17 | goblin = { version = "0.6", default-features = false, features = ["std", "pe32", "pe64"] } 18 | libloading = "0.7.3" 19 | promptly = "0.3.1" 20 | # Version 0.1.3 from crates.io assumes a 64-bit toolchain 21 | reflink = { git = "https://github.com/nicokoch/reflink", rev = "e8d93b465f5d9ad340cd052b64bbc77b8ee107e2" } 22 | rayon = "1.5.1" 23 | serde = "1.0.133" 24 | serde_derive = "1.0.133" 25 | serde_jsonrc = "0.1" 26 | textwrap = { version = "0.16.0", features = ["terminal_size"] } 27 | toml = "0.5.6" 28 | walkdir = "2.3.1" 29 | which = "4.2.2" 30 | xdg = "2.4.0" 31 | -------------------------------------------------------------------------------- /tools/yabridgectl/src/actions/blacklist.rs: -------------------------------------------------------------------------------- 1 | // yabridge: a Wine plugin bridge 2 | // Copyright (C) 2020-2024 Robbert van der Helm 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | 17 | //! Handlers for the blacklist subcommands, just to keep `main.rs` clean. 18 | 19 | use anyhow::Result; 20 | use std::path::{Path, PathBuf}; 21 | 22 | use crate::config::Config; 23 | 24 | /// Add a path to the blacklist. Duplicates get ignord because we're using ordered sets. 25 | pub fn add_path(config: &mut Config, path: PathBuf) -> Result<()> { 26 | config.blacklist.insert(path); 27 | config.write() 28 | } 29 | 30 | /// Remove a path from the blacklist. The path is assumed to be part of `config.blacklist`, 31 | /// otherwise this is silently ignored. 32 | pub fn remove_path(config: &mut Config, path: &Path) -> Result<()> { 33 | // We've already verified that this path is in `config.blacklist` 34 | config.blacklist.remove(path); 35 | config.write() 36 | } 37 | 38 | /// List the paths in the blacklist. 39 | pub fn list_paths(config: &Config) -> Result<()> { 40 | for directory in &config.blacklist { 41 | println!("{}", directory.display()); 42 | } 43 | 44 | Ok(()) 45 | } 46 | 47 | /// Clear the entire blacklist. 48 | pub fn clear(config: &mut Config) -> Result<()> { 49 | config.blacklist.clear(); 50 | config.write() 51 | } 52 | --------------------------------------------------------------------------------