Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 474e92c

Browse files
Implement Lv2 Urid feature (LMMS#5517)
This includes implementing general feature handling, since this is the first supported feature.
1 parent a628a9e commit 474e92c

File tree

9 files changed

+417
-3
lines changed

9 files changed

+417
-3
lines changed

include/Lv2Features.h

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Lv2Features.h - Lv2Features class
3+
*
4+
* Copyright (c) 2020-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
5+
*
6+
* This file is part of LMMS - https://lmms.io
7+
*
8+
* This program is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU General Public
10+
* License as published by the Free Software Foundation; either
11+
* version 2 of the License, or (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
* General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public
19+
* License along with this program (see COPYING); if not, write to the
20+
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
* Boston, MA 02110-1301 USA.
22+
*
23+
*/
24+
25+
#ifndef LV2FEATURES_H
26+
#define LV2FEATURES_H
27+
28+
#include "lmmsconfig.h"
29+
30+
#ifdef LMMS_HAVE_LV2
31+
32+
#include <lv2.h>
33+
#include <map>
34+
#include <vector>
35+
#include "Lv2Manager.h"
36+
37+
/**
38+
Feature container
39+
40+
References all available features for a plugin and maps them to their URIs.
41+
42+
The public member functions should be called in descending order:
43+
44+
1. initCommon: map plugin-common features
45+
2. operator[]: map plugin-specific features
46+
3. createFeatureVectors: create the feature vectors required for
47+
lilv_plugin_instantiate
48+
4. access the latter
49+
*/
50+
class Lv2Features
51+
{
52+
public:
53+
//! Return if a feature is supported by LMMS
54+
static bool isFeatureSupported(const char *featName);
55+
56+
Lv2Features();
57+
58+
//! Register only plugin-common features
59+
void initCommon();
60+
//! Return reference to feature data with given URI featName
61+
void*& operator[](const char* featName);
62+
//! Fill m_features and m_featurePointers with all features
63+
void createFeatureVectors();
64+
//! Return LV2_Feature pointer vector, suited for lilv_plugin_instantiate
65+
const LV2_Feature* const* featurePointers() const
66+
{
67+
return m_featurePointers.data();
68+
}
69+
70+
private:
71+
//! feature storage
72+
std::vector<LV2_Feature> m_features;
73+
//! pointers to m_features, required for lilv_plugin_instantiate
74+
std::vector<const LV2_Feature*> m_featurePointers;
75+
//! features + data, ordered by URI
76+
std::map<const char*, void*, Lv2Manager::CmpStr> m_featureByUri;
77+
};
78+
79+
#endif // LMMS_HAVE_LV2
80+
81+
#endif // LV2FEATURES_H

include/Lv2Manager.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@
3030
#ifdef LMMS_HAVE_LV2
3131

3232
#include <map>
33+
#include <set>
3334
#include <lilv/lilv.h>
3435

3536
#include "Lv2Basics.h"
37+
#include "Lv2UridMap.h"
3638
#include "Plugin.h"
3739

3840

@@ -114,10 +116,31 @@ class Lv2Manager
114116
Iterator begin() { return m_lv2InfoMap.begin(); }
115117
Iterator end() { return m_lv2InfoMap.end(); }
116118

119+
//! strcmp based key comparator for std::set and std::map
120+
struct CmpStr
121+
{
122+
bool operator()(char const *a, char const *b) const;
123+
};
124+
125+
UridMap& uridMap() { return m_uridMap; }
126+
//! Return all
127+
const std::set<const char*, CmpStr>& supportedFeatureURIs() const
128+
{
129+
return m_supportedFeatureURIs;
130+
}
131+
bool isFeatureSupported(const char* featName) const;
132+
117133
private:
134+
// general data
118135
bool m_debug; //!< if set, debug output will be printed
119136
LilvWorld* m_world;
120137
Lv2InfoMap m_lv2InfoMap;
138+
std::set<const char*, CmpStr> m_supportedFeatureURIs;
139+
140+
// feature data that are common for all Lv2Proc
141+
UridMap m_uridMap;
142+
143+
// functions
121144
bool isSubclassOf(const LilvPluginClass *clvss, const char *uriStr);
122145
};
123146

include/Lv2Proc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <QObject>
3535

3636
#include "Lv2Basics.h"
37+
#include "Lv2Features.h"
3738
#include "LinkedModelGroups.h"
3839
#include "Plugin.h"
3940
#include "PluginIssue.h"
@@ -156,13 +157,16 @@ class Lv2Proc : public LinkedModelGroup
156157

157158
const LilvPlugin* m_plugin;
158159
LilvInstance* m_instance;
160+
Lv2Features m_features;
159161

160162
std::vector<std::unique_ptr<Lv2Ports::PortBase>> m_ports;
161163
StereoPortRef m_inPorts, m_outPorts;
162164

163165
//! models for the controls, sorted by port symbols
164166
std::map<std::string, AutomatableModel *> m_connectedModels;
165167

168+
void initPluginSpecificFeatures();
169+
166170
//! load a file in the plugin, but don't do anything in LMMS
167171
void loadFileInternal(const QString &file);
168172
//! allocate m_ports, fill all with metadata, and assign meaning of ports

include/Lv2UridMap.h

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Lv2UridMap.cpp - Lv2UridMap class
3+
*
4+
* Copyright (c) 2019 Johannes Lorenz <j.git$$$lorenz-ho.me, $$$=@>
5+
*
6+
* This file is part of LMMS - https://lmms.io
7+
*
8+
* This program is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU General Public
10+
* License as published by the Free Software Foundation; either
11+
* version 2 of the License, or (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
* General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public
19+
* License along with this program (see COPYING); if not, write to the
20+
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
* Boston, MA 02110-1301 USA.
22+
*
23+
*/
24+
25+
#ifndef LV2URIDMAP_H
26+
#define LV2URIDMAP_H
27+
28+
#include "lmmsconfig.h"
29+
30+
#ifdef LMMS_HAVE_LV2
31+
32+
#include <lv2/lv2plug.in/ns/ext/urid/urid.h>
33+
#include <mutex> // TODO: use semaphore, even though this is not realtime critical
34+
#include <unordered_map>
35+
#include <vector>
36+
37+
/**
38+
* Complete implementation of the Lv2 Urid Map extension
39+
*/
40+
class UridMap
41+
{
42+
std::unordered_map<std::string, LV2_URID> m_map;
43+
std::vector<const char*> m_unMap;
44+
45+
//! mutex for both m_map and m_unMap
46+
//! the URID map is global, which is why a mutex is required here
47+
std::mutex m_MapMutex;
48+
49+
LV2_URID_Map m_mapFeature;
50+
LV2_URID_Unmap m_unmapFeature;
51+
52+
LV2_URID m_lastUrid = 0;
53+
54+
public:
55+
//! constructor; will set up the features
56+
UridMap();
57+
58+
//! map feature function
59+
LV2_URID map(const char* uri);
60+
//! unmap feature function
61+
const char* unmap(LV2_URID urid);
62+
63+
// access the features
64+
LV2_URID_Map* mapFeature() { return &m_mapFeature; }
65+
LV2_URID_Unmap* unmapFeature() { return &m_unmapFeature; }
66+
};
67+
68+
#endif // LMMS_HAVE_LV2
69+
#endif // LV2URIDMAP_H

src/core/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,12 @@ set(LMMS_SRCS
9393

9494
core/lv2/Lv2Basics.cpp
9595
core/lv2/Lv2ControlBase.cpp
96+
core/lv2/Lv2Features.cpp
9697
core/lv2/Lv2Ports.cpp
9798
core/lv2/Lv2Proc.cpp
9899
core/lv2/Lv2Manager.cpp
99100
core/lv2/Lv2SubPluginFeatures.cpp
101+
core/lv2/Lv2UridMap.cpp
100102

101103
core/midi/MidiAlsaRaw.cpp
102104
core/midi/MidiAlsaSeq.cpp

src/core/lv2/Lv2Features.cpp

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Lv2Features.cpp - Lv2Features implementation
3+
*
4+
* Copyright (c) 2020-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
5+
*
6+
* This file is part of LMMS - https://lmms.io
7+
*
8+
* This program is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU General Public
10+
* License as published by the Free Software Foundation; either
11+
* version 2 of the License, or (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
* General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public
19+
* License along with this program (see COPYING); if not, write to the
20+
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
* Boston, MA 02110-1301 USA.
22+
*
23+
*/
24+
25+
#include "Lv2Features.h"
26+
27+
#ifdef LMMS_HAVE_LV2
28+
29+
#include <QtGlobal>
30+
31+
#include "Engine.h"
32+
#include "Lv2Manager.h"
33+
34+
35+
bool Lv2Features::isFeatureSupported(const char* featName)
36+
{
37+
return Engine::getLv2Manager()->isFeatureSupported(featName);
38+
}
39+
40+
41+
42+
43+
Lv2Features::Lv2Features()
44+
{
45+
const Lv2Manager* man = Engine::getLv2Manager();
46+
// create (yet empty) map feature URI -> feature
47+
for(const char* uri : man->supportedFeatureURIs())
48+
{
49+
m_featureByUri.emplace(uri, nullptr);
50+
}
51+
}
52+
53+
54+
55+
56+
void Lv2Features::initCommon()
57+
{
58+
Lv2Manager* man = Engine::getLv2Manager();
59+
// init m_featureByUri with the plugin-common features
60+
operator[](LV2_URID__map) = man->uridMap().mapFeature();
61+
operator[](LV2_URID__unmap) = man->uridMap().unmapFeature();
62+
}
63+
64+
65+
66+
67+
void Lv2Features::createFeatureVectors()
68+
{
69+
// create vector of features
70+
for(std::pair<const char* const, void*>& pr : m_featureByUri)
71+
{
72+
Q_ASSERT(pr.second != nullptr);
73+
m_features.push_back(LV2_Feature { pr.first, pr.second });
74+
}
75+
76+
// create pointer vector (for lilv_plugin_instantiate)
77+
m_featurePointers.reserve(m_features.size() + 1);
78+
for(std::size_t i = 0; i < m_features.size(); ++i)
79+
{
80+
m_featurePointers.push_back(&m_features[i]);
81+
}
82+
m_featurePointers.push_back(nullptr);
83+
}
84+
85+
86+
87+
88+
void *&Lv2Features::operator[](const char *featName)
89+
{
90+
auto itr = m_featureByUri.find(featName);
91+
Q_ASSERT(itr != m_featureByUri.end());
92+
return itr->second;
93+
}
94+
95+
96+
#endif // LMMS_HAVE_LV2
97+

src/core/lv2/Lv2Manager.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#ifdef LMMS_HAVE_LV2
2828

2929
#include <cstdlib>
30+
#include <cstring>
3031
#include <lilv/lilv.h>
3132
#include <lv2.h>
3233
#include <QDebug>
@@ -50,6 +51,9 @@ Lv2Manager::Lv2Manager()
5051

5152
m_world = lilv_world_new();
5253
lilv_world_load_all(m_world);
54+
55+
m_supportedFeatureURIs.insert(LV2_URID__map);
56+
m_supportedFeatureURIs.insert(LV2_URID__unmap);
5357
}
5458

5559

@@ -133,6 +137,22 @@ void Lv2Manager::initPlugins()
133137

134138

135139

140+
bool Lv2Manager::CmpStr::operator()(const char *a, const char *b) const
141+
{
142+
return std::strcmp(a, b) < 0;
143+
}
144+
145+
146+
147+
148+
bool Lv2Manager::isFeatureSupported(const char *featName) const
149+
{
150+
return m_supportedFeatureURIs.find(featName) != m_supportedFeatureURIs.end();
151+
}
152+
153+
154+
155+
136156
// unused + untested yet
137157
bool Lv2Manager::isSubclassOf(const LilvPluginClass* clvss, const char* uriStr)
138158
{

0 commit comments

Comments
 (0)