[SCM] calf/master: Clean up the JACK host.
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:40:02 UTC 2013
The following commit has been merged in the master branch:
commit d08458e235440780e56916e14eb3555945a8254e
Author: Krzysztof Foltman <wdev at foltman.com>
Date: Tue Apr 6 22:24:13 2010 +0100
Clean up the JACK host.
Remove excessive inlines from the header. Move parts of the definitions and
code into separate files. Remove dead code.
diff --git a/src/Makefile.am b/src/Makefile.am
index 7942667..9efba46 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,7 +29,7 @@ if USE_JACK
AM_CXXFLAGS += $(JACK_DEPS_CFLAGS)
noinst_LTLIBRARIES += libcalfgui.la
bin_PROGRAMS += calfjackhost
-calfjackhost_SOURCES = jackhost.cpp
+calfjackhost_SOURCES = host_session.cpp jack_client.cpp jackhost.cpp
calfjackhost_LDADD = libcalfgui.la libcalfstatic.la $(JACK_DEPS_LIBS) $(GUI_DEPS_LIBS) $(FLUIDSYNTH_DEPS_LIBS)
if USE_LASH
AM_CXXFLAGS += $(LASH_DEPS_CFLAGS)
diff --git a/src/calf/Makefile.am b/src/calf/Makefile.am
index b667f6e..b233562 100644
--- a/src/calf/Makefile.am
+++ b/src/calf/Makefile.am
@@ -1,6 +1,7 @@
noinst_HEADERS = audio_fx.h benchmark.h biquad.h buffer.h custom_ctl.h \
ctl_curve.h ctl_keyboard.h ctl_led.h \
- delay.h envelope.h fft.h fixed_point.h giface.h gui.h gui_controls.h inertia.h jackhost.h ladspa_wrap.h loudness.h \
+ delay.h envelope.h fft.h fixed_point.h giface.h gui.h gui_controls.h inertia.h jackhost.h \
+ host_session.h ladspa_wrap.h loudness.h \
lv2_contexts.h lv2_data_access.h lv2_event.h lv2_external_ui.h \
lv2_progress.h lv2_polymorphic_port.h lv2_string_port.h lv2_ui.h \
lv2_uri_map.h lv2-midiport.h lv2helpers.h lv2wrap.h \
diff --git a/src/calf/giface.h b/src/calf/giface.h
index 0f08327..c07f6df 100644
--- a/src/calf/giface.h
+++ b/src/calf/giface.h
@@ -18,8 +18,8 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02111-1307, USA.
*/
-#ifndef __CALF_GIFACE_H
-#define __CALF_GIFACE_H
+#ifndef CALF_GIFACE_H
+#define CALF_GIFACE_H
#include <stdint.h>
#include <stdlib.h>
diff --git a/src/calf/host_session.h b/src/calf/host_session.h
new file mode 100644
index 0000000..90733ac
--- /dev/null
+++ b/src/calf/host_session.h
@@ -0,0 +1,91 @@
+/* Calf DSP Library Utility Application - calfjackhost
+ * Class for managing calfjackhost's
+ *
+ * Copyright (C) 2007 Krzysztof Foltman
+ *
+ * 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, 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.
+ */
+#ifndef CALF_HOST_SESSION_H
+#define CALF_HOST_SESSION_H
+
+#include <calf/jackhost.h>
+
+namespace calf_plugins {
+
+class main_window;
+
+struct host_session: public main_window_owner_iface, public calf_plugins::progress_report_iface
+{
+ std::string client_name, input_name, output_name, midi_name;
+ std::vector<std::string> plugin_names;
+ std::map<int, std::string> presets;
+#if USE_LASH
+ int lash_source_id;
+ lash_client_t *lash_client;
+# if !USE_LASH_0_6
+ lash_args_t *lash_args;
+# endif
+#endif
+
+ // these are not saved
+ jack_client client;
+ std::string autoconnect_midi;
+ int autoconnect_midi_index;
+ std::set<int> chains;
+ std::vector<jack_host *> plugins;
+ main_window *main_win;
+ bool restoring_session;
+ std::set<std::string> instances;
+ GtkWidget *progress_window;
+ plugin_gui_window *gui_win;
+
+ host_session();
+ void open();
+ void add_plugin(std::string name, std::string preset, std::string instance_name = std::string());
+ void create_plugins_from_list();
+ void connect();
+ void close();
+ bool activate_preset(int plugin, const std::string &preset, bool builtin);
+#if USE_LASH
+ static gboolean update_lash(void *self) { ((host_session *)self)->update_lash(); return TRUE; }
+ void update_lash();
+# if !USE_LASH_0_6
+ void send_lash(LASH_Event_Type type, const std::string &data) {
+ lash_send_event(lash_client, lash_event_new_with_all(type, data.c_str()));
+ }
+# endif
+#endif
+ virtual void new_plugin(const char *name);
+ virtual void remove_plugin(plugin_ctl_iface *plugin);
+ void remove_all_plugins();
+ std::string get_next_instance_name(const std::string &effect_name);
+
+ /// Create a toplevel window with progress bar
+ GtkWidget *create_progress_window();
+ /// Implementation of progress_report_iface function
+ void report_progress(float percentage, const std::string &message);
+
+ /// Implementation of open file functionality (TODO)
+ virtual char *open_file(const char *name);
+ /// Implementation of save file functionality
+ virtual char *save_file(const char *name);
+ /// Implementation of connection to LASH (or, in future, other session manager)
+ void connect_to_session_manager(int argc, char *argv[]);
+};
+
+};
+
+#endif
diff --git a/src/calf/jackhost.h b/src/calf/jackhost.h
index a1506d6..30133a9 100644
--- a/src/calf/jackhost.h
+++ b/src/calf/jackhost.h
@@ -25,6 +25,9 @@
#include <jack/jack.h>
#include <jack/midiport.h>
+#if USE_LASH
+#include <lash/lash.h>
+#endif
#include "gui.h"
#include "utils.h"
#include "vumeter.h"
@@ -44,72 +47,17 @@ public:
std::string name, input_name, output_name, midi_name;
int sample_rate;
- jack_client()
- {
- input_nr = output_nr = midi_nr = 1;
- input_name = "input_%d";
- output_name = "output_%d";
- midi_name = "midi_%d";
- sample_rate = 0;
- client = NULL;
- }
-
- void add(jack_host *plugin)
- {
- calf_utils::ptlock lock(mutex);
- plugins.push_back(plugin);
- }
-
- void del(int item)
- {
- calf_utils::ptlock lock(mutex);
- plugins.erase(plugins.begin()+item);
- }
-
- void open(const char *client_name)
- {
- jack_status_t status;
- client = jack_client_open(client_name, JackNullOption, &status);
- if (!client)
- throw calf_utils::text_exception("Could not initialize JACK subsystem");
- sample_rate = jack_get_sample_rate(client);
- jack_set_process_callback(client, do_jack_process, this);
- jack_set_buffer_size_callback(client, do_jack_bufsize, this);
- name = get_name();
- }
-
- std::string get_name()
- {
- return std::string(jack_get_client_name(client));
- }
-
- void activate()
- {
- jack_activate(client);
- }
-
- void deactivate()
- {
- jack_deactivate(client);
- }
-
+ jack_client();
+ void add(jack_host *plugin);
+ void del(int item);
+ void open(const char *client_name);
+ std::string get_name();
+ void activate();
+ void deactivate();
void delete_plugins();
-
- void connect(const std::string &p1, const std::string &p2)
- {
- if (jack_connect(client, p1.c_str(), p2.c_str()) != 0)
- throw calf_utils::text_exception("Could not connect JACK ports "+p1+" and "+p2);
- }
-
- void close()
- {
- jack_client_close(client);
- }
-
- const char **get_ports(const char *name_re, const char *type_re, unsigned long flags)
- {
- return jack_get_ports(client, name_re, type_re, flags);
- }
+ void connect(const std::string &p1, const std::string &p2);
+ void close();
+ const char **get_ports(const char *name_re, const char *type_re, unsigned long flags);
static int do_jack_process(jack_nframes_t nframes, void *p);
static int do_jack_bufsize(jack_nframes_t numsamples, void *p);
@@ -121,13 +69,13 @@ public:
jack_port_t *handle;
float *data;
std::string name;
+ vumeter meter;
port() : handle(NULL), data(NULL) {}
~port() { }
};
public:
float **ins, **outs, **params;
std::vector<port> inputs, outputs;
- std::vector<vumeter> input_vus, output_vus;
float *param_values;
float midi_meter;
audio_module_iface *module;
@@ -141,179 +89,35 @@ public:
std::string instance_name;
int in_count, out_count;
const plugin_metadata_iface *metadata;
- port *get_midi_port() { return get_metadata_iface()->get_midi() ? &midi_port : NULL; }
- void set_params(const float *params) {
- memcpy(get_params(), params, get_metadata_iface()->get_param_count() * sizeof(float));
- changed = true;
- }
-
- void set_params() {
- changed = true;
- }
-
- void open(jack_client *_client);
-
- virtual void create_ports();
-
- void close();
-
- jack_host(audio_module_iface *_module, const std::string &_name, const std::string &_instance_name, calf_plugins::progress_report_iface *_priface)
- : module(_module)
- {
- name = _name;
- instance_name = _instance_name;
-
- client = NULL;
- changed = true;
-
- module->get_port_arrays(ins, outs, params);
- metadata = module->get_metadata_iface();
- in_count = metadata->get_input_count();
- out_count = metadata->get_output_count();
- inputs.resize(in_count);
- outputs.resize(out_count);
- input_vus.resize(in_count);
- output_vus.resize(out_count);
- param_values = new float[metadata->get_param_count()];
- for (int i = 0; i < metadata->get_param_count(); i++) {
- params[i] = ¶m_values[i];
- }
- clear_preset();
- midi_meter = 0;
- module->set_progress_report_iface(_priface);
- module->post_instantiate();
- }
-
- ~jack_host()
- {
- delete []param_values;
- if (client)
- close();
- }
-
- virtual void init_module() {
- module->set_sample_rate(client->sample_rate);
- module->activate();
- module->params_changed();
- }
-
- virtual const parameter_properties* get_param_props(int param_no) { return metadata->get_param_props(param_no); }
-
- void handle_event(uint8_t *buffer, uint32_t size)
- {
- int value;
- switch(buffer[0] >> 4)
- {
- case 8:
- module->note_off(buffer[1], buffer[2]);
- break;
- case 9:
- if (!buffer[2])
- module->note_off(buffer[1], 0);
- else
- module->note_on(buffer[1], buffer[2]);
- break;
- case 11:
- module->control_change(buffer[1], buffer[2]);
- break;
- case 12:
- module->program_change(buffer[1]);
- break;
- case 13:
- module->channel_pressure(buffer[1]);
- break;
- case 14:
- value = buffer[1] + 128 * buffer[2] - 8192;
- module->pitch_bend(value);
- break;
- }
- }
- void process_part(unsigned int time, unsigned int len)
- {
- if (!len)
- return;
- for (int i = 0; i < in_count; i++)
- input_vus[i].update(ins[i] + time, len);
- unsigned int mask = module->process(time, len, -1, -1);
- for (int i = 0; i < out_count; i++)
- {
- if (!(mask & (1 << i))) {
- dsp::zero(outs[i] + time, len);
- output_vus[i].update_zeros(len);
- } else
- output_vus[i].update(outs[i] + time, len);
- }
- // decay linearly for 0.1s
- float new_meter = midi_meter - len / (0.1 * client->sample_rate);
- if (new_meter < 0)
- new_meter = 0;
- midi_meter = new_meter;
- }
- virtual float get_level(unsigned int port) {
- if (port < (unsigned)in_count)
- return input_vus[port].level;
- port -= in_count;
- if (port < (unsigned)out_count)
- return output_vus[port].level;
- port -= out_count;
- if (port == 0 && metadata->get_midi())
- return midi_meter;
- return 0.f;
- }
- int process(jack_nframes_t nframes)
- {
- for (int i=0; i<in_count; i++) {
- ins[i] = inputs[i].data = (float *)jack_port_get_buffer(inputs[i].handle, nframes);
- }
- if (metadata->get_midi())
- midi_port.data = (float *)jack_port_get_buffer(midi_port.handle, nframes);
- if (changed) {
- module->params_changed();
- changed = false;
- }
-
- unsigned int time = 0;
- if (metadata->get_midi())
- {
- jack_midi_event_t event;
-#ifdef OLD_JACK
- int count = jack_midi_get_event_count(midi_port.data, nframes);
-#else
- int count = jack_midi_get_event_count(midi_port.data);
-#endif
- for (int i = 0; i < count; i++)
- {
-#ifdef OLD_JACK
- jack_midi_event_get(&event, midi_port.data, i, nframes);
-#else
- jack_midi_event_get(&event, midi_port.data, i);
-#endif
- unsigned int len = event.time - time;
- process_part(time, len);
-
- midi_meter = 1.f;
- handle_event(event.buffer, event.size);
-
- time = event.time;
- }
- }
- process_part(time, nframes - time);
- module->params_reset();
- return 0;
- }
-
- void cache_ports()
- {
- for (int i=0; i<out_count; i++) {
- outs[i] = outputs[i].data = (float *)jack_port_get_buffer(outputs[i].handle, 0);
- }
- }
+public:
+ jack_host(audio_module_iface *_module, const std::string &_name, const std::string &_instance_name, calf_plugins::progress_report_iface *_priface);
+ void create(jack_client *_client);
+ void create_ports();
+ void init_module();
+ void destroy();
+ ~jack_host();
+
+ /// Handle JACK MIDI port data
+ void handle_event(uint8_t *buffer, uint32_t size);
+ /// Process audio and update meters
+ void process_part(unsigned int time, unsigned int len);
+ /// Get meter value for the Nth port
+ virtual float get_level(unsigned int port);
+ /// Process audio/MIDI buffers
+ int process(jack_nframes_t nframes);
+ /// Retrieve and cache output port buffers
+ void cache_ports();
- virtual port *get_inputs() { return &inputs[0]; }
- virtual port *get_outputs() { return &outputs[0]; }
- virtual float *get_params() { return param_values; }
- virtual bool activate_preset(int bank, int program) { return false; }
+public:
+ // Port access
+ port *get_inputs() { return &inputs[0]; }
+ port *get_outputs() { return &outputs[0]; }
+ float *get_params() { return param_values; }
+ port *get_midi_port() { return get_metadata_iface()->get_midi() ? &midi_port : NULL; }
+public:
+ // Implementations of methods in plugin_ctl_iface
+ bool activate_preset(int bank, int program) { return false; }
virtual float get_param_value(int param_no) {
return param_values[param_no];
}
diff --git a/src/jackhost.cpp b/src/host_session.cpp
similarity index 67%
copy from src/jackhost.cpp
copy to src/host_session.cpp
index 2ed27ae..6e1cbb3 100644
--- a/src/jackhost.cpp
+++ b/src/host_session.cpp
@@ -1,7 +1,7 @@
/* Calf DSP Library Utility Application - calfjackhost
- * Standalone application module wrapper example.
+ * A class that contains a JACK host session
*
- * Copyright (C) 2007 Krzysztof Foltman
+ * Copyright (C) 2007-2010 Krzysztof Foltman
*
* 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
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
+
#include <set>
#include <getopt.h>
#include <stdint.h>
@@ -25,11 +26,8 @@
#include <config.h>
#include <glade/glade.h>
#include <jack/jack.h>
-#if USE_LASH
-#include <lash/lash.h>
-#endif
#include <calf/giface.h>
-#include <calf/jackhost.h>
+#include <calf/host_session.h>
#include <calf/modules.h>
#include <calf/modules_dev.h>
#include <calf/organ.h>
@@ -39,206 +37,12 @@
#include <calf/main_win.h>
#include <calf/utils.h>
#include <stdio.h>
+
using namespace std;
using namespace calf_utils;
using namespace calf_plugins;
-// I don't need anyone to tell me this is stupid. I already know that :)
-plugin_gui_window *gui_win;
-
-const char *client_name = "calfhost";
-
-#if USE_LASH_0_6
-static bool save_data_set_cb(lash_config_handle_t *handle, void *user_data);
-static bool load_data_set_cb(lash_config_handle_t *handle, void *user_data);
-static bool quit_cb(void *user_data);
-#endif
-
-jack_host *calf_plugins::create_jack_host(const char *effect_name, const std::string &instance_name, calf_plugins::progress_report_iface *priface)
-{
- #define PER_MODULE_ITEM(name, isSynth, jackname) if (!strcasecmp(effect_name, jackname)) return new jack_host(new name##_audio_module, effect_name, instance_name, priface);
- #include <calf/modulelist.h>
- return NULL;
-}
-
-void jack_host::open(jack_client *_client)
-{
- client = _client; //jack_client_open(client_name, JackNullOption, &status);
-
- create_ports();
-
- cache_ports();
-
- init_module();
- changed = false;
-}
-
-void jack_host::create_ports() {
- char buf[32];
- char buf2[64];
- string prefix = client->name + ":";
- static const char *suffixes[] = { "l", "r", "2l", "2r" };
- port *inputs = get_inputs();
- port *outputs = get_outputs();
- int in_count = metadata->get_input_count(), out_count = metadata->get_output_count();
- for (int i=0; i<in_count; i++) {
- sprintf(buf, "%s_in_%s", instance_name.c_str(), suffixes[i]);
- sprintf(buf2, client->input_name.c_str(), client->input_nr++);
- inputs[i].name = buf2;
- inputs[i].handle = jack_port_register(client->client, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput , 0);
- inputs[i].data = NULL;
- if (!inputs[i].handle)
- throw text_exception("Could not create JACK input port");
- jack_port_set_alias(inputs[i].handle, (prefix + buf2).c_str());
- }
- if (metadata->get_midi()) {
- sprintf(buf, "%s_midi_in", instance_name.c_str());
- sprintf(buf2, client->midi_name.c_str(), client->midi_nr++);
- midi_port.name = buf2;
- midi_port.handle = jack_port_register(client->client, buf, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
- if (!midi_port.handle)
- throw text_exception("Could not create JACK MIDI port");
- jack_port_set_alias(midi_port.handle, (prefix + buf2).c_str());
- }
- for (int i=0; i<out_count; i++) {
- sprintf(buf, "%s_out_%s", instance_name.c_str(), suffixes[i]);
- sprintf(buf2, client->output_name.c_str(), client->output_nr++);
- outputs[i].name = buf2;
- outputs[i].handle = jack_port_register(client->client, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput , 0);
- outputs[i].data = NULL;
- if (!outputs[i].handle)
- throw text_exception("Could not create JACK output port");
- jack_port_set_alias(outputs[i].handle, (prefix + buf2).c_str());
- }
-}
-
-void jack_host::close() {
- port *inputs = get_inputs(), *outputs = get_outputs();
- int input_count = metadata->get_input_count(), output_count = metadata->get_output_count();
- for (int i = 0; i < input_count; i++) {
- jack_port_unregister(client->client, inputs[i].handle);
- inputs[i].data = NULL;
- }
- for (int i = 0; i < output_count; i++) {
- jack_port_unregister(client->client, outputs[i].handle);
- outputs[i].data = NULL;
- }
- if (metadata->get_midi())
- jack_port_unregister(client->client, midi_port.handle);
- client = NULL;
-}
-
-void destroy(GtkWindow *window, gpointer data)
-{
- gtk_main_quit();
-}
-
-void gui_win_destroy(GtkWindow *window, gpointer data)
-{
-}
-
-static struct option long_options[] = {
- {"help", 0, 0, 'h'},
- {"version", 0, 0, 'v'},
- {"client", 1, 0, 'c'},
- {"effect", 0, 0, 'e'},
- {"input", 1, 0, 'i'},
- {"output", 1, 0, 'o'},
- {"connect-midi", 1, 0, 'M'},
- {0,0,0,0},
-};
-
-void print_help(char *argv[])
-{
- printf("JACK host for Calf effects\n"
- "Syntax: %s [--client <name>] [--input <name>] [--output <name>] [--midi <name>]\n"
- " [--connect-midi <name|capture-index>] [--help] [--version] [!] pluginname[:<preset>] [!] ...\n",
- argv[0]);
-}
-
-int jack_client::do_jack_process(jack_nframes_t nframes, void *p)
-{
- jack_client *self = (jack_client *)p;
- ptlock lock(self->mutex);
- for(unsigned int i = 0; i < self->plugins.size(); i++)
- self->plugins[i]->process(nframes);
- return 0;
-}
-
-int jack_client::do_jack_bufsize(jack_nframes_t numsamples, void *p)
-{
- jack_client *self = (jack_client *)p;
- ptlock lock(self->mutex);
- for(unsigned int i = 0; i < self->plugins.size(); i++)
- self->plugins[i]->cache_ports();
- return 0;
-}
-
-void jack_client::delete_plugins()
-{
- ptlock lock(mutex);
- for (unsigned int i = 0; i < plugins.size(); i++) {
- // plugins[i]->close();
- delete plugins[i];
- }
- plugins.clear();
-}
-
-struct host_session: public main_window_owner_iface, public calf_plugins::progress_report_iface
-{
- string client_name, input_name, output_name, midi_name;
- vector<string> plugin_names;
- map<int, string> presets;
-#if USE_LASH
- int lash_source_id;
- lash_client_t *lash_client;
-# if !USE_LASH_0_6
- lash_args_t *lash_args;
-# endif
-#endif
-
- // these are not saved
- jack_client client;
- string autoconnect_midi;
- int autoconnect_midi_index;
- set<int> chains;
- vector<jack_host *> plugins;
- main_window *main_win;
- bool restoring_session;
- std::set<std::string> instances;
- GtkWidget *progress_window;
-
- host_session();
- void open();
- void add_plugin(string name, string preset, string instance_name = string());
- void create_plugins_from_list();
- void connect();
- void close();
- bool activate_preset(int plugin, const std::string &preset, bool builtin);
-#if USE_LASH
- static gboolean update_lash(void *self) { ((host_session *)self)->update_lash(); return TRUE; }
- void update_lash();
-# if !USE_LASH_0_6
- void send_lash(LASH_Event_Type type, const std::string &data) {
- lash_send_event(lash_client, lash_event_new_with_all(type, data.c_str()));
- }
-# endif
-#endif
- virtual void new_plugin(const char *name);
- virtual void remove_plugin(plugin_ctl_iface *plugin);
- void remove_all_plugins();
- std::string get_next_instance_name(const std::string &effect_name);
-
- /// Create a toplevel window with progress bar
- GtkWidget *create_progress_window();
- /// Implementation of progress_report_iface function
- void report_progress(float percentage, const std::string &message);
-
- /// Implementation of open file functionality (TODO)
- virtual char *open_file(const char *name);
- /// Implementation of save file functionality
- virtual char *save_file(const char *name);
-};
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
host_session::host_session()
{
@@ -255,6 +59,7 @@ host_session::host_session()
main_win->set_owner(this);
progress_window = NULL;
autoconnect_midi_index = -1;
+ gui_win = NULL;
}
std::string host_session::get_next_instance_name(const std::string &effect_name)
@@ -286,7 +91,7 @@ void host_session::add_plugin(string name, string preset, string instance_name)
throw text_exception("Unknown plugin name; allowed are: " + s);
}
instances.insert(jh->instance_name);
- jh->open(&client);
+ jh->create(&client);
plugins.push_back(jh);
client.add(jh);
@@ -349,6 +154,11 @@ GtkWidget *host_session::create_progress_window()
return tlw;
}
+static void window_destroy_cb(GtkWindow *window, gpointer data)
+{
+ gtk_main_quit();
+}
+
void host_session::open()
{
if (!input_name.empty()) client.input_name = input_name;
@@ -362,7 +172,7 @@ void host_session::open()
if (!restoring_session)
create_plugins_from_list();
main_win->create();
- gtk_signal_connect(GTK_OBJECT(main_win->toplevel), "destroy", G_CALLBACK(destroy), NULL);
+ gtk_signal_connect(GTK_OBJECT(main_win->toplevel), "destroy", G_CALLBACK(window_destroy_cb), NULL);
}
void host_session::new_plugin(const char *name)
@@ -371,7 +181,7 @@ void host_session::new_plugin(const char *name)
if (!jh)
return;
instances.insert(jh->instance_name);
- jh->open(&client);
+ jh->create(&client);
plugins.push_back(jh);
client.add(jh);
@@ -711,7 +521,7 @@ void host_session::update_lash()
lash_dispatch(lash_client);
}
-bool save_data_set_cb(lash_config_handle_t *handle, void *user_data)
+static bool save_data_set_cb(lash_config_handle_t *handle, void *user_data)
{
host_session *sess = static_cast<host_session *>(user_data);
dictionary tmp;
@@ -747,7 +557,7 @@ bool save_data_set_cb(lash_config_handle_t *handle, void *user_data)
return true;
}
-bool load_data_set_cb(lash_config_handle_t *handle, void *user_data)
+static bool load_data_set_cb(lash_config_handle_t *handle, void *user_data)
{
host_session *sess = static_cast<host_session *>(user_data);
int size, type;
@@ -789,7 +599,7 @@ bool load_data_set_cb(lash_config_handle_t *handle, void *user_data)
return true;
}
-bool quit_cb(void *user_data)
+static bool quit_cb(void *user_data)
{
gtk_main_quit();
return true;
@@ -798,116 +608,28 @@ bool quit_cb(void *user_data)
# endif
#endif
-host_session current_session;
-
-int main(int argc, char *argv[])
+void host_session::connect_to_session_manager(int argc, char *argv[])
{
- host_session &sess = current_session;
- gtk_rc_add_default_file(PKGLIBDIR "calf.rc");
- gtk_init(&argc, &argv);
-
#if USE_LASH
# if !USE_LASH_0_6
for (int i = 1; i < argc; i++)
{
if (!strncmp(argv[i], "--lash-project=", 14)) {
- sess.restoring_session = true;
+ restoring_session = true;
break;
}
}
- sess.lash_args = lash_extract_args(&argc, &argv);
- sess.lash_client = lash_init(sess.lash_args, PACKAGE_NAME, LASH_Config_Data_Set, LASH_PROTOCOL(2, 0));
+ lash_args = lash_extract_args(&argc, &argv);
+ lash_client = lash_init(lash_args, PACKAGE_NAME, LASH_Config_Data_Set, LASH_PROTOCOL(2, 0));
# else
- sess.lash_client = lash_client_open(PACKAGE_NAME, LASH_Config_Data_Set, argc, argv);
- sess.restoring_session = lash_client_is_being_restored(sess.lash_client);
- lash_set_save_data_set_callback(sess.lash_client, save_data_set_cb, &sess);
- lash_set_load_data_set_callback(sess.lash_client, load_data_set_cb, &sess);
- lash_set_quit_callback(sess.lash_client, quit_cb, NULL);
+ lash_client = lash_client_open(PACKAGE_NAME, LASH_Config_Data_Set, argc, argv);
+ restoring_session = lash_client_is_being_restored(lash_client);
+ lash_set_save_data_set_callback(lash_client, save_data_set_cb, this);
+ lash_set_load_data_set_callback(lash_client, load_data_set_cb, this);
+ lash_set_quit_callback(lash_client, quit_cb, NULL);
# endif
- if (!sess.lash_client) {
+ if (!lash_client) {
g_warning("Warning: failed to create a LASH connection");
}
#endif
- glade_init();
- while(1) {
- int option_index;
- int c = getopt_long(argc, argv, "c:i:o:m:M:ehv", long_options, &option_index);
- if (c == -1)
- break;
- switch(c) {
- case 'h':
- case '?':
- print_help(argv);
- return 0;
- case 'v':
- printf("%s\n", PACKAGE_STRING);
- return 0;
- case 'e':
- fprintf(stderr, "Warning: switch -%c is deprecated!\n", c);
- break;
- case 'c':
- sess.client_name = optarg;
- break;
- case 'i':
- sess.input_name = string(optarg) + "_%d";
- break;
- case 'o':
- sess.output_name = string(optarg) + "_%d";
- break;
- case 'm':
- sess.midi_name = string(optarg) + "_%d";
- break;
- case 'M':
- if (atoi(optarg)) {
- sess.autoconnect_midi_index = atoi(optarg);
- }
- else
- sess.autoconnect_midi = string(optarg);
- break;
- }
- }
- while(optind < argc) {
- if (!strcmp(argv[optind], "!")) {
- sess.chains.insert(sess.plugin_names.size());
- optind++;
- } else {
- string plugname = argv[optind++];
- size_t pos = plugname.find(":");
- if (pos != string::npos) {
- sess.presets[sess.plugin_names.size()] = plugname.substr(pos + 1);
- plugname = plugname.substr(0, pos);
- }
- sess.plugin_names.push_back(plugname);
- }
- }
- try {
- get_builtin_presets().load_defaults(true);
- get_user_presets().load_defaults(false);
- }
- catch(calf_plugins::preset_exception &e)
- {
- // XXXKF this exception is already handled by load_defaults, so this is redundant
- fprintf(stderr, "Error while loading presets: %s\n", e.what());
- exit(1);
- }
- try {
- sess.open();
- sess.connect();
- sess.client.activate();
- gtk_main();
- sess.close();
-
-#if USE_LASH && !USE_LASH_0_6
- if (sess.lash_args)
- lash_args_destroy(sess.lash_args);
-#endif
- // this is now done on preset add
- // save_presets(get_preset_filename().c_str());
- }
- catch(std::exception &e)
- {
- fprintf(stderr, "%s\n", e.what());
- exit(1);
- }
- return 0;
}
diff --git a/src/jack_client.cpp b/src/jack_client.cpp
new file mode 100644
index 0000000..c8557a9
--- /dev/null
+++ b/src/jack_client.cpp
@@ -0,0 +1,127 @@
+/* Calf DSP Library Utility Application - calfjackhost
+ * A class wrapping a JACK client
+ *
+ * Copyright (C) 2007-2010 Krzysztof Foltman
+ *
+ * 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, 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.
+ */
+
+#include <set>
+#include <getopt.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <config.h>
+#include <glade/glade.h>
+#include <jack/jack.h>
+#include <calf/giface.h>
+#include <calf/jackhost.h>
+
+using namespace std;
+using namespace calf_utils;
+using namespace calf_plugins;
+
+jack_client::jack_client()
+{
+ input_nr = output_nr = midi_nr = 1;
+ input_name = "input_%d";
+ output_name = "output_%d";
+ midi_name = "midi_%d";
+ sample_rate = 0;
+ client = NULL;
+}
+
+void jack_client::add(jack_host *plugin)
+{
+ calf_utils::ptlock lock(mutex);
+ plugins.push_back(plugin);
+}
+
+void jack_client::del(int item)
+{
+ calf_utils::ptlock lock(mutex);
+ plugins.erase(plugins.begin()+item);
+}
+
+void jack_client::open(const char *client_name)
+{
+ jack_status_t status;
+ client = jack_client_open(client_name, JackNullOption, &status);
+ if (!client)
+ throw calf_utils::text_exception("Could not initialize JACK subsystem");
+ sample_rate = jack_get_sample_rate(client);
+ jack_set_process_callback(client, do_jack_process, this);
+ jack_set_buffer_size_callback(client, do_jack_bufsize, this);
+ name = get_name();
+}
+
+std::string jack_client::get_name()
+{
+ return std::string(jack_get_client_name(client));
+}
+
+void jack_client::activate()
+{
+ jack_activate(client);
+}
+
+void jack_client::deactivate()
+{
+ jack_deactivate(client);
+}
+
+void jack_client::connect(const std::string &p1, const std::string &p2)
+{
+ if (jack_connect(client, p1.c_str(), p2.c_str()) != 0)
+ throw calf_utils::text_exception("Could not connect JACK ports "+p1+" and "+p2);
+}
+
+void jack_client::close()
+{
+ jack_client_close(client);
+}
+
+const char **jack_client::get_ports(const char *name_re, const char *type_re, unsigned long flags)
+{
+ return jack_get_ports(client, name_re, type_re, flags);
+}
+
+int jack_client::do_jack_process(jack_nframes_t nframes, void *p)
+{
+ jack_client *self = (jack_client *)p;
+ ptlock lock(self->mutex);
+ for(unsigned int i = 0; i < self->plugins.size(); i++)
+ self->plugins[i]->process(nframes);
+ return 0;
+}
+
+int jack_client::do_jack_bufsize(jack_nframes_t numsamples, void *p)
+{
+ jack_client *self = (jack_client *)p;
+ ptlock lock(self->mutex);
+ for(unsigned int i = 0; i < self->plugins.size(); i++)
+ self->plugins[i]->cache_ports();
+ return 0;
+}
+
+void jack_client::delete_plugins()
+{
+ ptlock lock(mutex);
+ for (unsigned int i = 0; i < plugins.size(); i++) {
+ delete plugins[i];
+ }
+ plugins.clear();
+}
+
diff --git a/src/jackhost.cpp b/src/jackhost.cpp
index 2ed27ae..566da1a 100644
--- a/src/jackhost.cpp
+++ b/src/jackhost.cpp
@@ -25,11 +25,8 @@
#include <config.h>
#include <glade/glade.h>
#include <jack/jack.h>
-#if USE_LASH
-#include <lash/lash.h>
-#endif
#include <calf/giface.h>
-#include <calf/jackhost.h>
+#include <calf/host_session.h>
#include <calf/modules.h>
#include <calf/modules_dev.h>
#include <calf/organ.h>
@@ -39,21 +36,13 @@
#include <calf/main_win.h>
#include <calf/utils.h>
#include <stdio.h>
+
using namespace std;
using namespace calf_utils;
using namespace calf_plugins;
-// I don't need anyone to tell me this is stupid. I already know that :)
-plugin_gui_window *gui_win;
-
const char *client_name = "calfhost";
-#if USE_LASH_0_6
-static bool save_data_set_cb(lash_config_handle_t *handle, void *user_data);
-static bool load_data_set_cb(lash_config_handle_t *handle, void *user_data);
-static bool quit_cb(void *user_data);
-#endif
-
jack_host *calf_plugins::create_jack_host(const char *effect_name, const std::string &instance_name, calf_plugins::progress_report_iface *priface)
{
#define PER_MODULE_ITEM(name, isSynth, jackname) if (!strcasecmp(effect_name, jackname)) return new jack_host(new name##_audio_module, effect_name, instance_name, priface);
@@ -61,15 +50,48 @@ jack_host *calf_plugins::create_jack_host(const char *effect_name, const std::st
return NULL;
}
-void jack_host::open(jack_client *_client)
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+jack_host::jack_host(audio_module_iface *_module, const std::string &_name, const std::string &_instance_name, calf_plugins::progress_report_iface *_priface)
+: module(_module)
{
- client = _client; //jack_client_open(client_name, JackNullOption, &status);
+ name = _name;
+ instance_name = _instance_name;
- create_ports();
+ client = NULL;
+ changed = true;
+
+ module->get_port_arrays(ins, outs, params);
+ metadata = module->get_metadata_iface();
+ in_count = metadata->get_input_count();
+ out_count = metadata->get_output_count();
+ inputs.resize(in_count);
+ outputs.resize(out_count);
+ param_values = new float[metadata->get_param_count()];
+ for (int i = 0; i < metadata->get_param_count(); i++) {
+ params[i] = ¶m_values[i];
+ }
+ clear_preset();
+ midi_meter = 0;
+ module->set_progress_report_iface(_priface);
+ module->post_instantiate();
+}
+
+jack_host::~jack_host()
+{
+ delete []param_values;
+ if (client)
+ destroy();
+}
+
+void jack_host::create(jack_client *_client)
+{
+ client = _client; //jack_client_open(client_name, JackNullOption, &status);
+ create_ports();
cache_ports();
-
init_module();
+
changed = false;
}
@@ -112,7 +134,38 @@ void jack_host::create_ports() {
}
}
-void jack_host::close() {
+void jack_host::handle_event(uint8_t *buffer, uint32_t size)
+{
+ int value;
+ switch(buffer[0] >> 4)
+ {
+ case 8:
+ module->note_off(buffer[1], buffer[2]);
+ break;
+ case 9:
+ if (!buffer[2])
+ module->note_off(buffer[1], 0);
+ else
+ module->note_on(buffer[1], buffer[2]);
+ break;
+ case 11:
+ module->control_change(buffer[1], buffer[2]);
+ break;
+ case 12:
+ module->program_change(buffer[1]);
+ break;
+ case 13:
+ module->channel_pressure(buffer[1]);
+ break;
+ case 14:
+ value = buffer[1] + 128 * buffer[2] - 8192;
+ module->pitch_bend(value);
+ break;
+ }
+}
+
+void jack_host::destroy()
+{
port *inputs = get_inputs(), *outputs = get_outputs();
int input_count = metadata->get_input_count(), output_count = metadata->get_output_count();
for (int i = 0; i < input_count; i++) {
@@ -128,706 +181,126 @@ void jack_host::close() {
client = NULL;
}
-void destroy(GtkWindow *window, gpointer data)
-{
- gtk_main_quit();
-}
-
-void gui_win_destroy(GtkWindow *window, gpointer data)
-{
-}
-
-static struct option long_options[] = {
- {"help", 0, 0, 'h'},
- {"version", 0, 0, 'v'},
- {"client", 1, 0, 'c'},
- {"effect", 0, 0, 'e'},
- {"input", 1, 0, 'i'},
- {"output", 1, 0, 'o'},
- {"connect-midi", 1, 0, 'M'},
- {0,0,0,0},
-};
-
-void print_help(char *argv[])
-{
- printf("JACK host for Calf effects\n"
- "Syntax: %s [--client <name>] [--input <name>] [--output <name>] [--midi <name>]\n"
- " [--connect-midi <name|capture-index>] [--help] [--version] [!] pluginname[:<preset>] [!] ...\n",
- argv[0]);
-}
-
-int jack_client::do_jack_process(jack_nframes_t nframes, void *p)
-{
- jack_client *self = (jack_client *)p;
- ptlock lock(self->mutex);
- for(unsigned int i = 0; i < self->plugins.size(); i++)
- self->plugins[i]->process(nframes);
- return 0;
-}
-
-int jack_client::do_jack_bufsize(jack_nframes_t numsamples, void *p)
-{
- jack_client *self = (jack_client *)p;
- ptlock lock(self->mutex);
- for(unsigned int i = 0; i < self->plugins.size(); i++)
- self->plugins[i]->cache_ports();
- return 0;
-}
-
-void jack_client::delete_plugins()
-{
- ptlock lock(mutex);
- for (unsigned int i = 0; i < plugins.size(); i++) {
- // plugins[i]->close();
- delete plugins[i];
- }
- plugins.clear();
-}
-
-struct host_session: public main_window_owner_iface, public calf_plugins::progress_report_iface
+void jack_host::process_part(unsigned int time, unsigned int len)
{
- string client_name, input_name, output_name, midi_name;
- vector<string> plugin_names;
- map<int, string> presets;
-#if USE_LASH
- int lash_source_id;
- lash_client_t *lash_client;
-# if !USE_LASH_0_6
- lash_args_t *lash_args;
-# endif
-#endif
-
- // these are not saved
- jack_client client;
- string autoconnect_midi;
- int autoconnect_midi_index;
- set<int> chains;
- vector<jack_host *> plugins;
- main_window *main_win;
- bool restoring_session;
- std::set<std::string> instances;
- GtkWidget *progress_window;
-
- host_session();
- void open();
- void add_plugin(string name, string preset, string instance_name = string());
- void create_plugins_from_list();
- void connect();
- void close();
- bool activate_preset(int plugin, const std::string &preset, bool builtin);
-#if USE_LASH
- static gboolean update_lash(void *self) { ((host_session *)self)->update_lash(); return TRUE; }
- void update_lash();
-# if !USE_LASH_0_6
- void send_lash(LASH_Event_Type type, const std::string &data) {
- lash_send_event(lash_client, lash_event_new_with_all(type, data.c_str()));
- }
-# endif
-#endif
- virtual void new_plugin(const char *name);
- virtual void remove_plugin(plugin_ctl_iface *plugin);
- void remove_all_plugins();
- std::string get_next_instance_name(const std::string &effect_name);
-
- /// Create a toplevel window with progress bar
- GtkWidget *create_progress_window();
- /// Implementation of progress_report_iface function
- void report_progress(float percentage, const std::string &message);
-
- /// Implementation of open file functionality (TODO)
- virtual char *open_file(const char *name);
- /// Implementation of save file functionality
- virtual char *save_file(const char *name);
-};
-
-host_session::host_session()
-{
- client_name = "calf";
-#if USE_LASH
- lash_source_id = 0;
- lash_client = NULL;
-# if !USE_LASH_0_6
- lash_args = NULL;
-# endif
-#endif
- restoring_session = false;
- main_win = new main_window;
- main_win->set_owner(this);
- progress_window = NULL;
- autoconnect_midi_index = -1;
-}
-
-std::string host_session::get_next_instance_name(const std::string &effect_name)
-{
- if (!instances.count(effect_name))
- return effect_name;
- for (int i = 2; ; i++)
- {
- string tmp = string(effect_name) + i2s(i);
- if (!instances.count(tmp))
- return tmp;
- }
- assert(0);
- return "-";
-}
-
-void host_session::add_plugin(string name, string preset, string instance_name)
-{
- if (instance_name.empty())
- instance_name = get_next_instance_name(name);
- jack_host *jh = create_jack_host(name.c_str(), instance_name, this);
- if (!jh) {
- string s =
- #define PER_MODULE_ITEM(name, isSynth, jackname) jackname ", "
- #include <calf/modulelist.h>
- ;
- if (!s.empty())
- s = s.substr(0, s.length() - 2);
- throw text_exception("Unknown plugin name; allowed are: " + s);
- }
- instances.insert(jh->instance_name);
- jh->open(&client);
-
- plugins.push_back(jh);
- client.add(jh);
- main_win->add_plugin(jh);
- if (!preset.empty()) {
- if (!activate_preset(plugins.size() - 1, preset, false))
- {
- if (!activate_preset(plugins.size() - 1, preset, true))
- {
- fprintf(stderr, "Unknown preset: %s\n", preset.c_str());
- }
- }
- }
-}
-
-void host_session::report_progress(float percentage, const std::string &message)
-{
- if (percentage < 100)
- {
- if (!progress_window) {
- progress_window = create_progress_window();
- gtk_window_set_modal (GTK_WINDOW (progress_window), TRUE);
- if (main_win->toplevel)
- gtk_window_set_transient_for (GTK_WINDOW (progress_window), main_win->toplevel);
- }
- gtk_widget_show(progress_window);
- GtkWidget *pbar = gtk_bin_get_child (GTK_BIN (progress_window));
- if (!message.empty())
- gtk_progress_bar_set_text (GTK_PROGRESS_BAR (pbar), message.c_str());
- gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pbar), percentage / 100.0);
- }
- else
- {
- if (progress_window) {
- gtk_window_set_modal (GTK_WINDOW (progress_window), FALSE);
- gtk_widget_destroy (progress_window);
- progress_window = NULL;
- }
- }
-
- while (gtk_events_pending ())
- gtk_main_iteration ();
-}
-
-
-void host_session::create_plugins_from_list()
-{
- for (unsigned int i = 0; i < plugin_names.size(); i++) {
- add_plugin(plugin_names[i], presets.count(i) ? presets[i] : string());
- }
-}
-
-GtkWidget *host_session::create_progress_window()
-{
- GtkWidget *tlw = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
- gtk_window_set_type_hint (GTK_WINDOW (tlw), GDK_WINDOW_TYPE_HINT_DIALOG);
- GtkWidget *pbar = gtk_progress_bar_new();
- gtk_container_add (GTK_CONTAINER(tlw), pbar);
- gtk_widget_show_all (pbar);
- return tlw;
-}
-
-void host_session::open()
-{
- if (!input_name.empty()) client.input_name = input_name;
- if (!output_name.empty()) client.output_name = output_name;
- if (!midi_name.empty()) client.midi_name = midi_name;
-
- client.open(client_name.c_str());
- main_win->prefix = client_name + " - ";
- main_win->conditions.insert("jackhost");
- main_win->conditions.insert("directlink");
- if (!restoring_session)
- create_plugins_from_list();
- main_win->create();
- gtk_signal_connect(GTK_OBJECT(main_win->toplevel), "destroy", G_CALLBACK(destroy), NULL);
-}
-
-void host_session::new_plugin(const char *name)
-{
- jack_host *jh = create_jack_host(name, get_next_instance_name(name), this);
- if (!jh)
+ if (!len)
return;
- instances.insert(jh->instance_name);
- jh->open(&client);
-
- plugins.push_back(jh);
- client.add(jh);
- main_win->add_plugin(jh);
-}
-
-void host_session::remove_plugin(plugin_ctl_iface *plugin)
-{
- for (unsigned int i = 0; i < plugins.size(); i++)
+ for (int i = 0; i < in_count; i++)
+ inputs[i].meter.update(ins[i] + time, len);
+ unsigned int mask = module->process(time, len, -1, -1);
+ for (int i = 0; i < out_count; i++)
{
- if (plugins[i] == plugin)
- {
- client.del(i);
- plugins.erase(plugins.begin() + i);
- main_win->del_plugin(plugin);
- delete plugin;
- return;
- }
- }
-}
-
-void host_session::remove_all_plugins()
+ if (!(mask & (1 << i))) {
+ dsp::zero(outs[i] + time, len);
+ outputs[i].meter.update_zeros(len);
+ } else
+ outputs[i].meter.update(outs[i] + time, len);
+ }
+ // decay linearly for 0.1s
+ float new_meter = midi_meter - len / (0.1 * client->sample_rate);
+ if (new_meter < 0)
+ new_meter = 0;
+ midi_meter = new_meter;
+}
+
+float jack_host::get_level(unsigned int port)
+{
+ if (port < (unsigned)in_count)
+ return inputs[port].meter.level;
+ port -= in_count;
+ if (port < (unsigned)out_count)
+ return outputs[port].meter.level;
+ port -= out_count;
+ if (port == 0 && metadata->get_midi())
+ return midi_meter;
+ return 0.f;
+}
+
+int jack_host::process(jack_nframes_t nframes)
{
- while(!plugins.empty())
- {
- plugin_ctl_iface *plugin = plugins[0];
- client.del(0);
- plugins.erase(plugins.begin());
- main_win->del_plugin(plugin);
- delete plugin;
+ for (int i=0; i<in_count; i++) {
+ ins[i] = inputs[i].data = (float *)jack_port_get_buffer(inputs[i].handle, nframes);
}
-}
-
-bool host_session::activate_preset(int plugin_no, const std::string &preset, bool builtin)
-{
- string cur_plugin = plugins[plugin_no]->metadata->get_id();
- preset_vector &pvec = (builtin ? get_builtin_presets() : get_user_presets()).presets;
- for (unsigned int i = 0; i < pvec.size(); i++) {
- if (pvec[i].name == preset && pvec[i].plugin == cur_plugin)
- {
- pvec[i].activate(plugins[plugin_no]);
- if (gui_win && gui_win->gui)
- gui_win->gui->refresh();
- return true;
- }
+ if (metadata->get_midi())
+ midi_port.data = (float *)jack_port_get_buffer(midi_port.handle, nframes);
+ if (changed) {
+ module->params_changed();
+ changed = false;
}
- return false;
-}
-void host_session::connect()
-{
- client.activate();
-#if USE_LASH && !USE_LASH_0_6
- if (lash_client)
- lash_jack_client_name(lash_client, client.get_name().c_str());
-#endif
- if (!restoring_session)
- {
- string cnp = client.get_name() + ":";
- for (unsigned int i = 0; i < plugins.size(); i++) {
- if (chains.count(i)) {
- if (!i)
- {
- if (plugins[0]->metadata->get_output_count() < 2)
- {
- fprintf(stderr, "Cannot connect input to plugin %s - incompatible ports\n", plugins[0]->name.c_str());
- } else {
- client.connect("system:capture_1", cnp + plugins[0]->get_inputs()[0].name);
- client.connect("system:capture_2", cnp + plugins[0]->get_inputs()[1].name);
- }
- }
- else
- {
- if (plugins[i - 1]->metadata->get_output_count() < 2 || plugins[i]->metadata->get_input_count() < 2)
- {
- fprintf(stderr, "Cannot connect plugins %s and %s - incompatible ports\n", plugins[i - 1]->name.c_str(), plugins[i]->name.c_str());
- }
- else {
- client.connect(cnp + plugins[i - 1]->get_outputs()[0].name, cnp + plugins[i]->get_inputs()[0].name);
- client.connect(cnp + plugins[i - 1]->get_outputs()[1].name, cnp + plugins[i]->get_inputs()[1].name);
- }
- }
- }
- }
- if (chains.count(plugins.size()) && plugins.size())
- {
- int last = plugins.size() - 1;
- if (plugins[last]->metadata->get_output_count() < 2)
- {
- fprintf(stderr, "Cannot connect plugin %s to output - incompatible ports\n", plugins[last]->name.c_str());
- } else {
- client.connect(cnp + plugins[last]->get_outputs()[0].name, "system:playback_1");
- client.connect(cnp + plugins[last]->get_outputs()[1].name, "system:playback_2");
- }
- }
- if (autoconnect_midi != "") {
- for (unsigned int i = 0; i < plugins.size(); i++)
- {
- if (plugins[i]->metadata->get_midi())
- client.connect(autoconnect_midi, cnp + plugins[i]->get_midi_port()->name);
- }
- }
- else
- if (autoconnect_midi_index != -1) {
- const char **ports = client.get_ports("(system|alsa_pcm):.*", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput);
- for (int j = 0; ports && ports[j]; j++)
- {
- if (j + 1 == autoconnect_midi_index) {
- for (unsigned int i = 0; i < plugins.size(); i++)
- {
- if (plugins[i]->metadata->get_midi())
- client.connect(ports[j], cnp + plugins[i]->get_midi_port()->name);
- }
- break;
- }
- }
- }
- }
-#if USE_LASH
- if (lash_client)
+ unsigned int time = 0;
+ if (metadata->get_midi())
{
-# if !USE_LASH_0_6
- send_lash(LASH_Client_Name, "calf-"+client_name);
-# endif
- lash_source_id = g_timeout_add_full(G_PRIORITY_LOW, 250, update_lash, this, NULL); // 4 LASH reads per second... should be enough?
- }
-#endif
-}
-
-void host_session::close()
-{
-#if USE_LASH
- if (lash_source_id)
- g_source_remove(lash_source_id);
+ jack_midi_event_t event;
+#ifdef OLD_JACK
+ int count = jack_midi_get_event_count(midi_port.data, nframes);
+#else
+ int count = jack_midi_get_event_count(midi_port.data);
#endif
- main_win->on_closed();
- main_win->close_guis();
- client.deactivate();
- client.delete_plugins();
- client.close();
-}
-
-static string stripfmt(string x)
-{
- if (x.length() < 2)
- return x;
- if (x.substr(x.length() - 2) != "%d")
- return x;
- return x.substr(0, x.length() - 2);
-}
-
-char *host_session::open_file(const char *name)
-{
- preset_list pl;
- try {
- remove_all_plugins();
- pl.load(name, true);
- printf("Size %d\n", (int)pl.plugins.size());
- for (unsigned int i = 0; i < pl.plugins.size(); i++)
+ for (int i = 0; i < count; i++)
{
- preset_list::plugin_snapshot &ps = pl.plugins[i];
- client.input_nr = ps.input_index;
- client.output_nr = ps.output_index;
- client.midi_nr = ps.midi_index;
- printf("Loading %s\n", ps.type.c_str());
- if (ps.preset_offset < (int)pl.presets.size())
- {
- add_plugin(ps.type, "", ps.instance_name);
- pl.presets[ps.preset_offset].activate(plugins[i]);
- main_win->refresh_plugin(plugins[i]);
- }
- }
- }
- catch(preset_exception &e)
- {
- // XXXKF this will leak
- char *data = strdup(e.what());
- return data;
- }
-
- return NULL;
-}
-
-char *host_session::save_file(const char *name)
-{
- string i_name = stripfmt(client.input_name);
- string o_name = stripfmt(client.output_name);
- string m_name = stripfmt(client.midi_name);
- string data;
- data = "<?xml version=\"1.1\" encoding=\"utf-8\">\n";
- data = "<rack>\n";
- for (unsigned int i = 0; i < plugins.size(); i++) {
- jack_host *p = plugins[i];
- plugin_preset preset;
- preset.plugin = p->metadata->get_id();
- preset.get_from(p);
- data += "<plugin";
- data += to_xml_attr("type", preset.plugin);
- data += to_xml_attr("instance-name", p->instance_name);
- if (p->metadata->get_input_count())
- data += to_xml_attr("input-index", p->get_inputs()[0].name.substr(i_name.length()));
- if (p->metadata->get_output_count())
- data += to_xml_attr("output-index", p->get_outputs()[0].name.substr(o_name.length()));
- if (p->get_midi_port())
- data += to_xml_attr("midi-index", p->get_midi_port()->name.substr(m_name.length()));
- data += ">\n";
- data += preset.to_xml();
- data += "</plugin>\n";
- }
- data += "</rack>\n";
- FILE *f = fopen(name, "w");
- if (!f || 1 != fwrite(data.c_str(), data.length(), 1, f))
- {
- int e = errno;
- fclose(f);
- return strdup(strerror(e));
- }
- if (fclose(f))
- return strdup(strerror(errno));
-
- return NULL;
-}
-
-#if USE_LASH
-
-# if !USE_LASH_0_6
-
-void host_session::update_lash()
-{
- do {
- lash_event_t *event = lash_get_event(lash_client);
- if (!event)
- break;
-
- // printf("type = %d\n", lash_event_get_type(event));
-
- switch(lash_event_get_type(event)) {
- case LASH_Save_Data_Set:
- {
- lash_config_t *cfg = lash_config_new_with_key("global");
- dictionary tmp;
- string pstr;
- string i_name = stripfmt(client.input_name);
- string o_name = stripfmt(client.output_name);
- string m_name = stripfmt(client.midi_name);
- tmp["input_prefix"] = i_name;
- tmp["output_prefix"] = stripfmt(client.output_name);
- tmp["midi_prefix"] = stripfmt(client.midi_name);
- pstr = encode_map(tmp);
- lash_config_set_value(cfg, pstr.c_str(), pstr.length());
- lash_send_config(lash_client, cfg);
-
- for (unsigned int i = 0; i < plugins.size(); i++) {
- jack_host *p = plugins[i];
- char ss[32];
- plugin_preset preset;
- preset.plugin = p->get_id();
- preset.get_from(p);
- sprintf(ss, "Plugin%d", i);
- pstr = preset.to_xml();
- tmp.clear();
- tmp["instance_name"] = p->instance_name;
- if (p->get_input_count())
- tmp["input_name"] = p->get_inputs()[0].name.substr(i_name.length());
- if (p->get_output_count())
- tmp["output_name"] = p->get_outputs()[0].name.substr(o_name.length());
- if (p->get_midi_port())
- tmp["midi_name"] = p->get_midi_port()->name.substr(m_name.length());
- tmp["preset"] = pstr;
- pstr = encode_map(tmp);
- lash_config_t *cfg = lash_config_new_with_key(ss);
- lash_config_set_value(cfg, pstr.c_str(), pstr.length());
- lash_send_config(lash_client, cfg);
- }
- send_lash(LASH_Save_Data_Set, "");
- break;
- }
+#ifdef OLD_JACK
+ jack_midi_event_get(&event, midi_port.data, i, nframes);
+#else
+ jack_midi_event_get(&event, midi_port.data, i);
+#endif
+ unsigned int len = event.time - time;
+ process_part(time, len);
- case LASH_Restore_Data_Set:
- {
- // printf("!!!Restore data set!!!\n");
- remove_all_plugins();
- while(lash_config_t *cfg = lash_get_config(lash_client)) {
- const char *key = lash_config_get_key(cfg);
- // printf("key = %s\n", lash_config_get_key(cfg));
- string data = string((const char *)lash_config_get_value(cfg), lash_config_get_value_size(cfg));
- if (!strcmp(key, "global"))
- {
- dictionary dict;
- decode_map(dict, data);
- if (dict.count("input_prefix")) client.input_name = dict["input_prefix"]+"%d";
- if (dict.count("output_prefix")) client.output_name = dict["output_prefix"]+"%d";
- if (dict.count("midi_prefix")) client.midi_name = dict["midi_prefix"]+"%d";
- }
- if (!strncmp(key, "Plugin", 6))
- {
- unsigned int nplugin = atoi(key + 6);
- dictionary dict;
- decode_map(dict, data);
- data = dict["preset"];
- string instance_name;
- if (dict.count("instance_name")) instance_name = dict["instance_name"];
- if (dict.count("input_name")) client.input_nr = atoi(dict["input_name"].c_str());
- if (dict.count("output_name")) client.output_nr = atoi(dict["output_name"].c_str());
- if (dict.count("midi_name")) client.midi_nr = atoi(dict["midi_name"].c_str());
- preset_list tmp;
- tmp.parse("<presets>"+data+"</presets>", false);
- if (tmp.presets.size())
- {
- printf("Load plugin %s\n", tmp.presets[0].plugin.c_str());
- add_plugin(tmp.presets[0].plugin, "", instance_name);
- tmp.presets[0].activate(plugins[nplugin]);
- main_win->refresh_plugin(plugins[nplugin]);
- }
- }
- lash_config_destroy(cfg);
- }
- send_lash(LASH_Restore_Data_Set, "");
- break;
- }
-
- case LASH_Quit:
- gtk_main_quit();
- break;
+ midi_meter = 1.f;
+ handle_event(event.buffer, event.size);
- default:
- g_warning("Unhandled LASH event %d (%s)", lash_event_get_type(event), lash_event_get_string(event));
- break;
+ time = event.time;
}
- } while(1);
+ }
+ process_part(time, nframes - time);
+ module->params_reset();
+ return 0;
}
-# else
-
-void host_session::update_lash()
+void jack_host::init_module()
{
- lash_dispatch(lash_client);
+ module->set_sample_rate(client->sample_rate);
+ module->activate();
+ module->params_changed();
}
-bool save_data_set_cb(lash_config_handle_t *handle, void *user_data)
+void jack_host::cache_ports()
{
- host_session *sess = static_cast<host_session *>(user_data);
- dictionary tmp;
- string pstr;
- string i_name = stripfmt(sess->client.input_name);
- string o_name = stripfmt(sess->client.output_name);
- string m_name = stripfmt(sess->client.midi_name);
- tmp["input_prefix"] = i_name;
- tmp["output_prefix"] = stripfmt(sess->client.output_name);
- tmp["midi_prefix"] = stripfmt(sess->client.midi_name);
- pstr = encode_map(tmp);
- lash_config_write_raw(handle, "global", pstr.c_str(), pstr.length());
- for (unsigned int i = 0; i < sess->plugins.size(); i++) {
- jack_host *p = sess->plugins[i];
- char ss[32];
- plugin_preset preset;
- preset.plugin = p->metadata->get_id();
- preset.get_from(p);
- sprintf(ss, "Plugin%d", i);
- pstr = preset.to_xml();
- tmp.clear();
- tmp["instance_name"] = p->instance_name;
- if (p->metadata->get_input_count())
- tmp["input_name"] = p->get_inputs()[0].name.substr(i_name.length());
- if (p->metadata->get_output_count())
- tmp["output_name"] = p->get_outputs()[0].name.substr(o_name.length());
- if (p->get_midi_port())
- tmp["midi_name"] = p->get_midi_port()->name.substr(m_name.length());
- tmp["preset"] = pstr;
- pstr = encode_map(tmp);
- lash_config_write_raw(handle, ss, pstr.c_str(), pstr.length());
+ for (int i=0; i<out_count; i++) {
+ outs[i] = outputs[i].data = (float *)jack_port_get_buffer(outputs[i].handle, 0);
}
- return true;
}
-bool load_data_set_cb(lash_config_handle_t *handle, void *user_data)
-{
- host_session *sess = static_cast<host_session *>(user_data);
- int size, type;
- const char *key;
- const char *value;
- sess->remove_all_plugins();
- while((size = lash_config_read(handle, &key, (void *)&value, &type))) {
- if (size == -1 || type != LASH_TYPE_RAW)
- continue;
- string data = string(value, size);
- if (!strcmp(key, "global"))
- {
- dictionary dict;
- decode_map(dict, data);
- if (dict.count("input_prefix")) sess->client.input_name = dict["input_prefix"]+"%d";
- if (dict.count("output_prefix")) sess->client.output_name = dict["output_prefix"]+"%d";
- if (dict.count("midi_prefix")) sess->client.midi_name = dict["midi_prefix"]+"%d";
- } else if (!strncmp(key, "Plugin", 6)) {
- unsigned int nplugin = atoi(key + 6);
- dictionary dict;
- decode_map(dict, data);
- data = dict["preset"];
- string instance_name;
- if (dict.count("instance_name")) instance_name = dict["instance_name"];
- if (dict.count("input_name")) sess->client.input_nr = atoi(dict["input_name"].c_str());
- if (dict.count("output_name")) sess->client.output_nr = atoi(dict["output_name"].c_str());
- if (dict.count("midi_name")) sess->client.midi_nr = atoi(dict["midi_name"].c_str());
- preset_list tmp;
- tmp.parse("<presets>"+data+"</presets>", false);
- if (tmp.presets.size())
- {
- printf("Load plugin %s\n", tmp.presets[0].plugin.c_str());
- sess->add_plugin(tmp.presets[0].plugin, "", instance_name);
- tmp.presets[0].activate(sess->plugins[nplugin]);
- sess->main_win->refresh_plugin(sess->plugins[nplugin]);
- }
- }
- }
- return true;
-}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static struct option long_options[] = {
+ {"help", 0, 0, 'h'},
+ {"version", 0, 0, 'v'},
+ {"client", 1, 0, 'c'},
+ {"effect", 0, 0, 'e'},
+ {"input", 1, 0, 'i'},
+ {"output", 1, 0, 'o'},
+ {"connect-midi", 1, 0, 'M'},
+ {0,0,0,0},
+};
-bool quit_cb(void *user_data)
+void print_help(char *argv[])
{
- gtk_main_quit();
- return true;
+ printf("JACK host for Calf effects\n"
+ "Syntax: %s [--client <name>] [--input <name>] [--output <name>] [--midi <name>]\n"
+ " [--connect-midi <name|capture-index>] [--help] [--version] [!] pluginname[:<preset>] [!] ...\n",
+ argv[0]);
}
-# endif
-#endif
-
-host_session current_session;
-
int main(int argc, char *argv[])
{
- host_session &sess = current_session;
+ host_session sess;
+
gtk_rc_add_default_file(PKGLIBDIR "calf.rc");
gtk_init(&argc, &argv);
-#if USE_LASH
-# if !USE_LASH_0_6
- for (int i = 1; i < argc; i++)
- {
- if (!strncmp(argv[i], "--lash-project=", 14)) {
- sess.restoring_session = true;
- break;
- }
- }
- sess.lash_args = lash_extract_args(&argc, &argv);
- sess.lash_client = lash_init(sess.lash_args, PACKAGE_NAME, LASH_Config_Data_Set, LASH_PROTOCOL(2, 0));
-# else
- sess.lash_client = lash_client_open(PACKAGE_NAME, LASH_Config_Data_Set, argc, argv);
- sess.restoring_session = lash_client_is_being_restored(sess.lash_client);
- lash_set_save_data_set_callback(sess.lash_client, save_data_set_cb, &sess);
- lash_set_load_data_set_callback(sess.lash_client, load_data_set_cb, &sess);
- lash_set_quit_callback(sess.lash_client, quit_cb, NULL);
-# endif
- if (!sess.lash_client) {
- g_warning("Warning: failed to create a LASH connection");
- }
-#endif
+ sess.connect_to_session_manager(argc, argv);
glade_init();
while(1) {
int option_index;
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list