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"
25 #define try_lo_send(...) \
27 lo_send(__VA_ARGS__); \
28 } CARLA_SAFE_EXCEPTION("lo_send");
30 // -----------------------------------------------------------------------
38 CarlaOscData() noexcept
44 ~CarlaOscData() noexcept
63 if (source
!= nullptr)
66 lo_address_free(source
);
67 } CARLA_SAFE_EXCEPTION("lo_address_free source");
71 if (target
!= nullptr)
74 lo_address_free(target
);
75 } CARLA_SAFE_EXCEPTION("lo_address_free target");
81 void setNewURL(const char* const url
)
89 if (target
!= nullptr)
92 lo_address_free(target
);
93 } CARLA_SAFE_EXCEPTION("lo_address_free target");
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
);
107 CARLA_PREVENT_HEAP_ALLOCATION
108 CARLA_DECLARE_NON_COPYABLE(CarlaOscData
)
111 // -----------------------------------------------------------------------
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
);
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
));
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
));
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
));
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
));
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
));
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
);
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
));
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
);
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
, "");
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
, "");
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
, "");
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 // -----------------------------------------------------------------------
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
);
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 // -----------------------------------------------------------------------
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
);
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