Audacity 3.2.0
Public Member Functions | Public Attributes | List of all members
LV2Ports Class Reference

#include <LV2Ports.h>

Collaboration diagram for LV2Ports:
[legend]

Public Member Functions

 LV2Ports (const LilvPlugin &plug)
 
void EmitPortValues (const LilvState &state, LV2EffectSettings &settings) const
 
const void * GetPortValue (const LV2EffectSettings &settings, const char *port_symbol, uint32_t *size, uint32_t *type) const
 
void SetPortValue (LV2EffectSettings &settings, const char *port_symbol, const void *value, uint32_t size, uint32_t type) const
 

Public Attributes

LV2AudioPortArray mAudioPorts
 
unsigned mAudioIn { 0 }
 
unsigned mAudioOut { 0 }
 
LV2AtomPortArray mAtomPorts
 
std::optional< size_t > mControlInIdx {}
 
std::optional< size_t > mControlOutIdx {}
 
unsigned mMidiIn { 0 }
 
unsigned mMidiOut { 0 }
 
LV2CVPortArray mCVPorts
 
LV2ControlPortArray mControlPorts
 
TranslatableStrings mGroups
 
std::unordered_map< TranslatableString, std::vector< int > > mGroupMap
 
std::unordered_map< uint32_t, size_t > mControlPortMap
 
int mLatencyPort { -1 }
 

Detailed Description

Definition at line 257 of file LV2Ports.h.

Constructor & Destructor Documentation

◆ LV2Ports()

LV2Ports::LV2Ports ( const LilvPlugin &  plug)
explicit
Postcondition
every member of mGroups occurs as a key in mGroupMap

Definition at line 153 of file LV2Ports.cpp.

