35 Glib::RefPtr<Gtk::AccelGroup> accels,
int nchan) {
36 Glib::RefPtr<gx_gui::GxBuilder> bld = gx_gui::GxBuilder::create_from_file(
40 bld->find_widget(
"file_selector_box", w);
47 return new IRWindow(bld, jcp, icon, machine, accels, nchan);
54 void IRWindow::init_connect() {
55 builder->find_widget(
"iredit", wIredit);
57 &IRWindow::on_delay_changed));
59 &IRWindow::on_offset_changed));
61 &IRWindow::on_length_changed));
63 &IRWindow::on_max_scale_reached));
65 &IRWindow::on_min_scale_reached));
67 builder->find_widget(
"file_combo:rack_button", wcombo);
68 wcombo->signal_changed().connect(
69 sigc::mem_fun(*
this, &IRWindow::on_combo_changed));
70 wcombo->set_model(model);
72 builder->find_widget(
"dir_combo:rack_button", dircombo);
73 if (dircombo->is_visible()) {
74 Gtk::TreeModelColumnRecord rec;
75 Gtk::TreeModelColumn<std::string> fname_col;
77 Gtk::TreeModelColumn<Glib::ustring> dname_col;
79 Glib::RefPtr<Gtk::ListStore> st = Gtk::ListStore::create(rec);
80 std::vector<gx_system::FileName> dirs;
82 for (std::vector<gx_system::FileName>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
83 Gtk::TreeIter j = st->append();
84 j->set_value(0, i->displayname);
85 j->set_value(1, i->filename);
87 dircombo->set_model(st);
88 dircombo->signal_changed().connect(
89 sigc::mem_fun(*
this, &IRWindow::on_dircombo_changed));
93 builder->find_widget(
"left", wLeft);
94 wLeft->signal_toggled().connect(sigc::mem_fun(*
this, &IRWindow::on_left));
95 builder->find_widget(
"right", wRight);
96 wRight->signal_toggled().connect(sigc::mem_fun(*
this, &IRWindow::on_right));
97 builder->find_widget(
"sum", wSum);
98 wSum->set_active(
true);
99 wSum->signal_toggled().connect(sigc::mem_fun(*
this, &IRWindow::on_sum));
101 wLeft = wRight = wSum = 0;
104 builder->find_widget(
"log", wLog);
105 wLog->set_active(
true);
106 builder->find_widget(
"linear", wLinear);
107 wLinear->signal_toggled().connect(sigc::mem_fun(*
this, &IRWindow::on_linear));
109 builder->find_widget(
"delay:show_always", wDelay);
110 wDelay->signal_value_changed().connect(sigc::mem_fun(*
this,
111 &IRWindow::on_m_delay_changed));
112 builder->find_widget(
"offset:show_always", wOffset);
113 wOffset->signal_value_changed().connect(sigc::mem_fun(*
this,
114 &IRWindow::on_m_offset_changed));
115 builder->find_widget(
"irlength:show_always", wLength);
116 wLength->signal_value_changed().connect(sigc::mem_fun(*
this,
117 &IRWindow::on_m_length_changed));
118 builder->find_widget(
"delay_ms:show_always", wDelay_ms);
119 wDelay_ms->signal_value_changed().connect(sigc::mem_fun(*
this,
120 &IRWindow::on_ms_delay_changed));
121 builder->find_widget(
"offset_ms:show_always", wOffset_ms);
122 wOffset_ms->signal_value_changed().connect(sigc::mem_fun(*
this,
123 &IRWindow::on_ms_offset_changed));
124 builder->find_widget(
"irlength_ms:show_always", wLength_ms);
125 wLength_ms->signal_value_changed().connect(sigc::mem_fun(*
this,
126 &IRWindow::on_ms_length_changed));
129 builder->find_widget(
"delay_delta", wDelay_delta);
131 &IRWindow::on_delay_delta_format_value));
134 builder->find_widget(
"home", wHome);
135 wHome->signal_clicked().connect(sigc::mem_fun(*
this, &IRWindow::on_home));
136 builder->find_widget(
"jump_zoom_mark", wJump_zoom_mark);
137 wJump_zoom_mark->signal_clicked().connect(sigc::mem_fun(*
this,
138 &IRWindow::on_jump_zoom_mark));
139 builder->find_widget(
"incr", wIncr);
140 wIncr->signal_clicked().connect(sigc::mem_fun(*
this, &IRWindow::on_incr));
141 builder->find_widget(
"decr", wDecr);
142 wDecr->signal_clicked().connect(sigc::mem_fun(*
this, &IRWindow::on_decr));
144 builder->find_widget(
"reset_button", wReset);
145 wReset->signal_clicked().connect(sigc::mem_fun(*
this, &IRWindow::on_reset_clicked));
146 builder->find_widget(
"open_button", wOpen);
147 wOpen->signal_clicked().connect(sigc::mem_fun(*
this, &IRWindow::on_open));
149 builder->find_widget(
"apply_button", wApply);
150 wApply->signal_clicked().connect(sigc::mem_fun(*
this,
151 &IRWindow::on_apply_button_clicked));
153 builder->find_widget(
"cancel_button", wCancel);
154 wCancel->signal_clicked().connect(sigc::mem_fun(*
this,
155 &IRWindow::on_cancel_button_clicked));
156 builder->find_widget(
"ok_button", wOk);
157 wOk->signal_clicked().connect(sigc::mem_fun(*
this,
158 &IRWindow::on_ok_button_clicked));
160 builder->find_widget(
"gain_button", wGain_correction);
161 autogain_conn = wGain_correction->signal_toggled().connect(
162 sigc::mem_fun(*
this, &IRWindow::on_gain_button_toggled));
164 builder->find_widget(
"length", wSamples);
165 builder->find_widget(
"samplerate", wSampleRate);
166 builder->find_widget(
"format", wFormat);
167 builder->find_widget(
"channels", wChan);
168 builder->find_widget(
"filename", wFilename);
173 builder->find_widget(
"channelbox", wChannelbox);
176 builder->find_widget(
"help_button", button);
177 button->signal_clicked().connect(sigc::mem_fun(*
this, &IRWindow::on_help_clicked));
178 builder->find_widget(
"HelpIR", wHelp);
179 builder->find_widget(
"close_irhelp", button);
180 button->signal_clicked().connect(sigc::mem_fun(wHelp, &Gtk::Widget::hide));
182 builder->find_widget(
"preset_button", button);
183 button->signal_clicked().connect(
184 sigc::mem_fun(
this, &IRWindow::on_preset_popup_clicked));
186 gtk_window->signal_key_press_event().connect(
187 sigc::mem_fun(
this, &IRWindow::on_key_press_event));
192 Glib::RefPtr<Gtk::AccelGroup> accels,
int nchan_)
206 model(Gtk::TreeStore::create(columns)),
207 current_combo_dir() {
208 bld->get_toplevel(
"DisplayIR", gtk_window);
211 gtk_window->set_icon(icon);
212 gtk_window->add_accel_group(accels);
214 sigc::mem_fun(
this, &IRWindow::load_state));
216 sigc::mem_fun(
this, &IRWindow::on_enumerate));
219 file_changed(
"", 0, 0, 0,
"");
220 on_delay_changed(0, 0);
221 on_offset_changed(0, 0);
222 on_length_changed(0, 0);
225 IRWindow::~IRWindow() {
236 double value,
int fs) {
240 s2 = (value*1000.0)/fs;
250 void IRWindow::file_changed(Glib::ustring filename,
int rate,
int length,
251 int channels, Glib::ustring format) {
252 Glib::ustring s_rate, s_length, s_channels;
253 if (filename.empty()) {
254 filename =
"no file selected";
255 s_length = s_rate = format = s_channels =
"--";
258 wDelay->set_range(0, 5*rate);
259 wDelay_ms->set_range(0, 5*1000);
260 wOffset->set_range(0, length-1);
261 wOffset_ms->set_range(0, (length-1)*1000.0/rate);
262 wLength->set_range(0, length);
263 wLength_ms->set_range(0, (length)*1000.0/rate);
264 s_length = (boost::format(
"%1%") % length).str();
265 s_rate = (boost::format(
"%1%") % rate).str();
266 s_channels = (boost::format(
"%1%") % channels).str();
268 wSamples->set_text(s_length);
269 wSampleRate->set_text(s_rate);
270 wFormat->set_text(format);
271 wChan->set_text(s_channels);
273 wChannelbox->set_sensitive(channels >= 2);
275 wFilename->set_text(Glib::path_get_dirname(filename));
289 autogain_conn.block();
290 wGain_correction->set_active(jcs->
getGainCor());
291 autogain_conn.unblock();
293 reload_impresp_list();
296 Gainline IRWindow::gain0 = Gainline();
298 bool IRWindow::load_data(Glib::ustring f,
int offset,
int delay,
int length,
const Gainline& gain) {
300 int audio_type, audio_form, audio_rate;
302 if (!machine.
read_audio(filename, &audio_size, &audio_chan, &audio_type, &audio_form, &audio_rate, &buffer)) {
306 switch (audio_type) {
313 switch (audio_form) {
320 delete[] audio_buffer;
321 audio_buffer = buffer;
322 file_changed(filename, audio_rate, audio_size, audio_chan, enc);
326 wIredit->
set_state(audio_buffer, audio_chan, audio_size, audio_rate, offset, offset+length, delay-offset, gain);
328 wSum->set_active(
true);
330 wLog->set_active(
true);
334 double IRWindow::calc_normalized_gain(
int offset,
int length,
const Gainline& points) {
335 if (audio_chan == 0) {
339 unsigned int idx = 0;
340 double gp = 0.0, fct = 0.0;
342 while (points[idx].i < offset) {
344 assert(idx < points.size());
346 if (points[idx].i > offset) {
351 for (
int i = offset; i < offset+length; i++) {
352 if (idx+1 < points.size() && points[idx].i == i) {
355 double g = pow(10, gp + i*fct);
356 for (
int j = 0; j < audio_chan; j++) {
357 double v = audio_buffer[i*audio_chan+j] * g;
361 gain = sqrt(gain / audio_chan);
369 Gainline gainline = wIredit->
get_gain();
372 double gain = calc_normalized_gain(offset, length, gainline);
379 jc.
setGainCor(wGain_correction->get_active());
382 void IRWindow::save_state() {
392 void IRWindow::on_combo_changed() {
393 Gtk::TreeModel::iterator iter = wcombo->get_active();
395 Gtk::TreeModel::Row row = *iter;
397 std::string fname = row[columns.filename];
399 load_data(Glib::build_filename(current_combo_dir, fname));
406 void IRWindow::on_dircombo_changed() {
407 Gtk::TreeModel::iterator iter = dircombo->get_active();
410 iter->get_value(1, dir);
411 if (dir != current_combo_dir) {
417 void IRWindow::reload_impresp_list() {
420 path = getenv(
"HOME");
423 if (current_combo_dir == path) {
424 Gtk::TreeNodeChildren ch = model->children();
425 for (Gtk::TreeIter i = ch.begin(); i != ch.end(); ++i) {
426 if (i->get_value(columns.filename) == irfile) {
427 wcombo->set_active(i);
436 void IRWindow::on_enumerate(
const std::string& path,
const std::vector<gx_system::FileName>& l) {
437 if (current_combo_dir == path) {
440 current_combo_dir = path;
444 wcombo->unset_model();
445 model->set_sort_column(Gtk::TreeSortable::DEFAULT_UNSORTED_COLUMN_ID, Gtk::SORT_ASCENDING);
446 for (std::vector<gx_system::FileName>::const_iterator f = l.begin(); f != l.end(); ++f) {
447 Gtk::TreeIter i = model->append();
448 i->set_value(columns.displayname, f->displayname);
449 i->set_value(columns.filename, f->filename);
450 if (f->filename == irfile) {
454 model->set_sort_column(columns.displayname, Gtk::SORT_ASCENDING);
455 wcombo->set_model(model);
457 wcombo->set_active(j);
459 if (dircombo->is_visible()) {
460 Gtk::TreeNodeChildren ch = dircombo->get_model()->children();
461 for (Gtk::TreeIter di = ch.begin(); di != ch.end(); ++di) {
464 if (p == current_combo_dir) {
465 dircombo->set_active(di);
472 void IRWindow::on_linear() {
473 wIredit->
set_log(not wLinear->get_active());
476 void IRWindow::on_left() {
477 if (wLeft->get_active()) {
482 void IRWindow::on_right() {
483 if (wRight->get_active()) {
488 void IRWindow::on_sum() {
489 if (wSum->get_active()) {
494 void IRWindow::on_delay_changed(
int delay,
int fs) {
495 int d =
static_cast<int>(round(set_val(wDelay, wDelay_ms, delay, fs)));
501 void IRWindow::on_offset_changed(
int offset,
int fs) {
502 set_val(wOffset, wOffset_ms, offset, fs);
505 void IRWindow::on_length_changed(
int length,
int fs) {
506 set_val(wLength, wLength_ms, length, fs);
509 void IRWindow::on_reset_clicked() {
516 jc.
setGain(calc_normalized_gain(0, audio_size, gain0));
519 const char *params[] = {
"jconv.balance",
"jconv.diff_delay",
"jconv.gain",
"jconv.wet_dry", 0};
520 for (
const char **p = params; *p; ++p) {
527 Glib::ustring IRWindow::on_delay_delta_format_value(
double v) {
528 Glib::ustring s =
"";
532 }
else if (v > 0.0) {
536 Glib::ustring fmt = (boost::format(
"%%.%df%%s") % wDelay_delta->property_digits()).str();
537 return (boost::format(fmt) % v % s).str();
540 void IRWindow::on_max_scale_reached(
bool v) {
541 wIncr->set_sensitive(not v);
544 void IRWindow::on_min_scale_reached(
bool v) {
545 wDecr->set_sensitive(not v);
548 void IRWindow::on_open() {
549 static Glib::ustring hostname =
"localhost";
551 hostname = Gio::Resolver::get_default()->lookup_by_address
554 Glib::ustring title = hostname +
": Select Impulse Response";
555 Gtk::FileChooserDialog d(*gtk_window, title);
556 d.set_local_only(
false);
557 d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
558 d.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
559 d.add_shortcut_folder_uri(Glib::filename_to_uri(GX_SOUND_BPA_DIR, hostname));
560 d.add_shortcut_folder_uri(Glib::filename_to_uri(GX_SOUND_BPB_DIR, hostname));
561 d.add_shortcut_folder_uri(Glib::filename_to_uri(
string(getenv(
"HOME")) +
string(
"/.config/guitarix/IR"), hostname));
563 wav.set_name(
"WAV Files");
564 wav.add_pattern(
"*.wav");
565 wav.add_pattern(
"*.WAV");
566 wav.add_pattern(
"*.Wav");
568 Gtk::FileFilter audio;
569 audio.set_name(
"Audio Files");
570 audio.add_mime_type(
"audio/*");
573 all.add_pattern(
"*");
574 all.set_name(
"All Files");
576 if (!filename.empty()) {
577 d.set_uri(Glib::filename_to_uri (filename, hostname));
579 d.set_current_folder_uri(Glib::filename_to_uri (
string(getenv(
"HOME")) +
string(
"/"), hostname));
581 if (d.run() != Gtk::RESPONSE_OK) {
584 filename = Glib::filename_from_uri(d.get_uri(), hostname);
585 Gtk::RecentManager::Data data;
586 bool result_uncertain;
587 data.mime_type = Gio::content_type_guess(filename,
"", result_uncertain);
588 data.app_name =
"guitarix";
589 data.groups.push_back(
"impulseresponse");
590 Gtk::RecentManager::get_default()->add_item(d.get_uri(), data);
593 reload_impresp_list();
596 void IRWindow::on_home() {
600 void IRWindow::on_jump_zoom_mark() {
604 void IRWindow::on_decr() {
608 void IRWindow::on_incr() {
612 void IRWindow::on_m_delay_changed() {
616 void IRWindow::on_ms_delay_changed() {
620 void IRWindow::on_m_offset_changed() {
624 void IRWindow::on_ms_offset_changed() {
628 void IRWindow::on_m_length_changed() {
632 void IRWindow::on_ms_length_changed() {
636 void IRWindow::on_apply_button_clicked() {
641 void IRWindow::destroy_self() {
645 void IRWindow::on_window_hide() {
646 Glib::signal_idle().connect(
647 sigc::bind_return(sigc::mem_fun(*
this, &IRWindow::destroy_self),
false));
650 void IRWindow::on_cancel_button_clicked() {
654 void IRWindow::on_ok_button_clicked() {
659 void IRWindow::on_preset_popup_clicked() {
660 Glib::ustring name = Glib::path_get_basename(filename);
661 Glib::ustring::size_type n = name.find_last_of(
'.');
662 if (n != Glib::ustring::npos) {
669 void IRWindow::on_help_clicked() {
673 void IRWindow::on_gain_button_toggled() {
677 bool IRWindow::on_key_press_event(GdkEventKey *event) {
678 if (event->keyval ==
GDK_KEY_Escape && (event->state & Gtk::AccelGroup::get_default_mod_mask()) == 0) {
686 if (gtk_window->get_visible() && !(gtk_window->get_window()->get_state() & Gdk::WINDOW_STATE_ICONIFIED)) {
690 gtk_window->present();
bool set(const GxJConvSettings &val) const
Glib::SignalProxy2< void, int, int > signal_length_changed()
virtual Parameter & get_parameter(const std::string &id)=0
void set_ir_data(float *p1, int p2, int p3, int p4)
Glib::SignalProxy2< void, int, int > signal_delay_changed()
static IRWindow * create(const std::string &unit_id, Glib::RefPtr< Gdk::Pixbuf > icon, gx_engine::GxMachineBase &machine, Glib::RefPtr< Gtk::AccelGroup > accels, int nchan)
virtual gx_jack::GxJack * get_jack()=0
sigc::signal< void, const GxJConvSettings * > & signal_changed()
const Glib::ustring & get_rpcaddress()
std::string getFullIRPath() const
void decr_scale(double p1)
sigc::signal< void, const std::string &, std::vector< gx_system::FileName > > & signal_impresp_list()
void cp_set_value(double value)
const std::string & getIRFile() const
void setGainCor(bool gain)
Glib::SignalProxy1< void, bool > signal_scale_max_reached()
std::string group_id() const
void setFullIRPath(string name)
const Gainline & getGainline() const
Glib::SignalProxy1< Glib::ustring, double > signal_format_value()
const GxJConvSettings & get_value() const
virtual gx_system::CmdlineOptions & get_options() const =0
Glib::SignalProxy1< void, bool > signal_scale_min_reached()
void setOffset(guint offs)
Glib::SignalProxy2< void, int, int > signal_offset_changed()
virtual void stdJSON_value()=0
void setGainline(const Gainline &gain)
const std::string & getIRDir() const
void set_state(float *data, int chan, int data_len, int samplerate, int cutoff_low, int cutoff_high, int offset, const Gainline &gain)
virtual Plugin * pluginlist_lookup_plugin(const std::string &id) const =0
std::string get_builder_filepath(const std::string &basename) const
void incr_scale(double p1)
virtual void load_impresp_dirs(std::vector< gx_system::FileName > &dirs)=0
virtual void setJSON_value()=0
virtual bool read_audio(const std::string &filename, unsigned int *audio_size, int *audio_chan, int *audio_type, int *audio_form, int *audio_rate, float **buffer)=0
void setLength(guint leng)
virtual void reload_impresp_list(const std::string &path)=0
static void compute_interpolation(double &fct, double &gp, unsigned int &idx, const Gainline &points, int offset)