Audacity 3.2.0
LV2InstanceFeaturesList.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 @file LV2InstanceFeaturesList.cpp
6
7 Paul Licameli split from LV2Effect.cpp
8
9 Audacity(R) is copyright (c) 1999-2008 Audacity Team.
10 License: GPL v2 or later. See License.txt.
11
12**********************************************************************/
13
15#include <wx/log.h>
16
18 const LV2FeaturesList &baseFeatures
19) : ExtendedLV2FeaturesList{ WithBase, baseFeatures }
20 , mOk{ InitializeOptions() }
21{
22 AddFeature(LV2_OPTIONS__options, mOptions.data());
23}
24
26{
27 using namespace LV2Symbols;
28
29 // Construct the null-terminated array describing options, and validate it
30 AddOption(urid_SequenceSize, sizeof(mSeqSize), urid_Int, &mSeqSize);
31 AddOption(urid_MinBlockLength,
32 sizeof(mMinBlockSize), urid_Int, &mMinBlockSize);
33 AddOption(urid_MaxBlockLength,
34 sizeof(mMaxBlockSize), urid_Int, &mMaxBlockSize);
35 // Two options are reset later
36 mBlockSizeOption = AddOption(urid_NominalBlockLength,
37 sizeof(mBlockSize), urid_Int, &mBlockSize);
38 AddOption(urid_SampleRate,
39 sizeof(mSampleRate), urid_Float, &mSampleRate);
40 AddOption(0, 0, 0, nullptr);
41 if (!ValidateOptions(lilv_plugin_get_uri(&mPlug)))
42 return false;
43
44 // Adjust the values in the block size features according to the plugin
45 if (LilvNodePtr minLength{ lilv_world_get(gWorld,
46 lilv_plugin_get_uri(&mPlug), node_MinBlockLength, nullptr) }
47 ; lilv_node_is_int(minLength.get())
48 ){
49 if (auto value = lilv_node_as_int(minLength.get())
50 ; value >= 0
51 )
52 mMinBlockSize = std::max<size_t>(mMinBlockSize, value);
53 }
54 if (LilvNodePtr maxLength{ lilv_world_get(gWorld,
55 lilv_plugin_get_uri(&mPlug), node_MaxBlockLength, nullptr) }
56 ; lilv_node_is_int(maxLength.get())
57 ){
58 if (auto value = lilv_node_as_int(maxLength.get())
59 ; value >= 1
60 )
61 mMaxBlockSize = std::min<size_t>(mMaxBlockSize, value);
62 }
64
65 return true;
66}
67
69 LV2_URID key, uint32_t size, LV2_URID type, const void *value)
70{
71 int ndx = mOptions.size();
72 if (key != 0)
73 mOptions.emplace_back(LV2_Options_Option{
74 LV2_OPTIONS_INSTANCE, 0, key, size, type, value });
75 else
76 mOptions.emplace_back(LV2_Options_Option{});
77 return ndx;
78}
79
80const LV2_Options_Option *
82{
85 else
86 return nullptr;
87}
88
89bool LV2InstanceFeaturesList::ValidateOptions(const LilvNode *subject)
90{
91 return CheckOptions(subject, true) && CheckOptions(subject, false);
92}
93
95 const LilvNode *subject, bool required)
96{
97 using namespace LV2Symbols;
98 bool supported = true;
99 const auto predicate =
100 required ? node_RequiredOption : node_SupportedOption;
101 if (LilvNodesPtr nodes{
102 lilv_world_find_nodes(gWorld, subject, predicate, nullptr) }
103 ){
104 LILV_FOREACH(nodes, i, nodes.get()) {
105 const auto node = lilv_nodes_get(nodes.get(), i);
106 const auto uri = lilv_node_as_string(node);
107 // The signature of our constructor justifies this static_cast
108 const auto urid = static_cast<const LV2FeaturesList&>(mBaseFeatures)
109 .URID_Map(uri);
110 if (urid == urid_NominalBlockLength)
112 // else if (urid == urid_SampleRate)
113 // mSupportsSampleRate = true; // supports changing sample rate
114 else if (required) {
115 const auto end = mOptions.end();
116 supported = (end != std::find_if(mOptions.begin(), end,
117 [&](const auto &option){ return option.key == urid; }));
118 if (!supported) {
119 wxLogError(wxT("%s requires unsupported option %s"),
120 lilv_node_as_string(lilv_plugin_get_uri(&mPlug)), uri);
121 break;
122 }
123 }
124 }
125 }
126 return supported;
127}
128
130 LV2InstanceFeaturesList &baseFeatures, float sampleRate,
131 const LV2_Worker_Schedule *pWorkerSchedule
132) : ExtendedLV2FeaturesList{ WithBase, baseFeatures }
133{
134 baseFeatures.mSampleRate = sampleRate;
135 auto &base = baseFeatures.Base();
136 if (base.SuppliesWorkerInterface()) {
137 // Inform the plugin how to send work to another thread
138 AddFeature( LV2_WORKER__schedule, pWorkerSchedule );
139 }
140}
wxT("CloseDown"))
constexpr WithBase_t WithBase
Lilv_ptr< LilvNodes, lilv_nodes_free > LilvNodesPtr
Lilv_ptr< LilvNode, lilv_node_free > LilvNodePtr
Definition: LV2Utils.h:33
static const AudacityProject::AttachedObjects::RegisteredFactory key
Extends one (immutable) feature list (whose lifetime contains this one's)
void AddFeature(const char *uri, const void *data)
const LV2FeaturesListBase & mBaseFeatures
const LilvPlugin & mPlug
LilvWorld * gWorld
Definition: LV2Symbols.cpp:31
const char * end(const char *str) noexcept
Definition: StringUtils.h:106
bool ValidateOptions(const LilvNode *subject)
bool CheckOptions(const LilvNode *subject, bool required)
size_t AddOption(LV2_URID, uint32_t size, LV2_URID, const void *value)
LV2InstanceFeaturesList(const LV2FeaturesList &baseFeatures)
const LV2_Options_Option * NominalBlockLengthOption() const
const LV2FeaturesList & Base() const
std::vector< LV2_Options_Option > mOptions
LV2WrapperFeaturesList(LV2InstanceFeaturesList &baseFeatures, float sampleRate=44100.0f, const LV2_Worker_Schedule *pWorkerSchedule=nullptr)