1 /* Calf DSP Library Utility Application - calfjackhost 2 * API wrapper for JACK Audio Connection Kit 3 * 4 * Copyright (C) 2007 Krzysztof Foltman 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2, or (at your option) 9 * any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 * 02110-1301, USA. 20 */ 21 #ifndef __CALF_JACKHOST_H 22 #define __CALF_JACKHOST_H 23 24 #include <config.h> 25 26 #if USE_JACK 27 28 #include "utils.h" 29 #include "vumeter.h" 30 #include <pthread.h> 31 #include <jack/jack.h> 32 #include <jack/session.h> 33 34 #ifdef OLD_JACK 35 #define NFRAMES_MAYBE(nframes) nframes 36 #else 37 #define NFRAMES_MAYBE(nframes) 38 #endif 39 40 namespace calf_plugins { 41 42 class jack_host; 43 44 struct automation_iface 45 { 46 virtual uint32_t apply_and_adjust(uint32_t start, uint32_t time) = 0; ~automation_ifaceautomation_iface47 virtual ~automation_iface() {} 48 }; 49 50 class jack_client { 51 protected: 52 std::vector<jack_host *> plugins; 53 calf_utils::ptmutex mutex; 54 55 /// Common port for MIDI parameter automation 56 jack_port_t *automation_port; 57 58 public: 59 jack_client_t *client; 60 int input_nr, output_nr, midi_nr; 61 std::string name, input_name, output_name, midi_name; 62 int sample_rate; 63 64 jack_client(); 65 void add(jack_host *plugin); 66 void del(jack_host *plugin); 67 void open(const char *client_name, const char *jack_session_id); 68 std::string get_name(); 69 void activate(); 70 void deactivate(); 71 void delete_plugins(); 72 void create_automation_input(); 73 void destroy_automation_input(); 74 void connect(const std::string &p1, const std::string &p2); 75 void close(); 76 void apply_plugin_order(const std::vector<int> &indices); 77 void calculate_plugin_order(std::vector<int> &indices); 78 const char **get_ports(const char *name_re, const char *type_re, unsigned long flags); 79 80 static int do_jack_process(jack_nframes_t nframes, void *p); 81 static int do_jack_bufsize(jack_nframes_t numsamples, void *p); 82 template<class T> atomic_swap(T & v1,T & v2)83 void atomic_swap(T &v1, T &v2) 84 { 85 calf_utils::ptlock lock(mutex); 86 std::swap(v1, v2); 87 } 88 }; 89 90 class jack_host: public plugin_ctl_iface { 91 public: 92 struct port { 93 jack_port_t *handle; 94 float *data; 95 std::string name, nice_name; 96 dsp::vumeter meter; portport97 port() : handle(NULL), data(NULL) {} ~portport98 ~port() { } 99 }; 100 public: 101 float **ins, **outs, **params; 102 std::vector<port> inputs, outputs; 103 float *param_values; 104 float midi_meter; 105 audio_module_iface *module; 106 automation_map *cc_mappings; 107 std::vector<int> write_serials; 108 int last_modify_serial; 109 uint32_t last_designator; 110 111 public: 112 typedef int (*process_func)(jack_nframes_t nframes, void *p); 113 jack_client *client; 114 bool changed; 115 port midi_port; 116 std::string name; 117 std::string instance_name; 118 int in_count, out_count, param_count; 119 const plugin_metadata_iface *metadata; 120 121 public: 122 jack_host(jack_client *_client, audio_module_iface *_module, const std::string &_name, const std::string &_instance_name, calf_plugins::progress_report_iface *_priface); 123 void create(); 124 void create_ports(); 125 void rename_ports(); 126 void init_module(); 127 void destroy(); 128 ~jack_host(); 129 130 void rename(std::string name); 131 /// Handle JACK MIDI port data 132 void handle_event(uint8_t *buffer, uint32_t size); 133 /// Process audio and update meters 134 void process_part(unsigned int time, unsigned int len); 135 /// Get meter value for the Nth port 136 virtual float get_level(unsigned int port); 137 /// Process audio/MIDI buffers 138 int process(jack_nframes_t nframes, automation_iface &automation); 139 /// Retrieve and cache output port buffers 140 void cache_ports(); 141 /// Retrieve the full list of input ports, audio+MIDI (the pointers are temporary, may point to nowhere after any changes etc.) 142 void get_all_input_ports(std::vector<port *> &ports); 143 /// Retrieve the full list of output ports (the pointers are temporary, may point to nowhere after any changes etc.) 144 void get_all_output_ports(std::vector<port *> &ports); 145 void handle_automation_cc(uint32_t designator, int value); 146 147 public: 148 // Port access get_inputs()149 port *get_inputs() { return inputs.empty() ? NULL : &inputs[0]; } get_outputs()150 port *get_outputs() { return outputs.empty() ? NULL : &outputs[0]; } get_params()151 float *get_params() { return param_values; } get_midi_port()152 port *get_midi_port() { return get_metadata_iface()->get_midi() ? &midi_port : NULL; } 153 public: 154 // Implementations of methods in plugin_ctl_iface activate_preset(int bank,int program)155 bool activate_preset(int bank, int program) { return false; } get_param_value(int param_no)156 virtual float get_param_value(int param_no) { 157 assert(param_no >= 0 && param_no < param_count); 158 return param_values[param_no]; 159 } set_param_value(int param_no,float value)160 virtual void set_param_value(int param_no, float value) { 161 assert(param_no >= 0 && param_no < param_count); 162 param_values[param_no] = value; 163 changed = true; 164 } get_instance_name()165 virtual std::string get_instance_name() { return instance_name; } execute(int cmd_no)166 virtual void execute(int cmd_no) { module->execute(cmd_no); } 167 virtual char *configure(const char *key, const char *value); send_configures(send_configure_iface * sci)168 virtual void send_configures(send_configure_iface *sci) { module->send_configures(sci); } 169 virtual void send_automation_configures(send_configure_iface *); send_status_updates(send_updates_iface * sui,int last_serial)170 virtual int send_status_updates(send_updates_iface *sui, int last_serial) { return module->send_status_updates(sui, last_serial); } get_metadata_iface()171 virtual const plugin_metadata_iface *get_metadata_iface() const { return module->get_metadata_iface(); } get_line_graph_iface()172 virtual const line_graph_iface *get_line_graph_iface() const { return module->get_line_graph_iface(); } get_phase_graph_iface()173 virtual const phase_graph_iface *get_phase_graph_iface() const { return module->get_phase_graph_iface(); } get_write_serial(int param_no)174 virtual int get_write_serial(int param_no) { return write_serials[param_no]; } 175 virtual void add_automation(uint32_t source, const automation_range &dest); 176 virtual void delete_automation(uint32_t source, int param_no); 177 virtual void get_automation(int param_no, std::multimap<uint32_t, automation_range> &dests); 178 virtual uint32_t get_last_automation_source(); 179 void replace_automation_map(automation_map *amap); 180 }; 181 182 extern jack_host *create_jack_host(jack_client *_client, const char *name, const std::string &instance_name, calf_plugins::progress_report_iface *priface); 183 184 }; 185 186 #endif 187 188 #endif 189