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 
38 namespace gx_engine {
39 class GxEngine;
40 }
41 
42 namespace gx_jack {
43 
44 /****************************************************************
45  ** port connection callback
46  */
47 
48 struct PortConnData {
49 public:
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 
59 class PortConnRing {
60 private:
61  jack_ringbuffer_t *ring;
63  int overflow; // should be bool but gives compiler error
67 public:
68  Glib::Dispatcher new_data;
69  Glib::Dispatcher portchange;
70  void push(const char *a, const char *b, bool conn);
71  bool pop(PortConnData*);
72  void set_send(bool v) { send_changes = v; }
75 };
76 
77 
78 /****************************************************************
79  ** class GxJack
80  */
81 
83 public:
84  jack_port_t *port;
85  list<string> conn;
86 };
87 
88 class JackPorts {
89 public:
97 };
98 
99 #ifdef HAVE_JACK_SESSION
100 extern "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 
110 class MidiCC {
111 private:
113  static const int max_midi_cc_cnt = 25;
114  std::atomic<bool> send_cc[max_midi_cc_cnt];
119 public:
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 
127 inline 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 
136 inline 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 
145 class 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;
186  float last_xrun;
189  void report_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 
219 public:
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 
235  static string get_default_instancename();
236  const string& get_instancename() { return client_instance; }
237  string client_name;
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);
251 #ifdef HAVE_JACK_SESSION
252  jack_session_event_t *get_last_session_event() {
253  return gx_system::atomic_get(session_event);
254  }
255  jack_session_event_t *get_last_session_event_ins() {
256  return gx_system::atomic_get(session_event_ins);
257  }
258  int return_last_session_event();
259  int return_last_session_event_ins();
260  string get_uuid_insert();
261  bool single_client;
262  gx_engine::GxEngine& get_engine() { return engine; }
263 #endif
264 };
265 
266 inline 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_
gx_jack::MidiCC::size
int size(int i) const
Definition: gx_jack.h:123
gx_jack::GxJack::insert_buffer
float * insert_buffer
Definition: gx_jack.h:184
gx_jack::GxJack::~GxJack
~GxJack()
gx_jack::PortConnData::PortConnData
PortConnData()
Definition: gx_jack.h:52
gx_jack::GxJack::client
jack_client_t * client
Definition: gx_jack.h:206
gx_jack::GxJack::signal_connection_changed
sigc::signal< void, string, string, bool > & signal_connection_changed()
Definition: gx_jack.h:246
gx_jack::GxJack::gx_jack_shutdown_callback
void gx_jack_shutdown_callback()
gx_jack::GxJack::buffersize_change
Glib::Dispatcher buffersize_change
Definition: gx_jack.h:177
gx_system::atomic_set
void atomic_set(volatile int *p, int v)
Definition: gx_system.h:90
gx_jack::GxJack::is_jack_down
bool is_jack_down()
Definition: gx_jack.h:242
gx_jack::GxJack::rt_watchdog_set_limit
static void rt_watchdog_set_limit(int limit)
gx_jack::GxJack::write_connections
void write_connections(gx_system::JsonWriter &w)
gx_jack::GxJack::ports
JackPorts ports
Definition: gx_jack.h:204
gx_jack::GxJack::shutdown_callback_client
static void shutdown_callback_client(void *arg)
gx_jack::PortConnRing::PortConnRing
PortConnRing()
gx_jack::GxJack::get_midi_buffer
void * get_midi_buffer(jack_nframes_t nframes)
gx_jack::GxJack::report_xrun
void report_xrun()
gx_jack::MidiCC
Definition: gx_jack.h:110
gx_jack::MidiCC::max_midi_cc_cnt
static const int max_midi_cc_cnt
Definition: gx_jack.h:113
gx_jack::GxJack::get_time_is
jack_nframes_t get_time_is()
Definition: gx_jack.h:217
gx_jack::MidiCC::next
int next(int i=-1) const
Definition: gx_jack.h:127
gx_jack::GxJack::client_change
sigc::signal< void > client_change
Definition: gx_jack.h:180
gx_jack::GxJack::last_xrun
float last_xrun
Definition: gx_jack.h:186
gx_jack
Definition: gx_internal_plugins.h:26
gx_jack::GxJack::process_midi_cc
void process_midi_cc(void *buf, jack_nframes_t nframes)
gx_jack::GxJack::gx_jack_buffersize_callback
static int gx_jack_buffersize_callback(jack_nframes_t, void *arg)
gx_jack::JackPorts::insert_out
PortConnection insert_out
Definition: gx_jack.h:92
gx_jack::GxJack::xrun_msg_blocked
bool xrun_msg_blocked
Definition: gx_jack.h:187
gx_jack::GxJack::gx_jack_portconn_callback
static void gx_jack_portconn_callback(jack_port_id_t a, jack_port_id_t b, int connect, void *arg)
gx_jack::MidiCC::send_cc
std::atomic< bool > send_cc[max_midi_cc_cnt]
Definition: gx_jack.h:114
gx_jack::PortConnRing::~PortConnRing
~PortConnRing()
gx_jack::PortConnRing::set_overflow
void set_overflow()
Definition: gx_jack.h:64
gx_jack::GxJack::transport_state
jack_transport_state_t transport_state
Definition: gx_jack.h:210
gx_jack::GxJack::client_instance
string client_instance
Definition: gx_jack.h:181
gx_jack::GxJack::client_insert_name
string client_insert_name
Definition: gx_jack.h:238
gx_jack::PortConnRing::ring
jack_ringbuffer_t * ring
Definition: gx_jack.h:61
gx_jack::GxJack::gx_jack_callbacks
void gx_jack_callbacks()
gx_jack::GxJack::set_jack_exit
void set_jack_exit(bool v)
Definition: gx_jack.h:224
gx_jack::JackPorts::midi_output
PortConnection midi_output
Definition: gx_jack.h:93
gx_jack::GxJack::gx_jack_init_port_connection
void gx_jack_init_port_connection(const gx_system::CmdlineOptions &opt)
gx_jack::JackPorts::output1
PortConnection output1
Definition: gx_jack.h:95
gx_jack::GxJack::write_jack_port_connections
void write_jack_port_connections(gx_system::JsonWriter &w, const char *key, const PortConnection &pc, bool replace=false)
gx_jack::JackPorts
Definition: gx_jack.h:88
gx_jack::GxJack::gx_jack_cleanup
void gx_jack_cleanup()
gx_jack::PortConnRing
Definition: gx_jack.h:59
gx_jack::GxJack::gx_jack_init
bool gx_jack_init(bool startserver, int wait_after_connect, const gx_system::CmdlineOptions &opt)
gx_jack::GxJack::get_default_instancename
static string get_default_instancename()
gx_jack::GxJack::gx_jack_process
static int gx_jack_process(jack_nframes_t, void *arg)
gx_jack::PortConnData::name_b
const char * name_b
Definition: gx_jack.h:57
gx_jack::GxJack::session_ins
Glib::Dispatcher session_ins
Definition: gx_jack.h:240
gx_jack::GxJack::replace_clientvar
std::string replace_clientvar(const std::string &s)
gx_jack::MidiCC::bg_num
int bg_num[max_midi_cc_cnt]
Definition: gx_jack.h:117
gx_jack::PortConnection::port
jack_port_t * port
Definition: gx_jack.h:86
gx_jack::GxJack::gx_jack_srate_callback
static int gx_jack_srate_callback(jack_nframes_t, void *arg)
gx_jack::MidiCC::engine
gx_engine::GxEngine & engine
Definition: gx_jack.h:112
gx_jack::GxJack::make_clientvar
std::string make_clientvar(const std::string &s)
gx_jack::GxJack::check_overload
void check_overload()
gx_jack::GxJack::is_jack_exit
bool is_jack_exit()
Definition: gx_jack.h:244
gx_jack::PortConnData::connect
bool connect
Definition: gx_jack.h:58
gx_jack::GxJack::shutdown_callback_client_insert
static void shutdown_callback_client_insert(void *arg)
gx_jack::JackPorts::output2
PortConnection output2
Definition: gx_jack.h:96
gx_jack::GxJack::get_last_xrun
float get_last_xrun()
Definition: gx_jack.h:229
gx_jack::PortConnRing::pop
bool pop(PortConnData *)
gx_jack::GxJack::shutdown
Glib::Dispatcher shutdown
Definition: gx_jack.h:241
gx_jack::GxJack
Definition: gx_jack.h:145
gx_jack::PortConnRing::push
void push(const char *a, const char *b, bool conn)
gx_jack::PortConnData
Definition: gx_jack.h:48
gx_jack::GxJack::get_jack_sr
jack_nframes_t get_jack_sr()
Definition: gx_jack.h:213
gx_jack::GxJack::get_jack_bs
jack_nframes_t get_jack_bs()
Definition: gx_jack.h:214
gx_jack::GxJack::old_transport_state
jack_transport_state_t old_transport_state
Definition: gx_jack.h:211
gx_jack::GxJack::fetch_connection_data
void fetch_connection_data()
gx_engine
Definition: gx_convolver.h:33
gx_jack::MidiCC::cc_num
int cc_num[max_midi_cc_cnt]
Definition: gx_jack.h:115
gx_jack::GxJack::send_connection_changes
void send_connection_changes(bool v)
Definition: gx_jack.h:249
gx_jack::GxJack::gx_jack_insert_process
static int gx_jack_insert_process(jack_nframes_t, void *arg)
gx_jack::GxJack::signal_client_change
sigc::signal< void > & signal_client_change()
Definition: gx_jack.h:245
gx_system::JsonWriter
Definition: gx_json.h:55
gx_jack::GxJack::send_midi_cc
bool send_midi_cc(int cc_num, int pgm_num, int bgn, int num)
Definition: gx_jack.h:266
gx_jack::GxJack::bypass_insert
bool bypass_insert
Definition: gx_jack.h:150
gx_jack::GxJack::get_is_rt
bool get_is_rt()
Definition: gx_jack.h:216
gx_jack::GxJack::xrun
Glib::Dispatcher xrun
Definition: gx_jack.h:185
gx_jack::GxJack::read_connections
void read_connections(gx_system::JsonParser &jp)
gx_system::JsonParser
Definition: gx_json.h:112
gx_jack::GxJack::client_change_rt
Glib::Dispatcher client_change_rt
Definition: gx_jack.h:179
gx_jack::JackPorts::input
PortConnection input
Definition: gx_jack.h:90
gx_jack::GxJack::mmessage
MidiCC mmessage
Definition: gx_jack.h:151
gx_jack::PortConnData::name_a
const char * name_a
Definition: gx_jack.h:56
gx_jack::GxJack::current
jack_position_t current
Definition: gx_jack.h:209
gx_jack::GxJack::set_jack_down
void set_jack_down(bool v)
Definition: gx_jack.h:223
gx_jack::JackPorts::insert_in
PortConnection insert_in
Definition: gx_jack.h:94
gx_jack::PortConnData::~PortConnData
~PortConnData()
Definition: gx_jack.h:55
gx_jack::PortConnRing::clear_overflow
void clear_overflow()
Definition: gx_jack.h:65
gx_jack::GxJack::jack_sr
jack_nframes_t jack_sr
Definition: gx_jack.h:182
gx_jack::GxJack::set_jack_insert
void set_jack_insert(bool v)
Definition: gx_jack.h:226
gx_jack::GxJack::get_instancename
const string & get_instancename()
Definition: gx_jack.h:236
gx_jack::GxJack::jack_is_exit
bool jack_is_exit
Definition: gx_jack.h:149
gx_jack::GxJack::jack_is_down
bool jack_is_down
Definition: gx_jack.h:148
gx_system::atomic_get
int atomic_get(volatile int &p)
Definition: gx_system.h:98
gx_system::CmdlineOptions
Definition: gx_system.h:384
gx_jack::MidiCC::pg_num
int pg_num[max_midi_cc_cnt]
Definition: gx_jack.h:116
gx_jack::GxJack::cleanup_slot
void cleanup_slot(bool otherthread)
gx_jack::PortConnRing::is_overflow
bool is_overflow()
Definition: gx_jack.h:66
gx_jack::GxJack::GxJack
GxJack(gx_engine::GxEngine &engine_)
gx_jack::GxJack::connection
Glib::Dispatcher connection
Definition: gx_jack.h:243
gx_jack::GxJack::client_name
string client_name
Definition: gx_jack.h:237
gx_jack::PortConnection
Definition: gx_jack.h:82
gx_jack::PortConnRing::overflow
int overflow
Definition: gx_jack.h:63
gx_jack::GxJack::signal_buffersize_change
Glib::Dispatcher & signal_buffersize_change()
Definition: gx_jack.h:248
gx_jack::GxJack::gx_jack_connection
bool gx_jack_connection(bool connect, bool startserver, int wait_after_connect, const gx_system::CmdlineOptions &opt)
gx_jack::MidiCC::MidiCC
MidiCC(gx_engine::GxEngine &engine_)
gx_engine::GxEngine
Definition: gx_engine.h:69
gx_jack::GxJack::gx_jack_portreg_callback
static void gx_jack_portreg_callback(jack_port_id_t, int, void *arg)
gx_jack::GxJack::report_xrun_clear
void report_xrun_clear()
gx_jack::PortConnRing::send_changes
bool send_changes
Definition: gx_jack.h:62
gx_jack::MidiCC::me_num
int me_num[max_midi_cc_cnt]
Definition: gx_jack.h:118
gx_jack::GxJack::connection_changed
sigc::signal< void, string, string, bool > connection_changed
Definition: gx_jack.h:176
gx_jack::JackPorts::midi_input
PortConnection midi_input
Definition: gx_jack.h:91
gx_jack::PortConnRing::portchange
Glib::Dispatcher portchange
Definition: gx_jack.h:69
gx_jack::MidiCC::send_midi_cc
bool send_midi_cc(int _cc, int _pg, int _bgn, int _num)
gx_jack::GxJack::jack_bs
jack_nframes_t jack_bs
Definition: gx_jack.h:183
gx_jack::GxJack::client_insert
jack_client_t * client_insert
Definition: gx_jack.h:207
gx_jack::GxJack::signal_portchange
Glib::Dispatcher & signal_portchange()
Definition: gx_jack.h:247
gx_jack::GxJack::connection_queue
PortConnRing connection_queue
Definition: gx_jack.h:175
gx_jack::MidiCC::fill
void fill(unsigned char *midi_send, int i)
Definition: gx_jack.h:136
gx_jack::PortConnRing::set_send
void set_send(bool v)
Definition: gx_jack.h:72
gx_jack::GxJack::is_power_of_two
int is_power_of_two(unsigned int x)
gx_jack::PortConnRing::new_data
Glib::Dispatcher new_data
Definition: gx_jack.h:68
gx_jack::GxJack::engine
gx_engine::GxEngine & engine
Definition: gx_jack.h:147
gx_jack::PortConnection::conn
list< string > conn
Definition: gx_jack.h:87
gx_jack::GxJack::get_jcpu_load
float get_jcpu_load()
Definition: gx_jack.h:215
gx_jack::GxJack::session
Glib::Dispatcher session
Definition: gx_jack.h:239
gx_jack::GxJack::gx_jack_xrun_callback
static int gx_jack_xrun_callback(void *arg)