mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 15:25:01 +01:00
Plugin analysis numerics
Show vertical marker-line (freq) and precise numeric data of the transfer function (dB, deg).
This commit is contained in:
parent
5599cdb911
commit
b68b4d10a2
2 changed files with 49 additions and 22 deletions
|
|
@ -63,6 +63,7 @@ PluginEqGui::PluginEqGui(boost::shared_ptr<ARDOUR::PluginInsert> pluginInsert)
|
||||||
, _signal_input_fft(0)
|
, _signal_input_fft(0)
|
||||||
, _signal_output_fft(0)
|
, _signal_output_fft(0)
|
||||||
, _plugin_insert(pluginInsert)
|
, _plugin_insert(pluginInsert)
|
||||||
|
, _pointer_in_area_xpos(-1)
|
||||||
{
|
{
|
||||||
_signal_analysis_running = false;
|
_signal_analysis_running = false;
|
||||||
_samplerate = ARDOUR_UI::instance()->the_session()->sample_rate();
|
_samplerate = ARDOUR_UI::instance()->the_session()->sample_rate();
|
||||||
|
|
@ -84,7 +85,6 @@ PluginEqGui::PluginEqGui(boost::shared_ptr<ARDOUR::PluginInsert> pluginInsert)
|
||||||
_analysis_area->signal_size_allocate().connect( sigc::mem_fun (*this, &PluginEqGui::resize_analysis_area));
|
_analysis_area->signal_size_allocate().connect( sigc::mem_fun (*this, &PluginEqGui::resize_analysis_area));
|
||||||
_analysis_area->signal_motion_notify_event().connect( sigc::mem_fun (*this, &PluginEqGui::analysis_area_mouseover));
|
_analysis_area->signal_motion_notify_event().connect( sigc::mem_fun (*this, &PluginEqGui::analysis_area_mouseover));
|
||||||
_analysis_area->signal_leave_notify_event().connect( sigc::mem_fun (*this, &PluginEqGui::analysis_area_mouseexit));
|
_analysis_area->signal_leave_notify_event().connect( sigc::mem_fun (*this, &PluginEqGui::analysis_area_mouseexit));
|
||||||
_analysis_area->signal_button_press_event().connect( sigc::mem_fun (*this, &PluginEqGui::analysis_area_mousedown));
|
|
||||||
|
|
||||||
// dB selection
|
// dB selection
|
||||||
dBScaleModel = Gtk::ListStore::create(dBColumns);
|
dBScaleModel = Gtk::ListStore::create(dBColumns);
|
||||||
|
|
@ -160,6 +160,12 @@ PluginEqGui::~PluginEqGui()
|
||||||
// all gui objects are *manage'd by the inherited Table object
|
// all gui objects are *manage'd by the inherited Table object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline float
|
||||||
|
power_to_dB(float a)
|
||||||
|
{
|
||||||
|
return 10.0 * log10f(a);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PluginEqGui::start_listening ()
|
PluginEqGui::start_listening ()
|
||||||
{
|
{
|
||||||
|
|
@ -448,10 +454,16 @@ PluginEqGui::run_impulse_analysis()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PluginEqGui::update_pointer_info(float x, float y)
|
PluginEqGui::update_pointer_info(float x)
|
||||||
{
|
{
|
||||||
const int freq = std::max(1, (int) roundf((powf(10, x / _analysis_width * _log_max) - 1) * _samplerate / 2.0 / _log_coeff));
|
/* find the bin corresponding to x (see plot_impulse_amplitude) */
|
||||||
const float dB = _max_dB - y / _analysis_height * ( _max_dB - _min_dB );
|
int i = roundf ((powf (10, _log_max * x / _analysis_width) - 1.0) * _impulse_fft->bins() / _log_coeff);
|
||||||
|
float dB = power_to_dB (_impulse_fft->power_at_bin (i));
|
||||||
|
/* calc freq corresponding to bin */
|
||||||
|
const int freq = std::max (1, (int) roundf((float)i / (float)_impulse_fft->bins() * _samplerate / 2.f));
|
||||||
|
|
||||||
|
_pointer_in_area_freq = round (_analysis_width * log10f(1.0 + (float)i / (float)_impulse_fft->bins() * _log_coeff) / _log_max);
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << std::fixed;
|
ss << std::fixed;
|
||||||
if (freq >= 10000) {
|
if (freq >= 10000) {
|
||||||
|
|
@ -461,15 +473,23 @@ PluginEqGui::update_pointer_info(float x, float y)
|
||||||
} else {
|
} else {
|
||||||
ss << std::setprecision (0) << freq << "Hz";
|
ss << std::setprecision (0) << freq << "Hz";
|
||||||
}
|
}
|
||||||
ss << " " << std::setw(5) << std::setprecision (1) << std::showpos << dB;
|
ss << " " << std::setw(6) << std::setprecision (1) << std::showpos << dB;
|
||||||
ss << std::setw(0) << "dB";
|
ss << std::setw(0) << "dB";
|
||||||
|
|
||||||
|
if (_phase_button->get_active()) {
|
||||||
|
float phase = 180. * _impulse_fft->phase_at_bin (i) / M_PI;
|
||||||
|
ss << " " << std::setw(6) << std::setprecision (1) << std::showpos << phase;
|
||||||
|
ss << std::setw(0) << "\u00B0";
|
||||||
|
}
|
||||||
_pointer_info->set_text(ss.str());
|
_pointer_info->set_text(ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PluginEqGui::analysis_area_mouseover(GdkEventMotion *event)
|
PluginEqGui::analysis_area_mouseover(GdkEventMotion *event)
|
||||||
{
|
{
|
||||||
update_pointer_info(event->x, event->y);
|
update_pointer_info(event->x);
|
||||||
|
_pointer_in_area_xpos = event->x;
|
||||||
|
_analysis_area->queue_draw();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -477,17 +497,11 @@ bool
|
||||||
PluginEqGui::analysis_area_mouseexit(GdkEventCrossing *)
|
PluginEqGui::analysis_area_mouseexit(GdkEventCrossing *)
|
||||||
{
|
{
|
||||||
_pointer_info->set_text("");
|
_pointer_info->set_text("");
|
||||||
|
_pointer_in_area_xpos = -1;
|
||||||
|
_analysis_area->queue_draw();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
PluginEqGui::analysis_area_mousedown(GdkEventButton *event)
|
|
||||||
{
|
|
||||||
update_pointer_info(event->x, event->y);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PluginEqGui::expose_analysis_area(GdkEventExpose *)
|
PluginEqGui::expose_analysis_area(GdkEventExpose *)
|
||||||
{
|
{
|
||||||
|
|
@ -535,15 +549,33 @@ PluginEqGui::redraw_analysis_area()
|
||||||
cairo_set_source_surface(cr, _analysis_scale_surface, 0.0, 0.0);
|
cairo_set_source_surface(cr, _analysis_scale_surface, 0.0, 0.0);
|
||||||
cairo_paint(cr);
|
cairo_paint(cr);
|
||||||
|
|
||||||
|
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
|
||||||
|
|
||||||
if (_phase_button->get_active()) {
|
if (_phase_button->get_active()) {
|
||||||
plot_impulse_phase(_analysis_area, cr);
|
plot_impulse_phase(_analysis_area, cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
plot_impulse_amplitude(_analysis_area, cr);
|
plot_impulse_amplitude(_analysis_area, cr);
|
||||||
|
|
||||||
|
if (_pointer_in_area_xpos >= 0) {
|
||||||
|
update_pointer_info (_pointer_in_area_xpos);
|
||||||
|
}
|
||||||
|
|
||||||
if (_signal_button->get_active()) {
|
if (_signal_button->get_active()) {
|
||||||
plot_signal_amplitude_difference(_analysis_area, cr);
|
plot_signal_amplitude_difference(_analysis_area, cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_pointer_in_area_xpos >= 0 && _pointer_in_area_freq > 0) {
|
||||||
|
const double dashed[] = {0.0, 2.0};
|
||||||
|
cairo_set_dash (cr, dashed, 2, 0);
|
||||||
|
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
|
||||||
|
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
|
||||||
|
cairo_set_line_width (cr, 1.0);
|
||||||
|
cairo_move_to (cr, _pointer_in_area_freq - .5, -.5);
|
||||||
|
cairo_line_to (cr, _pointer_in_area_freq - .5, _analysis_height - .5);
|
||||||
|
cairo_stroke(cr);
|
||||||
|
}
|
||||||
|
|
||||||
cairo_destroy(cr);
|
cairo_destroy(cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -747,12 +779,6 @@ PluginEqGui::draw_scales_power(Gtk::Widget */*w*/, cairo_t *cr)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float
|
|
||||||
power_to_dB(float a)
|
|
||||||
{
|
|
||||||
return 10.0 * log10f(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PluginEqGui::plot_impulse_amplitude(Gtk::Widget *w, cairo_t *cr)
|
PluginEqGui::plot_impulse_amplitude(Gtk::Widget *w, cairo_t *cr)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -79,10 +79,9 @@ private:
|
||||||
|
|
||||||
void plot_signal_amplitude_difference (Gtk::Widget *,cairo_t *);
|
void plot_signal_amplitude_difference (Gtk::Widget *,cairo_t *);
|
||||||
|
|
||||||
void update_pointer_info(float, float);
|
void update_pointer_info(float);
|
||||||
bool analysis_area_mouseover(GdkEventMotion *);
|
bool analysis_area_mouseover(GdkEventMotion *);
|
||||||
bool analysis_area_mouseexit(GdkEventCrossing *);
|
bool analysis_area_mouseexit(GdkEventCrossing *);
|
||||||
bool analysis_area_mousedown(GdkEventButton *);
|
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
bool timeout_callback ();
|
bool timeout_callback ();
|
||||||
|
|
@ -123,6 +122,8 @@ private:
|
||||||
Gtk::DrawingArea *_analysis_area;
|
Gtk::DrawingArea *_analysis_area;
|
||||||
cairo_surface_t *_analysis_scale_surface;
|
cairo_surface_t *_analysis_scale_surface;
|
||||||
Gtk::Label *_pointer_info;
|
Gtk::Label *_pointer_info;
|
||||||
|
int _pointer_in_area_xpos;
|
||||||
|
int _pointer_in_area_freq;
|
||||||
|
|
||||||
// dB scale selection:
|
// dB scale selection:
|
||||||
class dBSelectionColumns : public Gtk::TreeModel::ColumnRecord
|
class dBSelectionColumns : public Gtk::TreeModel::ColumnRecord
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue