From baa4de40ed5e251ad3b5807ec84f18323d511679 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 19 Apr 2011 16:05:28 +0000 Subject: fixes to avoid dreadfull thread races and deletion crashes related to the pluin EQ GUI git-svn-id: svn://localhost/ardour2/branches/3.0@9378 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/plugin_eq_gui.cc | 90 +++++++++++++++++++++++++------------------- gtk2_ardour/plugin_eq_gui.h | 3 ++ gtk2_ardour/plugin_ui.cc | 75 +++++++++++++++++------------------- gtk2_ardour/plugin_ui.h | 3 ++ 4 files changed, 92 insertions(+), 79 deletions(-) diff --git a/gtk2_ardour/plugin_eq_gui.cc b/gtk2_ardour/plugin_eq_gui.cc index 5c90f5a887..f4e5922cb5 100644 --- a/gtk2_ardour/plugin_eq_gui.cc +++ b/gtk2_ardour/plugin_eq_gui.cc @@ -36,29 +36,23 @@ #include using namespace ARDOUR; +using std::cerr; PluginEqGui::PluginEqGui(boost::shared_ptr pluginInsert) - : _min_dB(-12.0), - _max_dB(+12.0), - _step_dB(3.0), - _impulse_fft(0), - _signal_input_fft(0), - _signal_output_fft(0), - _plugin_insert(pluginInsert) + : _min_dB(-12.0) + , _max_dB(+12.0) + , _step_dB(3.0) + , _impulse_fft(0) + , _signal_input_fft(0) + , _signal_output_fft(0) + , _plugin_insert(pluginInsert) { _signal_analysis_running = false; _samplerate = ARDOUR_UI::instance()->the_session()->frame_rate(); - _plugin = _plugin_insert->get_impulse_analysis_plugin(); - _plugin->activate(); - - set_buffer_size(4096, 16384); - //set_buffer_size(4096, 4096); - _log_coeff = (1.0 - 2.0 * (1000.0/(_samplerate/2.0))) / powf(1000.0/(_samplerate/2.0), 2.0); _log_max = log10f(1 + _log_coeff); - // Setup analysis drawing area _analysis_scale_surface = 0; @@ -116,27 +110,47 @@ PluginEqGui::PluginEqGui(boost::shared_ptr pluginInsert) attach( *manage(_analysis_area), 1, 3, 1, 2); attach( *manage(dBSelectBin), 1, 2, 2, 3, Gtk::SHRINK, Gtk::SHRINK); attach( *manage(_phase_button), 2, 3, 2, 3, Gtk::SHRINK, Gtk::SHRINK); - - - // Connect the realtime signal collection callback - _plugin_insert->AnalysisDataGathered.connect (analysis_connection, invalidator (*this), ui_bind (&PluginEqGui::signal_collect_callback, this, _1, _2), gui_context()); } PluginEqGui::~PluginEqGui() { + cerr << "PEG::delete\n"; + + stop_listening (); + if (_analysis_scale_surface) { cairo_surface_destroy (_analysis_scale_surface); } delete _impulse_fft; + _impulse_fft = 0; delete _signal_input_fft; + _signal_input_fft = 0; delete _signal_output_fft; - - _plugin->deactivate(); + _signal_output_fft = 0; // all gui objects are *manage'd by the inherited Table object } +void +PluginEqGui::start_listening () +{ + if (!_plugin) { + _plugin = _plugin_insert->get_impulse_analysis_plugin(); + } + + _plugin->activate(); + set_buffer_size(4096, 16384); + // Connect the realtime signal collection callback + _plugin_insert->AnalysisDataGathered.connect (analysis_connection, invalidator (*this), ui_bind (&PluginEqGui::signal_collect_callback, this, _1, _2), gui_context()); +} + +void +PluginEqGui::stop_listening () +{ + analysis_connection.disconnect (); + _plugin->deactivate (); +} void PluginEqGui::on_hide() @@ -169,18 +183,15 @@ PluginEqGui::on_show() start_updating(); Gtk::Widget *toplevel = get_toplevel(); - if (!toplevel) { - std::cerr << "No toplevel widget for PluginEqGui?!?!" << std::endl; - } - - if (!_window_unmap_connection.connected()) { - _window_unmap_connection = toplevel->signal_unmap().connect( sigc::mem_fun(this, &PluginEqGui::stop_updating)); - } - - if (!_window_map_connection.connected()) { - _window_map_connection = toplevel->signal_map().connect( sigc::mem_fun(this, &PluginEqGui::start_updating)); + if (toplevel) { + if (!_window_unmap_connection.connected()) { + _window_unmap_connection = toplevel->signal_unmap().connect( sigc::mem_fun(this, &PluginEqGui::stop_updating)); + } + + if (!_window_map_connection.connected()) { + _window_map_connection = toplevel->signal_map().connect( sigc::mem_fun(this, &PluginEqGui::start_updating)); + } } - } void @@ -217,9 +228,9 @@ PluginEqGui::redraw_scales() void PluginEqGui::set_buffer_size(uint32_t size, uint32_t signal_size) { - if (_buffer_size == size && _signal_buffer_size == signal_size) + if (_buffer_size == size && _signal_buffer_size == signal_size) { return; - + } GTKArdour::FFT *tmp1 = _impulse_fft; GTKArdour::FFT *tmp2 = _signal_input_fft; @@ -245,6 +256,7 @@ PluginEqGui::set_buffer_size(uint32_t size, uint32_t signal_size) _signal_buffer_size = signal_size; ARDOUR::ChanCount count = ARDOUR::ChanCount::max (_plugin->get_info()->n_inputs, _plugin->get_info()->n_outputs); + for (ARDOUR::DataType::iterator i = ARDOUR::DataType::begin(); i != ARDOUR::DataType::end(); ++i) { _bufferset.ensure_buffers (*i, count.get (*i), _buffer_size); _collect_bufferset.ensure_buffers (*i, count.get (*i), _buffer_size); @@ -255,7 +267,7 @@ PluginEqGui::set_buffer_size(uint32_t size, uint32_t signal_size) } void -PluginEqGui::resize_analysis_area(Gtk::Allocation& size) +PluginEqGui::resize_analysis_area (Gtk::Allocation& size) { _analysis_width = (float)size.get_width(); _analysis_height = (float)size.get_height(); @@ -300,6 +312,7 @@ PluginEqGui::signal_collect_callback(ARDOUR::BufferSet *in, ARDOUR::BufferSet *o _signal_analysis_running = false; // This signals calls expose_analysis_area() + cerr << "PEG::queue_draw\n"; _analysis_area->queue_draw(); } @@ -401,8 +414,7 @@ bool PluginEqGui::expose_analysis_area(GdkEventExpose *) { redraw_analysis_area(); - - return false; + return true; } void @@ -563,8 +575,11 @@ PluginEqGui::plot_impulse_phase(Gtk::Widget *w, cairo_t *cr) void PluginEqGui::draw_scales_power(Gtk::Widget */*w*/, cairo_t *cr) { - static float scales[] = { 30.0, 70.0, 125.0, 250.0, 500.0, 1000.0, 2000.0, 5000.0, 10000.0, 15000.0, 20000.0, -1.0 }; + if (_impulse_fft == 0) { + return; + } + static float scales[] = { 30.0, 70.0, 125.0, 250.0, 500.0, 1000.0, 2000.0, 5000.0, 10000.0, 15000.0, 20000.0, -1.0 }; float divisor = _samplerate / 2.0 / _impulse_fft->bins(); float x; @@ -667,7 +682,6 @@ void PluginEqGui::plot_impulse_amplitude(Gtk::Widget *w, cairo_t *cr) { float x,y; - int prevX = 0; float avgY = 0.0; int avgNum = 0; diff --git a/gtk2_ardour/plugin_eq_gui.h b/gtk2_ardour/plugin_eq_gui.h index e38bc8e8f7..ebe54cb320 100644 --- a/gtk2_ardour/plugin_eq_gui.h +++ b/gtk2_ardour/plugin_eq_gui.h @@ -40,6 +40,9 @@ public: PluginEqGui (boost::shared_ptr); ~PluginEqGui (); + void start_listening (); + void stop_listening (); + private: // Setup void set_buffer_size (uint32_t, uint32_t); diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc index 341fadbeb8..dcfbb24fbb 100644 --- a/gtk2_ardour/plugin_ui.cc +++ b/gtk2_ardour/plugin_ui.cc @@ -125,16 +125,6 @@ PluginUIWindow::PluginUIWindow (Gtk::Window* win, boost::shared_ptrKeyboardFocused.connect (sigc::mem_fun (*this, &PluginUIWindow::keyboard_focused)); add (*pu); - - /* - Gtk::HBox *hbox = new Gtk::HBox(); - hbox->pack_start( *pu); - // TODO: this should be nicer - hbox->pack_start( eqgui_bin ); - - add (*manage(hbox)); - */ - set_wmclass (X_("ardour_plugin_editor"), PROGRAM_NAME); signal_map_event().connect (sigc::mem_fun (*pu, &GenericPluginUI::start_updating)); @@ -419,14 +409,16 @@ PluginUIWindow::plugin_going_away () } PlugUIBase::PlugUIBase (boost::shared_ptr pi) - : insert (pi), - plugin (insert->plugin()), - add_button (_("Add")), - save_button (_("Save")), - delete_button (_("Delete")), - bypass_button (_("Bypass")), - latency_gui (0), - plugin_analysis_expander (_("Plugin analysis")) + : insert (pi) + , plugin (insert->plugin()) + , add_button (_("Add")) + , save_button (_("Save")) + , delete_button (_("Delete")) + , bypass_button (_("Bypass")) + , latency_gui (0) + , latency_dialog (0) + , plugin_analysis_expander (_("Plugin analysis")) + , eqgui (0) { _preset_combo.set_size_request (100, -1); _preset_modified.set_size_request (16, -1); @@ -482,6 +474,7 @@ PlugUIBase::PlugUIBase (boost::shared_ptr pi) PlugUIBase::~PlugUIBase() { + delete eqgui; delete latency_gui; } @@ -634,36 +627,36 @@ PlugUIBase::toggle_plugin_analysis() if (plugin_analysis_expander.get_expanded() && !plugin_analysis_expander.get_child()) { // Create the GUI - PluginEqGui *foo = new PluginEqGui(insert); - plugin_analysis_expander.add( *foo ); - plugin_analysis_expander.show_all(); + if (eqgui == 0) { + eqgui = new PluginEqGui (insert); + } + + Gtk::Window *toplevel = (Gtk::Window*) plugin_analysis_expander.get_ancestor (GTK_TYPE_WINDOW); + + if (toplevel) { + toplevel->get_size (pre_eq_size.width, pre_eq_size.height); + cerr << "Pre EQ size was " << pre_eq_size.width << " x " << pre_eq_size.height << endl; + } + + plugin_analysis_expander.add (*eqgui); + plugin_analysis_expander.show_all (); + eqgui->start_listening (); } - Gtk::Widget *gui; + if (!plugin_analysis_expander.get_expanded()) { - if (!plugin_analysis_expander.get_expanded() && - (gui = plugin_analysis_expander.get_child())) { - // Hide & remove - gui->hide(); - //plugin_analysis_expander.remove(*gui); - plugin_analysis_expander.remove(); + // Hide & remove from expander - delete gui; + eqgui->hide (); + eqgui->stop_listening (); + plugin_analysis_expander.remove(); - Gtk::Widget *toplevel = plugin_analysis_expander.get_toplevel(); - if (!toplevel) { - std::cerr << "No toplevel widget?!?!" << std::endl; - return; - } + Gtk::Window *toplevel = (Gtk::Window*) plugin_analysis_expander.get_ancestor (GTK_TYPE_WINDOW); - Gtk::Container *cont = dynamic_cast(toplevel); - if (!cont) { - std::cerr << "Toplevel widget is not a container?!?" << std::endl; - return; + if (toplevel) { + cerr << "reset size too " << pre_eq_size.width << " x " << pre_eq_size.height << endl; + toplevel->resize (pre_eq_size.width, pre_eq_size.height); } - - Gtk::Allocation alloc(0, 0, 50, 50); // Just make it small - toplevel->size_allocate(alloc); } } diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h index 3d0a121e09..52e7b8fb60 100644 --- a/gtk2_ardour/plugin_ui.h +++ b/gtk2_ardour/plugin_ui.h @@ -71,6 +71,7 @@ namespace Gtkmm2ext { class LatencyGUI; class ArdourDialog; +class PluginEqGui; class PlugUIBase : public virtual sigc::trackable, public PBD::ScopedConnectionList { @@ -119,6 +120,8 @@ class PlugUIBase : public virtual sigc::trackable, public PBD::ScopedConnectionL ArdourDialog* latency_dialog; Gtk::Expander plugin_analysis_expander; + PluginEqGui* eqgui; + Gtk::Requisition pre_eq_size; Gtk::Image* focus_out_image; Gtk::Image* focus_in_image; -- cgit v1.2.3