154{
155 using namespace LV2Symbols;
156
157 // Collect information in mAudioPorts, mControlPorts, mAtomPorts, mCVPorts
158 // Retrieve the port ranges for all ports (some values may be NaN)
159 auto numPorts = lilv_plugin_get_num_ports(&plug);
160 Floats minimumVals {numPorts};
161 Floats maximumVals {numPorts};
162 Floats defaultVals {numPorts};
163 lilv_plugin_get_port_ranges_float(&plug,
164 minimumVals.get(), maximumVals.get(), defaultVals.get());
165
166 for (size_t i = 0; i < numPorts; ++i) {
167 const auto port = lilv_plugin_get_port_by_index(&plug, i);
168 int index = lilv_port_get_index(&plug, port);
169
170 // It must be input or output, anything else is bogus
171 bool isInput;
172 if (lilv_port_is_a(&plug, port, node_InputPort))
173 isInput = true;
174 else if (lilv_port_is_a(&plug, port, node_OutputPort))
175 isInput = false;
176 else {
177 assert(false);
178 continue;
179 }
180
181 // Get the port name and symbol
182 const auto symbol = LilvString(lilv_port_get_symbol(&plug, port));
183 const auto name = LilvStringMove(lilv_port_get_name(&plug, port));
184
185 // Get the group to which this port belongs or default to the main group
186 TranslatableString groupName{};
187 if (LilvNodePtr group{ lilv_port_get(&plug, port, node_Group) }) {
188 // lilv.h does not say whether return of lilv_world_get() needs to
189 // be freed, but that is easily seen to be so from source
190 auto groupMsg = LilvStringMove(
191 lilv_world_get(gWorld, group.get(), node_Label, nullptr));
192 if (groupMsg.empty())
193 groupMsg = LilvStringMove(
194 lilv_world_get(gWorld, group.get(), node_Name, nullptr));
195 if (groupMsg.empty())
196 groupMsg = LilvString(group.get());
197 groupName = Verbatim(groupMsg);
198 }
199 else
200 groupName = XO("Effect Settings");
201
202 // Get the latency port
203 const auto latencyIndex = lilv_plugin_get_latency_port_index(&plug);
204
205 // Get the ports designation (must be freed)
206 LilvNodePtr designation{ lilv_port_get(&plug, port, node_Designation) };
207
208 // Check for audio ports
209 if (lilv_port_is_a(&plug, port, node_AudioPort)) {
210 mAudioPorts.push_back(std::make_shared<LV2AudioPort>(
211 port, index, isInput, symbol, name, groupName));
212 isInput ? mAudioIn++ : mAudioOut++;
213 }
214 // Check for Control ports
215 else if (lilv_port_is_a(&plug, port, node_ControlPort)) {
216 // Add group if not previously done...
217 if (mGroupMap.find(groupName) == mGroupMap.end())
218 mGroups.push_back(groupName);
219 // ... That maintains the postcondition, after this:
220 mGroupMap[groupName].push_back(mControlPorts.size());
221
222 wxString units;
223 // Get any unit descriptor
224 if (LilvNodePtr unit{ lilv_port_get(&plug, port, node_Unit) })
225 // Really should use lilv_world_get_symbol()
226 if (LilvNodePtr symbol{ lilv_world_get_symbol(gWorld, unit.get()) })
227 units = LilvString(symbol.get());
228
229 // Collect the value and range info
230 bool hasLo = !std::isnan(minimumVals[i]);
231 bool hasHi = !std::isnan(maximumVals[i]);
232 float min = hasLo ? minimumVals[i] : 0.0f;
233 float max = hasHi ? maximumVals[i] : 1.0f;
234 float def = !std::isnan(defaultVals[i])
235 ? defaultVals[i]
236 : hasLo
237 ? min
238 : hasHi
239 ? max
240 : 0.0f;
241
242 // Figure out the type of port we have
243 bool toggle = isInput &&
244 lilv_port_has_property(&plug, port, node_Toggled);
245 bool enumeration = isInput &&
246 lilv_port_has_property(&plug, port, node_Enumeration);
247 bool integer = isInput &&
248 lilv_port_has_property(&plug, port, node_Integer);
249 bool sampleRate = isInput &&
250 lilv_port_has_property(&plug, port, node_SampleRate);
251 // Trigger properties can be combined with other types, but it
252 // seems mostly to be combined with toggle. So, we turn the
253 // checkbox into a button.
254 bool trigger = isInput &&
255 lilv_port_has_property(&plug, port, node_Trigger);
256 // We'll make the slider logarithmic
257 bool logarithmic = isInput &&
258 lilv_port_has_property(&plug, port, node_Logarithmic);
259
260 // Get the scale points
261 std::vector<double> scaleValues;
262 wxArrayString scaleLabels;
263 {
264 using LilvScalePointsPtr =
266 LilvScalePointsPtr points{
267 lilv_port_get_scale_points(&plug, port) };
268 LILV_FOREACH(scale_points, j, points.get()) {
269 const auto point = lilv_scale_points_get(points.get(), j);
270 scaleValues.push_back(
271 lilv_node_as_float(lilv_scale_point_get_value(point)));
272 scaleLabels.push_back(
273 LilvString(lilv_scale_point_get_label(point)));
274 }
275 }
276
277 const auto &controlPort = mControlPorts.emplace_back(
278 std::make_shared<LV2ControlPort>(
279 port, index, isInput, symbol, name, groupName,
280 move(scaleValues), std::move(scaleLabels), units,
281 min, max, def, hasLo, hasHi,
282 toggle, enumeration, integer, sampleRate,
283 trigger, logarithmic));
284 // Figure out the type of port we have
285 if (isInput)
286 mControlPortMap[controlPort->mIndex] = mControlPorts.size() - 1;
287 else if (controlPort->mIndex == latencyIndex)
288 mLatencyPort = i;
289 }
290 // Check for atom ports
291 else if (lilv_port_is_a(&plug, port, node_AtomPort)) {
292 uint32_t minimumSize = 8192;
293 if (LilvNodePtr min{ lilv_port_get(&plug, port, node_MinimumSize) }
294 ; lilv_node_is_int(min.get())
295 ){
296 if (auto value = lilv_node_as_int(min.get())
297 ; value > 0
298 )
299 minimumSize = std::max<uint32_t>(minimumSize, value);
300 }
301 bool wantsPosition =
302 lilv_port_supports_event(&plug, port, node_Position);
303 bool isMidi = lilv_port_supports_event(&plug, port, node_MidiEvent);
304 if (isMidi)
305 (isInput ? mMidiIn : mMidiOut) += 1;
306 mAtomPorts.push_back(std::make_shared<LV2AtomPort>(
307 port, index, isInput, symbol, name, groupName,
308 minimumSize, isMidi, wantsPosition));
309 bool isControl = lilv_node_equals(designation.get(), node_Control);
310 if (isInput) {
311 if (!mControlInIdx || isControl)
312 mControlInIdx = mAtomPorts.size() - 1;
313 }
314 else if (!mControlOutIdx || isControl)
315 mControlOutIdx = mAtomPorts.size() - 1;
316 }
317 // Check for CV ports
318 else if (lilv_port_is_a(&plug, port, node_CVPort)) {
319 // Collect the value and range info
320 float min = 0;
321 float max = 1;
322 float def = 0;
323 bool hasLo = false;
324 bool hasHi = false;
325 if (!std::isnan(minimumVals[i]))
326 hasLo = true, min = minimumVals[i];
327 if (!std::isnan(maximumVals[i]))
328 hasHi = true, max = maximumVals[i];
329 if (!std::isnan(defaultVals[i]))
330 def = defaultVals[i];
331 else if (hasLo)
332 def = min;
333 else if (hasHi)
334 def = max;
335 mCVPorts.push_back(std::make_shared<LV2CVPort>(
336 port, index, isInput, symbol, name, groupName,
337 min, max, def, hasLo, hasHi));
338 }
339 }
340}
int min(int a, int b)
const TranslatableString name
Definition: Distortion.cpp:76
XO("Cut/Copy/Paste")
wxString LilvString(const LilvNode *node)
Definition: LV2Utils.h:37
std::unique_ptr< Type, Lilv_deleter< Type, f > > Lilv_ptr
Generate classes of smart pointers to lv2 resources.
Definition: LV2Utils.h:26
wxString LilvStringMove(LilvNode *node)
Definition: LV2Utils.h:45
Lilv_ptr< LilvNode, lilv_node_free > LilvNodePtr
Definition: LV2Utils.h:33
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
std::unordered_map< TranslatableString, std::vector< int > > mGroupMap
Definition: LV2Ports.h:285
unsigned mMidiIn
Definition: LV2Ports.h:278
std::optional< size_t > mControlInIdx
Definition: LV2Ports.h:276
TranslatableStrings mGroups
Definition: LV2Ports.h:284
unsigned mAudioOut
Definition: LV2Ports.h:273
unsigned mAudioIn
Definition: LV2Ports.h:272
LV2CVPortArray mCVPorts
Definition: LV2Ports.h:281
LV2ControlPortArray mControlPorts
Definition: LV2Ports.h:283
LV2AtomPortArray mAtomPorts
Definition: LV2Ports.h:275
std::optional< size_t > mControlOutIdx
Definition: LV2Ports.h:277
unsigned mMidiOut
Definition: LV2Ports.h:279
std::unordered_map< uint32_t, size_t > mControlPortMap
Definition: LV2Ports.h:288
int mLatencyPort
Definition: LV2Ports.h:289
LV2AudioPortArray mAudioPorts
Definition: LV2Ports.h:271
Holds a msgid for the translation catalog; may also bind format arguments.
LilvWorld * gWorld
Definition: LV2Symbols.cpp:31

