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 #ifndef CARLA_LIBJACK_HPP_INCLUDED
19 #define CARLA_LIBJACK_HPP_INCLUDED
21 // need to include this first
22 #include "CarlaDefines.h"
24 // now define as bridge
25 #define BUILD_BRIDGE 1
27 // now include a bunch of stuff
28 #include "CarlaBackendUtils.hpp"
29 #include "CarlaBridgeUtils.hpp"
30 #include "CarlaMIDI.h"
31 #include "CarlaMutex.hpp"
32 #include "LinkedList.hpp"
35 #include <jack/jack.h>
36 #include <jack/midiport.h>
37 #include <jack/transport.h>
38 #include <jack/session.h>
39 #include <jack/metadata.h>
47 # include <xmmintrin.h>
50 // must be last include
53 // small check to not hurt myself
54 #ifdef JACKBRIDGE_DIRECT
55 # error "Cannot create custom jack server while linking to libjack directly"
58 CARLA_BACKEND_START_NAMESPACE
60 // --------------------------------------------------------------------------------------------------------------------
62 class CarlaJackAppClient
;
63 struct JackClientState
;
64 struct JackServerState
;
66 struct JackMidiPortBufferBase
{
67 static const uint8_t kMaxEventSize
= 128;
68 static const size_t kMaxEventCount
= 512;
69 static const size_t kBufferPoolSize
= kMaxEventCount
*8;
75 struct JackMidiPortBufferOnStack
: JackMidiPortBufferBase
{
79 jack_midi_event_t events
[kMaxEventCount
];
80 jack_midi_data_t bufferPool
[kBufferPoolSize
];
82 JackMidiPortBufferOnStack()
92 CARLA_DECLARE_NON_COPYABLE(JackMidiPortBufferOnStack
)
95 struct JackMidiPortBufferDummy
: JackMidiPortBufferBase
{
96 JackMidiPortBufferDummy(const bool input
)
102 CARLA_DECLARE_NON_COPYABLE(JackMidiPortBufferDummy
)
105 struct JackPortState
{
107 kPortIdOffsetAudioIn
= 100,
108 kPortIdOffsetMidiIn
= 300,
109 kPortIdOffsetAudioOut
= 500,
110 kPortIdOffsetMidiOut
= 700,
111 kPortIdOffsetUser
= 1000,
123 bool isConnected
: 1;
126 JackPortState(const char* const fullPortName
,
127 const char* const portName
,
128 const uint i
, const int f
, const uint id
,
129 const bool midi
, const bool con
)
130 : name(portName
!= nullptr ? strdup(portName
) : nullptr),
131 fullname(fullPortName
!= nullptr ? strdup(fullPortName
) : nullptr),
136 uuid(jack_port_uuid_generate(id
)),
142 JackPortState(const char* const clientName
,
143 const char* const portName
,
144 const uint i
, const int f
, const uint id
,
145 const bool midi
, const bool sys
, const bool con
)
146 : name(portName
!= nullptr ? strdup(portName
) : nullptr),
152 uuid(jack_port_uuid_generate(id
)),
158 if (clientName
!= nullptr && portName
!= nullptr)
160 char strBuf
[STR_MAX
+1];
161 snprintf(strBuf
, STR_MAX
, "%s:%s", clientName
, portName
);
162 strBuf
[STR_MAX
] = '\0';
164 fullname
= strdup(strBuf
);
177 CARLA_DECLARE_NON_COPYABLE(JackPortState
)
180 struct JackClientState
{
181 const JackServerState
& server
;
185 bool deactivated
; // activated once, then deactivated
190 LinkedList
<JackPortState
*> audioIns
;
191 LinkedList
<JackPortState
*> audioOuts
;
192 LinkedList
<JackPortState
*> midiIns
;
193 LinkedList
<JackPortState
*> midiOuts
;
195 std::map
<uint
, JackPortState
*> portIdMapping
;
196 std::map
<std::string
, JackPortState
*> portNameMapping
;
198 JackShutdownCallback shutdownCb
;
201 JackInfoShutdownCallback infoShutdownCb
;
202 void* infoShutdownCbPtr
;
204 JackProcessCallback processCb
;
207 JackFreewheelCallback freewheelCb
;
208 void* freewheelCbPtr
;
210 JackBufferSizeCallback bufferSizeCb
;
211 void* bufferSizeCbPtr
;
213 JackSampleRateCallback sampleRateCb
;
214 void* sampleRateCbPtr
;
216 JackSyncCallback syncCb
;
219 JackThreadInitCallback threadInitCb
;
220 void* threadInitCbPtr
;
222 JackClientState(const JackServerState
& s
, const char* const n
)
228 uuid(jack_client_uuid_generate()),
236 shutdownCbPtr(nullptr),
237 infoShutdownCb(nullptr),
238 infoShutdownCbPtr(nullptr),
240 processCbPtr(nullptr),
241 freewheelCb(nullptr),
242 freewheelCbPtr(nullptr),
243 bufferSizeCb(nullptr),
244 bufferSizeCbPtr(nullptr),
245 sampleRateCb(nullptr),
246 sampleRateCbPtr(nullptr),
249 threadInitCb(nullptr),
250 threadInitCbPtr(nullptr) {}
254 const CarlaMutexLocker
cms(mutex
);
256 for (LinkedList
<JackPortState
*>::Itenerator it
= audioIns
.begin2(); it
.valid(); it
.next())
258 if (JackPortState
* const jport
= it
.getValue(nullptr))
262 for (LinkedList
<JackPortState
*>::Itenerator it
= audioOuts
.begin2(); it
.valid(); it
.next())
264 if (JackPortState
* const jport
= it
.getValue(nullptr))
268 for (LinkedList
<JackPortState
*>::Itenerator it
= midiIns
.begin2(); it
.valid(); it
.next())
270 if (JackPortState
* const jport
= it
.getValue(nullptr))
274 for (LinkedList
<JackPortState
*>::Itenerator it
= midiOuts
.begin2(); it
.valid(); it
.next())
276 if (JackPortState
* const jport
= it
.getValue(nullptr))
288 portIdMapping
.clear();
289 portNameMapping
.clear();
292 CARLA_DECLARE_NON_COPYABLE(JackClientState
)
295 struct JackServerState
{
296 CarlaJackAppClient
* jackAppPtr
;
304 uint8_t numAudioOuts
;
309 jack_position_t position
;
310 jack_nframes_t monotonic_frame
;
312 JackServerState(CarlaJackAppClient
* const app
)
316 uuid(jack_client_uuid_generate()),
325 carla_zeroStruct(position
);
328 CARLA_DECLARE_NON_COPYABLE(JackServerState
)
331 CARLA_BACKEND_END_NAMESPACE
333 // --------------------------------------------------------------------------------------------------------------------
335 #endif // CARLA_LIBJACK_HPP_INCLUDED