Anklang 0.3.0-460-gc4ef46ba
ASE — Anklang Sound Engine (C++)

« « « Anklang Documentation
Loading...
Searching...
No Matches
clapdevice.cc
Go to the documentation of this file.
1 // This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
2#include "clapdevice.hh"
3#include "clapplugin.hh"
4#include "project.hh"
5#include "processor.hh"
6#include "serialize.hh"
7#include "internal.hh"
8#include <dlfcn.h>
9
10#define CDEBUG(...) Ase::debug ("clap", __VA_ARGS__)
11#define CDEBUG_ENABLED() Ase::debug_key_enabled ("clap")
12
13namespace Ase {
14
15// == ClapPropertyImpl ==
16struct ClapPropertyImpl : public Property, public virtual EmittableImpl {
17 ClapDeviceImplP device_;
18 clap_id param_id = CLAP_INVALID_ID; // uint32_t
19 uint32_t flags = 0; // clap_param_info_flags
20 String ident_, label_, module_;
21 double min_value = NAN, max_value = NAN, default_value = NAN;
22public:
23 String ident () const override { return ident_; }
24 String label () const override { return label_; }
25 String nick () const override { return parameter_guess_nick (label_); }
26 String unit () const override { return ""; }
27 double get_min () const override { return min_value; }
28 double get_max () const override { return max_value; }
29 double get_step () const override { return is_stepped() ? 1 : 0; }
30 bool is_numeric () const override { return true; }
31 bool is_stepped () const { return strstr (hints().c_str(), ":stepped:"); }
32 void reset () override { set_value (default_value); }
33 ClapPropertyImpl (ClapDeviceImplP device, const ClapParamInfo info) :
34 device_ (device)
35 {
36 param_id = info.param_id;
37 flags = info.flags;
38 ident_ = info.ident;
39 label_ = info.name;
40 module_ = info.module;
41 min_value = info.min_value;
42 max_value = info.max_value;
43 default_value = info.default_value;
44 }
45 ChoiceS
46 choices () const override
47 {
48 const double mi = get_min(), ma = get_max();
49 const bool down = ma < mi;
50 return_unless (is_stepped(), {});
51 ChoiceS choices;
52 if (ma - mi <= 100)
53 for (double d = mi; down ? d > ma : d < ma; d += down ? -1 : +1) {
54 const String ident = string_format ("%f", d);
55 choices.push_back ({ ident, ident });
56 }
57 return choices;
58 }
60 get_metadata () const override
61 {
62 StringS md;
63 md.push_back ("hints=" + ClapParamInfo::hints_from_param_info_flags (flags));
64 if (!module_.empty())
65 md.push_back ("group=" + module_);
66 return md;
67 }
68 double
69 get_normalized () const override
70 {
71 const double mi = get_min(), ma = get_max();
72 const double value = get_value().as_double();
73 return (value - mi) / (ma - mi);
74 }
75 bool
76 set_normalized (double v) override
77 {
78 const double mi = get_min(), ma = get_max();
79 const double value = v * (ma - mi) + mi;
80 return set_value (value);
81 }
82 String
83 get_text () const override
84 {
85 String txt;
86 device_->handle_->param_get_value (param_id, &txt);
87 return txt;
88 }
89 bool
90 set_text (String vstr) override
91 {
92 return device_->handle_->param_set_value (param_id, vstr);
93 }
94 Value
95 get_value () const override
96 {
97 return Value (device_->handle_->param_get_value (param_id));
98 }
99 bool
100 set_value (const Value &val) override
101 {
102 return device_->handle_->param_set_value (param_id, val.as_double());
103 }
104};
105
106// == ClapDeviceImpl ==
107ClapDeviceImpl::ClapDeviceImpl (ClapPluginHandleP claphandle) :
108 handle_ (claphandle)
109{
110 assert_return (claphandle != nullptr);
111 paramschange_ = on_event ("params:change", [this] (const Event &event) {
112 proc_params_change (event);
113 });
114 if (handle_)
115 handle_->_set_parent (this);
116}
117
118ClapDeviceImpl::~ClapDeviceImpl()
119{
120 if (handle_)
121 handle_->_set_parent (nullptr);
122 if (handle_)
123 handle_->destroy();
124 handle_ = nullptr;
125}
126
127String
128ClapDeviceImpl::get_device_path ()
129{
131 NativeDevice *parent = dynamic_cast<NativeDevice*> (this->_parent());
132 for (Device *dev = this; parent; dev = parent, parent = dynamic_cast<NativeDevice*> (dev->_parent()))
133 {
134 ssize_t index = Aux::index_of (parent->get_devices(),
135 [dev] (const DeviceP &e) { return dev == &*e; });
136 if (index >= 0)
137 nums.insert (nums.begin(), string_from_int (index));
138 }
139 String s = string_join ("d", nums);
140 ProjectImpl *project = _project();
141 Track *track = _track();
142 if (project && track)
143 s = string_format ("t%ud%s", project->track_index (*track), s);
144 return s;
145}
146
147void
149{
151
152 if (xs.in_save() && handle_)
153 handle_->save_state (xs, get_device_path());
154 if (xs.in_load() && handle_ && !handle_->clap_activated())
155 handle_->load_state (xs);
156}
157
160{
161 return clap_device_info (handle_->descriptor);
162}
163
164PropertyS
166{
167 // reuse existing properties
168 ClapDeviceImplP selfp = shared_ptr_cast<ClapDeviceImpl> (this);
169 PropertyS properties;
170 for (const ClapParamInfo &pinfo : handle_->param_infos())
171 {
172 auto aseprop = handle_->param_get_property (pinfo.param_id);
173 if (aseprop)
174 properties.push_back (aseprop);
175 else
176 {
177 auto prop = std::make_shared<ClapPropertyImpl> (selfp, pinfo);
178 handle_->param_set_property (prop->param_id, prop);
179 properties.push_back (prop);
180 }
181 }
182 return properties;
183}
184
185void
186ClapDeviceImpl::proc_params_change (const Event &event)
187{
188 if (handle_)
189 handle_->params_changed();
190}
191
192void
194{
196 ClapDeviceImplP selfp = shared_ptr_cast<ClapDeviceImpl> (this);
197 // deactivate and destroy plugin
198 if (!parent && handle_)
199 {
200 handle_->destroy_gui();
201 handle_->clap_deactivate();
202 handle_->destroy();
203 }
204}
205
206void
208{
209 if (_parent() && handle_)
210 handle_->clap_activate();
211}
212
213void
215{
216 if (handle_->gui_visible())
217 handle_->hide_gui();
218 else if (handle_->supports_gui())
219 handle_->show_gui();
220}
221
222bool
224{
225 return handle_->supports_gui();
226}
227
228bool
230{
231 return handle_->gui_visible();
232}
233
234DeviceInfoS
235ClapDeviceImpl::list_clap_plugins ()
236{
237 static DeviceInfoS devs;
238 if (devs.size())
239 return devs;
240 for (ClapPluginDescriptor *descriptor : ClapPluginDescriptor::collect_descriptors()) {
241 std::string title = descriptor->name;
242 if (!descriptor->version.empty())
243 title = title + " " + descriptor->version;
244 if (!descriptor->vendor.empty())
245 title = title + " - " + descriptor->vendor;
246 devs.push_back (clap_device_info (*descriptor));
247 }
248 return devs;
249}
250
251AudioProcessorP
253{
254 return handle_->audio_processor();
255}
256
257void
258ClapDeviceImpl::_set_event_source (AudioProcessorP esource)
259{
260 // TODO: _set_event_source may be needed for nested plugins
261}
262
263void
265{
266 // TODO: this needs adjustments when _set_event_source is implemented
267}
268
269String
270ClapDeviceImpl::clap_version ()
271{
272 const String clapversion = string_format ("%u.%u.%u", CLAP_VERSION.major, CLAP_VERSION.minor, CLAP_VERSION.revision);
273 return clapversion;
274}
275
276ClapPluginHandleP
277ClapDeviceImpl::access_clap_handle (DeviceP device)
278{
279 ClapDeviceImpl *clapdevice = dynamic_cast<ClapDeviceImpl*> (&*device);
280 return clapdevice ? clapdevice->handle_ : nullptr;
281}
282
283DeviceP
284ClapDeviceImpl::create_clap_device (AudioEngine &engine, const String &clapuri)
285{
286 assert_return (string_startswith (clapuri, "CLAP:"), nullptr);
287 const String clapid = clapuri.substr (5);
288 ClapPluginDescriptor *descriptor = nullptr;
289 for (ClapPluginDescriptor *desc : ClapPluginDescriptor::collect_descriptors())
290 if (clapid == desc->id) {
291 descriptor = desc;
292 break;
293 }
294 if (descriptor)
295 {
296 auto make_clap_device = [&descriptor] (const String &aseid, AudioProcessor::StaticInfo static_info, AudioProcessorP aproc) -> DeviceP {
297 ClapPluginHandleP handlep = ClapPluginHandle::make_clap_handle (*descriptor, aproc);
298 return ClapDeviceImpl::make_shared (handlep);
299 };
300 DeviceP devicep = AudioProcessor::registry_create (ClapPluginHandle::audio_processor_type(), engine, make_clap_device);
301 ClapDeviceImplP clapdevicep = shared_ptr_cast<ClapDeviceImpl> (devicep);
302 return clapdevicep;
303 }
304 return nullptr;
305}
306
307} // Ase
void _disconnect_remove() override
Disconnect the device and remove all object references.
DeviceInfo device_info() override
Describe this Device type.
PropertyS access_properties() override
Retrieve handles for all properties.
void gui_toggle() override
Toggle GUI display.
void _activate() override
Add AudioProcessor to the Engine and start processing.
bool gui_visible() override
Is GUI currently visible.
AudioProcessorP _audio_processor() const override
Retrieve the corresponding AudioProcessor.
void _set_parent(GadgetImpl *parent) override
Assign parent container.
bool gui_supported() override
Has GUI display facilities.
void serialize(WritNode &xs) override
Serialize members and childern.
void _set_parent(GadgetImpl *parent) override
Assign parent container.
Definition device.cc:14
Track * _track() const
Find Track in parent ancestry.
Definition device.cc:87
Implementation type for classes with Event subscription.
Definition object.hh:11
Base type for classes that have a Property.
Definition gadget.hh:12
GadgetImpl * _parent() const override
Retrieve parent container.
Definition gadget.hh:30
ProjectImpl * _project() const
Find Project in parent ancestry.
Definition gadget.cc:168
A Property allows querying, setting and monitoring of an object property.
Definition api.hh:135
String hints() const
Hints for parameter handling (metadata).
Definition parameter.cc:455
virtual void serialize(WritNode &xs)=0
Serialize members and childern.
Definition serialize.cc:379
One entry in a Writ serialization document.
Definition serialize.hh:24
bool in_load() const
Return true during deserialization.
Definition serialize.hh:175
bool in_save() const
Return true during serialization.
Definition serialize.hh:181
T empty(T... args)
#define assert_return(expr,...)
Return from the current function if expr is unmet and issue an assertion warning.
Definition internal.hh:29
#define return_unless(cond,...)
Return silently if cond does not evaluate to true with return value ...
Definition internal.hh:71
The Anklang C++ API namespace.
Definition api.hh:9
std::string string_format(const char *format, const Args &...args) __attribute__((__format__(__printf__
Format a string similar to sprintf(3) with support for std::string and std::ostringstream convertible...
String string_join(const String &junctor, const StringS &strvec)
Definition strings.cc:452
String parameter_guess_nick(const String &parameter_label)
Create a few letter nick name from a multi word parameter label.
Definition parameter.cc:583
String string_from_int(int64 value)
Convert a 64bit signed integer into a string.
Definition strings.cc:604
std::string String
Convenience alias for std::string.
Definition cxxaux.hh:35
bool string_startswith(const String &string, const String &fragment)
Returns whether string starts with fragment.
Definition strings.cc:846
Info for device types.
Definition api.hh:203
T push_back(T... args)
typedef uint32_t
strstr
String get_text() const override
Get the current property value, converted to a text String.
Definition clapdevice.cc:83
bool is_numeric() const override
Whether the property settings can be represented as a floating point number.
Definition clapdevice.cc:30
Value get_value() const override
Get the native property value.
Definition clapdevice.cc:95
bool set_normalized(double v) override
Set the normalized property value as double.
Definition clapdevice.cc:76
ChoiceS choices() const override
Enumerate choices for choosable properties.
Definition clapdevice.cc:46
bool set_text(String vstr) override
Set the current property value as a text String.
Definition clapdevice.cc:90
double get_min() const override
Get the minimum property value, converted to double.
Definition clapdevice.cc:27
bool set_value(const Value &val) override
Set the native property value.
String nick() const override
Abbreviated user interface name, usually not more than 6 characters.
Definition clapdevice.cc:25
String label() const override
Preferred user interface name.
Definition clapdevice.cc:24
String ident() const override
Unique name (per owner) of this Property.
Definition clapdevice.cc:23
double get_max() const override
Get the maximum property value, converted to double.
Definition clapdevice.cc:28
double get_normalized() const override
Get the normalized property value, converted to double.
Definition clapdevice.cc:69
double get_step() const override
Get the property value stepping, converted to double.
Definition clapdevice.cc:29
String unit() const override
Units of the values within range.
Definition clapdevice.cc:26
void reset() override
Assign default as normalized property value.
Definition clapdevice.cc:32
Structure for callback based notifications.
Definition value.hh:113
Value type used to interface with various property types.
Definition value.hh:54
double as_double() const
Convert Value to double or return 0.
Definition value.cc:77
T substr(T... args)
typedef ssize_t