VST3: fetch midi mappings all at once, use it for note/sound-off
[carla.git] / source / libjack / libjack_ports.cpp
blob16790b33e077cabd952f82d607ee54aa766e4db3
1 /*
2 * Carla JACK API for external applications
3 * Copyright (C) 2016-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 #include "libjack.hpp"
20 CARLA_BACKEND_USE_NAMESPACE
22 // --------------------------------------------------------------------------------------------------------------------
24 static uint32_t gPortId = JackPortState::kPortIdOffsetUser;
26 CARLA_PLUGIN_EXPORT
27 jack_port_t* jack_port_register(jack_client_t* client, const char* port_name, const char* port_type,
28 unsigned long flags, unsigned long buffer_size)
30 carla_debug("%s(%p, %s, %s, 0x%lx, %lu)", __FUNCTION__, client, port_name, port_type, flags, buffer_size);
32 JackClientState* const jclient = (JackClientState*)client;
33 CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, nullptr);
35 CARLA_SAFE_ASSERT_RETURN(port_name != nullptr && port_name[0] != '\0', nullptr);
36 CARLA_SAFE_ASSERT_RETURN(port_type != nullptr && port_type[0] != '\0', nullptr);
38 const JackServerState& jserver(jclient->server);
40 if (std::strcmp(port_type, JACK_DEFAULT_AUDIO_TYPE) == 0)
42 if (flags & JackPortIsInput)
44 const std::size_t index = jclient->audioIns.count();
45 const uint gid = ++gPortId;
46 JackPortState* const port = new JackPortState(jclient->name, port_name,
47 static_cast<uint>(index),
48 static_cast<int>(flags),
49 gid,
50 false, false, index < jserver.numAudioIns);
53 const CarlaMutexLocker cms(jclient->mutex);
54 jclient->audioIns.append(port);
57 jclient->portIdMapping[gid] = port;
58 jclient->portNameMapping[port->fullname] = port;
59 return (jack_port_t*)port;
62 if (flags & JackPortIsOutput)
64 const std::size_t index = jclient->audioOuts.count();
65 const uint gid = ++gPortId;
66 JackPortState* const port = new JackPortState(jclient->name, port_name,
67 static_cast<uint>(index),
68 static_cast<int>(flags),
69 gid,
70 false, false, index < jserver.numAudioOuts);
73 const CarlaMutexLocker cms(jclient->mutex);
74 jclient->audioOuts.append(port);
77 jclient->portIdMapping[gid] = port;
78 jclient->portNameMapping[port->fullname] = port;
79 return (jack_port_t*)port;
82 carla_stderr2("jack_port_register: invalid port flags '%x'", flags);
83 return nullptr;
86 if (std::strcmp(port_type, JACK_DEFAULT_MIDI_TYPE) == 0)
88 if (flags & JackPortIsInput)
90 const std::size_t index = jclient->midiIns.count();
91 const uint gid = ++gPortId;
92 JackPortState* const port = new JackPortState(jclient->name, port_name,
93 static_cast<uint>(index),
94 static_cast<int>(flags),
95 gid,
96 true, false, index < jserver.numMidiIns);
99 const CarlaMutexLocker cms(jclient->mutex);
100 jclient->midiIns.append(port);
103 jclient->portIdMapping[gid] = port;
104 jclient->portNameMapping[port->fullname] = port;
105 return (jack_port_t*)port;
108 if (flags & JackPortIsOutput)
110 const std::size_t index = jclient->midiOuts.count();
111 const uint gid = ++gPortId;
112 JackPortState* const port = new JackPortState(jclient->name, port_name,
113 static_cast<uint>(index),
114 static_cast<int>(flags),
115 gid,
116 true, false, index < jserver.numMidiOuts);
119 const CarlaMutexLocker cms(jclient->mutex);
120 jclient->midiOuts.append(port);
123 jclient->portIdMapping[gid] = port;
124 jclient->portNameMapping[port->fullname] = port;
125 return (jack_port_t*)port;
128 carla_stderr2("jack_port_register: invalid port flags '%x'", flags);
129 return nullptr;
132 carla_stderr2("jack_port_register: invalid port type '%s'", port_type);
133 return nullptr;
135 // unused
136 (void)buffer_size;
139 CARLA_PLUGIN_EXPORT
140 int jack_port_unregister(jack_client_t* client, jack_port_t* port)
142 carla_debug("%s(%p, %p)", __FUNCTION__, client, port);
144 JackClientState* const jclient = (JackClientState*)client;
145 CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, EINVAL);
147 JackPortState* const jport = (JackPortState*)port;
148 CARLA_SAFE_ASSERT_RETURN(jport != nullptr, EINVAL);
149 CARLA_SAFE_ASSERT_RETURN(! jport->isSystem, EINVAL);
152 const CarlaMutexLocker cms(jclient->mutex);
154 if (jport->isMidi)
156 if (jport->flags & JackPortIsInput)
158 CARLA_SAFE_ASSERT_RETURN(jclient->midiIns.removeOne(jport), ENOENT);
159 jclient->portIdMapping.erase(jport->gid);
160 jclient->portNameMapping.erase(jport->fullname);
161 return 0;
164 if (jport->flags & JackPortIsOutput)
166 CARLA_SAFE_ASSERT_RETURN(jclient->midiOuts.removeOne(jport), ENOENT);
167 jclient->portIdMapping.erase(jport->gid);
168 jclient->portNameMapping.erase(jport->fullname);
169 return 0;
172 else
174 if (jport->flags & JackPortIsInput)
176 CARLA_SAFE_ASSERT_RETURN(jclient->audioIns.removeOne(jport), ENOENT);
177 jclient->portIdMapping.erase(jport->gid);
178 jclient->portNameMapping.erase(jport->fullname);
179 return 0;
182 if (jport->flags & JackPortIsOutput)
184 CARLA_SAFE_ASSERT_RETURN(jclient->audioOuts.removeOne(jport), ENOENT);
185 jclient->portIdMapping.erase(jport->gid);
186 jclient->portNameMapping.erase(jport->fullname);
187 return 0;
192 carla_stderr2("jack_port_register: invalid port '%s'", jport->name);
193 return EINVAL;
196 CARLA_PLUGIN_EXPORT
197 void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t)
199 JackPortState* const jport = (JackPortState*)port;
200 CARLA_SAFE_ASSERT_RETURN(jport != nullptr, nullptr);
202 return jport->buffer;
205 // --------------------------------------------------------------------------------------------------------------------
207 CARLA_PLUGIN_EXPORT
208 jack_uuid_t jack_port_uuid(const jack_port_t* port)
210 carla_debug("%s(%p)", __FUNCTION__, port);
212 const JackPortState* const jport = (const JackPortState*)port;
213 CARLA_SAFE_ASSERT_RETURN(jport != nullptr, 0);
215 return jport->uuid;
218 CARLA_PLUGIN_EXPORT
219 const char* jack_port_name(const jack_port_t* port)
221 carla_debug("%s(%p)", __FUNCTION__, port);
223 const JackPortState* const jport = (const JackPortState*)port;
224 CARLA_SAFE_ASSERT_RETURN(jport != nullptr, nullptr);
226 return jport->fullname;
229 CARLA_PLUGIN_EXPORT
230 const char* jack_port_short_name(const jack_port_t* port)
232 carla_debug("%s(%p)", __FUNCTION__, port);
234 const JackPortState* const jport = (const JackPortState*)port;
235 CARLA_SAFE_ASSERT_RETURN(jport != nullptr, nullptr);
237 return jport->name;
240 CARLA_PLUGIN_EXPORT
241 int jack_port_flags(const jack_port_t* port)
243 carla_debug("%s(%p)", __FUNCTION__, port);
245 const JackPortState* const jport = (const JackPortState*)port;
246 CARLA_SAFE_ASSERT_RETURN(jport != nullptr, 0);
248 return jport->flags;
251 CARLA_PLUGIN_EXPORT
252 const char* jack_port_type(const jack_port_t* port)
254 carla_debug("%s(%p)", __FUNCTION__, port);
256 const JackPortState* const jport = (const JackPortState*)port;
257 CARLA_SAFE_ASSERT_RETURN(jport != nullptr, nullptr);
259 static const char* const kAudioType = JACK_DEFAULT_AUDIO_TYPE;
260 static const char* const kMidiType = JACK_DEFAULT_MIDI_TYPE;
262 return jport->isMidi ? kMidiType : kAudioType;
265 CARLA_PLUGIN_EXPORT
266 uint32_t jack_port_type_id(const jack_port_t* port)
268 carla_debug("%s(%p)", __FUNCTION__, port);
270 const JackPortState* const jport = (const JackPortState*)port;
271 CARLA_SAFE_ASSERT_RETURN(jport != nullptr, 0);
273 return jport->isMidi ? 1 : 0;
276 // --------------------------------------------------------------------------------------------------------------------
278 CARLA_PLUGIN_EXPORT
279 int jack_port_is_mine(const jack_client_t*, const jack_port_t* port)
281 const JackPortState* const jport = (const JackPortState*)port;
282 CARLA_SAFE_ASSERT_RETURN(jport != nullptr, 0);
284 return jport->isSystem ? 0 : 1;
287 CARLA_PLUGIN_EXPORT
288 int jack_port_connected(const jack_port_t* port)
290 const JackPortState* const jport = (const JackPortState*)port;
291 CARLA_SAFE_ASSERT_RETURN(jport != nullptr, 0);
293 return jport->isConnected ? 1 : 0;
296 CARLA_PLUGIN_EXPORT
297 int jack_port_connected_to(const jack_port_t* port, const char* port_name)
299 carla_stderr2("%s(%p, %s) WIP", __FUNCTION__, port, port_name);
301 const JackPortState* const jport = (const JackPortState*)port;
302 CARLA_SAFE_ASSERT_RETURN(jport != nullptr, 0);
304 if (! jport->isConnected)
305 return 0;
307 // TODO
308 return 1;
311 // --------------------------------------------------------------------------------------------------------------------
313 CARLA_PLUGIN_EXPORT
314 int jack_port_tie(jack_port_t* src, jack_port_t* dst)
316 carla_debug("%s(%p, %p)", __FUNCTION__, src, dst);
317 return ENOSYS;
319 // unused
320 (void)src;
321 (void)dst;
324 CARLA_PLUGIN_EXPORT
325 int jack_port_untie(jack_port_t* port)
327 carla_debug("%s(%p)", __FUNCTION__, port);
328 return ENOSYS;
330 // unused
331 (void)port;
334 // --------------------------------------------------------------------------------------------------------------------
336 CARLA_PLUGIN_EXPORT
337 int jack_port_set_name(jack_port_t *port, const char *port_name)
339 carla_stderr2("%s(%p, %s)", __FUNCTION__, port, port_name);
340 return ENOSYS;
343 CARLA_PLUGIN_EXPORT
344 int jack_port_rename(jack_client_t* client, jack_port_t *port, const char *port_name)
346 carla_stderr2("%s(%p, %p, %s) WIP", __FUNCTION__, client, port, port_name);
348 JackClientState* const jclient = (JackClientState*)client;
349 CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, EINVAL);
351 CARLA_SAFE_ASSERT_RETURN(port_name != nullptr && port_name[0] != '\0', EINVAL);
353 JackPortState* const jport = (JackPortState*)port;
354 CARLA_SAFE_ASSERT_RETURN(jport != nullptr, EINVAL);
355 CARLA_SAFE_ASSERT_RETURN(! jport->isSystem, EINVAL);
357 // TODO: verify uniqueness
359 char* const fullname = (char*)std::malloc(STR_MAX);
360 CARLA_SAFE_ASSERT_RETURN(fullname != nullptr, ENOMEM);
362 std::snprintf(fullname, STR_MAX, "%s:%s", jclient->name, port_name);
363 fullname[STR_MAX-1] = '\0';
365 jclient->portNameMapping.erase(jport->fullname);
366 jclient->portNameMapping[fullname] = jport;
368 std::free(jport->name);
369 std::free(jport->fullname);
371 jport->name = strdup(port_name);
372 jport->fullname = fullname;
374 // TODO: port rename callback
376 return 0;
379 CARLA_PLUGIN_EXPORT
380 int jack_port_set_alias(jack_port_t* port, const char* alias)
382 carla_stderr2("%s(%p, %s)", __FUNCTION__, port, alias);
383 return ENOSYS;
386 CARLA_PLUGIN_EXPORT
387 int jack_port_unset_alias(jack_port_t* port, const char* alias)
389 carla_stderr2("%s(%p, %s)", __FUNCTION__, port, alias);
390 return ENOSYS;
393 CARLA_PLUGIN_EXPORT
394 int jack_port_get_aliases(const jack_port_t*, char* const aliases[2])
396 *aliases[0] = '\0';
397 *aliases[1] = '\0';
398 return 0;
401 // --------------------------------------------------------------------------------------------------------------------
403 CARLA_PLUGIN_EXPORT
404 int jack_port_request_monitor(jack_port_t* port, int onoff)
406 carla_stderr2("%s(%p, %i)", __FUNCTION__, port, onoff);
407 return ENOSYS;
410 CARLA_PLUGIN_EXPORT
411 int jack_port_request_monitor_by_name(jack_client_t* client, const char* port_name, int onoff)
413 carla_stderr2("%s(%p, %s, %i)", __FUNCTION__, client, port_name, onoff);
414 return ENOSYS;
417 CARLA_PLUGIN_EXPORT
418 int jack_port_ensure_monitor(jack_port_t* port, int onoff)
420 carla_stderr2("%s(%p, %i)", __FUNCTION__, port, onoff);
421 return ENOSYS;
424 CARLA_PLUGIN_EXPORT
425 int jack_port_monitoring_input(jack_port_t* port)
427 carla_stderr2("%s(%p)", __FUNCTION__, port);
428 return 0;
431 // --------------------------------------------------------------------------------------------------------------------
433 CARLA_PLUGIN_EXPORT
434 int jack_connect(jack_client_t* client, const char* a, const char* b)
436 carla_stderr2("%s(%p, %s. %s)", __FUNCTION__, client, a, b);
437 return 0;
440 CARLA_PLUGIN_EXPORT
441 int jack_disconnect(jack_client_t* client, const char* a, const char* b)
443 carla_stderr2("%s(%p, %s. %s)", __FUNCTION__, client, a, b);
444 return 0;
447 CARLA_PLUGIN_EXPORT
448 int jack_port_disconnect(jack_client_t* client, jack_port_t* port)
450 carla_stderr2("%s(%p, %p)", __FUNCTION__, client, port);
451 return 0;
454 // --------------------------------------------------------------------------------------------------------------------
456 CARLA_PLUGIN_EXPORT
457 int jack_port_name_size(void)
459 return STR_MAX;
462 CARLA_PLUGIN_EXPORT
463 int jack_port_type_size(void)
465 return STR_MAX;
468 CARLA_PLUGIN_EXPORT
469 size_t jack_port_type_get_buffer_size(jack_client_t* client, const char* port_type)
471 carla_debug("%s(%p, %s)", __FUNCTION__, client, port_type);
472 CARLA_SAFE_ASSERT_RETURN(port_type != nullptr && port_type[0] != '\0', 0);
474 if (std::strcmp(port_type, JACK_DEFAULT_MIDI_TYPE) == 0)
475 return JackMidiPortBufferBase::kMaxEventSize;
477 return 0;
479 // unused
480 (void)client;
483 // --------------------------------------------------------------------------------------------------------------------