References LV2Symbols::gWorld, LilvString(), LilvStringMove(), mAtomPorts, mAudioIn, mAudioOut, mAudioPorts, mControlInIdx, mControlOutIdx, mControlPortMap, mControlPorts, mCVPorts, mGroupMap, mGroups, min(), mLatencyPort, mMidiIn, mMidiOut, name, anonymous_namespace{ClipSegmentTest.cpp}::sampleRate, Verbatim(), and XO().

Here is the call graph for this function:

Member Function Documentation

◆ EmitPortValues()

void LV2Ports::EmitPortValues ( const LilvState &  state,
LV2EffectSettings settings 
) const

Definition at line 411 of file LV2Ports.cpp.

413{
414 SetValueData data{ *this, settings };
415 // Get the control port values from the state into settings
416 lilv_state_emit_port_values(&state, set_value_func, &data);
417}
static Settings & settings()
Definition: TrackInfo.cpp:47
void set_value_func(const char *port_symbol, void *user_data, const void *value, uint32_t size, uint32_t type)
Definition: LV2Ports.cpp:376

References anonymous_namespace{LV2Ports.cpp}::set_value_func(), and settings().

Referenced by LV2EffectBase::LoadFactoryPreset().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetPortValue()

const void * LV2Ports::GetPortValue ( const LV2EffectSettings settings,
const char *  port_symbol,
uint32_t *  size,
uint32_t *  type 
) const

Definition at line 356 of file LV2Ports.cpp.

358{
359 wxString symbol = wxString::FromUTF8(port_symbol);
360 size_t index = 0;
361 for (auto & port : mControlPorts) {
362 if (port->mSymbol == symbol) {
363 *size = sizeof(float);
364 *type = LV2Symbols::urid_Float;
365 return &settings.values[index];
366 }
367 ++index;
368 }
369 *size = 0;
370 *type = 0;
371 return nullptr;
372}

