3 * Copyright (C) 2011-2019 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 "CarlaEngineOsc.hpp"
22 #include "CarlaBackendUtils.hpp"
23 #include "CarlaEngine.hpp"
24 #include "CarlaPlugin.hpp"
26 CARLA_BACKEND_START_NAMESPACE
28 static const char* const kNullString
= "";
30 // -----------------------------------------------------------------------
32 void CarlaEngineOsc::sendCallback(const EngineCallbackOpcode action
, const uint pluginId
,
33 const int value1
, const int value2
, const int value3
,
34 const float valuef
, const char* const valueStr
) const noexcept
36 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.path
!= nullptr && fControlDataTCP
.path
[0] != '\0',);
37 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.target
!= nullptr,);
38 carla_stdout("CarlaEngineOsc::sendCallback(%i:%s, %i, %i, %i, %i, %f, \"%s\")",
39 action
, EngineCallbackOpcode2Str(action
), pluginId
, value1
, value2
, value3
,
40 static_cast<double>(valuef
), valueStr
);
42 char targetPath
[std::strlen(fControlDataTCP
.path
)+4];
43 std::strcpy(targetPath
, fControlDataTCP
.path
);
44 std::strcat(targetPath
, "/cb");
45 try_lo_send(fControlDataTCP
.target
, targetPath
, "iiiiifs",
46 action
, pluginId
, value1
, value2
, value3
, static_cast<double>(valuef
),
47 valueStr
!= nullptr ? valueStr
: kNullString
);
50 void CarlaEngineOsc::sendPluginInfo(const CarlaPluginPtr
& plugin
) const noexcept
52 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.path
!= nullptr && fControlDataTCP
.path
[0] != '\0',);
53 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.target
!= nullptr,);
54 CARLA_SAFE_ASSERT_RETURN(plugin
!= nullptr,);
55 carla_stdout("CarlaEngineOsc::sendPluginInfo(%p)", plugin
.get());
57 char bufRealName
[STR_MAX
+1], bufLabel
[STR_MAX
+1], bufMaker
[STR_MAX
+1], bufCopyright
[STR_MAX
+1];
58 carla_zeroChars(bufRealName
, STR_MAX
+1);
59 carla_zeroChars(bufLabel
, STR_MAX
+1);
60 carla_zeroChars(bufMaker
, STR_MAX
+1);
61 carla_zeroChars(bufCopyright
, STR_MAX
+1);
63 if (! plugin
->getRealName(bufRealName
))
64 bufRealName
[0] = '\0';
65 if (! plugin
->getLabel(bufLabel
))
67 if (! plugin
->getMaker(bufMaker
))
69 if (! plugin
->getCopyright(bufCopyright
))
70 bufCopyright
[0] = '\0';
72 const char* name
= plugin
->getName();
73 const char* filename
= plugin
->getFilename();
74 const char* iconName
= plugin
->getIconName();
78 if (filename
== nullptr)
79 filename
= kNullString
;
80 if (iconName
== nullptr)
81 iconName
= kNullString
;
83 char targetPath
[std::strlen(fControlDataTCP
.path
)+6];
84 std::strcpy(targetPath
, fControlDataTCP
.path
);
85 std::strcat(targetPath
, "/info");
86 try_lo_send(fControlDataTCP
.target
, targetPath
, "iiiihiisssssss",
87 static_cast<int32_t>(plugin
->getId()),
88 static_cast<int32_t>(plugin
->getType()),
89 static_cast<int32_t>(plugin
->getCategory()),
90 static_cast<int32_t>(plugin
->getHints()),
91 static_cast<int64_t>(plugin
->getUniqueId()),
92 static_cast<int64_t>(plugin
->getOptionsAvailable()),
93 static_cast<int64_t>(plugin
->getOptionsEnabled()),
94 name
, filename
, iconName
,
95 bufRealName
, bufLabel
, bufMaker
, bufCopyright
);
98 void CarlaEngineOsc::sendPluginPortCount(const CarlaPluginPtr
& plugin
) const noexcept
100 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.path
!= nullptr && fControlDataTCP
.path
[0] != '\0',);
101 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.target
!= nullptr,);
102 CARLA_SAFE_ASSERT_RETURN(plugin
!= nullptr,);
103 carla_stdout("CarlaEngineOsc::sendPluginPortCount(%p)", plugin
.get());
105 uint32_t paramIns
, paramOuts
;
106 plugin
->getParameterCountInfo(paramIns
, paramOuts
);
113 char targetPath
[std::strlen(fControlDataTCP
.path
)+7];
114 std::strcpy(targetPath
, fControlDataTCP
.path
);
115 std::strcat(targetPath
, "/ports");
116 try_lo_send(fControlDataTCP
.target
, targetPath
, "iiiiiiii",
117 static_cast<int32_t>(plugin
->getId()),
118 static_cast<int32_t>(plugin
->getAudioInCount()),
119 static_cast<int32_t>(plugin
->getAudioOutCount()),
120 static_cast<int32_t>(plugin
->getMidiInCount()),
121 static_cast<int32_t>(plugin
->getMidiOutCount()),
122 static_cast<int32_t>(paramIns
),
123 static_cast<int32_t>(paramOuts
),
124 static_cast<int32_t>(plugin
->getParameterCount()));
127 void CarlaEngineOsc::sendPluginParameterInfo(const CarlaPluginPtr
& plugin
, const uint32_t index
) const noexcept
129 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.path
!= nullptr && fControlDataTCP
.path
[0] != '\0',);
130 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.target
!= nullptr,);
131 CARLA_SAFE_ASSERT_RETURN(plugin
!= nullptr,);
132 carla_debug("CarlaEngineOsc::sendPluginParameterInfo(%p, %u)", plugin
.get(), index
);
134 char bufName
[STR_MAX
+1], bufUnit
[STR_MAX
+1], bufComment
[STR_MAX
+1], bufGroupName
[STR_MAX
+1];
135 carla_zeroChars(bufName
, STR_MAX
+1);
136 carla_zeroChars(bufUnit
, STR_MAX
+1);
137 carla_zeroChars(bufComment
, STR_MAX
+1);
138 carla_zeroChars(bufGroupName
, STR_MAX
+1);
140 if (! plugin
->getParameterName(index
, bufName
))
142 if (! plugin
->getParameterUnit(index
, bufUnit
))
144 if (! plugin
->getParameterComment(index
, bufComment
))
145 bufComment
[0] = '\0';
146 if (! plugin
->getParameterGroupName(index
, bufGroupName
))
147 bufGroupName
[0] = '\0';
149 const ParameterData
& paramData(plugin
->getParameterData(index
));
150 const ParameterRanges
& paramRanges(plugin
->getParameterRanges(index
));
152 const int32_t pluginId
= static_cast<int32_t>(plugin
->getId());
153 const int32_t paramId
= static_cast<int32_t>(index
);
155 char targetPath
[std::strlen(fControlDataTCP
.path
)+13];
157 std::strcpy(targetPath
, fControlDataTCP
.path
);
158 std::strcat(targetPath
, "/paramInfo");
159 try_lo_send(fControlDataTCP
.target
, targetPath
, "iissss",
167 std::strcpy(targetPath
, fControlDataTCP
.path
);
168 std::strcat(targetPath
, "/paramData");
169 try_lo_send(fControlDataTCP
.target
, targetPath
, "iiiiiifff",
172 static_cast<int32_t>(paramData
.type
),
173 static_cast<int32_t>(paramData
.hints
),
174 static_cast<int32_t>(paramData
.midiChannel
),
175 static_cast<int32_t>(paramData
.mappedControlIndex
),
176 static_cast<double>(paramData
.mappedMinimum
),
177 static_cast<double>(paramData
.mappedMaximum
),
178 static_cast<double>(plugin
->getParameterValue(index
)));
180 std::strcpy(targetPath
, fControlDataTCP
.path
);
181 std::strcat(targetPath
, "/paramRanges");
182 try_lo_send(fControlDataTCP
.target
, targetPath
, "iiffffff",
185 static_cast<double>(paramRanges
.def
),
186 static_cast<double>(paramRanges
.min
),
187 static_cast<double>(paramRanges
.max
),
188 static_cast<double>(paramRanges
.step
),
189 static_cast<double>(paramRanges
.stepSmall
),
190 static_cast<double>(paramRanges
.stepLarge
));
193 void CarlaEngineOsc::sendPluginDataCount(const CarlaPluginPtr
& plugin
) const noexcept
195 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.path
!= nullptr && fControlDataTCP
.path
[0] != '\0',);
196 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.target
!= nullptr,);
197 CARLA_SAFE_ASSERT_RETURN(plugin
!= nullptr,);
198 carla_stdout("CarlaEngineOsc::sendPluginDataCount(%p)", plugin
.get());
200 char targetPath
[std::strlen(fControlDataTCP
.path
)+7];
201 std::strcpy(targetPath
, fControlDataTCP
.path
);
202 std::strcat(targetPath
, "/count");
203 try_lo_send(fControlDataTCP
.target
, targetPath
, "iiiiii",
204 static_cast<int32_t>(plugin
->getId()),
205 static_cast<int32_t>(plugin
->getProgramCount()),
206 static_cast<int32_t>(plugin
->getMidiProgramCount()),
207 static_cast<int32_t>(plugin
->getCustomDataCount()),
208 static_cast<int32_t>(plugin
->getCurrentProgram()),
209 static_cast<int32_t>(plugin
->getCurrentMidiProgram()));
212 void CarlaEngineOsc::sendPluginProgramCount(const CarlaPluginPtr
& plugin
) const noexcept
214 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.path
!= nullptr && fControlDataTCP
.path
[0] != '\0',);
215 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.target
!= nullptr,);
216 CARLA_SAFE_ASSERT_RETURN(plugin
!= nullptr,);
217 carla_stdout("CarlaEngineOsc::sendPluginDataCount(%p)", plugin
.get());
219 char targetPath
[std::strlen(fControlDataTCP
.path
)+7];
220 std::strcpy(targetPath
, fControlDataTCP
.path
);
221 std::strcat(targetPath
, "/pcount");
222 try_lo_send(fControlDataTCP
.target
, targetPath
, "iii",
223 static_cast<int32_t>(plugin
->getId()),
224 static_cast<int32_t>(plugin
->getProgramCount()),
225 static_cast<int32_t>(plugin
->getMidiProgramCount()));
228 void CarlaEngineOsc::sendPluginProgram(const CarlaPluginPtr
& plugin
, const uint32_t index
) const noexcept
230 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.path
!= nullptr && fControlDataTCP
.path
[0] != '\0',);
231 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.target
!= nullptr,);
232 carla_stdout("CarlaEngineOsc::sendPluginProgram(%p, %u)", plugin
.get(), index
);
234 char strBuf
[STR_MAX
+1];
235 carla_zeroChars(strBuf
, STR_MAX
+1);
236 if (! plugin
->getProgramName(index
, strBuf
))
239 char targetPath
[std::strlen(fControlDataTCP
.path
)+6];
240 std::strcpy(targetPath
, fControlDataTCP
.path
);
241 std::strcat(targetPath
, "/prog");
242 try_lo_send(fControlDataTCP
.target
, targetPath
, "iis",
243 static_cast<int32_t>(plugin
->getId()), static_cast<int32_t>(index
), strBuf
);
246 void CarlaEngineOsc::sendPluginMidiProgram(const CarlaPluginPtr
& plugin
, const uint32_t index
) const noexcept
248 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.path
!= nullptr && fControlDataTCP
.path
[0] != '\0',);
249 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.target
!= nullptr,);
250 carla_stdout("CarlaEngineOsc::sendPluginProgram(%p, %u)", plugin
.get(), index
);
252 const MidiProgramData
& mpdata(plugin
->getMidiProgramData(index
));
253 CARLA_SAFE_ASSERT_RETURN(mpdata
.name
!= nullptr,);
255 char targetPath
[std::strlen(fControlDataTCP
.path
)+7];
256 std::strcpy(targetPath
, fControlDataTCP
.path
);
257 std::strcat(targetPath
, "/mprog");
258 try_lo_send(fControlDataTCP
.target
, targetPath
, "iiiis",
259 static_cast<int32_t>(plugin
->getId()),
260 static_cast<int32_t>(index
),
261 static_cast<int32_t>(mpdata
.bank
), static_cast<int32_t>(mpdata
.program
), mpdata
.name
);
264 void CarlaEngineOsc::sendPluginCustomData(const CarlaPluginPtr
& plugin
, const uint32_t index
) const noexcept
266 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.path
!= nullptr && fControlDataTCP
.path
[0] != '\0',);
267 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.target
!= nullptr,);
268 carla_stdout("CarlaEngineOsc::sendPluginCustomData(%p, %u)", plugin
.get(), index
);
270 const CustomData
& cdata(plugin
->getCustomData(index
));
271 CARLA_SAFE_ASSERT_RETURN(cdata
.isValid(),);
273 char targetPath
[std::strlen(fControlDataTCP
.path
)+7];
274 std::strcpy(targetPath
, fControlDataTCP
.path
);
275 std::strcat(targetPath
, "/cdata");
276 try_lo_send(fControlDataTCP
.target
, targetPath
, "iisss",
277 static_cast<int32_t>(plugin
->getId()),
278 static_cast<int32_t>(index
),
279 cdata
.type
, cdata
.key
, cdata
.value
);
282 void CarlaEngineOsc::sendPluginInternalParameterValues(const CarlaPluginPtr
& plugin
) const noexcept
284 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.path
!= nullptr && fControlDataTCP
.path
[0] != '\0',);
285 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.target
!= nullptr,);
286 CARLA_SAFE_ASSERT_RETURN(plugin
!= nullptr,);
287 carla_debug("CarlaEngineOsc::sendPluginInternalParameterValues(%p)", plugin
.get());
289 #ifdef CARLA_PROPER_CPP11_SUPPORT
290 static_assert(PARAMETER_ACTIVE
== -2 && PARAMETER_MAX
== -9, "Incorrect data");
295 for (int32_t i
= 0; i
< 7; ++i
)
296 iparams
[i
] = plugin
->getInternalParameterValue(PARAMETER_ACTIVE
- i
);
298 char targetPath
[std::strlen(fControlDataTCP
.path
)+9];
299 std::strcpy(targetPath
, fControlDataTCP
.path
);
300 std::strcat(targetPath
, "/iparams");
301 try_lo_send(fControlDataTCP
.target
, targetPath
, "ifffffff",
302 static_cast<int32_t>(plugin
->getId()),
303 iparams
[0], // PARAMETER_ACTIVE
304 iparams
[1], // PARAMETER_DRYWET
305 iparams
[2], // PARAMETER_VOLUME
306 iparams
[3], // PARAMETER_BALANCE_LEFT
307 iparams
[4], // PARAMETER_BALANCE_RIGHT
308 iparams
[5], // PARAMETER_PANNING
309 iparams
[6] // PARAMETER_CTRL_CHANNEL
313 // -----------------------------------------------------------------------
315 void CarlaEngineOsc::sendPing() const noexcept
317 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.path
!= nullptr && fControlDataTCP
.path
[0] != '\0',);
318 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.target
!= nullptr,);
320 char targetPath
[std::strlen(fControlDataTCP
.path
)+6];
321 std::strcpy(targetPath
, fControlDataTCP
.path
);
322 std::strcat(targetPath
, "/ping");
323 try_lo_send(fControlDataTCP
.target
, targetPath
, "");
326 void CarlaEngineOsc::sendResponse(const int messageId
, const char* const error
) const noexcept
328 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.path
!= nullptr && fControlDataTCP
.path
[0] != '\0',);
329 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.target
!= nullptr,);
330 carla_debug("CarlaEngineOsc::sendResponse()");
332 char targetPath
[std::strlen(fControlDataTCP
.path
)+6];
333 std::strcpy(targetPath
, fControlDataTCP
.path
);
334 std::strcat(targetPath
, "/resp");
335 try_lo_send(fControlDataTCP
.target
, targetPath
, "is", messageId
, error
);
338 void CarlaEngineOsc::sendExit() const noexcept
340 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.path
!= nullptr && fControlDataTCP
.path
[0] != '\0',);
341 CARLA_SAFE_ASSERT_RETURN(fControlDataTCP
.target
!= nullptr,);
342 carla_debug("CarlaEngineOsc::sendExit()");
344 char targetPath
[std::strlen(fControlDataTCP
.path
)+6];
345 std::strcpy(targetPath
, fControlDataTCP
.path
);
346 std::strcat(targetPath
, "/exit");
347 try_lo_send(fControlDataTCP
.target
, targetPath
, "");
350 // -----------------------------------------------------------------------
352 void CarlaEngineOsc::sendRuntimeInfo() const noexcept
354 CARLA_SAFE_ASSERT_RETURN(fControlDataUDP
.path
!= nullptr && fControlDataUDP
.path
[0] != '\0',);
355 CARLA_SAFE_ASSERT_RETURN(fControlDataUDP
.target
!= nullptr,);
357 const EngineTimeInfo
timeInfo(fEngine
->getTimeInfo());
359 char targetPath
[std::strlen(fControlDataUDP
.path
)+9];
360 std::strcpy(targetPath
, fControlDataUDP
.path
);
361 std::strcat(targetPath
, "/runtime");
362 try_lo_send(fControlDataUDP
.target
, targetPath
, "fiihiiif",
363 static_cast<double>(fEngine
->getDSPLoad()),
364 static_cast<int32_t>(fEngine
->getTotalXruns()),
365 timeInfo
.playing
? 1 : 0,
366 static_cast<int64_t>(timeInfo
.frame
),
367 static_cast<int32_t>(timeInfo
.bbt
.bar
),
368 static_cast<int32_t>(timeInfo
.bbt
.beat
),
369 static_cast<int32_t>(timeInfo
.bbt
.tick
),
370 timeInfo
.bbt
.beatsPerMinute
);
373 void CarlaEngineOsc::sendParameterValue(const uint pluginId
, const uint32_t index
, const float value
) const noexcept
375 CARLA_SAFE_ASSERT_RETURN(fControlDataUDP
.path
!= nullptr && fControlDataUDP
.path
[0] != '\0',);
376 CARLA_SAFE_ASSERT_RETURN(fControlDataUDP
.target
!= nullptr,);
378 char targetPath
[std::strlen(fControlDataUDP
.path
)+7];
379 std::strcpy(targetPath
, fControlDataUDP
.path
);
380 std::strcat(targetPath
, "/param");
381 try_lo_send(fControlDataUDP
.target
, targetPath
, "iif",
382 static_cast<int32_t>(pluginId
),
384 static_cast<double>(value
));
387 void CarlaEngineOsc::sendPeaks(const uint pluginId
, const float peaks
[4]) const noexcept
389 CARLA_SAFE_ASSERT_RETURN(fControlDataUDP
.path
!= nullptr && fControlDataUDP
.path
[0] != '\0',);
390 CARLA_SAFE_ASSERT_RETURN(fControlDataUDP
.target
!= nullptr,);
392 char targetPath
[std::strlen(fControlDataUDP
.path
)+7];
393 std::strcpy(targetPath
, fControlDataUDP
.path
);
394 std::strcat(targetPath
, "/peaks");
395 try_lo_send(fControlDataUDP
.target
, targetPath
, "iffff", static_cast<int32_t>(pluginId
),
396 static_cast<double>(peaks
[0]),
397 static_cast<double>(peaks
[1]),
398 static_cast<double>(peaks
[2]),
399 static_cast<double>(peaks
[3]));
402 // -----------------------------------------------------------------------
404 CARLA_BACKEND_END_NAMESPACE