diff --git a/src/common/serialization/clap/ext/params.cpp b/src/common/serialization/clap/ext/params.cpp new file mode 100644 index 00000000..fe8def80 --- /dev/null +++ b/src/common/serialization/clap/ext/params.cpp @@ -0,0 +1,49 @@ +// yabridge: a Wine plugin bridge +// Copyright (C) 2020-2022 Robbert van der Helm +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "params.h" + +#include "../../../utils.h" + +namespace clap { +namespace ext { +namespace params { + +ParamInfo::ParamInfo(const clap_param_info_t& original) + : id(original.id), + flags(original.flags), + cookie(reinterpret_cast(original.cookie)), + name(original.name), + module(original.module), + min_value(original.min_value), + max_value(original.max_value), + default_value(original.default_value) {} + +void ParamInfo::reconstruct(clap_param_info_t& port_info) const { + port_info = clap_param_info_t{}; + port_info.id = id; + port_info.flags = flags; + port_info.cookie = reinterpret_cast(static_cast(cookie)); + strlcpy_buffer(port_info.name, name); + strlcpy_buffer(port_info.module, module); + port_info.min_value = min_value; + port_info.max_value = max_value; + port_info.default_value = default_value; +} + +} // namespace params +} // namespace ext +} // namespace clap diff --git a/src/common/serialization/clap/ext/params.h b/src/common/serialization/clap/ext/params.h new file mode 100644 index 00000000..6a397c3b --- /dev/null +++ b/src/common/serialization/clap/ext/params.h @@ -0,0 +1,300 @@ +// yabridge: a Wine plugin bridge +// Copyright (C) 2020-2022 Robbert van der Helm +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once + +#include +#include +#include + +#include + +#include "../../../bitsery/ext/in-place-optional.h" +#include "../../common.h" + +// Serialization messages for `clap/ext/params.h` + +namespace clap { +namespace ext { +namespace params { + +/** + * A serializable version of `clap_param_info` that owns all of the data it + * references. + */ +struct ParamInfo { + /** + * Parse a native `clap_param_info` struct so it can be serialized and sent + * to the Wine plugin host. + */ + ParamInfo(const clap_param_info_t& original); + + /** + * Default constructor for bitsery. + */ + ParamInfo() {} + + /** + * Write the stored information to a host provided info struct. + */ + void reconstruct(clap_param_info_t& port_info) const; + + clap_id id; + clap_param_info_flags flags; + // This is the `void*` provided by the plugin, as an integer + native_size_t cookie; + std::string name; + std::string module; + double min_value; + double max_value; + double default_value; + + template + void serialize(S& s) { + s.value4b(id); + s.value4b(flags); + s.value8b(cookie); + s.text1b(name, 4096); + s.text1b(module, 4096); + s.value8b(min_value); + s.value8b(max_value); + s.value8b(default_value); + } +}; + +namespace plugin { + +/** + * Message struct for `clap_plugin_params::count()`. + */ +struct Count { + using Response = PrimitiveResponse; + + native_size_t instance_id; + + template + void serialize(S& s) { + s.value8b(instance_id); + } +}; + +/** + * The response to the `clap::ext::params::GetInfo` message defined below. + */ +struct GetInfoResponse { + std::optional result; + + template + void serialize(S& s) { + s.ext(result, bitsery::ext::InPlaceOptional(), + [](S& s, auto& v) { s.object(v); }); + } +}; + +/** + * Message struct for `clap_plugin_params::get_info()`. + */ +struct GetInfo { + using Response = GetInfoResponse; + + native_size_t instance_id; + uint32_t param_index; + + template + void serialize(S& s) { + s.value8b(instance_id); + s.value4b(param_index); + } +}; + +/** + * The response to the `clap::ext::params::GetValue` message defined below. + */ +struct GetValueResponse { + std::optional result; + + template + void serialize(S& s) { + s.ext(result, bitsery::ext::InPlaceOptional(), + [](S& s, auto& v) { s.value8b(v); }); + } +}; + +/** + * Message struct for `clap_plugin_params::get_value()`. + */ +struct GetValue { + using Response = GetValueResponse; + + native_size_t instance_id; + clap_id param_id; + + template + void serialize(S& s) { + s.value8b(instance_id); + s.value4b(param_id); + } +}; + +/** + * The response to the `clap::ext::params::ValueToText` message defined below. + */ +struct ValueToTextResponse { + std::optional result; + + template + void serialize(S& s) { + s.ext(result, bitsery::ext::InPlaceOptional(), + [](S& s, auto& v) { s.text1b(v, 4096); }); + } +}; + +/** + * Message struct for `clap_plugin_params::value_to_text()`. + */ +struct ValueToText { + using Response = ValueToTextResponse; + + native_size_t instance_id; + clap_id param_id; + double value; + + template + void serialize(S& s) { + s.value8b(instance_id); + s.value4b(param_id); + s.value8b(value); + } +}; + +/** + * The response to the `clap::ext::params::TextToValue` message defined below. + */ +struct TextToValueResponse { + std::optional result; + + template + void serialize(S& s) { + s.ext(result, bitsery::ext::InPlaceOptional(), + [](S& s, auto& v) { s.value8b(v); }); + } +}; + +/** + * Message struct for `clap_plugin_params::text_to_value()`. + */ +struct TextToValue { + using Response = TextToValueResponse; + + native_size_t instance_id; + clap_id param_id; + std::string display; + + template + void serialize(S& s) { + s.value8b(instance_id); + s.value4b(param_id); + s.text1b(display, 4096); + } +}; + +/** + * The response to the `clap::ext::params::Flush` message defined below. + */ +struct FlushResponse { + // TODO: Output events + + template + void serialize(S& s) { + // TODO: Output events + } +}; + +// TODO: This can be either a main thread or an audio thread function call +// depending on whether or not the plugin is active +/** + * Message struct for `clap_plugin_params::flush()`. + */ +struct Flush { + using Response = FlushResponse; + + native_size_t instance_id; + // TODO: Input events + + template + void serialize(S& s) { + s.value8b(instance_id); + // TODO: Input events + } +}; + +} // namespace plugin + +namespace host { + +/** + * Message struct for `clap_host_params::rescan()`. + */ +struct Rescan { + using Response = Ack; + + native_size_t owner_instance_id; + clap_param_rescan_flags flags; + + template + void serialize(S& s) { + s.value8b(owner_instance_id); + s.value4b(flags); + } +}; + +/** + * Message struct for `clap_host_params::clear()`. + */ +struct Clear { + using Response = Ack; + + native_size_t owner_instance_id; + clap_id param_id; + clap_param_clear_flags flags; + + template + void serialize(S& s) { + s.value8b(owner_instance_id); + s.value4b(param_id); + s.value4b(flags); + } +}; + +/** + * Message struct for `clap_host_params::request_flush()`. + */ +struct RequestFlush { + using Response = Ack; + + native_size_t owner_instance_id; + + template + void serialize(S& s) { + s.value8b(owner_instance_id); + } +}; + +} // namespace host + +} // namespace params +} // namespace ext +} // namespace clap diff --git a/src/plugin/meson.build b/src/plugin/meson.build index f6e2e659..c0139462 100644 --- a/src/plugin/meson.build +++ b/src/plugin/meson.build @@ -79,6 +79,7 @@ if with_clap '../common/process.cpp', '../common/serialization/clap/ext/audio-ports.cpp', '../common/serialization/clap/ext/note-ports.cpp', + '../common/serialization/clap/ext/params.cpp', '../common/serialization/clap/host.cpp', '../common/serialization/clap/plugin.cpp', '../common/utils.cpp', diff --git a/src/wine-host/meson.build b/src/wine-host/meson.build index 375ffc41..d901fa65 100644 --- a/src/wine-host/meson.build +++ b/src/wine-host/meson.build @@ -82,6 +82,7 @@ if with_clap '../common/logging/clap.cpp', '../common/serialization/clap/ext/audio-ports.cpp', '../common/serialization/clap/ext/note-ports.cpp', + '../common/serialization/clap/ext/params.cpp', '../common/serialization/clap/plugin.cpp', 'bridges/clap-impls/host-proxy.cpp', 'bridges/clap.cpp',