References mControlPorts, settings(), and size.

Here is the call graph for this function:

◆ SetPortValue()

void LV2Ports::SetPortValue ( LV2EffectSettings settings,
const char *  port_symbol,
const void *  value,
uint32_t  size,
uint32_t  type 
) const

Definition at line 385 of file LV2Ports.cpp.

388{
389 wxString symbol = wxString::FromUTF8(port_symbol);
390 size_t index = 0;
391 for (auto & port : mControlPorts) {
392 if (port->mSymbol == symbol) {
393 auto &dst = settings.values[index];
394 using namespace LV2Symbols;
395 if (type == urid_Bool && size == sizeof(bool))
396 dst = *static_cast<const bool *>(value) ? 1.0f : 0.0f;
397 else if (type == urid_Double && size == sizeof(double))
398 dst = *static_cast<const double *>(value);
399 else if (type == urid_Float && size == sizeof(float))
400 dst = *static_cast<const float *>(value);
401 else if (type == urid_Int && size == sizeof(int32_t))
402 dst = *static_cast<const int32_t *>(value);
403 else if (type == urid_Long && size == sizeof(int64_t))
404 dst = *static_cast<const int64_t *>(value);
405 break;
406 }
407 ++index;
408 }
409}

References mControlPorts, settings(), and size.

Here is the call graph for this function:

Member Data Documentation

◆ mAtomPorts

LV2AtomPortArray LV2Ports::mAtomPorts

Definition at line 275 of file LV2Ports.h.

Referenced by LV2Ports(), and LV2PortStates::LV2PortStates().

◆ mAudioIn

unsigned LV2Ports::mAudioIn { 0 }

Definition at line 272 of file LV2Ports.h.

Referenced by LV2Instance::GetAudioInCount(), LV2EffectBase::GetType(), and LV2Ports().

◆ mAudioOut

unsigned LV2Ports::mAudioOut { 0 }

Definition at line 273 of file LV2Ports.h.

Referenced by LV2Instance::GetAudioOutCount(), LV2EffectBase::GetType(), and LV2Ports().

◆ mAudioPorts

LV2AudioPortArray LV2Ports::mAudioPorts

Definition at line 271 of file LV2Ports.h.

Referenced by LV2Ports(), LV2Instance::ProcessBlock(), and LV2Instance::RealtimeProcess().

◆ mControlInIdx

std::optional<size_t> LV2Ports::mControlInIdx {}

Definition at line 276 of file LV2Ports.h.

Referenced by LV2Ports(), and LV2PortUIStates::LV2PortUIStates().

◆ mControlOutIdx

std::optional<size_t> LV2Ports::mControlOutIdx {}

Definition at line 277 of file LV2Ports.h.

Referenced by LV2Ports(), and LV2PortUIStates::LV2PortUIStates().

◆ mControlPortMap

std::unordered_map<uint32_t, size_t> LV2Ports::mControlPortMap

Mapping from index number among all ports, to position among the control ports only

Definition at line 288 of file LV2Ports.h.

Referenced by LV2Ports(), and LV2Editor::suil_port_write().

◆ mControlPorts

LV2ControlPortArray LV2Ports::mControlPorts

◆ mCVPorts

LV2CVPortArray LV2Ports::mCVPorts

Definition at line 281 of file LV2Ports.h.

Referenced by LV2Ports(), and LV2PortStates::LV2PortStates().

◆ mGroupMap

std::unordered_map<TranslatableString, std::vector<int> > LV2Ports::mGroupMap

Definition at line 285 of file LV2Ports.h.

Referenced by LV2Editor::BuildPlain(), LV2Ports(), and LV2Editor::UpdateUI().

◆ mGroups

TranslatableStrings LV2Ports::mGroups

Definition at line 284 of file LV2Ports.h.

Referenced by LV2Editor::BuildPlain(), LV2Ports(), and LV2Editor::UpdateUI().

◆ mLatencyPort

int LV2Ports::mLatencyPort { -1 }

Definition at line 289 of file LV2Ports.h.

Referenced by LV2Wrapper::ConnectControlPorts(), and LV2Ports().

◆ mMidiIn

unsigned LV2Ports::mMidiIn { 0 }

Definition at line 278 of file LV2Ports.h.

Referenced by LV2Ports().

◆ mMidiOut

unsigned LV2Ports::mMidiOut { 0 }

Definition at line 279 of file LV2Ports.h.

Referenced by LV2Ports().


The documentation for this class was generated from the following files: