drumstick 2.6.0
backendmanager.cpp
Go to the documentation of this file.
1/*
2 Drumstick RT (realtime MIDI In/Out)
3 Copyright (C) 2009-2022 Pedro Lopez-Cabanillas <plcl@users.sf.net>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#include <QCoreApplication>
20#include <QDir>
21#include <QLibraryInfo>
22#include <QPluginLoader>
23#include <QtGlobal>
25
31namespace drumstick { namespace rt {
32
50 class BackendManager::BackendManagerPrivate {
51 public:
52 QList<MIDIInput*> m_inputsList;
53 QList<MIDIOutput*> m_outputsList;
54
55 QString m_inputBackend{QLatin1String("Network")};
56 #if defined(Q_OS_LINUX)
57 QStringList m_outputBackends{QLatin1String("SonivoxEAS"),QLatin1String("FluidSynth"),QLatin1String("ALSA")};
58 #elif defined(Q_OS_DARWIN)
59 QStringList m_outputBackends{QLatin1String("DLS Synth"),QLatin1String("FluidSynth"),QLatin1String("CoreMIDI")};
60 #elif defined(Q_OS_WINDOWS)
61 QStringList m_outputBackends{QLatin1String("Windows MM"),QLatin1String("FluidSynth")};
62 #elif defined(Q_OS_UNIX)
63 QStringList m_outputBackends{QLatin1String("FluidSynth"),QLatin1String("OSS")};
64 #else
65 QStringList m_outputBackends{m_inputBackend};
66 #endif
67
68 ~BackendManagerPrivate()
69 {
70 clearLists();
71 }
72 void clearLists()
73 {
74 m_inputsList.clear();
75 m_outputsList.clear();
76 }
77 void appendDir(const QString& candidate, QStringList& result)
78 {
79 QDir checked(candidate.trimmed());
80 //qDebug() << Q_FUNC_INFO << candidate << "exists:" << checked.exists();
81 if (checked.exists() && !result.contains(checked.absolutePath())) {
82 result << checked.absolutePath();
83 }
84 }
85 };
86
90 BackendManager::BackendManager(): d(new BackendManagerPrivate)
91 {
92 QVariantMap defaultSettings {
93 { QSTR_DRUMSTICKRT_PUBLICNAMEIN, QStringLiteral("MIDI In")},
94 { QSTR_DRUMSTICKRT_PUBLICNAMEOUT, QStringLiteral("MIDI Out")}
95 };
96 refresh(defaultSettings);
97 }
98
103 { }
104
110 {
111 QStringList result;
112 QString appPath = QCoreApplication::applicationDirPath() + QDir::separator();
113 #if defined(Q_OS_WIN)
114 d->appendDir( appPath + QSTR_DRUMSTICK, result );
115 d->appendDir( appPath + "../lib/" + QSTR_DRUMSTICK, result );
116 #else
117 #if defined(Q_OS_MAC)
118 d->appendDir( appPath + QStringLiteral("../PlugIns/") + QSTR_DRUMSTICK, result );
119 #endif // Linux, Unix...
120 QStringList libs;
121 libs << "../lib/";
122 #if defined(LIBSUFFIX)
123 libs << QString("../%1/").arg(QT_STRINGIFY(LIBSUFFIX));
124 #endif
125 foreach(const QString& lib, libs) {
126 d->appendDir( appPath + lib + QSTR_DRUMSTICK, result );
127 }
128 #endif
129 d->appendDir( appPath + ".." + QDir::separator() + QSTR_DRUMSTICK, result );
130 QByteArray envdir = qgetenv(QSTR_DRUMSTICKRT.toLatin1());
131 //qDebug() << Q_FUNC_INFO << "envdir:" << envdir;
132 if(!envdir.isEmpty()) {
133 d->appendDir(QString(envdir), result );
134 }
135 d->appendDir( QDir::homePath() + QDir::separator() + QSTR_DRUMSTICK, result );
136#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
137 d->appendDir( QLibraryInfo::location(QLibraryInfo::PluginsPath) + QDir::separator() + QSTR_DRUMSTICK, result );
138#else
139 d->appendDir( QLibraryInfo::path(QLibraryInfo::PluginsPath) + QDir::separator() + QSTR_DRUMSTICK, result );
140#endif
141 foreach(const QString& path, QCoreApplication::libraryPaths()) {
142 d->appendDir( path + QDir::separator() + QSTR_DRUMSTICK, result );
143 }
144 return result;
145 }
146
152 {
153 QVariantMap tmpMap;
154 settings->beginGroup(QSTR_DRUMSTICKRT_GROUP);
155 const QStringList allKeys = settings->allKeys();
156 //qDebug() << Q_FUNC_INFO << allKeys;
157 for(const auto &k : allKeys) {
158 tmpMap.insert(k, settings->value(k));
159 }
160 settings->endGroup();
161 refresh(tmpMap);
162 }
163
169 void BackendManager::refresh(const QVariantMap &map)
170 {
171 QString name_in;
172 QString name_out;
173 QStringList names;
174 QStringList paths;
175
176 d->appendDir(map.value(QSTR_DRUMSTICKRT_PATH).toString(), paths);
177 name_in = map.value(QSTR_DRUMSTICKRT_PUBLICNAMEIN).toString();
178 name_out = map.value(QSTR_DRUMSTICKRT_PUBLICNAMEOUT).toString();
179 names << map.value(QSTR_DRUMSTICKRT_EXCLUDED).toStringList();
180 names << (name_in.isEmpty() ? QStringLiteral("MIDI In") : name_in);
181 names << (name_out.isEmpty() ? QStringLiteral("MIDI Out") : name_out);
182 paths << defaultPaths();
183 //qDebug() << Q_FUNC_INFO << "names:" << names;
184 //qDebug() << Q_FUNC_INFO << "paths:" << paths;
185
186 d->clearLists();
187
188 // Dynamic backends
189 foreach(const QString& dir, paths) {
190 QDir pluginsDir(dir);
191 foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
192 if (QLibrary::isLibrary(fileName)) {
193 QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
194 QObject *obj = loader.instance();
195 if (obj != nullptr) {
196 MIDIInput *input = qobject_cast<MIDIInput*>(obj);
197 if (input != nullptr && !d->m_inputsList.contains(input)) {
198 if (!name_in.isEmpty()) {
199 input->setPublicName(name_in);
200 }
201 input->setExcludedConnections(names);
202 d->m_inputsList << input;
203 } else {
204 MIDIOutput *output = qobject_cast<MIDIOutput*>(obj);
205 if (output != nullptr && !d->m_outputsList.contains(output)) {
206 if (!name_out.isEmpty()) {
207 output->setPublicName(name_out);
208 }
209 output->setExcludedConnections(names);
210 d->m_outputsList << output;
211 }
212 }
213 }
214 }
215 }
216 }
217
218 // Static backends
219 foreach(QObject* obj, QPluginLoader::staticInstances()) {
220 if (obj != nullptr) {
221 MIDIInput *input = qobject_cast<MIDIInput*>(obj);
222 if (input != nullptr && !d->m_inputsList.contains(input)) {
223 if (!name_in.isEmpty()) {
224 input->setPublicName(name_in);
225 }
226 input->setExcludedConnections(names);
227 d->m_inputsList << input;
228 } else {
229 MIDIOutput *output = qobject_cast<MIDIOutput*>(obj);
230 if (output != nullptr && !d->m_outputsList.contains(output)) {
231 if (!name_out.isEmpty()) {
232 output->setPublicName(name_out);
233 }
234 output->setExcludedConnections(names);
235 d->m_outputsList << output;
236 }
237 }
238 }
239 }
240 }
241
243 {
244 return d->m_inputsList;
245 }
246
248 {
249 return d->m_outputsList;
250 }
251
253 {
254 foreach (MIDIInput* i, d->m_inputsList) {
255 if (i->backendName() == name) {
256 return i;
257 }
258 }
259 return nullptr;
260 }
261
263 {
264 foreach (MIDIOutput* i, d->m_outputsList) {
265 if (i->backendName() == name) {
266 return i;
267 }
268 }
269 return nullptr;
270 }
271
273 {
274 QStringList names{name};
275 names << d->m_inputBackend;
276 names.removeDuplicates();
277 if (!names.isEmpty()) {
278 foreach(const QString& n, names) {
279 foreach(MIDIInput* input, d->m_inputsList) {
280 if (input->backendName() == n) {
281 return input;
282 }
283 }
284 }
285 }
286 return nullptr;
287 }
288
290 {
291 QStringList names{name};
292 names << d->m_outputBackends;
293 names.removeDuplicates();
294 if (!names.isEmpty()) {
295 foreach(const QString& n, names) {
296 foreach(MIDIOutput* output, d->m_outputsList) {
297 if (output->backendName() == n) {
298 return output;
299 }
300 }
301 }
302 }
303 return nullptr;
304 }
305
306 const QString BackendManager::QSTR_DRUMSTICK = QStringLiteral("drumstick2");
307 const QString BackendManager::QSTR_DRUMSTICK_VERSION = QStringLiteral(QT_STRINGIFY(VERSION));
308 const QString BackendManager::QSTR_DRUMSTICKRT = QStringLiteral("DRUMSTICKRT");
309 const QString BackendManager::QSTR_DRUMSTICKRT_GROUP = QStringLiteral("DrumstickRT");
310 const QString BackendManager::QSTR_DRUMSTICKRT_PUBLICNAMEIN = QStringLiteral("PublicNameIN");
311 const QString BackendManager::QSTR_DRUMSTICKRT_PUBLICNAMEOUT = QStringLiteral("PublicNameOUT");
312 const QString BackendManager::QSTR_DRUMSTICKRT_EXCLUDED = QStringLiteral("ExcludedNames");
313 const QString BackendManager::QSTR_DRUMSTICKRT_PATH = QStringLiteral("BackendsPath");
314
320 {
321 return BackendManager::QSTR_DRUMSTICK_VERSION;
322 }
323
324} // namespace rt
325} // namespace drumstick
BackendManager class declaration.
The QObject class is the base class of all Qt objects.
The QSettings class provides persistent platform-independent application settings.
QList< MIDIInput * > availableInputs()
availableInputs
virtual ~BackendManager()
~BackendManager destructor
BackendManager()
BackendManager constructor.
MIDIOutput * outputBackendByName(const QString name)
outputBackendByName
void refresh(QSettings *settings=nullptr)
refresh the list of backends
QList< MIDIOutput * > availableOutputs()
availableOutputs
MIDIOutput * findOutput(QString name)
findOutput returns the backend corresponding to the provided name, or a suitable output instead.
MIDIInput * findInput(QString name)
findInput returns the backend corresponding to the provided name, or a suitable input instead.
QStringList defaultPaths()
defaultPaths
MIDIInput * inputBackendByName(const QString name)
inputBackendByName
MIDI IN interface.
Definition: rtmidiinput.h:46
virtual void setExcludedConnections(QStringList conns)=0
setExcludedConnections
virtual QString backendName()=0
backendName
virtual void setPublicName(QString name)=0
setPublicName
MIDI OUT interface.
Definition: rtmidioutput.h:112
virtual void setExcludedConnections(QStringList conns)=0
setExcludedConnections
virtual QString backendName()=0
backendName
virtual void setPublicName(QString name)=0
setPublicName
QString DRUMSTICK_EXPORT drumstickLibraryVersion()
drumstickLibraryVersion provides the Drumstick version as an edited QString
Drumstick common.
Definition: alsaclient.cpp:68