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
)
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';
49 // next number is 10, 2 digits
50 sname
.truncate(len
-4);
52 //sname.replace(" (9)", " (10)");
55 sname
[len
-2] = char('0' + number
+ 1);
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];
69 n3
= static_cast<char>(n3
+ 1);
72 n2
= static_cast<char>(n2
+ 1);
81 // Modify string if not
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
94 CarlaEngineClient::ProtectedData::ProtectedData(const CarlaEngine
& eng
) noexcept
99 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
111 CarlaEngineClient::ProtectedData::~ProtectedData()
113 carla_debug("CarlaEngineClient::ProtectedData::~ProtectedData()");
114 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
115 CARLA_SAFE_ASSERT(plugin
.get() == nullptr);
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);
150 _getUniquePortName(sname
, audioInList
);
151 _getUniquePortName(sname
, audioOutList
);
152 _getUniquePortName(sname
, cvInList
);
153 _getUniquePortName(sname
, cvOutList
);
154 _getUniquePortName(sname
, eventInList
);
155 _getUniquePortName(sname
, eventOutList
);
160 void CarlaEngineClient::ProtectedData::clearPorts()
163 audioOutList
.clear();
167 eventOutList
.clear();
170 // -----------------------------------------------------------------------
172 CarlaEngineClient::CarlaEngineClient(ProtectedData
* const 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;
200 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
201 pData
->cvSourcePorts
.resetGraphAndPlugin();
202 pData
->plugin
.reset();
207 bool CarlaEngineClient::isActive() const noexcept
209 return pData
->active
;
212 bool CarlaEngineClient::isOk() const noexcept
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
);
234 case kEnginePortTypeNull
:
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
));
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
));
258 case kEnginePortTypeNull
:
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
);
278 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
279 CarlaEngineCVSourcePorts
* CarlaEngineClient::createCVSourcePorts()
281 pData
->cvSourcePorts
.setGraphAndPlugin(pData
->egraph
.getPatchbayGraphOrNull(), pData
->plugin
);
282 return &pData
->cvSourcePorts
;
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
302 case kEnginePortTypeNull
:
304 case kEnginePortTypeAudio
:
305 ret
= isInput
? pData
->audioInList
.count() : pData
->audioOutList
.count();
307 case kEnginePortTypeCV
:
308 ret
= isInput
? pData
->cvInList
.count() : pData
->cvOutList
.count();
310 case kEnginePortTypeEvent
:
311 ret
= isInput
? pData
->eventInList
.count() : pData
->eventOutList
.count();
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