Guitarix
Loading...
Searching...
No Matches
gx_jack.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2009, 2010 Hermann Meyer, James Warden, Andreas Degert
3 * Copyright (C) 2011 Pete Shorthose
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
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.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * --------------------------------------------------------------------------
19 */
20
21/* ------- This is the JACK namespace ------- */
22
23#pragma once
24
25#ifndef SRC_HEADERS_GX_JACK_H_
26#define SRC_HEADERS_GX_JACK_H_
27
28#include <atomic>
29
30#ifndef GUITARIX_AS_PLUGIN
31
32#include <jack/jack.h> // NOLINT
33#include <jack/midiport.h>
34#include <jack/ringbuffer.h>
35
36#ifdef HAVE_JACK_SESSION
37#include <jack/session.h>
38#endif
39
40namespace gx_engine {
41class GxEngine;
42}
43
44namespace gx_jack {
45
46/****************************************************************
47 ** class GxRtCheck
48 ** check if user have realtime priority
49 */
50
51class GxRtCheck {
52private:
53 std::thread _thd;
54 std::mutex m;
55 std::condition_variable cv;
56 bool isRT;
57 std::atomic<bool> _execute;
59 void run();
60
61public:
62 bool run_check();
65};
66
67/****************************************************************
68 ** port connection callback
69 */
70
72public:
73 PortConnData() {} // no init
74 PortConnData(const char *a, const char *b, bool conn)
75 : name_a(a), name_b(b), connect(conn) {}
77 const char *name_a;
78 const char *name_b;
79 bool connect;
80};
81
83private:
84 jack_ringbuffer_t *ring;
86 int overflow; // should be bool but gives compiler error
90public:
91 Glib::Dispatcher new_data;
92 Glib::Dispatcher portchange;
93 void push(const char *a, const char *b, bool conn);
95 void set_send(bool v) { send_changes = v; }
98};
99
100
101/****************************************************************
102 ** class GxJack
103 */
104
106public:
107 jack_port_t *port;
108 list<string> conn;
109};
110
121
122#ifdef HAVE_JACK_SESSION
123extern "C" {
124 typedef int (*jack_set_session_callback_type)(
125 jack_client_t *, JackSessionCallback, void *arg);
126 typedef char *(*jack_get_uuid_for_client_name_type)(
127 jack_client_t *, const char *);
128 typedef char *(*jack_client_get_uuid_type)(jack_client_t *);
129}
130#endif
131
132
133class MidiCC {
134private:
136 static const int max_midi_cc_cnt = 25;
137 std::atomic<bool> send_cc[max_midi_cc_cnt];
142public:
144 bool send_midi_cc(int _cc, int _pg, int _bgn, int _num);
145 inline int next(int i = -1) const;
146 inline int size(int i) const { return me_num[i]; }
147 inline void fill(unsigned char *midi_send, int i);
148};
149
150inline int MidiCC::next(int i) const {
151 while (++i < max_midi_cc_cnt) {
152 if (send_cc[i].load(std::memory_order_acquire)) {
153 return i;
154 }
155 }
156 return -1;
157}
158
159inline void MidiCC::fill(unsigned char *midi_send, int i) {
160 if (size(i) == 3) {
161 midi_send[2] = bg_num[i];
162 }
163 midi_send[1] = pg_num[i]; // program value
164 midi_send[0] = cc_num[i]; // controller+ channel
165 send_cc[i].store(false, std::memory_order_release);
166}
167
168class GxJack: public sigc::trackable {
169 private:
171 bool IS_RT;
177 static int gx_jack_srate_callback(jack_nframes_t, void* arg);
178 static int gx_jack_xrun_callback(void* arg);
179 static int gx_jack_buffersize_callback(jack_nframes_t, void* arg);
180 static int gx_jack_process(jack_nframes_t, void* arg);
181 static int gx_jack_insert_process(jack_nframes_t, void* arg);
182
183 static void shutdown_callback_client(void* arg);
184 static void shutdown_callback_client_insert(void* arg);
186 static void gx_jack_portreg_callback(jack_port_id_t, int, void* arg);
187 static void gx_jack_portconn_callback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg);
188#ifdef HAVE_JACK_SESSION
189 jack_session_event_t *session_event;
190 jack_session_event_t *session_event_ins;
191 int session_callback_seen;
192 static void gx_jack_session_callback(jack_session_event_t *event, void *arg);
193 static void gx_jack_session_callback_ins(jack_session_event_t *event, void *arg);
194 static jack_set_session_callback_type jack_set_session_callback_fp;
195 static jack_get_uuid_for_client_name_type jack_get_uuid_for_client_name_fp;
196 static jack_client_get_uuid_type jack_client_get_uuid_fp;
197#endif
198 void cleanup_slot(bool otherthread);
201 sigc::signal<void,string,string,bool> connection_changed;
202 Glib::Dispatcher buffersize_change;
203
204 Glib::Dispatcher client_change_rt;
205 sigc::signal<void> client_change;
207 jack_nframes_t jack_sr; // jack sample rate
208 jack_nframes_t jack_bs; // jack buffer size
210 Glib::Dispatcher xrun;
216 gx_system::JsonWriter& w, const char *key, const PortConnection& pc, bool replace=false);
217 std::string make_clientvar(const std::string& s);
218 std::string replace_clientvar(const std::string& s);
219 int is_power_of_two (unsigned int x);
220 bool gx_jack_init(bool startserver, int wait_after_connect,
221 const gx_system::CmdlineOptions& opt);
225 inline void check_overload();
226 void process_midi_cc(void *buf, jack_nframes_t nframes);
227
228 public:
230
231 jack_client_t* client;
232 jack_client_t* client_insert;
233
234 jack_position_t current;
235 jack_transport_state_t transport_state;
236 jack_transport_state_t old_transport_state;
237
238 jack_nframes_t get_jack_sr() { return jack_sr; }
239 jack_nframes_t get_jack_bs() { return jack_bs; }
240 float get_jcpu_load() { return client ? jack_cpu_load(client) : -1; }
241 bool get_is_rt() { return client ? IS_RT: false; }
242 jack_nframes_t get_time_is() { return client ? jack_frame_time(client) : 0; }
243
244public:
247
248 void set_jack_down(bool v) { jack_is_down = v; }
249 void set_jack_exit(bool v) { jack_is_exit = v; }
250
251 void set_jack_insert(bool v) { bypass_insert = v;}
252 bool gx_jack_connection(bool connect, bool startserver,
253 int wait_after_connect, const gx_system::CmdlineOptions& opt);
254 float get_last_xrun() { return last_xrun; }
255 void* get_midi_buffer(jack_nframes_t nframes);
256 bool send_midi_cc(int cc_num, int pgm_num, int bgn, int num);
257
261 const string& get_instancename() { return client_instance; }
264 Glib::Dispatcher session;
265 Glib::Dispatcher session_ins;
266 Glib::Dispatcher shutdown;
267 bool is_jack_down() { return jack_is_down; }
268 Glib::Dispatcher connection;
269 bool is_jack_exit() { return jack_is_exit; }
270 sigc::signal<void>& signal_client_change() { return client_change; }
271 sigc::signal<void,string,string,bool>& signal_connection_changed() { return connection_changed; }
272 Glib::Dispatcher& signal_portchange() { return connection_queue.portchange; }
273 Glib::Dispatcher& signal_buffersize_change() { return buffersize_change; }
274 void send_connection_changes(bool v) { connection_queue.set_send(v); }
275 static void rt_watchdog_set_limit(int limit);
278#ifdef HAVE_JACK_SESSION
279 jack_session_event_t *get_last_session_event() {
280 return gx_system::atomic_get(session_event);
281 }
282 jack_session_event_t *get_last_session_event_ins() {
283 return gx_system::atomic_get(session_event_ins);
284 }
285 int return_last_session_event();
286 int return_last_session_event_ins();
287 string get_uuid_insert();
288#endif
289};
290
291inline bool GxJack::send_midi_cc(int cc_num, int pgm_num, int bgn, int num) {
292 if (!client) {
293 return false;
294 }
295 return mmessage.send_midi_cc(cc_num, pgm_num, bgn, num);
296}
297
298} /* end of jack namespace */
299
300#endif // SRC_HEADERS_GX_JACK_H_
301#endif
static int gx_jack_insert_process(jack_nframes_t, void *arg)
bool is_jack_down()
Definition gx_jack.h:267
string client_insert_name
Definition gx_jack.h:263
static void gx_jack_portreg_callback(jack_port_id_t, int, void *arg)
gx_engine::GxEngine & get_engine()
Definition gx_jack.h:276
void set_jack_exit(bool v)
Definition gx_jack.h:249
string client_name
Definition gx_jack.h:262
bool gx_jack_init(bool startserver, int wait_after_connect, const gx_system::CmdlineOptions &opt)
static string get_default_instancename()
void write_connections(gx_system::JsonWriter &w)
Glib::Dispatcher shutdown
Definition gx_jack.h:266
JackPorts ports
Definition gx_jack.h:229
bool send_midi_cc(int cc_num, int pgm_num, int bgn, int num)
Definition gx_jack.h:291
static void gx_jack_portconn_callback(jack_port_id_t a, jack_port_id_t b, int connect, void *arg)
void write_jack_port_connections(gx_system::JsonWriter &w, const char *key, const PortConnection &pc, bool replace=false)
Glib::Dispatcher & signal_portchange()
Definition gx_jack.h:272
bool jack_is_down
Definition gx_jack.h:173
jack_nframes_t get_jack_sr()
Definition gx_jack.h:238
float get_last_xrun()
Definition gx_jack.h:254
void gx_jack_cleanup()
void report_xrun_clear()
void set_jack_insert(bool v)
Definition gx_jack.h:251
sigc::signal< void, string, string, bool > & signal_connection_changed()
Definition gx_jack.h:271
const string & get_instancename()
Definition gx_jack.h:261
float * insert_buffer
Definition gx_jack.h:209
GxRtCheck rtc
Definition gx_jack.h:170
void gx_jack_init_port_connection(const gx_system::CmdlineOptions &opt)
void * get_midi_buffer(jack_nframes_t nframes)
bool is_jack_exit()
Definition gx_jack.h:269
bool single_client
Definition gx_jack.h:277
void check_overload()
gx_engine::GxEngine & engine
Definition gx_jack.h:172
bool jack_is_exit
Definition gx_jack.h:174
float get_jcpu_load()
Definition gx_jack.h:240
static int gx_jack_process(jack_nframes_t, void *arg)
Glib::Dispatcher connection
Definition gx_jack.h:268
bool xrun_msg_blocked
Definition gx_jack.h:212
Glib::Dispatcher & signal_buffersize_change()
Definition gx_jack.h:273
void process_midi_cc(void *buf, jack_nframes_t nframes)
Glib::Dispatcher session
Definition gx_jack.h:264
sigc::signal< void > client_change
Definition gx_jack.h:205
static void shutdown_callback_client(void *arg)
jack_client_t * client
Definition gx_jack.h:231
Glib::Dispatcher session_ins
Definition gx_jack.h:265
std::string replace_clientvar(const std::string &s)
void read_connections(gx_system::JsonParser &jp)
static int gx_jack_buffersize_callback(jack_nframes_t, void *arg)
static void shutdown_callback_client_insert(void *arg)
GxJack(gx_engine::GxEngine &engine_)
static void rt_watchdog_set_limit(int limit)
jack_transport_state_t transport_state
Definition gx_jack.h:235
PortConnRing connection_queue
Definition gx_jack.h:200
static int gx_jack_xrun_callback(void *arg)
Glib::Dispatcher client_change_rt
Definition gx_jack.h:204
jack_nframes_t jack_bs
Definition gx_jack.h:208
MidiCC mmessage
Definition gx_jack.h:176
void fetch_connection_data()
void gx_jack_callbacks()
jack_transport_state_t old_transport_state
Definition gx_jack.h:236
sigc::signal< void > & signal_client_change()
Definition gx_jack.h:270
Glib::Dispatcher xrun
Definition gx_jack.h:210
Glib::Dispatcher buffersize_change
Definition gx_jack.h:202
sigc::signal< void, string, string, bool > connection_changed
Definition gx_jack.h:201
static int gx_jack_srate_callback(jack_nframes_t, void *arg)
void gx_jack_shutdown_callback()
void set_jack_down(bool v)
Definition gx_jack.h:248
bool gx_jack_connection(bool connect, bool startserver, int wait_after_connect, const gx_system::CmdlineOptions &opt)
jack_position_t current
Definition gx_jack.h:234
bool bypass_insert
Definition gx_jack.h:175
float last_xrun
Definition gx_jack.h:211
jack_nframes_t jack_sr
Definition gx_jack.h:207
void cleanup_slot(bool otherthread)
bool get_is_rt()
Definition gx_jack.h:241
jack_client_t * client_insert
Definition gx_jack.h:232
jack_nframes_t get_time_is()
Definition gx_jack.h:242
string client_instance
Definition gx_jack.h:206
jack_nframes_t get_jack_bs()
Definition gx_jack.h:239
void send_connection_changes(bool v)
Definition gx_jack.h:274
int is_power_of_two(unsigned int x)
std::string make_clientvar(const std::string &s)
std::thread _thd
Definition gx_jack.h:53
std::condition_variable cv
Definition gx_jack.h:55
std::atomic< bool > _execute
Definition gx_jack.h:57
std::mutex m
Definition gx_jack.h:54
PortConnection output2
Definition gx_jack.h:119
PortConnection midi_input
Definition gx_jack.h:114
PortConnection midi_output
Definition gx_jack.h:116
PortConnection insert_out
Definition gx_jack.h:115
PortConnection input
Definition gx_jack.h:113
PortConnection insert_in
Definition gx_jack.h:117
PortConnection output1
Definition gx_jack.h:118
void fill(unsigned char *midi_send, int i)
Definition gx_jack.h:159
int next(int i=-1) const
Definition gx_jack.h:150
int me_num[max_midi_cc_cnt]
Definition gx_jack.h:141
std::atomic< bool > send_cc[max_midi_cc_cnt]
Definition gx_jack.h:137
static const int max_midi_cc_cnt
Definition gx_jack.h:136
bool send_midi_cc(int _cc, int _pg, int _bgn, int _num)
int pg_num[max_midi_cc_cnt]
Definition gx_jack.h:139
gx_engine::GxEngine & engine
Definition gx_jack.h:135
int size(int i) const
Definition gx_jack.h:146
int cc_num[max_midi_cc_cnt]
Definition gx_jack.h:138
int bg_num[max_midi_cc_cnt]
Definition gx_jack.h:140
MidiCC(gx_engine::GxEngine &engine_)
bool pop(PortConnData *)
void push(const char *a, const char *b, bool conn)
Glib::Dispatcher portchange
Definition gx_jack.h:92
jack_ringbuffer_t * ring
Definition gx_jack.h:84
Glib::Dispatcher new_data
Definition gx_jack.h:91
void set_send(bool v)
Definition gx_jack.h:95
jack_port_t * port
Definition gx_jack.h:107
list< string > conn
Definition gx_jack.h:108
int atomic_get(volatile int &p)
Definition gx_system.h:98
void atomic_set(volatile int *p, int v)
Definition gx_system.h:90
const char * name_a
Definition gx_jack.h:77
const char * name_b
Definition gx_jack.h:78
PortConnData(const char *a, const char *b, bool conn)
Definition gx_jack.h:74