Guitarix
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#include <jack/jack.h> // NOLINT
31#include <jack/midiport.h>
32#include <jack/ringbuffer.h>
33
34#ifdef HAVE_JACK_SESSION
35#include <jack/session.h>
36#endif
37
38namespace gx_engine {
39class GxEngine;
40}
41
42namespace gx_jack {
43
44/****************************************************************
45 ** port connection callback
46 */
47
49public:
50 PortConnData() {} // no init
51 PortConnData(const char *a, const char *b, bool conn)
52 : name_a(a), name_b(b), connect(conn) {}
54 const char *name_a;
55 const char *name_b;
56 bool connect;
57};
58
60private:
61 jack_ringbuffer_t *ring;
63 int overflow; // should be bool but gives compiler error
67public:
68 Glib::Dispatcher new_data;
69 Glib::Dispatcher portchange;
70 void push(const char *a, const char *b, bool conn);
72 void set_send(bool v) { send_changes = v; }
75};
76
77
78/****************************************************************
79 ** class GxJack
80 */
81
83public:
84 jack_port_t *port;
85 list<string> conn;
86};
87
88class JackPorts {
89public:
97};
98
99#ifdef HAVE_JACK_SESSION
100extern "C" {
101 typedef int (*jack_set_session_callback_type)(
102 jack_client_t *, JackSessionCallback, void *arg);
103 typedef char *(*jack_get_uuid_for_client_name_type)(
104 jack_client_t *, const char *);
105 typedef char *(*jack_client_get_uuid_type)(jack_client_t *);
106}
107#endif
108
109
110class MidiCC {
111private:
113 static const int max_midi_cc_cnt = 25;
114 std::atomic<bool> send_cc[max_midi_cc_cnt];
119public:
121 bool send_midi_cc(int _cc, int _pg, int _bgn, int _num);
122 inline int next(int i = -1) const;
123 inline int size(int i) const { return me_num[i]; }
124 inline void fill(unsigned char *midi_send, int i);
125};
126
127inline int MidiCC::next(int i) const {
128 while (++i < max_midi_cc_cnt) {
129 if (send_cc[i].load(std::memory_order_acquire)) {
130 return i;
131 }
132 }
133 return -1;
134}
135
136inline void MidiCC::fill(unsigned char *midi_send, int i) {
137 if (size(i) == 3) {
138 midi_send[2] = bg_num[i];
139 }
140 midi_send[1] = pg_num[i]; // program value
141 midi_send[0] = cc_num[i]; // controller+ channel
142 send_cc[i].store(false, std::memory_order_release);
143}
144
145class GxJack: public sigc::trackable {
146 private:
152 static int gx_jack_srate_callback(jack_nframes_t, void* arg);
153 static int gx_jack_xrun_callback(void* arg);
154 static int gx_jack_buffersize_callback(jack_nframes_t, void* arg);
155 static int gx_jack_process(jack_nframes_t, void* arg);
156 static int gx_jack_insert_process(jack_nframes_t, void* arg);
157
158 static void shutdown_callback_client(void* arg);
159 static void shutdown_callback_client_insert(void* arg);
161 static void gx_jack_portreg_callback(jack_port_id_t, int, void* arg);
162 static void gx_jack_portconn_callback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg);
163#ifdef HAVE_JACK_SESSION
164 jack_session_event_t *session_event;
165 jack_session_event_t *session_event_ins;
166 int session_callback_seen;
167 static void gx_jack_session_callback(jack_session_event_t *event, void *arg);
168 static void gx_jack_session_callback_ins(jack_session_event_t *event, void *arg);
169 static jack_set_session_callback_type jack_set_session_callback_fp;
170 static jack_get_uuid_for_client_name_type jack_get_uuid_for_client_name_fp;
171 static jack_client_get_uuid_type jack_client_get_uuid_fp;
172#endif
173 void cleanup_slot(bool otherthread);
176 sigc::signal<void,string,string,bool> connection_changed;
177 Glib::Dispatcher buffersize_change;
178
179 Glib::Dispatcher client_change_rt;
180 sigc::signal<void> client_change;
182 jack_nframes_t jack_sr; // jack sample rate
183 jack_nframes_t jack_bs; // jack buffer size
185 Glib::Dispatcher xrun;
191 gx_system::JsonWriter& w, const char *key, const PortConnection& pc, bool replace=false);
192 std::string make_clientvar(const std::string& s);
193 std::string replace_clientvar(const std::string& s);
194 int is_power_of_two (unsigned int x);
195 bool gx_jack_init(bool startserver, int wait_after_connect,
196 const gx_system::CmdlineOptions& opt);
200 inline void check_overload();
201 void process_midi_cc(void *buf, jack_nframes_t nframes);
202
203 public:
205
206 jack_client_t* client;
207 jack_client_t* client_insert;
208
209 jack_position_t current;
210 jack_transport_state_t transport_state;
211 jack_transport_state_t old_transport_state;
212
213 jack_nframes_t get_jack_sr() { return jack_sr; }
214 jack_nframes_t get_jack_bs() { return jack_bs; }
215 float get_jcpu_load() { return client ? jack_cpu_load(client) : -1; }
216 bool get_is_rt() { return client ? jack_is_realtime(client) : false; }
217 jack_nframes_t get_time_is() { return client ? jack_frame_time(client) : 0; }
218
219public:
222
223 void set_jack_down(bool v) { jack_is_down = v; }
224 void set_jack_exit(bool v) { jack_is_exit = v; }
225
226 void set_jack_insert(bool v) { bypass_insert = v;}
227 bool gx_jack_connection(bool connect, bool startserver,
228 int wait_after_connect, const gx_system::CmdlineOptions& opt);
229 float get_last_xrun() { return last_xrun; }
230 void* get_midi_buffer(jack_nframes_t nframes);
231 bool send_midi_cc(int cc_num, int pgm_num, int bgn, int num);
232
236 const string& get_instancename() { return client_instance; }
239 Glib::Dispatcher session;
240 Glib::Dispatcher session_ins;
241 Glib::Dispatcher shutdown;
242 bool is_jack_down() { return jack_is_down; }
243 Glib::Dispatcher connection;
244 bool is_jack_exit() { return jack_is_exit; }
245 sigc::signal<void>& signal_client_change() { return client_change; }
246 sigc::signal<void,string,string,bool>& signal_connection_changed() { return connection_changed; }
247 Glib::Dispatcher& signal_portchange() { return connection_queue.portchange; }
248 Glib::Dispatcher& signal_buffersize_change() { return buffersize_change; }
250 static void rt_watchdog_set_limit(int limit);
253#ifdef HAVE_JACK_SESSION
254 jack_session_event_t *get_last_session_event() {
255 return gx_system::atomic_get(session_event);
256 }
257 jack_session_event_t *get_last_session_event_ins() {
258 return gx_system::atomic_get(session_event_ins);
259 }
260 int return_last_session_event();
261 int return_last_session_event_ins();
262 string get_uuid_insert();
263#endif
264};
265
266inline bool GxJack::send_midi_cc(int cc_num, int pgm_num, int bgn, int num) {
267 if (!client) {
268 return false;
269 }
270 return mmessage.send_midi_cc(cc_num, pgm_num, bgn, num);
271}
272
273} /* end of jack namespace */
274
275#endif // SRC_HEADERS_GX_JACK_H_
static int gx_jack_insert_process(jack_nframes_t, void *arg)
bool is_jack_down()
Definition: gx_jack.h:242
string client_insert_name
Definition: gx_jack.h:238
static void gx_jack_portreg_callback(jack_port_id_t, int, void *arg)
gx_engine::GxEngine & get_engine()
Definition: gx_jack.h:251
void set_jack_exit(bool v)
Definition: gx_jack.h:224
string client_name
Definition: gx_jack.h:237
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:241
JackPorts ports
Definition: gx_jack.h:204
bool send_midi_cc(int cc_num, int pgm_num, int bgn, int num)
Definition: gx_jack.h:266
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:247
bool jack_is_down
Definition: gx_jack.h:148
jack_nframes_t get_jack_sr()
Definition: gx_jack.h:213
float get_last_xrun()
Definition: gx_jack.h:229
void gx_jack_cleanup()
void report_xrun_clear()
void set_jack_insert(bool v)
Definition: gx_jack.h:226
sigc::signal< void, string, string, bool > & signal_connection_changed()
Definition: gx_jack.h:246
const string & get_instancename()
Definition: gx_jack.h:236
float * insert_buffer
Definition: gx_jack.h:184
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:244
bool single_client
Definition: gx_jack.h:252
void check_overload()
gx_engine::GxEngine & engine
Definition: gx_jack.h:147
bool jack_is_exit
Definition: gx_jack.h:149
float get_jcpu_load()
Definition: gx_jack.h:215
static int gx_jack_process(jack_nframes_t, void *arg)
Glib::Dispatcher connection
Definition: gx_jack.h:243
bool xrun_msg_blocked
Definition: gx_jack.h:187
Glib::Dispatcher & signal_buffersize_change()
Definition: gx_jack.h:248
void process_midi_cc(void *buf, jack_nframes_t nframes)
Glib::Dispatcher session
Definition: gx_jack.h:239
sigc::signal< void > client_change
Definition: gx_jack.h:180
static void shutdown_callback_client(void *arg)
jack_client_t * client
Definition: gx_jack.h:206
Glib::Dispatcher session_ins
Definition: gx_jack.h:240
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:210
PortConnRing connection_queue
Definition: gx_jack.h:175
static int gx_jack_xrun_callback(void *arg)
Glib::Dispatcher client_change_rt
Definition: gx_jack.h:179
jack_nframes_t jack_bs
Definition: gx_jack.h:183
MidiCC mmessage
Definition: gx_jack.h:151
void fetch_connection_data()
void gx_jack_callbacks()
jack_transport_state_t old_transport_state
Definition: gx_jack.h:211
sigc::signal< void > & signal_client_change()
Definition: gx_jack.h:245
Glib::Dispatcher xrun
Definition: gx_jack.h:185
Glib::Dispatcher buffersize_change
Definition: gx_jack.h:177
sigc::signal< void, string, string, bool > connection_changed
Definition: gx_jack.h:176
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:223
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:209
bool bypass_insert
Definition: gx_jack.h:150
float last_xrun
Definition: gx_jack.h:186
jack_nframes_t jack_sr
Definition: gx_jack.h:182
void cleanup_slot(bool otherthread)
bool get_is_rt()
Definition: gx_jack.h:216
jack_client_t * client_insert
Definition: gx_jack.h:207
jack_nframes_t get_time_is()
Definition: gx_jack.h:217
string client_instance
Definition: gx_jack.h:181
jack_nframes_t get_jack_bs()
Definition: gx_jack.h:214
void send_connection_changes(bool v)
Definition: gx_jack.h:249
int is_power_of_two(unsigned int x)
std::string make_clientvar(const std::string &s)
PortConnection output2
Definition: gx_jack.h:96
PortConnection midi_input
Definition: gx_jack.h:91
PortConnection midi_output
Definition: gx_jack.h:93
PortConnection insert_out
Definition: gx_jack.h:92
PortConnection input
Definition: gx_jack.h:90
PortConnection insert_in
Definition: gx_jack.h:94
PortConnection output1
Definition: gx_jack.h:95
void fill(unsigned char *midi_send, int i)
Definition: gx_jack.h:136
int next(int i=-1) const
Definition: gx_jack.h:127
int me_num[max_midi_cc_cnt]
Definition: gx_jack.h:118
std::atomic< bool > send_cc[max_midi_cc_cnt]
Definition: gx_jack.h:114
static const int max_midi_cc_cnt
Definition: gx_jack.h:113
bool send_midi_cc(int _cc, int _pg, int _bgn, int _num)
int pg_num[max_midi_cc_cnt]
Definition: gx_jack.h:116
gx_engine::GxEngine & engine
Definition: gx_jack.h:112
int size(int i) const
Definition: gx_jack.h:123
int cc_num[max_midi_cc_cnt]
Definition: gx_jack.h:115
int bg_num[max_midi_cc_cnt]
Definition: gx_jack.h:117
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:69
jack_ringbuffer_t * ring
Definition: gx_jack.h:61
Glib::Dispatcher new_data
Definition: gx_jack.h:68
void clear_overflow()
Definition: gx_jack.h:65
void set_send(bool v)
Definition: gx_jack.h:72
jack_port_t * port
Definition: gx_jack.h:84
list< string > conn
Definition: gx_jack.h:85
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:54
const char * name_b
Definition: gx_jack.h:55
PortConnData(const char *a, const char *b, bool conn)
Definition: gx_jack.h:51