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 <jack/jack.h> // NOLINT
29 #include <jack/midiport.h>
30 #include <jack/ringbuffer.h>
31 
32 #ifdef HAVE_JACK_SESSION
33 #include <jack/session.h>
34 #endif
35 
36 namespace gx_jack {
37 
38 /****************************************************************
39  ** port connection callback
40  */
41 
42 struct PortConnData {
43 public:
44  PortConnData() {} // no init
45  PortConnData(const char *a, const char *b, bool conn)
46  : name_a(a), name_b(b), connect(conn) {}
48  const char *name_a;
49  const char *name_b;
50  bool connect;
51 };
52 
53 class PortConnRing {
54 private:
55  jack_ringbuffer_t *ring;
56  bool send_changes;
57  int overflow; // should be bool but gives compiler error
58  void set_overflow() { gx_system::atomic_set(&overflow, true); }
59  void clear_overflow() { gx_system::atomic_set(&overflow, false); }
60  bool is_overflow() { return gx_system::atomic_get(overflow); }
61 public:
62  Glib::Dispatcher new_data;
63  Glib::Dispatcher portchange;
64  void push(const char *a, const char *b, bool conn);
65  bool pop(PortConnData*);
66  void set_send(bool v) { send_changes = v; }
67  PortConnRing();
68  ~PortConnRing();
69 };
70 
71 
72 /****************************************************************
73  ** class GxJack
74  */
75 
77 public:
78  jack_port_t *port;
79  list<string> conn;
80 };
81 
82 class JackPorts {
83 public:
91 };
92 
93 #ifdef HAVE_JACK_SESSION
94 extern "C" {
95  typedef int (*jack_set_session_callback_type)(
96  jack_client_t *, JackSessionCallback, void *arg);
97  typedef char *(*jack_get_uuid_for_client_name_type)(
98  jack_client_t *, const char *);
99  typedef char *(*jack_client_get_uuid_type)(jack_client_t *);
100 }
101 #endif
102 
103 struct midi_cc {
104  bool send_cc[5];
105  int cc_num[5];
106  int pg_num[5];
107  int bg_num[5];
108  int me_num[5];
109 };
110 
111 class GxJack: public sigc::trackable {
112  private:
113  gx_engine::GxEngine& engine;
114  bool jack_is_down;
115  bool jack_is_exit;
116  bool bypass_insert;
117  midi_cc mmessage;
118  static int gx_jack_srate_callback(jack_nframes_t, void* arg);
119  static int gx_jack_xrun_callback(void* arg);
120  static int gx_jack_buffersize_callback(jack_nframes_t, void* arg);
121  static int gx_jack_process(jack_nframes_t, void* arg);
122  static int gx_jack_insert_process(jack_nframes_t, void* arg);
123 
124  static void shutdown_callback_client(void* arg);
125  static void shutdown_callback_client_insert(void* arg);
126  void gx_jack_shutdown_callback();
127  static void gx_jack_portreg_callback(jack_port_id_t, int, void* arg);
128  static void gx_jack_portconn_callback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg);
129 #ifdef HAVE_JACK_SESSION
130  jack_session_event_t *session_event;
131  jack_session_event_t *session_event_ins;
132  int session_callback_seen;
133  static void gx_jack_session_callback(jack_session_event_t *event, void *arg);
134  static void gx_jack_session_callback_ins(jack_session_event_t *event, void *arg);
135  static jack_set_session_callback_type jack_set_session_callback_fp;
136  static jack_get_uuid_for_client_name_type jack_get_uuid_for_client_name_fp;
137  static jack_client_get_uuid_type jack_client_get_uuid_fp;
138 #endif
139  void cleanup_slot(bool otherthread);
140  void fetch_connection_data();
141  PortConnRing connection_queue;
142  sigc::signal<void,string,string,bool> connection_changed;
143  Glib::Dispatcher buffersize_change;
144 
145  Glib::Dispatcher client_change_rt;
146  sigc::signal<void> client_change;
147  string client_instance;
148  jack_nframes_t jack_sr; // jack sample rate
149  jack_nframes_t jack_bs; // jack buffer size
150  float *insert_buffer;
151  Glib::Dispatcher xrun;
152  float last_xrun;
153  bool xrun_msg_blocked;
154  void report_xrun_clear();
155  void report_xrun();
156  void write_jack_port_connections(
157  gx_system::JsonWriter& w, const char *key, const PortConnection& pc, bool replace=false);
158  std::string make_clientvar(const std::string& s);
159  std::string replace_clientvar(const std::string& s);
160  int is_power_of_two (unsigned int x);
161  bool gx_jack_init(bool startserver, int wait_after_connect,
162  const gx_system::CmdlineOptions& opt);
163  void gx_jack_init_port_connection(const gx_system::CmdlineOptions& opt);
164  void gx_jack_callbacks();
165  void gx_jack_cleanup();
166  inline void check_overload();
167 
168  public:
170 
171  jack_client_t* client;
172  jack_client_t* client_insert;
173 
174  jack_position_t current;
175  jack_transport_state_t transport_state;
176  jack_transport_state_t old_transport_state;
177 
178  jack_nframes_t get_jack_sr() { return jack_sr; }
179  jack_nframes_t get_jack_bs() { return jack_bs; }
180  float get_jcpu_load() { return client ? jack_cpu_load(client) : -1; }
181  bool get_is_rt() { return client ? jack_is_realtime(client) : false; }
182  jack_nframes_t get_time_is() { return client ? jack_frame_time(client) : 0; }
183 
184 public:
185  GxJack(gx_engine::GxEngine& engine_);
186  ~GxJack();
187 
188  void set_jack_down(bool v) { jack_is_down = v; }
189  void set_jack_exit(bool v) { jack_is_exit = v; }
190 
191  void set_jack_insert(bool v) { bypass_insert = v;}
192  bool gx_jack_connection(bool connect, bool startserver,
193  int wait_after_connect, const gx_system::CmdlineOptions& opt);
194  float get_last_xrun() { return last_xrun; }
195  void* get_midi_buffer(jack_nframes_t nframes);
196  void send_midi_cc(int cc_num, int pgm_num, int bgn, int num);
197  void process_midi_cc(void *buf, jack_nframes_t nframes);
198 
199  void read_connections(gx_system::JsonParser& jp);
200  void write_connections(gx_system::JsonWriter& w);
201  static string get_default_instancename();
202  const string& get_instancename() { return client_instance; }
203  string client_name;
205  Glib::Dispatcher session;
206  Glib::Dispatcher session_ins;
207  Glib::Dispatcher shutdown;
208  bool is_jack_down() { return jack_is_down; }
209  Glib::Dispatcher connection;
210  bool is_jack_exit() { return jack_is_exit; }
211  sigc::signal<void>& signal_client_change() { return client_change; }
212  sigc::signal<void,string,string,bool>& signal_connection_changed() { return connection_changed; }
213  Glib::Dispatcher& signal_portchange() { return connection_queue.portchange; }
214  Glib::Dispatcher& signal_buffersize_change() { return buffersize_change; }
215  void send_connection_changes(bool v) { connection_queue.set_send(v); }
216  static void rt_watchdog_set_limit(int limit);
217 #ifdef HAVE_JACK_SESSION
218  jack_session_event_t *get_last_session_event() {
219  return gx_system::atomic_get(session_event);
220  }
221  jack_session_event_t *get_last_session_event_ins() {
222  return gx_system::atomic_get(session_event_ins);
223  }
224  int return_last_session_event();
225  int return_last_session_event_ins();
226  string get_uuid_insert();
227  bool single_client;
228  gx_engine::GxEngine& get_engine() { return engine; }
229 #endif
230 };
231 
232 } /* end of jack namespace */
233 
234 #endif // SRC_HEADERS_GX_JACK_H_
Glib::Dispatcher session
Definition: gx_jack.h:205
void send_connection_changes(bool v)
Definition: gx_jack.h:215
void set_jack_down(bool v)
Definition: gx_jack.h:188
jack_nframes_t get_jack_sr()
Definition: gx_jack.h:178
bool get_is_rt()
Definition: gx_jack.h:181
Glib::Dispatcher & signal_portchange()
Definition: gx_jack.h:213
PortConnection midi_output
Definition: gx_jack.h:87
PortConnection output1
Definition: gx_jack.h:89
PortConnection insert_out
Definition: gx_jack.h:86
void set_send(bool v)
Definition: gx_jack.h:66
jack_nframes_t get_jack_bs()
Definition: gx_jack.h:179
Glib::Dispatcher connection
Definition: gx_jack.h:209
const char * name_b
Definition: gx_jack.h:49
void set_jack_insert(bool v)
Definition: gx_jack.h:191
int atomic_get(volatile int &p)
Definition: gx_system.h:98
float get_jcpu_load()
Definition: gx_jack.h:180
PortConnection output2
Definition: gx_jack.h:90
jack_port_t * port
Definition: gx_jack.h:78
Glib::Dispatcher new_data
Definition: gx_jack.h:62
jack_client_t * client
Definition: gx_jack.h:171
PortConnection insert_in
Definition: gx_jack.h:88
bool is_jack_exit()
Definition: gx_jack.h:210
bool is_jack_down()
Definition: gx_jack.h:208
void set_jack_exit(bool v)
Definition: gx_jack.h:189
PortConnection input
Definition: gx_jack.h:84
sigc::signal< void, string, string, bool > & signal_connection_changed()
Definition: gx_jack.h:212
Glib::Dispatcher & signal_buffersize_change()
Definition: gx_jack.h:214
jack_position_t current
Definition: gx_jack.h:174
PortConnData(const char *a, const char *b, bool conn)
Definition: gx_jack.h:45
list< string > conn
Definition: gx_jack.h:79
jack_transport_state_t transport_state
Definition: gx_jack.h:175
const char * name_a
Definition: gx_jack.h:48
JackPorts ports
Definition: gx_jack.h:169
jack_client_t * client_insert
Definition: gx_jack.h:172
PortConnection midi_input
Definition: gx_jack.h:85
const string & get_instancename()
Definition: gx_jack.h:202
void atomic_set(volatile int *p, int v)
Definition: gx_system.h:90
Glib::Dispatcher shutdown
Definition: gx_jack.h:207
sigc::signal< void > & signal_client_change()
Definition: gx_jack.h:211
Glib::Dispatcher portchange
Definition: gx_jack.h:63
float get_last_xrun()
Definition: gx_jack.h:194
Glib::Dispatcher session_ins
Definition: gx_jack.h:206
string client_name
Definition: gx_jack.h:203
jack_transport_state_t old_transport_state
Definition: gx_jack.h:176
string client_insert_name
Definition: gx_jack.h:204
jack_nframes_t get_time_is()
Definition: gx_jack.h:182