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)
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
26 #include <glade/glade.h>
27 #include <jack/jack.h>
29 #include <lash/lash.h>
31 #include <calf/giface.h>
32 #include <calf/jackhost.h>
33 #include <calf/modules.h>
34 #include <calf/modules_dev.h>
36 #include <calf/preset.h>
37 #include <calf/preset_gui.h>
38 #include <calf/main_win.h>
39 #include <calf/utils.h>
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";
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
);
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>
63 void jack_host_base::open(jack_client
*_client
)
65 client
= _client
; //jack_client_open(client_name, JackNullOption, &status);
75 void jack_host_base::create_ports() {
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());
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
;
126 jack_port_unregister(client
->client
, midi_port
.handle
);
130 void destroy(GtkWindow
*window
, gpointer data
)
135 void gui_win_destroy(GtkWindow
*window
, gpointer data
)
139 static struct option long_options
[] = {
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'},
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",
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
);
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();
176 void jack_client::delete_plugins()
179 for (unsigned int i
= 0; i
< plugins
.size(); i
++) {
180 // plugins[i]->close();
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
;
193 lash_client_t
*lash_client
;
195 lash_args_t
*lash_args
;
199 // these are not saved
201 string autoconnect_midi
;
202 int autoconnect_midi_index
;
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
;
212 void add_plugin(string name
, string preset
, string instance_name
= string());
213 void create_plugins_from_list();
216 bool activate_preset(int plugin
, const std::string
&preset
, bool builtin
);
218 static gboolean
update_lash(void *self
) { ((host_session
*)self
)->update_lash(); return TRUE
; }
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()));
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";
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
))
258 for (int i
= 2; ; i
++)
260 string tmp
= string(effect_name
) + i2s(i
);
261 if (!instances
.count(tmp
))
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);
275 #define PER_MODULE_ITEM(name, isSynth, jackname) jackname ", "
276 #include <calf/modulelist.h>
279 s
= s
.substr(0, s
.length() - 2);
280 throw text_exception("Unknown plugin name; allowed are: " + s
);
282 instances
.insert(jh
->instance_name
);
285 plugins
.push_back(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);
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
);
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();
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);
366 instances
.insert(jh
->instance_name
);
369 plugins
.push_back(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
)
381 plugins
.erase(plugins
.begin() + i
);
382 main_win
->del_plugin(plugin
);
389 void host_session::remove_all_plugins()
391 while(!plugins
.empty())
393 plugin_ctl_iface
*plugin
= plugins
[0];
395 plugins
.erase(plugins
.begin());
396 main_win
->del_plugin(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();
417 void host_session::connect()
420 #if USE_LASH && !USE_LASH_0_6
422 lash_jack_client_name(lash_client
, client
.get_name().c_str());
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
)) {
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());
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
);
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());
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());
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
);
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
);
490 send_lash(LASH_Client_Name
, "calf-"+client_name
);
492 lash_source_id
= g_timeout_add_full(G_PRIORITY_LOW
, 250, update_lash
, this, NULL
); // 4 LASH reads per second... should be enough?
497 void host_session::close()
501 g_source_remove(lash_source_id
);
503 main_win
->on_closed();
504 main_win
->close_guis();
506 client
.delete_plugins();
512 static string
stripfmt(string x
)
516 if (x
.substr(x
.length() - 2) != "%d")
518 return x
.substr(0, x
.length() - 2);
523 void host_session::update_lash()
526 lash_event_t
*event
= lash_get_event(lash_client
);
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");
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
];
551 plugin_preset preset
;
552 preset
.plugin
= p
->get_id();
554 sprintf(ss
, "Plugin%d", i
);
555 pstr
= preset
.to_xml();
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
, "");
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"))
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);
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());
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
, "");
622 g_warning("Unhandled LASH event %d (%s)", lash_event_get_type(event
), lash_event_get_string(event
));
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
);
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
];
651 plugin_preset preset
;
652 preset
.plugin
= p
->get_id();
654 sprintf(ss
, "Plugin%d", i
);
655 pstr
= preset
.to_xml();
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());
671 bool load_data_set_cb(lash_config_handle_t
*handle
, void *user_data
)
673 host_session
*sess
= static_cast<host_session
*>(user_data
);
677 sess
->remove_all_plugins();
678 while((size
= lash_config_read(handle
, &key
, (void *)&value
, &type
))) {
679 if (size
== -1 || type
!= LASH_TYPE_RAW
)
681 string data
= string(value
, size
);
682 if (!strcmp(key
, "global"))
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);
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());
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
]);
713 bool quit_cb(void *user_data
)
722 host_session current_session
;
724 int main(int argc
, char *argv
[])
726 host_session
&sess
= current_session
;
727 gtk_init(&argc
, &argv
);
731 for (int i
= 1; i
< argc
; i
++)
733 if (!strncmp(argv
[i
], "--lash-project=", 14)) {
734 sess
.restoring_session
= true;
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));
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
);
747 if (!sess
.lash_client
) {
748 g_warning("Warning: failed to create a LASH connection");
754 int c
= getopt_long(argc
, argv
, "c:i:o:m:M:ehv", long_options
, &option_index
);
763 printf("%s\n", PACKAGE_STRING
);
766 fprintf(stderr
, "Warning: switch -%c is deprecated!\n", c
);
769 sess
.client_name
= optarg
;
772 sess
.input_name
= string(optarg
) + "_%d";
775 sess
.output_name
= string(optarg
) + "_%d";
778 sess
.midi_name
= string(optarg
) + "_%d";
782 sess
.autoconnect_midi_index
= atoi(optarg
);
785 sess
.autoconnect_midi
= string(optarg
);
789 while(optind
< argc
) {
790 if (!strcmp(argv
[optind
], "!")) {
791 sess
.chains
.insert(sess
.plugin_names
.size());
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
);
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());
816 sess
.client
.activate();
820 #if USE_LASH && !USE_LASH_0_6
822 lash_args_destroy(sess
.lash_args
);
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());