Fix last commit
[carla.git] / source / utils / CarlaOscUtils.hpp
blob8df7057939a0b6c5c1397eeac4d7f1d0f90b0c2d
1 /*
2 * Carla OSC utils
3 * Copyright (C) 2012-2022 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 #ifndef CARLA_OSC_UTILS_HPP_INCLUDED
19 #define CARLA_OSC_UTILS_HPP_INCLUDED
21 #include "CarlaUtils.hpp"
23 #include <lo/lo.h>
25 #define try_lo_send(...) \
26 try { \
27 lo_send(__VA_ARGS__); \
28 } CARLA_SAFE_EXCEPTION("lo_send");
30 // -----------------------------------------------------------------------
32 struct CarlaOscData {
33 const char* owner;
34 const char* path;
35 lo_address source;
36 lo_address target;
38 CarlaOscData() noexcept
39 : owner(nullptr),
40 path(nullptr),
41 source(nullptr),
42 target(nullptr) {}
44 ~CarlaOscData() noexcept
46 clear();
49 void clear() noexcept
51 if (owner != nullptr)
53 delete[] owner;
54 owner = nullptr;
57 if (path != nullptr)
59 delete[] path;
60 path = nullptr;
63 if (source != nullptr)
65 try {
66 lo_address_free(source);
67 } CARLA_SAFE_EXCEPTION("lo_address_free source");
68 source = nullptr;
71 if (target != nullptr)
73 try {
74 lo_address_free(target);
75 } CARLA_SAFE_EXCEPTION("lo_address_free target");
76 target = nullptr;
80 #if 0
81 void setNewURL(const char* const url)
83 if (path != nullptr)
85 delete[] path;
86 path = nullptr;
89 if (target != nullptr)
91 try {
92 lo_address_free(target);
93 } CARLA_SAFE_EXCEPTION("lo_address_free target");
94 target = nullptr;
97 char* const host = lo_url_get_hostname(url);
98 char* const port = lo_url_get_port(url);
99 path = carla_strdup_free(lo_url_get_path(url));
100 target = lo_address_new_with_proto(LO_UDP, host, port);
102 std::free(host);
103 std::free(port);
105 #endif
107 CARLA_PREVENT_HEAP_ALLOCATION
108 CARLA_DECLARE_NON_COPYABLE(CarlaOscData)
111 // -----------------------------------------------------------------------
113 static inline
114 void osc_send_configure(const CarlaOscData& oscData, const char* const key, const char* const value) noexcept
116 CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
117 CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
118 CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
119 CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
120 carla_debug("osc_send_configure(path:\"%s\", \"%s\", \"%s\")", oscData.path, key, value);
122 char targetPath[std::strlen(oscData.path)+11];
123 std::strcpy(targetPath, oscData.path);
124 std::strcat(targetPath, "/configure");
125 try_lo_send(oscData.target, targetPath, "ss", key, value);
128 static inline
129 void osc_send_control(const CarlaOscData& oscData, const int32_t index, const float value) noexcept
131 CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
132 CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
133 CARLA_SAFE_ASSERT_RETURN(index != -1,); // -1 == PARAMETER_NULL
134 carla_debug("osc_send_control(path:\"%s\", %i, %f)", oscData.path, index, static_cast<double>(value));
136 char targetPath[std::strlen(oscData.path)+9];
137 std::strcpy(targetPath, oscData.path);
138 std::strcat(targetPath, "/control");
139 try_lo_send(oscData.target, targetPath, "if", index, static_cast<double>(value));
142 static inline
143 void osc_send_program(const CarlaOscData& oscData, const uint32_t index) noexcept
145 CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
146 CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
147 carla_debug("osc_send_program(path:\"%s\", %u)", oscData.path, index);
149 char targetPath[std::strlen(oscData.path)+9];
150 std::strcpy(targetPath, oscData.path);
151 std::strcat(targetPath, "/program");
152 try_lo_send(oscData.target, targetPath, "i", static_cast<int32_t>(index));
155 static inline
156 void osc_send_program(const CarlaOscData& oscData, const uint32_t bank, const uint32_t program) noexcept
158 CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
159 CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
160 carla_debug("osc_send_program(path:\"%s\", %u, %u)", oscData.path, bank, program);
162 char targetPath[std::strlen(oscData.path)+9];
163 std::strcpy(targetPath, oscData.path);
164 std::strcat(targetPath, "/program");
165 try_lo_send(oscData.target, targetPath, "ii", static_cast<int32_t>(bank), static_cast<int32_t>(program));
168 static inline
169 void osc_send_midi_program(const CarlaOscData& oscData, const uint32_t index) noexcept
171 CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
172 CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
173 carla_debug("osc_send_midi_program(path:\"%s\", %u)", oscData.path, index);
175 char targetPath[std::strlen(oscData.path)+14];
176 std::strcpy(targetPath, oscData.path);
177 std::strcat(targetPath, "/midi-program");
178 try_lo_send(oscData.target, targetPath, "i", static_cast<int32_t>(index));
181 static inline
182 void osc_send_midi_program(const CarlaOscData& oscData, const uint32_t bank, const uint32_t program) noexcept
184 CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
185 CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
186 carla_debug("osc_send_midi_program(path:\"%s\", %u, %u)", oscData.path, bank, program);
188 char targetPath[std::strlen(oscData.path)+14];
189 std::strcpy(targetPath, oscData.path);
190 std::strcat(targetPath, "/midi-program");
191 try_lo_send(oscData.target, targetPath, "ii", static_cast<int32_t>(bank), static_cast<int32_t>(program));
194 static inline
195 void osc_send_midi(const CarlaOscData& oscData, const uint8_t buf[4]) noexcept
197 CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
198 CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
199 CARLA_SAFE_ASSERT_RETURN(buf[0] == 0,);
200 CARLA_SAFE_ASSERT_RETURN(buf[1] != 0,);
201 carla_debug("osc_send_midi(path:\"%s\", port:%u, {0x%X, %03u, %03u})", oscData.path, buf[0], buf[1], buf[2], buf[3]);
203 char targetPath[std::strlen(oscData.path)+6];
204 std::strcpy(targetPath, oscData.path);
205 std::strcat(targetPath, "/midi");
206 try_lo_send(oscData.target, targetPath, "m", buf);
209 static inline
210 void osc_send_sample_rate(const CarlaOscData& oscData, const float sampleRate) noexcept
212 CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
213 CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
214 CARLA_SAFE_ASSERT_RETURN(sampleRate > 0.0f,);
215 carla_debug("osc_send_sample_rate(path:\"%s\", %f)", oscData.path, static_cast<double>(sampleRate));
217 char targetPath[std::strlen(oscData.path)+13];
218 std::strcpy(targetPath, oscData.path);
219 std::strcat(targetPath, "/sample-rate");
220 try_lo_send(oscData.target, targetPath, "f", static_cast<double>(sampleRate));
223 static inline
224 void osc_send_update(const CarlaOscData& oscData, const char* const url) noexcept
226 CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
227 CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
228 CARLA_SAFE_ASSERT_RETURN(url != nullptr && url[0] != '\0',);
229 carla_debug("osc_send_update(path:\"%s\", \"%s\")", oscData.path, url);
231 char targetPath[std::strlen(oscData.path)+8];
232 std::strcpy(targetPath, oscData.path);
233 std::strcat(targetPath, "/update");
234 try_lo_send(oscData.target, targetPath, "s", url);
237 static inline
238 void osc_send_show(const CarlaOscData& oscData) noexcept
240 CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
241 CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
242 carla_debug("osc_send_show(path:\"%s\")", oscData.path);
244 char targetPath[std::strlen(oscData.path)+6];
245 std::strcpy(targetPath, oscData.path);
246 std::strcat(targetPath, "/show");
247 try_lo_send(oscData.target, targetPath, "");
250 static inline
251 void osc_send_hide(const CarlaOscData& oscData) noexcept
253 CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
254 CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
255 carla_debug("osc_send_hide(path:\"%s\")", oscData.path);
257 char targetPath[std::strlen(oscData.path)+6];
258 std::strcpy(targetPath, oscData.path);
259 std::strcat(targetPath, "/hide");
260 try_lo_send(oscData.target, targetPath, "");
263 static inline
264 void osc_send_quit(const CarlaOscData& oscData) noexcept
266 CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
267 CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
268 carla_debug("osc_send_quit(path:\"%s\")", oscData.path);
270 char targetPath[std::strlen(oscData.path)+6];
271 std::strcpy(targetPath, oscData.path);
272 std::strcat(targetPath, "/quit");
273 try_lo_send(oscData.target, targetPath, "");
276 static inline
277 void osc_send_exiting(const CarlaOscData& oscData) noexcept
279 CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
280 CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
281 carla_debug("osc_send_exiting(path:\"%s\")", oscData.path);
283 char targetPath[std::strlen(oscData.path)+9];
284 std::strcpy(targetPath, oscData.path);
285 std::strcat(targetPath, "/exiting");
286 try_lo_send(oscData.target, targetPath, "");
289 // -----------------------------------------------------------------------
291 static inline
292 void osc_send_bridge_ready(const CarlaOscData& oscData, const char* const url) noexcept
294 CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
295 CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
296 CARLA_SAFE_ASSERT_RETURN(url != nullptr && url[0] != '\0',);
297 carla_debug("osc_send_bridge_ready(path:\"%s\", \"%s\")", oscData.path, url);
299 char targetPath[std::strlen(oscData.path)+18];
300 std::strcpy(targetPath, oscData.path);
301 std::strcat(targetPath, "/bridge_ready");
302 try_lo_send(oscData.target, targetPath, "s", url);
305 static inline
306 void osc_send_bridge_error(const CarlaOscData& oscData, const char* const error) noexcept
308 CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
309 CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
310 CARLA_SAFE_ASSERT_RETURN(error != nullptr && error[0] != '\0',);
311 carla_debug("osc_send_bridge_error(path:\"%s\", \"%s\")", oscData.path, error);
313 char targetPath[std::strlen(oscData.path)+14];
314 std::strcpy(targetPath, oscData.path);
315 std::strcat(targetPath, "/bridge_error");
316 try_lo_send(oscData.target, targetPath, "s", error);
319 // -----------------------------------------------------------------------
321 static inline
322 void osc_send_lv2_atom_transfer(const CarlaOscData& oscData, const uint32_t portIndex, const char* const atomBuf) noexcept
324 CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
325 CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
326 CARLA_SAFE_ASSERT_RETURN(atomBuf != nullptr && atomBuf[0] != '\0',);
327 carla_debug("osc_send_lv2_atom_transfer(path:\"%s\", %u, <atomBuf:%p>)", oscData.path, portIndex, atomBuf);
329 char targetPath[std::strlen(oscData.path)+19];
330 std::strcpy(targetPath, oscData.path);
331 std::strcat(targetPath, "/lv2_atom_transfer");
332 try_lo_send(oscData.target, targetPath, "is", static_cast<int32_t>(portIndex), atomBuf);
335 static inline
336 void osc_send_lv2_urid_map(const CarlaOscData& oscData, const uint32_t urid, const char* const uri) noexcept
338 CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
339 CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
340 //CARLA_SAFE_ASSERT_RETURN(urid != 0,);
341 CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0',);
342 carla_debug("osc_send_lv2_urid_map(path:\"%s\", %u, \"%s\")", oscData.path, urid, uri);
344 char targetPath[std::strlen(oscData.path)+14];
345 std::strcpy(targetPath, oscData.path);
346 std::strcat(targetPath, "/lv2_urid_map");
347 try_lo_send(oscData.target, targetPath, "is", static_cast<int32_t>(urid), uri);
350 // -----------------------------------------------------------------------
352 #endif // CARLA_OSC_UTILS_HPP_INCLUDED