Loading...
Searching...
No Matches
gx_jack.h
Go to the documentation of this file.
/*
* Copyright (C) 2009, 2010 Hermann Meyer, James Warden, Andreas Degert
* Copyright (C) 2011 Pete Shorthose
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* --------------------------------------------------------------------------
*/
/* ------- This is the JACK namespace ------- */
#pragma once
#ifndef SRC_HEADERS_GX_JACK_H_
#define SRC_HEADERS_GX_JACK_H_
#include <atomic>
#ifndef GUITARIX_AS_PLUGIN
#include <jack/jack.h> // NOLINT
#include <jack/midiport.h>
#include <jack/ringbuffer.h>
#ifdef HAVE_JACK_SESSION
#include <jack/session.h>
#endif
namespace gx_engine {
class GxEngine;
}
namespace gx_jack {
/****************************************************************
** class GxRtCheck
** check if user have realtime priority
*/
class GxRtCheck {
private:
std::thread _thd;
std::mutex m;
std::condition_variable cv;
bool isRT;
std::atomic<bool> _execute;
bool set_priority();
void run();
public:
bool run_check();
GxRtCheck();
~GxRtCheck();
};
/****************************************************************
** port connection callback
*/
struct PortConnData {
public:
PortConnData() {} // no init
PortConnData(const char *a, const char *b, bool conn)
: name_a(a), name_b(b), connect(conn) {}
~PortConnData() {}
const char *name_a;
const char *name_b;
bool connect;
};
class PortConnRing {
private:
jack_ringbuffer_t *ring;
bool send_changes;
int overflow; // should be bool but gives compiler error
void set_overflow() { gx_system::atomic_set(&overflow, true); }
void clear_overflow() { gx_system::atomic_set(&overflow, false); }
bool is_overflow() { return gx_system::atomic_get(overflow); }
public:
Glib::Dispatcher new_data;
Glib::Dispatcher portchange;
void push(const char *a, const char *b, bool conn);
bool pop(PortConnData*);
void set_send(bool v) { send_changes = v; }
PortConnRing();
~PortConnRing();
};
/****************************************************************
** class GxJack
*/
class PortConnection {
public:
jack_port_t *port;
list<string> conn;
};
class JackPorts {
public:
PortConnection input;
PortConnection midi_input;
PortConnection insert_out;
PortConnection midi_output;
PortConnection insert_in;
PortConnection output1;
PortConnection output2;
};
#ifdef HAVE_JACK_SESSION
extern "C" {
typedef int (*jack_set_session_callback_type)(
jack_client_t *, JackSessionCallback, void *arg);
typedef char *(*jack_get_uuid_for_client_name_type)(
jack_client_t *, const char *);
typedef char *(*jack_client_get_uuid_type)(jack_client_t *);
}
#endif
class MidiCC {
private:
gx_engine::GxEngine& engine;
static const int max_midi_cc_cnt = 25;
std::atomic<bool> send_cc[max_midi_cc_cnt];
int cc_num[max_midi_cc_cnt];
int pg_num[max_midi_cc_cnt];
int bg_num[max_midi_cc_cnt];
int me_num[max_midi_cc_cnt];
public:
MidiCC(gx_engine::GxEngine& engine_);
bool send_midi_cc(int _cc, int _pg, int _bgn, int _num);
inline int next(int i = -1) const;
inline int size(int i) const { return me_num[i]; }
inline void fill(unsigned char *midi_send, int i);
};
inline int MidiCC::next(int i) const {
while (++i < max_midi_cc_cnt) {
if (send_cc[i].load(std::memory_order_acquire)) {
return i;
}
}
return -1;
}
inline void MidiCC::fill(unsigned char *midi_send, int i) {
if (size(i) == 3) {
midi_send[2] = bg_num[i];
}
midi_send[1] = pg_num[i]; // program value
midi_send[0] = cc_num[i]; // controller+ channel
send_cc[i].store(false, std::memory_order_release);
}
class GxJack: public sigc::trackable {
private:
GxRtCheck rtc;
bool IS_RT;
gx_engine::GxEngine& engine;
bool jack_is_down;
bool jack_is_exit;
bool bypass_insert;
MidiCC mmessage;
static int gx_jack_srate_callback(jack_nframes_t, void* arg);
static int gx_jack_xrun_callback(void* arg);
static int gx_jack_buffersize_callback(jack_nframes_t, void* arg);
static int gx_jack_process(jack_nframes_t, void* arg);
static int gx_jack_insert_process(jack_nframes_t, void* arg);
static void shutdown_callback_client(void* arg);
static void shutdown_callback_client_insert(void* arg);
void gx_jack_shutdown_callback();
static void gx_jack_portreg_callback(jack_port_id_t, int, void* arg);
static void gx_jack_portconn_callback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg);
#ifdef HAVE_JACK_SESSION
jack_session_event_t *session_event;
jack_session_event_t *session_event_ins;
int session_callback_seen;
static void gx_jack_session_callback(jack_session_event_t *event, void *arg);
static void gx_jack_session_callback_ins(jack_session_event_t *event, void *arg);
static jack_set_session_callback_type jack_set_session_callback_fp;
static jack_get_uuid_for_client_name_type jack_get_uuid_for_client_name_fp;
static jack_client_get_uuid_type jack_client_get_uuid_fp;
#endif
void cleanup_slot(bool otherthread);
void fetch_connection_data();
PortConnRing connection_queue;
sigc::signal<void,string,string,bool> connection_changed;
Glib::Dispatcher buffersize_change;
Glib::Dispatcher client_change_rt;
sigc::signal<void> client_change;
string client_instance;
jack_nframes_t jack_sr; // jack sample rate
jack_nframes_t jack_bs; // jack buffer size
float *insert_buffer;
Glib::Dispatcher xrun;
float last_xrun;
bool xrun_msg_blocked;
void report_xrun_clear();
void report_xrun();
void write_jack_port_connections(
gx_system::JsonWriter& w, const char *key, const PortConnection& pc, bool replace=false);
std::string make_clientvar(const std::string& s);
std::string replace_clientvar(const std::string& s);
int is_power_of_two (unsigned int x);
bool gx_jack_init(bool startserver, int wait_after_connect,
const gx_system::CmdlineOptions& opt);
void gx_jack_init_port_connection(const gx_system::CmdlineOptions& opt);
void gx_jack_callbacks();
void gx_jack_cleanup();
inline void check_overload();
void process_midi_cc(void *buf, jack_nframes_t nframes);
public:
JackPorts ports;
jack_client_t* client;
jack_client_t* client_insert;
jack_position_t current;
jack_transport_state_t transport_state;
jack_transport_state_t old_transport_state;
jack_nframes_t get_jack_sr() { return jack_sr; }
jack_nframes_t get_jack_bs() { return jack_bs; }
float get_jcpu_load() { return client ? jack_cpu_load(client) : -1; }
bool get_is_rt() { return client ? IS_RT: false; }
jack_nframes_t get_time_is() { return client ? jack_frame_time(client) : 0; }
public:
GxJack(gx_engine::GxEngine& engine_);
~GxJack();
void set_jack_down(bool v) { jack_is_down = v; }
void set_jack_exit(bool v) { jack_is_exit = v; }
void set_jack_insert(bool v) { bypass_insert = v;}
bool gx_jack_connection(bool connect, bool startserver,
int wait_after_connect, const gx_system::CmdlineOptions& opt);
float get_last_xrun() { return last_xrun; }
void* get_midi_buffer(jack_nframes_t nframes);
bool send_midi_cc(int cc_num, int pgm_num, int bgn, int num);
void read_connections(gx_system::JsonParser& jp);
void write_connections(gx_system::JsonWriter& w);
static string get_default_instancename();
const string& get_instancename() { return client_instance; }
string client_name;
string client_insert_name;
Glib::Dispatcher session;
Glib::Dispatcher session_ins;
Glib::Dispatcher shutdown;
bool is_jack_down() { return jack_is_down; }
Glib::Dispatcher connection;
bool is_jack_exit() { return jack_is_exit; }
sigc::signal<void>& signal_client_change() { return client_change; }
sigc::signal<void,string,string,bool>& signal_connection_changed() { return connection_changed; }
Glib::Dispatcher& signal_portchange() { return connection_queue.portchange; }
Glib::Dispatcher& signal_buffersize_change() { return buffersize_change; }
void send_connection_changes(bool v) { connection_queue.set_send(v); }
static void rt_watchdog_set_limit(int limit);
gx_engine::GxEngine& get_engine() { return engine; }
bool single_client;
#ifdef HAVE_JACK_SESSION
jack_session_event_t *get_last_session_event() {
return gx_system::atomic_get(session_event);
}
jack_session_event_t *get_last_session_event_ins() {
return gx_system::atomic_get(session_event_ins);
}
int return_last_session_event();
int return_last_session_event_ins();
string get_uuid_insert();
#endif
};
inline bool GxJack::send_midi_cc(int cc_num, int pgm_num, int bgn, int num) {
if (!client) {
return false;
}
return mmessage.send_midi_cc(cc_num, pgm_num, bgn, num);
}
} /* end of jack namespace */
#endif // SRC_HEADERS_GX_JACK_H_
#endif
gx_engine::GxEngine
Definition gx_engine.h:70
gx_jack::GxJack::gx_jack_insert_process
static int gx_jack_insert_process(jack_nframes_t, void *arg)
gx_jack::GxJack::is_jack_down
bool is_jack_down()
Definition gx_jack.h:267
gx_jack::GxJack::client_insert_name
string client_insert_name
Definition gx_jack.h:263
gx_jack::GxJack::gx_jack_portreg_callback
static void gx_jack_portreg_callback(jack_port_id_t, int, void *arg)
gx_jack::GxJack::get_engine
gx_engine::GxEngine & get_engine()
Definition gx_jack.h:276
gx_jack::GxJack::set_jack_exit
void set_jack_exit(bool v)
Definition gx_jack.h:249
gx_jack::GxJack::client_name
string client_name
Definition gx_jack.h:262
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::write_connections
void write_connections(gx_system::JsonWriter &w)
gx_jack::GxJack::shutdown
Glib::Dispatcher shutdown
Definition gx_jack.h:266
gx_jack::GxJack::ports
JackPorts ports
Definition gx_jack.h:229
gx_jack::GxJack::~GxJack
~GxJack()
gx_jack::GxJack::send_midi_cc
bool send_midi_cc(int cc_num, int pgm_num, int bgn, int num)
Definition gx_jack.h:291
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::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::GxJack::signal_portchange
Glib::Dispatcher & signal_portchange()
Definition gx_jack.h:272
gx_jack::GxJack::jack_is_down
bool jack_is_down
Definition gx_jack.h:173
gx_jack::GxJack::get_jack_sr
jack_nframes_t get_jack_sr()
Definition gx_jack.h:238
gx_jack::GxJack::get_last_xrun
float get_last_xrun()
Definition gx_jack.h:254
gx_jack::GxJack::gx_jack_cleanup
void gx_jack_cleanup()
gx_jack::GxJack::report_xrun_clear
void report_xrun_clear()
gx_jack::GxJack::set_jack_insert
void set_jack_insert(bool v)
Definition gx_jack.h:251
gx_jack::GxJack::signal_connection_changed
sigc::signal< void, string, string, bool > & signal_connection_changed()
Definition gx_jack.h:271
gx_jack::GxJack::get_instancename
const string & get_instancename()
Definition gx_jack.h:261
gx_jack::GxJack::insert_buffer
float * insert_buffer
Definition gx_jack.h:209
gx_jack::GxJack::rtc
GxRtCheck rtc
Definition gx_jack.h:170
gx_jack::GxJack::gx_jack_init_port_connection
void gx_jack_init_port_connection(const gx_system::CmdlineOptions &opt)
gx_jack::GxJack::get_midi_buffer
void * get_midi_buffer(jack_nframes_t nframes)
gx_jack::GxJack::is_jack_exit
bool is_jack_exit()
Definition gx_jack.h:269
gx_jack::GxJack::single_client
bool single_client
Definition gx_jack.h:277
gx_jack::GxJack::check_overload
void check_overload()
gx_jack::GxJack::engine
gx_engine::GxEngine & engine
Definition gx_jack.h:172
gx_jack::GxJack::jack_is_exit
bool jack_is_exit
Definition gx_jack.h:174
gx_jack::GxJack::get_jcpu_load
float get_jcpu_load()
Definition gx_jack.h:240
gx_jack::GxJack::gx_jack_process
static int gx_jack_process(jack_nframes_t, void *arg)
gx_jack::GxJack::connection
Glib::Dispatcher connection
Definition gx_jack.h:268
gx_jack::GxJack::xrun_msg_blocked
bool xrun_msg_blocked
Definition gx_jack.h:212
gx_jack::GxJack::signal_buffersize_change
Glib::Dispatcher & signal_buffersize_change()
Definition gx_jack.h:273
gx_jack::GxJack::process_midi_cc
void process_midi_cc(void *buf, jack_nframes_t nframes)
gx_jack::GxJack::session
Glib::Dispatcher session
Definition gx_jack.h:264
gx_jack::GxJack::client_change
sigc::signal< void > client_change
Definition gx_jack.h:205
gx_jack::GxJack::shutdown_callback_client
static void shutdown_callback_client(void *arg)
gx_jack::GxJack::client
jack_client_t * client
Definition gx_jack.h:231
gx_jack::GxJack::session_ins
Glib::Dispatcher session_ins
Definition gx_jack.h:265
gx_jack::GxJack::replace_clientvar
std::string replace_clientvar(const std::string &s)
gx_jack::GxJack::read_connections
void read_connections(gx_system::JsonParser &jp)
gx_jack::GxJack::gx_jack_buffersize_callback
static int gx_jack_buffersize_callback(jack_nframes_t, void *arg)
gx_jack::GxJack::shutdown_callback_client_insert
static void shutdown_callback_client_insert(void *arg)
gx_jack::GxJack::GxJack
GxJack(gx_engine::GxEngine &engine_)
gx_jack::GxJack::rt_watchdog_set_limit
static void rt_watchdog_set_limit(int limit)
gx_jack::GxJack::transport_state
jack_transport_state_t transport_state
Definition gx_jack.h:235
gx_jack::GxJack::connection_queue
PortConnRing connection_queue
Definition gx_jack.h:200
gx_jack::GxJack::gx_jack_xrun_callback
static int gx_jack_xrun_callback(void *arg)
gx_jack::GxJack::client_change_rt
Glib::Dispatcher client_change_rt
Definition gx_jack.h:204
gx_jack::GxJack::jack_bs
jack_nframes_t jack_bs
Definition gx_jack.h:208
gx_jack::GxJack::mmessage
MidiCC mmessage
Definition gx_jack.h:176
gx_jack::GxJack::fetch_connection_data
void fetch_connection_data()
gx_jack::GxJack::report_xrun
void report_xrun()
gx_jack::GxJack::gx_jack_callbacks
void gx_jack_callbacks()
gx_jack::GxJack::old_transport_state
jack_transport_state_t old_transport_state
Definition gx_jack.h:236
gx_jack::GxJack::signal_client_change
sigc::signal< void > & signal_client_change()
Definition gx_jack.h:270
gx_jack::GxJack::IS_RT
bool IS_RT
Definition gx_jack.h:171
gx_jack::GxJack::xrun
Glib::Dispatcher xrun
Definition gx_jack.h:210
gx_jack::GxJack::buffersize_change
Glib::Dispatcher buffersize_change
Definition gx_jack.h:202
gx_jack::GxJack::connection_changed
sigc::signal< void, string, string, bool > connection_changed
Definition gx_jack.h:201
gx_jack::GxJack::gx_jack_srate_callback
static int gx_jack_srate_callback(jack_nframes_t, void *arg)
gx_jack::GxJack::gx_jack_shutdown_callback
void gx_jack_shutdown_callback()
gx_jack::GxJack::set_jack_down
void set_jack_down(bool v)
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::GxJack::current
jack_position_t current
Definition gx_jack.h:234
gx_jack::GxJack::bypass_insert
bool bypass_insert
Definition gx_jack.h:175
gx_jack::GxJack::last_xrun
float last_xrun
Definition gx_jack.h:211
gx_jack::GxJack::jack_sr
jack_nframes_t jack_sr
Definition gx_jack.h:207
gx_jack::GxJack::cleanup_slot
void cleanup_slot(bool otherthread)
gx_jack::GxJack::get_is_rt
bool get_is_rt()
Definition gx_jack.h:241
gx_jack::GxJack::client_insert
jack_client_t * client_insert
Definition gx_jack.h:232
gx_jack::GxJack::get_time_is
jack_nframes_t get_time_is()
Definition gx_jack.h:242
gx_jack::GxJack::client_instance
string client_instance
Definition gx_jack.h:206
gx_jack::GxJack::get_jack_bs
jack_nframes_t get_jack_bs()
Definition gx_jack.h:239
gx_jack::GxJack::send_connection_changes
void send_connection_changes(bool v)
Definition gx_jack.h:274
gx_jack::GxJack::is_power_of_two
int is_power_of_two(unsigned int x)
gx_jack::GxJack::make_clientvar
std::string make_clientvar(const std::string &s)
gx_jack::GxRtCheck
Definition gx_jack.h:51
gx_jack::GxRtCheck::GxRtCheck
GxRtCheck()
gx_jack::GxRtCheck::~GxRtCheck
~GxRtCheck()
gx_jack::GxRtCheck::_thd
std::thread _thd
Definition gx_jack.h:53
gx_jack::GxRtCheck::cv
std::condition_variable cv
Definition gx_jack.h:55
gx_jack::GxRtCheck::run_check
bool run_check()
gx_jack::GxRtCheck::_execute
std::atomic< bool > _execute
Definition gx_jack.h:57
gx_jack::GxRtCheck::m
std::mutex m
Definition gx_jack.h:54
gx_jack::GxRtCheck::isRT
bool isRT
Definition gx_jack.h:56
gx_jack::GxRtCheck::set_priority
bool set_priority()
gx_jack::GxRtCheck::run
void run()
gx_jack::JackPorts
Definition gx_jack.h:111
gx_jack::JackPorts::output2
PortConnection output2
Definition gx_jack.h:119
gx_jack::JackPorts::midi_input
PortConnection midi_input
Definition gx_jack.h:114
gx_jack::JackPorts::midi_output
PortConnection midi_output
Definition gx_jack.h:116
gx_jack::JackPorts::insert_out
PortConnection insert_out
Definition gx_jack.h:115
gx_jack::JackPorts::input
PortConnection input
Definition gx_jack.h:113
gx_jack::JackPorts::insert_in
PortConnection insert_in
Definition gx_jack.h:117
gx_jack::JackPorts::output1
PortConnection output1
Definition gx_jack.h:118
gx_jack::MidiCC
Definition gx_jack.h:133
gx_jack::MidiCC::fill
void fill(unsigned char *midi_send, int i)
Definition gx_jack.h:159
gx_jack::MidiCC::next
int next(int i=-1) const
Definition gx_jack.h:150
gx_jack::MidiCC::me_num
int me_num[max_midi_cc_cnt]
Definition gx_jack.h:141
gx_jack::MidiCC::send_cc
std::atomic< bool > send_cc[max_midi_cc_cnt]
Definition gx_jack.h:137
gx_jack::MidiCC::max_midi_cc_cnt
static const int max_midi_cc_cnt
Definition gx_jack.h:136
gx_jack::MidiCC::send_midi_cc
bool send_midi_cc(int _cc, int _pg, int _bgn, int _num)
gx_jack::MidiCC::pg_num
int pg_num[max_midi_cc_cnt]
Definition gx_jack.h:139
gx_jack::MidiCC::engine
gx_engine::GxEngine & engine
Definition gx_jack.h:135
gx_jack::MidiCC::size
int size(int i) const
Definition gx_jack.h:146
gx_jack::MidiCC::cc_num
int cc_num[max_midi_cc_cnt]
Definition gx_jack.h:138
gx_jack::MidiCC::bg_num
int bg_num[max_midi_cc_cnt]
Definition gx_jack.h:140
gx_jack::MidiCC::MidiCC
MidiCC(gx_engine::GxEngine &engine_)
gx_jack::PortConnRing
Definition gx_jack.h:82
gx_jack::PortConnRing::is_overflow
bool is_overflow()
Definition gx_jack.h:89
gx_jack::PortConnRing::pop
bool pop(PortConnData *)
gx_jack::PortConnRing::push
void push(const char *a, const char *b, bool conn)
gx_jack::PortConnRing::~PortConnRing
~PortConnRing()
gx_jack::PortConnRing::overflow
int overflow
Definition gx_jack.h:86
gx_jack::PortConnRing::portchange
Glib::Dispatcher portchange
Definition gx_jack.h:92
gx_jack::PortConnRing::send_changes
bool send_changes
Definition gx_jack.h:85
gx_jack::PortConnRing::PortConnRing
PortConnRing()
gx_jack::PortConnRing::set_overflow
void set_overflow()
Definition gx_jack.h:87
gx_jack::PortConnRing::ring
jack_ringbuffer_t * ring
Definition gx_jack.h:84
gx_jack::PortConnRing::new_data
Glib::Dispatcher new_data
Definition gx_jack.h:91
gx_jack::PortConnRing::clear_overflow
void clear_overflow()
Definition gx_jack.h:88
gx_jack::PortConnRing::set_send
void set_send(bool v)
Definition gx_jack.h:95
gx_jack::PortConnection
Definition gx_jack.h:105
gx_jack::PortConnection::port
jack_port_t * port
Definition gx_jack.h:107
gx_jack::PortConnection::conn
list< string > conn
Definition gx_jack.h:108
gx_system::CmdlineOptions
Definition gx_system.h:395
gx_system::JsonParser
Definition gx_json.h:112
gx_system::JsonWriter
Definition gx_json.h:55
gx_engine
Definition gx_convolver.h:37
gx_jack
Definition gx_internal_plugins.h:27
gx_system::atomic_get
int atomic_get(volatile int &p)
Definition gx_system.h:98
gx_system::atomic_set
void atomic_set(volatile int *p, int v)
Definition gx_system.h:90
gx_jack::PortConnData
Definition gx_jack.h:71
gx_jack::PortConnData::connect
bool connect
Definition gx_jack.h:79
gx_jack::PortConnData::name_a
const char * name_a
Definition gx_jack.h:77
gx_jack::PortConnData::name_b
const char * name_b
Definition gx_jack.h:78
gx_jack::PortConnData::~PortConnData
~PortConnData()
Definition gx_jack.h:76
gx_jack::PortConnData::PortConnData
PortConnData(const char *a, const char *b, bool conn)
Definition gx_jack.h:74
gx_jack::PortConnData::PortConnData
PortConnData()
Definition gx_jack.h:73