mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 06:44:57 +01:00
Improvements to the plugin eq gui:
- phase correction for analysis - move gui elements to a more common location so that it's available for VSTs (needs packing in each PluginUI derived class though) git-svn-id: svn://localhost/ardour2/branches/3.0@4745 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
e09c51251f
commit
bcd217ec8e
7 changed files with 125 additions and 52 deletions
|
|
@ -50,7 +50,6 @@
|
|||
#include "utils.h"
|
||||
#include "gui_thread.h"
|
||||
#include "automation_controller.h"
|
||||
#include "plugin_eq_gui.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
|
@ -65,7 +64,6 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrol
|
|||
: PlugUIBase (pi),
|
||||
button_table (initial_button_rows, initial_button_cols),
|
||||
output_table (initial_output_rows, initial_output_cols),
|
||||
eqgui_toggle(_("Freq Analysis")),
|
||||
hAdjustment(0.0, 0.0, 0.0),
|
||||
vAdjustment(0.0, 0.0, 0.0),
|
||||
scroller_view(hAdjustment, vAdjustment),
|
||||
|
|
@ -99,6 +97,7 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrol
|
|||
VBox* v1_box = manage (new VBox);
|
||||
VBox* v2_box = manage (new VBox);
|
||||
constraint_hbox->pack_start (eqgui_toggle, false, false);
|
||||
add2(plugin_eq_bin);
|
||||
|
||||
v1_box->pack_start (*smaller_hbox, false, true);
|
||||
v2_box->pack_start (focus_button, false, true);
|
||||
|
|
@ -124,9 +123,6 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrol
|
|||
main_contents.pack_start (hpacker, false, false);
|
||||
}
|
||||
|
||||
eqgui_toggle.set_active (false);
|
||||
eqgui_toggle.signal_toggled().connect( mem_fun(*this, &GenericPluginUI::toggle_plugin_analysis));
|
||||
|
||||
pi->ActiveChanged.connect (bind(mem_fun(*this, &GenericPluginUI::processor_active_changed),
|
||||
boost::weak_ptr<Processor>(pi)));
|
||||
|
||||
|
|
@ -836,41 +832,4 @@ GenericPluginUI::setup_scale_values(guint32 port_index, ControlUI* cui)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
GenericPluginUI::toggle_plugin_analysis()
|
||||
{
|
||||
|
||||
|
||||
|
||||
if (eqgui_toggle.get_active() && !get_child2()) {
|
||||
// Create the GUI
|
||||
PluginEqGui *foo = new PluginEqGui(insert);
|
||||
pack2( *foo );
|
||||
show_all();
|
||||
}
|
||||
|
||||
Gtk::Widget *gui;
|
||||
|
||||
if (!eqgui_toggle.get_active() && (gui = get_child2())) {
|
||||
// Hide & remove
|
||||
gui->hide();
|
||||
remove(*gui);
|
||||
|
||||
delete gui;
|
||||
|
||||
Gtk::Widget *toplevel = get_toplevel();
|
||||
if (!toplevel) {
|
||||
std::cerr << "No toplevel widget?!?!" << std::endl;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,9 +246,11 @@ PluginEqGui::set_buffer_size(uint32_t size, uint32_t signal_size)
|
|||
// buffers for the signal analysis are ensured inside PluginInsert
|
||||
uint32_t n_chans = std::max(inputs, outputs);
|
||||
_bufferset.ensure_buffers(ARDOUR::DataType::AUDIO, n_chans, _buffer_size);
|
||||
_collect_bufferset.ensure_buffers(ARDOUR::DataType::AUDIO, n_chans, _buffer_size);
|
||||
|
||||
ARDOUR::ChanCount chanCount(ARDOUR::DataType::AUDIO, n_chans);
|
||||
_bufferset.set_count(chanCount);
|
||||
_collect_bufferset.set_count(chanCount);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -313,15 +315,79 @@ PluginEqGui::run_impulse_analysis()
|
|||
memset(d, 0, sizeof(ARDOUR::Sample)*_buffer_size);
|
||||
*d = 1.0;
|
||||
}
|
||||
|
||||
uint32_t x,y;
|
||||
x=y=0;
|
||||
|
||||
_plugin->connect_and_run(_bufferset, x, y, _buffer_size, (nframes_t)0);
|
||||
|
||||
// Analyze all output buffers
|
||||
|
||||
_plugin->connect_and_run(_bufferset, x, y, _buffer_size, (nframes_t)0);
|
||||
nframes_t f = _plugin->signal_latency();
|
||||
// Adding user_latency() could be interesting
|
||||
|
||||
// Gather all output, taking latency into account.
|
||||
_impulse_fft->reset();
|
||||
|
||||
// Silence collect buffers to copy data to, can't use silence() because consecutive calls won't work
|
||||
for (uint32_t i = 0; i < outputs; ++i) {
|
||||
_impulse_fft->analyze(_bufferset.get_audio(i).data(_buffer_size, 0));
|
||||
ARDOUR::AudioBuffer &buf = _collect_bufferset.get_audio(i);
|
||||
ARDOUR::Sample *d = buf.data(_buffer_size, 0);
|
||||
memset(d, 0, sizeof(ARDOUR::Sample)*_buffer_size);
|
||||
}
|
||||
|
||||
if (f == 0) {
|
||||
//std::cerr << "0: no latency, copying full buffer, trivial.." << std::endl;
|
||||
for (uint32_t i = 0; i < outputs; ++i) {
|
||||
memcpy(_collect_bufferset.get_audio(i).data(_buffer_size, 0),
|
||||
_bufferset.get_audio(i).data(_buffer_size, 0), _buffer_size * sizeof(float));
|
||||
}
|
||||
} else {
|
||||
//int C = 0;
|
||||
//std::cerr << (++C) << ": latency is " << f << " frames, doing split processing.." << std::endl;
|
||||
nframes_t target_offset = 0;
|
||||
nframes_t frames_left = _buffer_size; // refaktoroi
|
||||
do {
|
||||
if (f >= _buffer_size) {
|
||||
//std::cerr << (++C) << ": f (=" << f << ") is larger than buffer_size, still trying to reach the actual output" << std::endl;
|
||||
// there is no data in this buffer regarding to the input!
|
||||
f -= _buffer_size;
|
||||
} else {
|
||||
// this buffer contains either the first, last or a whole bu the output of the impulse
|
||||
// first part: offset is 0, so we copy to the start of _collect_bufferset
|
||||
// we start at output offset "f"
|
||||
// .. and copy "buffer size" - "f" - "offset" frames
|
||||
|
||||
nframes_t length = _buffer_size - f - target_offset;
|
||||
|
||||
//std::cerr << (++C) << ": copying " << length << " frames to _collect_bufferset.get_audio(i)+" << target_offset << " from bufferset at offset " << f << std::endl;
|
||||
for (uint32_t i = 0; i < outputs; ++i) {
|
||||
memcpy(_collect_bufferset.get_audio(i).data(_buffer_size, target_offset),
|
||||
_bufferset.get_audio(i).data(_buffer_size, 0) + f,
|
||||
length * sizeof(float));
|
||||
}
|
||||
|
||||
target_offset += length;
|
||||
frames_left -= length;
|
||||
f = 0;
|
||||
}
|
||||
if (frames_left > 0) {
|
||||
// Silence the buffers
|
||||
for (uint32_t i = 0; i < inputs; ++i) {
|
||||
ARDOUR::AudioBuffer &buf = _bufferset.get_audio(i);
|
||||
ARDOUR::Sample *d = buf.data(_buffer_size, 0);
|
||||
memset(d, 0, sizeof(ARDOUR::Sample)*_buffer_size);
|
||||
}
|
||||
|
||||
x=y=0;
|
||||
_plugin->connect_and_run(_bufferset, x, y, _buffer_size, (nframes_t)0);
|
||||
}
|
||||
} while ( frames_left > 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (uint32_t i = 0; i < outputs; ++i) {
|
||||
_impulse_fft->analyze(_collect_bufferset.get_audio(i).data(_buffer_size, 0));
|
||||
}
|
||||
|
||||
// normalize the output
|
||||
|
|
@ -329,7 +395,6 @@ PluginEqGui::run_impulse_analysis()
|
|||
|
||||
// This signals calls expose_analysis_area()
|
||||
_analysis_area->queue_draw();
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ class PluginEqGui : public Gtk::Table
|
|||
|
||||
// buffers
|
||||
ARDOUR::BufferSet _bufferset;
|
||||
ARDOUR::BufferSet _collect_bufferset;
|
||||
|
||||
|
||||
// dimensions
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
#include "gui_thread.h"
|
||||
#include "public_editor.h"
|
||||
#include "keyboard.h"
|
||||
#include "plugin_eq_gui.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
|
@ -340,7 +341,8 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
|
|||
plugin (insert->plugin()),
|
||||
save_button(_("Add")),
|
||||
bypass_button (_("Bypass")),
|
||||
latency_gui (*pi, pi->session().frame_rate(), pi->session().get_block_size())
|
||||
latency_gui (*pi, pi->session().frame_rate(), pi->session().get_block_size()),
|
||||
eqgui_toggle (_("Freq Analysis"))
|
||||
{
|
||||
//preset_combo.set_use_arrows_always(true);
|
||||
update_presets();
|
||||
|
|
@ -354,6 +356,10 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
|
|||
insert->ActiveChanged.connect (bind(
|
||||
mem_fun(*this, &PlugUIBase::processor_active_changed),
|
||||
boost::weak_ptr<Processor>(insert)));
|
||||
|
||||
eqgui_toggle.set_active (false);
|
||||
eqgui_toggle.signal_toggled().connect( mem_fun(*this, &PlugUIBase::toggle_plugin_analysis));
|
||||
|
||||
|
||||
bypass_button.set_active (!pi->active());
|
||||
|
||||
|
|
@ -373,6 +379,8 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
|
|||
|
||||
ARDOUR_UI::instance()->set_tip (&focus_button, _("Click to focus all keyboard events on this plugin window"), "");
|
||||
ARDOUR_UI::instance()->set_tip (&bypass_button, _("Click to enable/disable this plugin"), "");
|
||||
|
||||
plugin_eq_bin.set_expanded(true);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -458,6 +466,43 @@ PlugUIBase::focus_toggled (GdkEventButton* ev)
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PlugUIBase::toggle_plugin_analysis()
|
||||
{
|
||||
if (eqgui_toggle.get_active() && !plugin_eq_bin.get_child()) {
|
||||
// Create the GUI
|
||||
PluginEqGui *foo = new PluginEqGui(insert);
|
||||
plugin_eq_bin.add( *foo );
|
||||
plugin_eq_bin.show_all();
|
||||
}
|
||||
|
||||
Gtk::Widget *gui;
|
||||
|
||||
if (!eqgui_toggle.get_active() && (gui = plugin_eq_bin.get_child())) {
|
||||
// Hide & remove
|
||||
gui->hide();
|
||||
//plugin_eq_bin.remove(*gui);
|
||||
plugin_eq_bin.remove();
|
||||
|
||||
delete gui;
|
||||
|
||||
Gtk::Widget *toplevel = plugin_eq_bin.get_toplevel();
|
||||
if (!toplevel) {
|
||||
std::cerr << "No toplevel widget?!?!" << std::endl;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PlugUIBase::update_presets ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -93,6 +93,9 @@ class PlugUIBase : public virtual sigc::trackable
|
|||
|
||||
LatencyGUI latency_gui;
|
||||
|
||||
Gtk::Expander plugin_eq_bin;
|
||||
Gtk::ToggleButton eqgui_toggle;
|
||||
|
||||
Gtk::Image* focus_out_image;
|
||||
Gtk::Image* focus_in_image;
|
||||
|
||||
|
|
@ -100,6 +103,7 @@ class PlugUIBase : public virtual sigc::trackable
|
|||
void save_plugin_setting (void);
|
||||
bool focus_toggled(GdkEventButton*);
|
||||
void bypass_toggled();
|
||||
void toggle_plugin_analysis ();
|
||||
void processor_active_changed (boost::weak_ptr<ARDOUR::Processor> p);
|
||||
};
|
||||
|
||||
|
|
@ -124,8 +128,6 @@ class GenericPluginUI : public PlugUIBase, public Gtk::HPaned
|
|||
Gtk::Table button_table;
|
||||
Gtk::Table output_table;
|
||||
|
||||
Gtk::ToggleButton eqgui_toggle;
|
||||
|
||||
Gtk::ScrolledWindow scroller;
|
||||
Gtk::Adjustment hAdjustment;
|
||||
Gtk::Adjustment vAdjustment;
|
||||
|
|
@ -212,8 +214,6 @@ class GenericPluginUI : public PlugUIBase, public Gtk::HPaned
|
|||
void start_touch (ControlUI*);
|
||||
void stop_touch (ControlUI*);
|
||||
|
||||
void toggle_plugin_analysis ();
|
||||
|
||||
void print_parameter (char *buf, uint32_t len, uint32_t param);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -40,11 +40,14 @@ VSTPluginUI::VSTPluginUI (boost::shared_ptr<PluginInsert> pi, boost::shared_ptr<
|
|||
preset_box.pack_end (bypass_button, false, false, 10);
|
||||
preset_box.pack_end (save_button, false, false);
|
||||
preset_box.pack_end (preset_combo, false, false);
|
||||
preset_box.pack_end (eqgui_toggle, false, false);
|
||||
|
||||
|
||||
bypass_button.set_active (!insert->active());
|
||||
|
||||
pack_start (preset_box, false, false);
|
||||
pack_start (socket, true, true);
|
||||
pack_start (plugin_eq_bin, true, true);
|
||||
}
|
||||
|
||||
VSTPluginUI::~VSTPluginUI ()
|
||||
|
|
|
|||
|
|
@ -111,8 +111,8 @@ class PluginInsert : public Processor
|
|||
_signal_analysis_input_bufferset.ensure_buffers(input_streams(), nframes);
|
||||
_signal_analysis_output_bufferset.ensure_buffers(output_streams(), nframes);
|
||||
|
||||
_signal_analysis_collect_nframes_max = nframes;
|
||||
_signal_analysis_collected_nframes = 0;
|
||||
_signal_analysis_collect_nframes_max = nframes;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue