+ GUI: remove unused (and misleading) fields - the widget pointer is always stored...
[calf.git] / src / jackhost.cpp
blob00db5a1103ff71173779d820c75c220b77dd9e58
1 /* Calf DSP Library Utility Application - calfjackhost
2 * Standalone application module wrapper example.
4 * Copyright (C) 2007 Krzysztof Foltman
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.
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.
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.
21 #include <set>
22 #include <getopt.h>
23 #include <stdint.h>
24 #include <stdlib.h>
25 #include <config.h>
26 #include <glade/glade.h>
27 #include <jack/jack.h>
28 #if USE_LASH
29 #include <lash/lash.h>
30 #endif
31 #include <calf/giface.h>
32 #include <calf/jackhost.h>
33 #include <calf/modules.h>
34 #include <calf/modules_dev.h>
35 #include <calf/gui.h>
36 #include <calf/preset.h>
37 #include <calf/preset_gui.h>
38 #include <calf/main_win.h>
39 #include <calf/utils.h>
41 using namespace std;
42 using namespace calf_utils;
43 using namespace calf_plugins;
45 // I don't need anyone to tell me this is stupid. I already know that :)
46 plugin_gui_window *gui_win;
48 const char *client_name = "calfhost";
50 #if USE_LASH_0_6
51 static bool save_data_set_cb(lash_config_handle_t *handle, void *user_data);
52 static bool load_data_set_cb(lash_config_handle_t *handle, void *user_data);
53 static bool quit_cb(void *user_data);
54 #endif
56 jack_host_base *calf_plugins::create_jack_host(const char *effect_name, const std::string &instance_name, calf_plugins::progress_report_iface *priface)
58 #define PER_MODULE_ITEM(name, isSynth, jackname) if (!strcasecmp(effect_name, jackname)) return new jack_host<name##_audio_module>(effect_name, instance_name, priface);
59 #include <calf/modulelist.h>
60 return NULL;
63 void jack_host_base::open(jack_client *_client)
65 client = _client; //jack_client_open(client_name, JackNullOption, &status);
67 create_ports();
69 cache_ports();
71 init_module();
72 changed = false;
75 void jack_host_base::create_ports() {
76 char buf[32];
77 char buf2[64];
78 string prefix = client->name + ":";
79 static const char *suffixes[] = { "l", "r", "2l", "2r" };
80 port *inputs = get_inputs();
81 port *outputs = get_outputs();
82 int in_count = get_input_count(), out_count = get_output_count();
83 for (int i=0; i<in_count; i++) {
84 sprintf(buf, "%s_in_%s", instance_name.c_str(), suffixes[i]);
85 sprintf(buf2, client->input_name.c_str(), client->input_nr++);
86 inputs[i].name = buf2;
87 inputs[i].handle = jack_port_register(client->client, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput , 0);
88 inputs[i].data = NULL;
89 if (!inputs[i].handle)
90 throw text_exception("Could not create JACK input port");
91 jack_port_set_alias(inputs[i].handle, (prefix + buf2).c_str());
93 if (get_midi()) {
94 sprintf(buf, "%s_midi_in", instance_name.c_str());
95 sprintf(buf2, client->midi_name.c_str(), client->midi_nr++);
96 midi_port.name = buf2;
97 midi_port.handle = jack_port_register(client->client, buf, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
98 if (!midi_port.handle)
99 throw text_exception("Could not create JACK MIDI port");
100 jack_port_set_alias(midi_port.handle, (prefix + buf2).c_str());
102 for (int i=0; i<out_count; i++) {
103 sprintf(buf, "%s_out_%s", instance_name.c_str(), suffixes[i]);
104 sprintf(buf2, client->output_name.c_str(), client->output_nr++);
105 outputs[i].name = buf2;
106 outputs[i].handle = jack_port_register(client->client, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput , 0);
107 outputs[i].data = NULL;
108 if (!outputs[i].handle)
109 throw text_exception("Could not create JACK output port");
110 jack_port_set_alias(outputs[i].handle, (prefix + buf2).c_str());
114 void jack_host_base::close() {
115 port *inputs = get_inputs(), *outputs = get_outputs();
116 int input_count = get_input_count(), output_count = get_output_count();
117 for (int i = 0; i < input_count; i++) {
118 jack_port_unregister(client->client, inputs[i].handle);
119 inputs[i].data = NULL;
121 for (int i = 0; i < output_count; i++) {
122 jack_port_unregister(client->client, outputs[i].handle);
123 outputs[i].data = NULL;
125 if (get_midi())
126 jack_port_unregister(client->client, midi_port.handle);
127 client = NULL;
130 void destroy(GtkWindow *window, gpointer data)
132 gtk_main_quit();
135 void gui_win_destroy(GtkWindow *window, gpointer data)
139 static struct option long_options[] = {
140 {"help", 0, 0, 'h'},
141 {"version", 0, 0, 'v'},
142 {"client", 1, 0, 'c'},
143 {"effect", 0, 0, 'e'},
144 {"input", 1, 0, 'i'},
145 {"output", 1, 0, 'o'},
146 {"connect-midi", 1, 0, 'M'},
147 {0,0,0,0},
150 void print_help(char *argv[])
152 printf("JACK host for Calf effects\n"
153 "Syntax: %s [--client <name>] [--input <name>] [--output <name>] [--midi <name>]\n"
154 " [--connect-midi <name|capture-index>] [--help] [--version] [!] pluginname[:<preset>] [!] ...\n",
155 argv[0]);
158 int jack_client::do_jack_process(jack_nframes_t nframes, void *p)
160 jack_client *self = (jack_client *)p;
161 ptlock lock(self->mutex);
162 for(unsigned int i = 0; i < self->plugins.size(); i++)
163 self->plugins[i]->process(nframes);
164 return 0;
167 int jack_client::do_jack_bufsize(jack_nframes_t numsamples, void *p)
169 jack_client *self = (jack_client *)p;
170 ptlock lock(self->mutex);
171 for(unsigned int i = 0; i < self->plugins.size(); i++)
172 self->plugins[i]->cache_ports();
173 return 0;
176 void jack_client::delete_plugins()
178 ptlock lock(mutex);
179 for (unsigned int i = 0; i < plugins.size(); i++) {
180 // plugins[i]->close();
181 delete plugins[i];
183 plugins.clear();
186 struct host_session: public main_window_owner_iface, public calf_plugins::progress_report_iface
188 string client_name, input_name, output_name, midi_name;
189 vector<string> plugin_names;
190 map<int, string> presets;
191 #if USE_LASH
192 int lash_source_id;
193 lash_client_t *lash_client;
194 # if !USE_LASH_0_6
195 lash_args_t *lash_args;
196 # endif
197 #endif
199 // these are not saved
200 jack_client client;
201 string autoconnect_midi;
202 int autoconnect_midi_index;
203 set<int> chains;
204 vector<jack_host_base *> plugins;
205 main_window *main_win;
206 bool restoring_session;
207 std::set<std::string> instances;
208 GtkWidget *progress_window;
210 host_session();
211 void open();
212 void add_plugin(string name, string preset, string instance_name = string());
213 void create_plugins_from_list();
214 void connect();
215 void close();
216 bool activate_preset(int plugin, const std::string &preset, bool builtin);
217 #if USE_LASH
218 static gboolean update_lash(void *self) { ((host_session *)self)->update_lash(); return TRUE; }
219 void update_lash();
220 # if !USE_LASH_0_6
221 void send_lash(LASH_Event_Type type, const std::string &data) {
222 lash_send_event(lash_client, lash_event_new_with_all(type, data.c_str()));
224 # endif
225 #endif
226 virtual void new_plugin(const char *name);
227 virtual void remove_plugin(plugin_ctl_iface *plugin);
228 void remove_all_plugins();
229 std::string get_next_instance_name(const std::string &effect_name);
231 /// Create a toplevel window with progress bar
232 GtkWidget *create_progress_window();
233 /// Implementation of progress_report_iface function
234 void report_progress(float percentage, const std::string &message);
237 host_session::host_session()
239 client_name = "calf";
240 #if USE_LASH
241 lash_source_id = 0;
242 lash_client = NULL;
243 # if !USE_LASH_0_6
244 lash_args = NULL;
245 # endif
246 #endif
247 restoring_session = false;
248 main_win = new main_window;
249 main_win->set_owner(this);
250 progress_window = NULL;
251 autoconnect_midi_index = -1;
254 std::string host_session::get_next_instance_name(const std::string &effect_name)
256 if (!instances.count(effect_name))
257 return effect_name;
258 for (int i = 2; ; i++)
260 string tmp = string(effect_name) + i2s(i);
261 if (!instances.count(tmp))
262 return tmp;
264 assert(0);
265 return "-";
268 void host_session::add_plugin(string name, string preset, string instance_name)
270 if (instance_name.empty())
271 instance_name = get_next_instance_name(name);
272 jack_host_base *jh = create_jack_host(name.c_str(), instance_name, this);
273 if (!jh) {
274 string s =
275 #define PER_MODULE_ITEM(name, isSynth, jackname) jackname ", "
276 #include <calf/modulelist.h>
278 if (!s.empty())
279 s = s.substr(0, s.length() - 2);
280 throw text_exception("Unknown plugin name; allowed are: " + s);
282 instances.insert(jh->instance_name);
283 jh->open(&client);
285 plugins.push_back(jh);
286 client.add(jh);
287 main_win->add_plugin(jh);
288 if (!preset.empty()) {
289 if (!activate_preset(plugins.size() - 1, preset, false))
291 if (!activate_preset(plugins.size() - 1, preset, true))
293 fprintf(stderr, "Unknown preset: %s\n", preset.c_str());
299 void host_session::report_progress(float percentage, const std::string &message)
301 if (percentage < 100)
303 if (!progress_window) {
304 progress_window = create_progress_window();
305 gtk_window_set_modal (GTK_WINDOW (progress_window), TRUE);
306 if (main_win->toplevel)
307 gtk_window_set_transient_for (GTK_WINDOW (progress_window), main_win->toplevel);
309 gtk_widget_show(progress_window);
310 GtkWidget *pbar = gtk_bin_get_child (GTK_BIN (progress_window));
311 if (!message.empty())
312 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (pbar), message.c_str());
313 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pbar), percentage / 100.0);
315 else
317 if (progress_window) {
318 gtk_window_set_modal (GTK_WINDOW (progress_window), FALSE);
319 gtk_widget_destroy (progress_window);
320 progress_window = NULL;
324 while (gtk_events_pending ())
325 gtk_main_iteration ();
329 void host_session::create_plugins_from_list()
331 for (unsigned int i = 0; i < plugin_names.size(); i++) {
332 add_plugin(plugin_names[i], presets.count(i) ? presets[i] : string());
336 GtkWidget *host_session::create_progress_window()
338 GtkWidget *tlw = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
339 gtk_window_set_type_hint (GTK_WINDOW (tlw), GDK_WINDOW_TYPE_HINT_DIALOG);
340 GtkWidget *pbar = gtk_progress_bar_new();
341 gtk_container_add (GTK_CONTAINER(tlw), pbar);
342 gtk_widget_show_all (pbar);
343 return tlw;
346 void host_session::open()
348 if (!input_name.empty()) client.input_name = input_name;
349 if (!output_name.empty()) client.output_name = output_name;
350 if (!midi_name.empty()) client.midi_name = midi_name;
351 client.open(client_name.c_str());
352 main_win->prefix = client_name + " - ";
353 main_win->conditions.insert("jackhost");
354 main_win->conditions.insert("directlink");
355 if (!restoring_session)
356 create_plugins_from_list();
357 main_win->create();
358 gtk_signal_connect(GTK_OBJECT(main_win->toplevel), "destroy", G_CALLBACK(destroy), NULL);
361 void host_session::new_plugin(const char *name)
363 jack_host_base *jh = create_jack_host(name, get_next_instance_name(name), this);
364 if (!jh)
365 return;
366 instances.insert(jh->instance_name);
367 jh->open(&client);
369 plugins.push_back(jh);
370 client.add(jh);
371 main_win->add_plugin(jh);
374 void host_session::remove_plugin(plugin_ctl_iface *plugin)
376 for (unsigned int i = 0; i < plugins.size(); i++)
378 if (plugins[i] == plugin)
380 client.del(i);
381 plugins.erase(plugins.begin() + i);
382 main_win->del_plugin(plugin);
383 delete plugin;
384 return;
389 void host_session::remove_all_plugins()
391 while(!plugins.empty())
393 plugin_ctl_iface *plugin = plugins[0];
394 client.del(0);
395 plugins.erase(plugins.begin());
396 main_win->del_plugin(plugin);
397 delete plugin;
401 bool host_session::activate_preset(int plugin_no, const std::string &preset, bool builtin)
403 string cur_plugin = plugins[plugin_no]->get_id();
404 preset_vector &pvec = (builtin ? get_builtin_presets() : get_user_presets()).presets;
405 for (unsigned int i = 0; i < pvec.size(); i++) {
406 if (pvec[i].name == preset && pvec[i].plugin == cur_plugin)
408 pvec[i].activate(plugins[plugin_no]);
409 if (gui_win && gui_win->gui)
410 gui_win->gui->refresh();
411 return true;
414 return false;
417 void host_session::connect()
419 client.activate();
420 #if USE_LASH && !USE_LASH_0_6
421 if (lash_client)
422 lash_jack_client_name(lash_client, client.get_name().c_str());
423 #endif
424 if (!restoring_session)
426 string cnp = client.get_name() + ":";
427 for (unsigned int i = 0; i < plugins.size(); i++) {
428 if (chains.count(i)) {
429 if (!i)
431 if (plugins[0]->get_output_count() < 2)
433 fprintf(stderr, "Cannot connect input to plugin %s - incompatible ports\n", plugins[0]->name.c_str());
434 } else {
435 client.connect("system:capture_1", cnp + plugins[0]->get_inputs()[0].name);
436 client.connect("system:capture_2", cnp + plugins[0]->get_inputs()[1].name);
439 else
441 if (plugins[i - 1]->get_output_count() < 2 || plugins[i]->get_input_count() < 2)
443 fprintf(stderr, "Cannot connect plugins %s and %s - incompatible ports\n", plugins[i - 1]->name.c_str(), plugins[i]->name.c_str());
445 else {
446 client.connect(cnp + plugins[i - 1]->get_outputs()[0].name, cnp + plugins[i]->get_inputs()[0].name);
447 client.connect(cnp + plugins[i - 1]->get_outputs()[1].name, cnp + plugins[i]->get_inputs()[1].name);
452 if (chains.count(plugins.size()) && plugins.size())
454 int last = plugins.size() - 1;
455 if (plugins[last]->get_output_count() < 2)
457 fprintf(stderr, "Cannot connect plugin %s to output - incompatible ports\n", plugins[last]->name.c_str());
458 } else {
459 client.connect(cnp + plugins[last]->get_outputs()[0].name, "system:playback_1");
460 client.connect(cnp + plugins[last]->get_outputs()[1].name, "system:playback_2");
463 if (autoconnect_midi != "") {
464 for (unsigned int i = 0; i < plugins.size(); i++)
466 if (plugins[i]->get_midi())
467 client.connect(autoconnect_midi, cnp + plugins[i]->get_midi_port()->name);
470 else
471 if (autoconnect_midi_index != -1) {
472 const char **ports = client.get_ports("(system|alsa_pcm):.*", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput);
473 for (int j = 0; ports[j]; j++)
475 if (j + 1 == autoconnect_midi_index) {
476 for (unsigned int i = 0; i < plugins.size(); i++)
478 if (plugins[i]->get_midi())
479 client.connect(ports[j], cnp + plugins[i]->get_midi_port()->name);
481 break;
486 #if USE_LASH
487 if (lash_client)
489 # if !USE_LASH_0_6
490 send_lash(LASH_Client_Name, "calf-"+client_name);
491 # endif
492 lash_source_id = g_timeout_add_full(G_PRIORITY_LOW, 250, update_lash, this, NULL); // 4 LASH reads per second... should be enough?
494 #endif
497 void host_session::close()
499 #if USE_LASH
500 if (lash_source_id)
501 g_source_remove(lash_source_id);
502 #endif
503 main_win->on_closed();
504 main_win->close_guis();
505 client.deactivate();
506 client.delete_plugins();
507 client.close();
510 #if USE_LASH
512 static string stripfmt(string x)
514 if (x.length() < 2)
515 return x;
516 if (x.substr(x.length() - 2) != "%d")
517 return x;
518 return x.substr(0, x.length() - 2);
521 # if !USE_LASH_0_6
523 void host_session::update_lash()
525 do {
526 lash_event_t *event = lash_get_event(lash_client);
527 if (!event)
528 break;
530 // printf("type = %d\n", lash_event_get_type(event));
532 switch(lash_event_get_type(event)) {
533 case LASH_Save_Data_Set:
535 lash_config_t *cfg = lash_config_new_with_key("global");
536 dictionary tmp;
537 string pstr;
538 string i_name = stripfmt(client.input_name);
539 string o_name = stripfmt(client.output_name);
540 string m_name = stripfmt(client.midi_name);
541 tmp["input_prefix"] = i_name;
542 tmp["output_prefix"] = stripfmt(client.output_name);
543 tmp["midi_prefix"] = stripfmt(client.midi_name);
544 pstr = encode_map(tmp);
545 lash_config_set_value(cfg, pstr.c_str(), pstr.length());
546 lash_send_config(lash_client, cfg);
548 for (unsigned int i = 0; i < plugins.size(); i++) {
549 jack_host_base *p = plugins[i];
550 char ss[32];
551 plugin_preset preset;
552 preset.plugin = p->get_id();
553 preset.get_from(p);
554 sprintf(ss, "Plugin%d", i);
555 pstr = preset.to_xml();
556 tmp.clear();
557 tmp["instance_name"] = p->instance_name;
558 if (p->get_input_count())
559 tmp["input_name"] = p->get_inputs()[0].name.substr(i_name.length());
560 if (p->get_output_count())
561 tmp["output_name"] = p->get_outputs()[0].name.substr(o_name.length());
562 if (p->get_midi_port())
563 tmp["midi_name"] = p->get_midi_port()->name.substr(m_name.length());
564 tmp["preset"] = pstr;
565 pstr = encode_map(tmp);
566 lash_config_t *cfg = lash_config_new_with_key(ss);
567 lash_config_set_value(cfg, pstr.c_str(), pstr.length());
568 lash_send_config(lash_client, cfg);
570 send_lash(LASH_Save_Data_Set, "");
571 break;
574 case LASH_Restore_Data_Set:
576 // printf("!!!Restore data set!!!\n");
577 remove_all_plugins();
578 while(lash_config_t *cfg = lash_get_config(lash_client)) {
579 const char *key = lash_config_get_key(cfg);
580 // printf("key = %s\n", lash_config_get_key(cfg));
581 string data = string((const char *)lash_config_get_value(cfg), lash_config_get_value_size(cfg));
582 if (!strcmp(key, "global"))
584 dictionary dict;
585 decode_map(dict, data);
586 if (dict.count("input_prefix")) client.input_name = dict["input_prefix"]+"%d";
587 if (dict.count("output_prefix")) client.output_name = dict["output_prefix"]+"%d";
588 if (dict.count("midi_prefix")) client.midi_name = dict["midi_prefix"]+"%d";
590 if (!strncmp(key, "Plugin", 6))
592 unsigned int nplugin = atoi(key + 6);
593 dictionary dict;
594 decode_map(dict, data);
595 data = dict["preset"];
596 string instance_name;
597 if (dict.count("instance_name")) instance_name = dict["instance_name"];
598 if (dict.count("input_name")) client.input_nr = atoi(dict["input_name"].c_str());
599 if (dict.count("output_name")) client.output_nr = atoi(dict["output_name"].c_str());
600 if (dict.count("midi_name")) client.midi_nr = atoi(dict["midi_name"].c_str());
601 preset_list tmp;
602 tmp.parse("<presets>"+data+"</presets>");
603 if (tmp.presets.size())
605 printf("Load plugin %s\n", tmp.presets[0].plugin.c_str());
606 add_plugin(tmp.presets[0].plugin, "", instance_name);
607 tmp.presets[0].activate(plugins[nplugin]);
608 main_win->refresh_plugin(plugins[nplugin]);
611 lash_config_destroy(cfg);
613 send_lash(LASH_Restore_Data_Set, "");
614 break;
617 case LASH_Quit:
618 gtk_main_quit();
619 break;
621 default:
622 g_warning("Unhandled LASH event %d (%s)", lash_event_get_type(event), lash_event_get_string(event));
623 break;
625 } while(1);
628 # else
630 void host_session::update_lash()
632 lash_dispatch(lash_client);
635 bool save_data_set_cb(lash_config_handle_t *handle, void *user_data)
637 host_session *sess = static_cast<host_session *>(user_data);
638 dictionary tmp;
639 string pstr;
640 string i_name = stripfmt(sess->client.input_name);
641 string o_name = stripfmt(sess->client.output_name);
642 string m_name = stripfmt(sess->client.midi_name);
643 tmp["input_prefix"] = i_name;
644 tmp["output_prefix"] = stripfmt(sess->client.output_name);
645 tmp["midi_prefix"] = stripfmt(sess->client.midi_name);
646 pstr = encode_map(tmp);
647 lash_config_write_raw(handle, "global", pstr.c_str(), pstr.length());
648 for (unsigned int i = 0; i < sess->plugins.size(); i++) {
649 jack_host_base *p = sess->plugins[i];
650 char ss[32];
651 plugin_preset preset;
652 preset.plugin = p->get_id();
653 preset.get_from(p);
654 sprintf(ss, "Plugin%d", i);
655 pstr = preset.to_xml();
656 tmp.clear();
657 tmp["instance_name"] = p->instance_name;
658 if (p->get_input_count())
659 tmp["input_name"] = p->get_inputs()[0].name.substr(i_name.length());
660 if (p->get_output_count())
661 tmp["output_name"] = p->get_outputs()[0].name.substr(o_name.length());
662 if (p->get_midi_port())
663 tmp["midi_name"] = p->get_midi_port()->name.substr(m_name.length());
664 tmp["preset"] = pstr;
665 pstr = encode_map(tmp);
666 lash_config_write_raw(handle, ss, pstr.c_str(), pstr.length());
668 return true;
671 bool load_data_set_cb(lash_config_handle_t *handle, void *user_data)
673 host_session *sess = static_cast<host_session *>(user_data);
674 int size, type;
675 const char *key;
676 const char *value;
677 sess->remove_all_plugins();
678 while((size = lash_config_read(handle, &key, (void *)&value, &type))) {
679 if (size == -1 || type != LASH_TYPE_RAW)
680 continue;
681 string data = string(value, size);
682 if (!strcmp(key, "global"))
684 dictionary dict;
685 decode_map(dict, data);
686 if (dict.count("input_prefix")) sess->client.input_name = dict["input_prefix"]+"%d";
687 if (dict.count("output_prefix")) sess->client.output_name = dict["output_prefix"]+"%d";
688 if (dict.count("midi_prefix")) sess->client.midi_name = dict["midi_prefix"]+"%d";
689 } else if (!strncmp(key, "Plugin", 6)) {
690 unsigned int nplugin = atoi(key + 6);
691 dictionary dict;
692 decode_map(dict, data);
693 data = dict["preset"];
694 string instance_name;
695 if (dict.count("instance_name")) instance_name = dict["instance_name"];
696 if (dict.count("input_name")) sess->client.input_nr = atoi(dict["input_name"].c_str());
697 if (dict.count("output_name")) sess->client.output_nr = atoi(dict["output_name"].c_str());
698 if (dict.count("midi_name")) sess->client.midi_nr = atoi(dict["midi_name"].c_str());
699 preset_list tmp;
700 tmp.parse("<presets>"+data+"</presets>");
701 if (tmp.presets.size())
703 printf("Load plugin %s\n", tmp.presets[0].plugin.c_str());
704 sess->add_plugin(tmp.presets[0].plugin, "", instance_name);
705 tmp.presets[0].activate(sess->plugins[nplugin]);
706 sess->main_win->refresh_plugin(sess->plugins[nplugin]);
710 return true;
713 bool quit_cb(void *user_data)
715 gtk_main_quit();
716 return true;
719 # endif
720 #endif
722 host_session current_session;
724 int main(int argc, char *argv[])
726 host_session &sess = current_session;
727 gtk_init(&argc, &argv);
729 #if USE_LASH
730 # if !USE_LASH_0_6
731 for (int i = 1; i < argc; i++)
733 if (!strncmp(argv[i], "--lash-project=", 14)) {
734 sess.restoring_session = true;
735 break;
738 sess.lash_args = lash_extract_args(&argc, &argv);
739 sess.lash_client = lash_init(sess.lash_args, PACKAGE_NAME, LASH_Config_Data_Set, LASH_PROTOCOL(2, 0));
740 # else
741 sess.lash_client = lash_client_open(PACKAGE_NAME, LASH_Config_Data_Set, argc, argv);
742 sess.restoring_session = lash_client_is_being_restored(sess.lash_client);
743 lash_set_save_data_set_callback(sess.lash_client, save_data_set_cb, &sess);
744 lash_set_load_data_set_callback(sess.lash_client, load_data_set_cb, &sess);
745 lash_set_quit_callback(sess.lash_client, quit_cb, NULL);
746 # endif
747 if (!sess.lash_client) {
748 g_warning("Warning: failed to create a LASH connection");
750 #endif
751 glade_init();
752 while(1) {
753 int option_index;
754 int c = getopt_long(argc, argv, "c:i:o:m:M:ehv", long_options, &option_index);
755 if (c == -1)
756 break;
757 switch(c) {
758 case 'h':
759 case '?':
760 print_help(argv);
761 return 0;
762 case 'v':
763 printf("%s\n", PACKAGE_STRING);
764 return 0;
765 case 'e':
766 fprintf(stderr, "Warning: switch -%c is deprecated!\n", c);
767 break;
768 case 'c':
769 sess.client_name = optarg;
770 break;
771 case 'i':
772 sess.input_name = string(optarg) + "_%d";
773 break;
774 case 'o':
775 sess.output_name = string(optarg) + "_%d";
776 break;
777 case 'm':
778 sess.midi_name = string(optarg) + "_%d";
779 break;
780 case 'M':
781 if (atoi(optarg)) {
782 sess.autoconnect_midi_index = atoi(optarg);
784 else
785 sess.autoconnect_midi = string(optarg);
786 break;
789 while(optind < argc) {
790 if (!strcmp(argv[optind], "!")) {
791 sess.chains.insert(sess.plugin_names.size());
792 optind++;
793 } else {
794 string plugname = argv[optind++];
795 size_t pos = plugname.find(":");
796 if (pos != string::npos) {
797 sess.presets[sess.plugin_names.size()] = plugname.substr(pos + 1);
798 plugname = plugname.substr(0, pos);
800 sess.plugin_names.push_back(plugname);
803 try {
804 get_builtin_presets().load_defaults(true);
805 get_user_presets().load_defaults(false);
807 catch(calf_plugins::preset_exception &e)
809 // XXXKF this exception is already handled by load_defaults, so this is redundant
810 fprintf(stderr, "Error while loading presets: %s\n", e.what());
811 exit(1);
813 try {
814 sess.open();
815 sess.connect();
816 sess.client.activate();
817 gtk_main();
818 sess.close();
820 #if USE_LASH && !USE_LASH_0_6
821 if (sess.lash_args)
822 lash_args_destroy(sess.lash_args);
823 #endif
824 // this is now done on preset add
825 // save_presets(get_preset_filename().c_str());
827 catch(std::exception &e)
829 fprintf(stderr, "%s\n", e.what());
830 exit(1);
832 return 0;