mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 23:05:04 +01:00
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
This commit is contained in:
parent
480986bb60
commit
baa4de40ed
4 changed files with 92 additions and 79 deletions
|
|
@ -36,29 +36,23 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
using namespace ARDOUR;
|
using namespace ARDOUR;
|
||||||
|
using std::cerr;
|
||||||
|
|
||||||
PluginEqGui::PluginEqGui(boost::shared_ptr<ARDOUR::PluginInsert> pluginInsert)
|
PluginEqGui::PluginEqGui(boost::shared_ptr<ARDOUR::PluginInsert> pluginInsert)
|
||||||
: _min_dB(-12.0),
|
: _min_dB(-12.0)
|
||||||
_max_dB(+12.0),
|
, _max_dB(+12.0)
|
||||||
_step_dB(3.0),
|
, _step_dB(3.0)
|
||||||
_impulse_fft(0),
|
, _impulse_fft(0)
|
||||||
_signal_input_fft(0),
|
, _signal_input_fft(0)
|
||||||
_signal_output_fft(0),
|
, _signal_output_fft(0)
|
||||||
_plugin_insert(pluginInsert)
|
, _plugin_insert(pluginInsert)
|
||||||
{
|
{
|
||||||
_signal_analysis_running = false;
|
_signal_analysis_running = false;
|
||||||
_samplerate = ARDOUR_UI::instance()->the_session()->frame_rate();
|
_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_coeff = (1.0 - 2.0 * (1000.0/(_samplerate/2.0))) / powf(1000.0/(_samplerate/2.0), 2.0);
|
||||||
_log_max = log10f(1 + _log_coeff);
|
_log_max = log10f(1 + _log_coeff);
|
||||||
|
|
||||||
|
|
||||||
// Setup analysis drawing area
|
// Setup analysis drawing area
|
||||||
_analysis_scale_surface = 0;
|
_analysis_scale_surface = 0;
|
||||||
|
|
||||||
|
|
@ -116,27 +110,47 @@ PluginEqGui::PluginEqGui(boost::shared_ptr<ARDOUR::PluginInsert> pluginInsert)
|
||||||
attach( *manage(_analysis_area), 1, 3, 1, 2);
|
attach( *manage(_analysis_area), 1, 3, 1, 2);
|
||||||
attach( *manage(dBSelectBin), 1, 2, 2, 3, Gtk::SHRINK, Gtk::SHRINK);
|
attach( *manage(dBSelectBin), 1, 2, 2, 3, Gtk::SHRINK, Gtk::SHRINK);
|
||||||
attach( *manage(_phase_button), 2, 3, 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()
|
PluginEqGui::~PluginEqGui()
|
||||||
{
|
{
|
||||||
|
cerr << "PEG::delete\n";
|
||||||
|
|
||||||
|
stop_listening ();
|
||||||
|
|
||||||
if (_analysis_scale_surface) {
|
if (_analysis_scale_surface) {
|
||||||
cairo_surface_destroy (_analysis_scale_surface);
|
cairo_surface_destroy (_analysis_scale_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete _impulse_fft;
|
delete _impulse_fft;
|
||||||
|
_impulse_fft = 0;
|
||||||
delete _signal_input_fft;
|
delete _signal_input_fft;
|
||||||
|
_signal_input_fft = 0;
|
||||||
delete _signal_output_fft;
|
delete _signal_output_fft;
|
||||||
|
_signal_output_fft = 0;
|
||||||
_plugin->deactivate();
|
|
||||||
|
|
||||||
// all gui objects are *manage'd by the inherited Table object
|
// 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
|
void
|
||||||
PluginEqGui::on_hide()
|
PluginEqGui::on_hide()
|
||||||
|
|
@ -169,10 +183,7 @@ PluginEqGui::on_show()
|
||||||
start_updating();
|
start_updating();
|
||||||
|
|
||||||
Gtk::Widget *toplevel = get_toplevel();
|
Gtk::Widget *toplevel = get_toplevel();
|
||||||
if (!toplevel) {
|
if (toplevel) {
|
||||||
std::cerr << "No toplevel widget for PluginEqGui?!?!" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_window_unmap_connection.connected()) {
|
if (!_window_unmap_connection.connected()) {
|
||||||
_window_unmap_connection = toplevel->signal_unmap().connect( sigc::mem_fun(this, &PluginEqGui::stop_updating));
|
_window_unmap_connection = toplevel->signal_unmap().connect( sigc::mem_fun(this, &PluginEqGui::stop_updating));
|
||||||
}
|
}
|
||||||
|
|
@ -180,7 +191,7 @@ PluginEqGui::on_show()
|
||||||
if (!_window_map_connection.connected()) {
|
if (!_window_map_connection.connected()) {
|
||||||
_window_map_connection = toplevel->signal_map().connect( sigc::mem_fun(this, &PluginEqGui::start_updating));
|
_window_map_connection = toplevel->signal_map().connect( sigc::mem_fun(this, &PluginEqGui::start_updating));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -217,9 +228,9 @@ PluginEqGui::redraw_scales()
|
||||||
void
|
void
|
||||||
PluginEqGui::set_buffer_size(uint32_t size, uint32_t signal_size)
|
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
GTKArdour::FFT *tmp1 = _impulse_fft;
|
GTKArdour::FFT *tmp1 = _impulse_fft;
|
||||||
GTKArdour::FFT *tmp2 = _signal_input_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;
|
_signal_buffer_size = signal_size;
|
||||||
|
|
||||||
ARDOUR::ChanCount count = ARDOUR::ChanCount::max (_plugin->get_info()->n_inputs, _plugin->get_info()->n_outputs);
|
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) {
|
for (ARDOUR::DataType::iterator i = ARDOUR::DataType::begin(); i != ARDOUR::DataType::end(); ++i) {
|
||||||
_bufferset.ensure_buffers (*i, count.get (*i), _buffer_size);
|
_bufferset.ensure_buffers (*i, count.get (*i), _buffer_size);
|
||||||
_collect_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
|
void
|
||||||
PluginEqGui::resize_analysis_area(Gtk::Allocation& size)
|
PluginEqGui::resize_analysis_area (Gtk::Allocation& size)
|
||||||
{
|
{
|
||||||
_analysis_width = (float)size.get_width();
|
_analysis_width = (float)size.get_width();
|
||||||
_analysis_height = (float)size.get_height();
|
_analysis_height = (float)size.get_height();
|
||||||
|
|
@ -300,6 +312,7 @@ PluginEqGui::signal_collect_callback(ARDOUR::BufferSet *in, ARDOUR::BufferSet *o
|
||||||
_signal_analysis_running = false;
|
_signal_analysis_running = false;
|
||||||
|
|
||||||
// This signals calls expose_analysis_area()
|
// This signals calls expose_analysis_area()
|
||||||
|
cerr << "PEG::queue_draw\n";
|
||||||
_analysis_area->queue_draw();
|
_analysis_area->queue_draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -401,8 +414,7 @@ bool
|
||||||
PluginEqGui::expose_analysis_area(GdkEventExpose *)
|
PluginEqGui::expose_analysis_area(GdkEventExpose *)
|
||||||
{
|
{
|
||||||
redraw_analysis_area();
|
redraw_analysis_area();
|
||||||
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -563,8 +575,11 @@ PluginEqGui::plot_impulse_phase(Gtk::Widget *w, cairo_t *cr)
|
||||||
void
|
void
|
||||||
PluginEqGui::draw_scales_power(Gtk::Widget */*w*/, cairo_t *cr)
|
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 divisor = _samplerate / 2.0 / _impulse_fft->bins();
|
||||||
float x;
|
float x;
|
||||||
|
|
||||||
|
|
@ -667,7 +682,6 @@ void
|
||||||
PluginEqGui::plot_impulse_amplitude(Gtk::Widget *w, cairo_t *cr)
|
PluginEqGui::plot_impulse_amplitude(Gtk::Widget *w, cairo_t *cr)
|
||||||
{
|
{
|
||||||
float x,y;
|
float x,y;
|
||||||
|
|
||||||
int prevX = 0;
|
int prevX = 0;
|
||||||
float avgY = 0.0;
|
float avgY = 0.0;
|
||||||
int avgNum = 0;
|
int avgNum = 0;
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,9 @@ public:
|
||||||
PluginEqGui (boost::shared_ptr<ARDOUR::PluginInsert>);
|
PluginEqGui (boost::shared_ptr<ARDOUR::PluginInsert>);
|
||||||
~PluginEqGui ();
|
~PluginEqGui ();
|
||||||
|
|
||||||
|
void start_listening ();
|
||||||
|
void stop_listening ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Setup
|
// Setup
|
||||||
void set_buffer_size (uint32_t, uint32_t);
|
void set_buffer_size (uint32_t, uint32_t);
|
||||||
|
|
|
||||||
|
|
@ -125,16 +125,6 @@ PluginUIWindow::PluginUIWindow (Gtk::Window* win, boost::shared_ptr<PluginInsert
|
||||||
_pluginui = pu;
|
_pluginui = pu;
|
||||||
_pluginui->KeyboardFocused.connect (sigc::mem_fun (*this, &PluginUIWindow::keyboard_focused));
|
_pluginui->KeyboardFocused.connect (sigc::mem_fun (*this, &PluginUIWindow::keyboard_focused));
|
||||||
add (*pu);
|
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);
|
set_wmclass (X_("ardour_plugin_editor"), PROGRAM_NAME);
|
||||||
|
|
||||||
signal_map_event().connect (sigc::mem_fun (*pu, &GenericPluginUI::start_updating));
|
signal_map_event().connect (sigc::mem_fun (*pu, &GenericPluginUI::start_updating));
|
||||||
|
|
@ -419,14 +409,16 @@ PluginUIWindow::plugin_going_away ()
|
||||||
}
|
}
|
||||||
|
|
||||||
PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
|
PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
|
||||||
: insert (pi),
|
: insert (pi)
|
||||||
plugin (insert->plugin()),
|
, plugin (insert->plugin())
|
||||||
add_button (_("Add")),
|
, add_button (_("Add"))
|
||||||
save_button (_("Save")),
|
, save_button (_("Save"))
|
||||||
delete_button (_("Delete")),
|
, delete_button (_("Delete"))
|
||||||
bypass_button (_("Bypass")),
|
, bypass_button (_("Bypass"))
|
||||||
latency_gui (0),
|
, latency_gui (0)
|
||||||
plugin_analysis_expander (_("Plugin analysis"))
|
, latency_dialog (0)
|
||||||
|
, plugin_analysis_expander (_("Plugin analysis"))
|
||||||
|
, eqgui (0)
|
||||||
{
|
{
|
||||||
_preset_combo.set_size_request (100, -1);
|
_preset_combo.set_size_request (100, -1);
|
||||||
_preset_modified.set_size_request (16, -1);
|
_preset_modified.set_size_request (16, -1);
|
||||||
|
|
@ -482,6 +474,7 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
|
||||||
|
|
||||||
PlugUIBase::~PlugUIBase()
|
PlugUIBase::~PlugUIBase()
|
||||||
{
|
{
|
||||||
|
delete eqgui;
|
||||||
delete latency_gui;
|
delete latency_gui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -634,36 +627,36 @@ PlugUIBase::toggle_plugin_analysis()
|
||||||
if (plugin_analysis_expander.get_expanded() &&
|
if (plugin_analysis_expander.get_expanded() &&
|
||||||
!plugin_analysis_expander.get_child()) {
|
!plugin_analysis_expander.get_child()) {
|
||||||
// Create the GUI
|
// Create the GUI
|
||||||
PluginEqGui *foo = new PluginEqGui(insert);
|
if (eqgui == 0) {
|
||||||
plugin_analysis_expander.add( *foo );
|
eqgui = new PluginEqGui (insert);
|
||||||
plugin_analysis_expander.show_all();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Gtk::Widget *gui;
|
Gtk::Window *toplevel = (Gtk::Window*) plugin_analysis_expander.get_ancestor (GTK_TYPE_WINDOW);
|
||||||
|
|
||||||
if (!plugin_analysis_expander.get_expanded() &&
|
if (toplevel) {
|
||||||
(gui = plugin_analysis_expander.get_child())) {
|
toplevel->get_size (pre_eq_size.width, pre_eq_size.height);
|
||||||
// Hide & remove
|
cerr << "Pre EQ size was " << pre_eq_size.width << " x " << pre_eq_size.height << endl;
|
||||||
gui->hide();
|
}
|
||||||
//plugin_analysis_expander.remove(*gui);
|
|
||||||
|
plugin_analysis_expander.add (*eqgui);
|
||||||
|
plugin_analysis_expander.show_all ();
|
||||||
|
eqgui->start_listening ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!plugin_analysis_expander.get_expanded()) {
|
||||||
|
|
||||||
|
// Hide & remove from expander
|
||||||
|
|
||||||
|
eqgui->hide ();
|
||||||
|
eqgui->stop_listening ();
|
||||||
plugin_analysis_expander.remove();
|
plugin_analysis_expander.remove();
|
||||||
|
|
||||||
delete gui;
|
Gtk::Window *toplevel = (Gtk::Window*) plugin_analysis_expander.get_ancestor (GTK_TYPE_WINDOW);
|
||||||
|
|
||||||
Gtk::Widget *toplevel = plugin_analysis_expander.get_toplevel();
|
if (toplevel) {
|
||||||
if (!toplevel) {
|
cerr << "reset size too " << pre_eq_size.width << " x " << pre_eq_size.height << endl;
|
||||||
std::cerr << "No toplevel widget?!?!" << std::endl;
|
toplevel->resize (pre_eq_size.width, pre_eq_size.height);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Gtk::Container *cont = dynamic_cast<Gtk::Container *>(toplevel);
|
|
||||||
if (!cont) {
|
|
||||||
std::cerr << "Toplevel widget is not a container?!?" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Gtk::Allocation alloc(0, 0, 50, 50); // Just make it small
|
|
||||||
toplevel->size_allocate(alloc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ namespace Gtkmm2ext {
|
||||||
|
|
||||||
class LatencyGUI;
|
class LatencyGUI;
|
||||||
class ArdourDialog;
|
class ArdourDialog;
|
||||||
|
class PluginEqGui;
|
||||||
|
|
||||||
class PlugUIBase : public virtual sigc::trackable, public PBD::ScopedConnectionList
|
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;
|
ArdourDialog* latency_dialog;
|
||||||
|
|
||||||
Gtk::Expander plugin_analysis_expander;
|
Gtk::Expander plugin_analysis_expander;
|
||||||
|
PluginEqGui* eqgui;
|
||||||
|
Gtk::Requisition pre_eq_size;
|
||||||
|
|
||||||
Gtk::Image* focus_out_image;
|
Gtk::Image* focus_out_image;
|
||||||
Gtk::Image* focus_in_image;
|
Gtk::Image* focus_in_image;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue