Cleanup
[carla.git] / source / backend / engine / CarlaEngineClient.cpp
blob5d76b6dcf229d79f3be25b57b7570b5576099b0a
1 /*
2 * Carla Plugin Host
3 * Copyright (C) 2011-2020 Filipe Coelho <falktx@falktx.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or any later version.
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.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #include "CarlaEngineClient.hpp"
19 #include "CarlaEngineUtils.hpp"
21 #include "CarlaString.hpp"
23 CARLA_BACKEND_START_NAMESPACE
25 // -----------------------------------------------------------------------
27 static void _getUniquePortName(CarlaString& sname, const CarlaStringList& list)
29 for (CarlaStringList::Itenerator it = list.begin2(); it.valid(); it.next())
31 const char* const portName(it.getValue(nullptr));
32 CARLA_SAFE_ASSERT_CONTINUE(portName != nullptr && portName[0] != '\0');
34 // Check if unique name doesn't exist
35 if (sname != portName)
36 continue;
38 // Check if string has already been modified
40 const std::size_t len(sname.length());
42 // 1 digit, ex: " (2)"
43 if (sname[len-4] == ' ' && sname[len-3] == '(' && sname.isDigit(len-2) && sname[len-1] == ')')
45 const int number = sname[len-2] - '0';
47 if (number == 9)
49 // next number is 10, 2 digits
50 sname.truncate(len-4);
51 sname += " (10)";
52 //sname.replace(" (9)", " (10)");
54 else
55 sname[len-2] = char('0' + number + 1);
57 continue;
60 // 2 digits, ex: " (11)"
61 if (sname[len-5] == ' ' && sname[len-4] == '(' && sname.isDigit(len-3) && sname.isDigit(len-2) && sname[len-1] == ')')
63 char n2 = sname[len-2];
64 char n3 = sname[len-3];
66 if (n2 == '9')
68 n2 = '0';
69 n3 = static_cast<char>(n3 + 1);
71 else
72 n2 = static_cast<char>(n2 + 1);
74 sname[len-2] = n2;
75 sname[len-3] = n3;
77 continue;
81 // Modify string if not
82 sname += " (2)";
86 // -----------------------------------------------------------------------
87 // Carla Engine Client
89 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
90 CarlaEngineClient::ProtectedData::ProtectedData(const CarlaEngine& eng,
91 EngineInternalGraph& eg,
92 const CarlaPluginPtr p) noexcept
93 #else
94 CarlaEngineClient::ProtectedData::ProtectedData(const CarlaEngine& eng) noexcept
95 #endif
96 : engine(eng),
97 active(false),
98 latency(0),
99 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
100 cvSourcePorts(),
101 egraph(eg),
102 plugin(p),
103 #endif
104 audioInList(),
105 audioOutList(),
106 cvInList(),
107 cvOutList(),
108 eventInList(),
109 eventOutList() {}
111 CarlaEngineClient::ProtectedData::~ProtectedData()
113 carla_debug("CarlaEngineClient::ProtectedData::~ProtectedData()");
114 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
115 CARLA_SAFE_ASSERT(plugin.get() == nullptr);
116 #endif
119 void CarlaEngineClient::ProtectedData::addAudioPortName(const bool isInput, const char* const name)
121 CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',);
123 CarlaStringList& portList(isInput ? audioInList : audioOutList);
124 portList.append(name);
127 void CarlaEngineClient::ProtectedData::addCVPortName(const bool isInput, const char* const name)
129 CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',);
131 CarlaStringList& portList(isInput ? cvInList : cvOutList);
132 portList.append(name);
135 void CarlaEngineClient::ProtectedData::addEventPortName(const bool isInput, const char* const name)
137 CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',);
139 CarlaStringList& portList(isInput ? eventInList : eventOutList);
140 portList.append(name);
143 const char* CarlaEngineClient::ProtectedData::getUniquePortName(const char* const name)
145 CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', nullptr);
147 CarlaString sname;
148 sname = name;
150 _getUniquePortName(sname, audioInList);
151 _getUniquePortName(sname, audioOutList);
152 _getUniquePortName(sname, cvInList);
153 _getUniquePortName(sname, cvOutList);
154 _getUniquePortName(sname, eventInList);
155 _getUniquePortName(sname, eventOutList);
157 return sname.dup();
160 void CarlaEngineClient::ProtectedData::clearPorts()
162 audioInList.clear();
163 audioOutList.clear();
164 cvInList.clear();
165 cvOutList.clear();
166 eventInList.clear();
167 eventOutList.clear();
170 // -----------------------------------------------------------------------
172 CarlaEngineClient::CarlaEngineClient(ProtectedData* const p)
173 : pData(p)
175 carla_debug("CarlaEngineClient::CarlaEngineClient()");
178 CarlaEngineClient::~CarlaEngineClient() noexcept
180 carla_debug("CarlaEngineClient::~CarlaEngineClient()");
183 void CarlaEngineClient::activate() noexcept
185 CARLA_SAFE_ASSERT(! pData->active);
186 carla_debug("CarlaEngineClient::activate()");
188 pData->active = true;
191 void CarlaEngineClient::deactivate(const bool willClose) noexcept
193 CARLA_SAFE_ASSERT(pData->active || willClose);
194 carla_debug("CarlaEngineClient::deactivate(%s)", bool2str(willClose));
196 pData->active = false;
198 if (willClose)
200 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
201 pData->cvSourcePorts.resetGraphAndPlugin();
202 pData->plugin.reset();
203 #endif
207 bool CarlaEngineClient::isActive() const noexcept
209 return pData->active;
212 bool CarlaEngineClient::isOk() const noexcept
214 return true;
217 uint32_t CarlaEngineClient::getLatency() const noexcept
219 return pData->latency;
222 void CarlaEngineClient::setLatency(const uint32_t samples) noexcept
224 pData->latency = samples;
227 CarlaEnginePort* CarlaEngineClient::addPort(const EnginePortType portType, const char* const name, const bool isInput, const uint32_t indexOffset)
229 CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', nullptr);
230 carla_debug("CarlaEngineClient::addPort(%i:%s, \"%s\", %s, %u)", portType, EnginePortType2Str(portType), name, bool2str(isInput), indexOffset);
232 switch (portType)
234 case kEnginePortTypeNull:
235 break;
236 case kEnginePortTypeAudio:
237 pData->addAudioPortName(isInput, name);
238 return new CarlaEngineAudioPort(*this, isInput, indexOffset);
239 case kEnginePortTypeCV:
240 pData->addCVPortName(isInput, name);
241 return new CarlaEngineCVPort(*this, isInput, indexOffset);
242 case kEnginePortTypeEvent:
243 pData->addEventPortName(isInput, name);
244 return new CarlaEngineEventPort(*this, isInput, indexOffset);
247 carla_stderr("CarlaEngineClient::addPort(%i, \"%s\", %s) - invalid type", portType, name, bool2str(isInput));
248 return nullptr;
251 bool CarlaEngineClient::removePort(const EnginePortType portType, const char* const name, const bool isInput)
253 CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', false);
254 carla_debug("CarlaEngineClient::removePort(%i:%s, \"%s\", %s)", portType, EnginePortType2Str(portType), name, bool2str(isInput));
256 switch (portType)
258 case kEnginePortTypeNull:
259 break;
260 case kEnginePortTypeAudio: {
261 CarlaStringList& portList(isInput ? pData->audioInList : pData->audioOutList);
262 portList.append(name);
263 return portList.removeOne(name);
265 case kEnginePortTypeCV: {
266 CarlaStringList& portList(isInput ? pData->cvInList : pData->cvOutList);
267 return portList.removeOne(name);
269 case kEnginePortTypeEvent: {
270 CarlaStringList& portList(isInput ? pData->eventInList : pData->eventOutList);
271 return portList.removeOne(name);
275 return false;
278 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
279 CarlaEngineCVSourcePorts* CarlaEngineClient::createCVSourcePorts()
281 pData->cvSourcePorts.setGraphAndPlugin(pData->egraph.getPatchbayGraphOrNull(), pData->plugin);
282 return &pData->cvSourcePorts;
284 #endif
286 const CarlaEngine& CarlaEngineClient::getEngine() const noexcept
288 return pData->engine;
291 EngineProcessMode CarlaEngineClient::getProcessMode() const noexcept
293 return pData->engine.getProccessMode();
296 uint CarlaEngineClient::getPortCount(const EnginePortType portType, const bool isInput) const noexcept
298 size_t ret = 0;
300 switch (portType)
302 case kEnginePortTypeNull:
303 break;
304 case kEnginePortTypeAudio:
305 ret = isInput ? pData->audioInList.count() : pData->audioOutList.count();
306 break;
307 case kEnginePortTypeCV:
308 ret = isInput ? pData->cvInList.count() : pData->cvOutList.count();
309 break;
310 case kEnginePortTypeEvent:
311 ret = isInput ? pData->eventInList.count() : pData->eventOutList.count();
312 break;
315 return static_cast<uint>(ret);
318 const char* CarlaEngineClient::getAudioPortName(const bool isInput, const uint index) const noexcept
320 CarlaStringList& portList(isInput ? pData->audioInList : pData->audioOutList);
321 CARLA_SAFE_ASSERT_RETURN(index < portList.count(), nullptr);
323 return portList.getAt(index);
326 const char* CarlaEngineClient::getCVPortName(const bool isInput, const uint index) const noexcept
328 CarlaStringList& portList(isInput ? pData->cvInList : pData->cvOutList);
329 CARLA_SAFE_ASSERT_RETURN(index < portList.count(), nullptr);
331 return portList.getAt(index);
334 const char* CarlaEngineClient::getEventPortName(const bool isInput, const uint index) const noexcept
336 CarlaStringList& portList(isInput ? pData->eventInList : pData->eventOutList);
337 CARLA_SAFE_ASSERT_RETURN(index < portList.count(), nullptr);
339 return portList.getAt(index);
342 // -----------------------------------------------------------------------
344 CARLA_BACKEND_END_NAMESPACE