27 #define ISINF(val) !((bool)_finite((double)val))
28 #define ISNAN(val) (bool)_isnan((double)val)
30 #define ISINF(val) std::isinf((val))
31 #define ISNAN(val) std::isnan((val))
34 #include <gtkmm/box.h>
35 #include <gtkmm/button.h>
36 #include <gtkmm/checkbutton.h>
57 , _signal_input_fft(0)
58 , _signal_output_fft(0)
59 , _plugin_insert(pluginInsert)
87 #define ADD_DB_ROW(MIN,MAX,STEP,NAME) \
89 Gtk::TreeModel::Row row = *(dBScaleModel->append()); \
90 row[dBColumns.dBMin] = (MIN); \
91 row[dBColumns.dBMax] = (MAX); \
92 row[dBColumns.dBStep] = (STEP); \
93 row[dBColumns.name] = NAME; \
109 Gtk::Label *dBComboLabel =
new Gtk::Label (
_(
"dB scale"));
111 Gtk::HBox *dBSelectBin =
new Gtk::HBox(
false, 5);
112 dBSelectBin->add( *manage(dBComboLabel));
122 attach( *manage(dBSelectBin), 1, 2, 2, 3, Gtk::SHRINK, Gtk::SHRINK);
123 attach( *manage(
_phase_button), 2, 3, 2, 3, Gtk::SHRINK, Gtk::SHRINK);
168 Gtk::Table::on_hide();
190 Gtk::Table::on_show();
194 Gtk::Widget *toplevel = get_toplevel();
209 Gtk::TreeModel::iterator iter =
dBScaleCombo -> get_active();
211 Gtk::TreeModel::Row row;
213 if(iter && (row = *iter)) {
337 for (uint32_t i = 0; i < inputs; ++i) {
355 for (uint32_t i = 0; i < outputs; ++i) {
363 for (uint32_t i = 0; i < outputs; ++i) {
386 for (uint32_t i = 0; i < outputs; ++i) {
389 length *
sizeof(float));
396 if (frames_left > 0) {
398 for (uint32_t i = 0; i < inputs; ++i) {
408 }
while ( frames_left > 0);
413 for (uint32_t i = 0; i < outputs; ++i) {
444 cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
463 cr = gdk_cairo_create(GDK_DRAWABLE(
_analysis_area->get_window()->gobj()));
488 #define PHASE_PROPORTION 0.5
494 cairo_font_extents_t extents;
495 cairo_font_extents(cr, &extents);
498 cairo_text_extents_t t_ext;
500 for (uint32_t i = 0; i < 3; i++) {
504 cairo_set_source_rgb(cr, .8, .9, 0.2);
506 snprintf(buf,256,
"0\u00b0");
508 snprintf(buf,256,
"%d\u00b0", (i * 45));
510 cairo_text_extents(cr, buf, &t_ext);
511 cairo_move_to(cr,
_analysis_width - t_ext.width - t_ext.x_bearing - 2.0, y - extents.descent);
512 cairo_show_text(cr, buf);
518 cairo_set_source_rgba(cr, .8, .9, 0.2, 0.6/(
float)i);
519 cairo_move_to(cr, 0.0, y);
526 snprintf(buf,256,
"-%d\u00b0", (i * 45));
527 cairo_set_source_rgb(cr, .8, .9, 0.2);
528 cairo_text_extents(cr, buf, &t_ext);
529 cairo_move_to(cr,
_analysis_width - t_ext.width - t_ext.x_bearing - 2.0, y - extents.descent);
530 cairo_show_text(cr, buf);
533 cairo_set_source_rgba(cr, .8, .9, 0.2, 0.6/(
float)i);
534 cairo_move_to(cr, 0.0, y);
537 cairo_set_line_width (cr, 0.25 + 1.0/(
float)(i+1));
552 float height = w->get_height();
554 cairo_set_source_rgba(cr, 0.95, 0.3, 0.2, 1.0);
563 cairo_move_to(cr, x, y);
568 avgY = avgY/(float)avgNum;
569 if (avgY > (height * 10.0) ) avgY = height * 10.0;
570 if (avgY < (-height * 10.0) ) avgY = -height * 10.0;
571 cairo_line_to(cr, prevX, avgY);
584 cairo_set_line_width (cr, 2.0);
595 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 };
599 cairo_set_line_width (cr, 1.5);
600 cairo_set_font_size(cr, 9);
602 cairo_font_extents_t extents;
603 cairo_font_extents(cr, &extents);
608 for (uint32_t i = 0; scales[i] != -1.0; ++i) {
609 float bin = scales[i] / divisor;
614 if (scales[i] < 1000.0) {
615 snprintf(buf, 256,
"%0.0f", scales[i]);
617 snprintf(buf, 256,
"%0.0fk", scales[i]/1000.0);
620 cairo_set_source_rgb(cr, 0.4, 0.4, 0.4);
623 cairo_move_to(cr, x - extents.height, 3.0);
625 cairo_rotate(cr, M_PI / 2.0);
626 cairo_show_text(cr, buf);
627 cairo_rotate(cr, -M_PI / 2.0);
630 cairo_set_source_rgb(cr, 0.3, 0.3, 0.3);
632 cairo_line_to(cr, x, 0.0);
639 double dashes[] = { 3.0, 5.0 };
642 snprintf(buf, 256,
"+%0.0f", dB );
644 y = ( _max_dB - dB) / ( _max_dB -
_min_dB );
649 cairo_set_source_rgb(cr, 0.4, 0.4, 0.4);
650 cairo_move_to(cr, 1.0, y + extents.height + 1.0);
651 cairo_show_text(cr, buf);
655 cairo_set_source_rgb(cr, 0.2, 0.2, 0.2);
656 cairo_move_to(cr, 0, y);
661 cairo_set_dash(cr, dashes, 2, 0.0);
668 snprintf(buf, 256,
"%0.0f", dB );
670 y = ( _max_dB - dB) / ( _max_dB - _min_dB );
673 cairo_set_source_rgb(cr, 0.4, 0.4, 0.4);
674 cairo_move_to(cr, 1.0, y - extents.descent - 1.0);
675 cairo_show_text(cr, buf);
678 cairo_set_source_rgb(cr, 0.2, 0.2, 0.2);
679 cairo_move_to(cr, 0, y);
684 cairo_set_dash(cr, 0, 0, 0.0);
691 return 10.0 * log10f(a);
703 float height = w->get_height();
705 cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
706 cairo_set_line_width (cr, 2.5);
718 cairo_move_to(cr, x, y);
723 avgY = avgY/(float)avgNum;
724 if (avgY > (height * 10.0) ) avgY = height * 10.0;
725 if (avgY < (-height * 10.0) ) avgY = -height * 10.0;
726 cairo_line_to(cr, prevX, avgY);
752 float height = w->get_height();
754 cairo_set_source_rgb(cr, 0.0, 1.0, 0.0);
755 cairo_set_line_width (cr, 2.5);
764 float power = power_out - power_in;
784 }
else if (
ISNAN(power)) {
793 cairo_move_to(cr, x, y);
798 avgY = avgY/(float)avgNum;
799 if (avgY > (height * 10.0) ) avgY = height * 10.0;
800 if (avgY < (-height * 10.0) ) avgY = -height * 10.0;
801 cairo_line_to(cr, prevX, avgY);
ARDOUR::framecnt_t _signal_buffer_size
void run_impulse_analysis()
ARDOUR::BufferSet _bufferset
float phase_at_bin(uint32_t i) const
void ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capacity)
void resize_analysis_area(Gtk::Allocation &)
boost::shared_ptr< ARDOUR::Plugin > _plugin
Glib::RefPtr< Gtk::ListStore > dBScaleModel
float _signal_analysis_running
void set_count(const ChanCount &count)
PluginEqGui(boost::shared_ptr< ARDOUR::PluginInsert >)
static ARDOUR_UI * instance()
Gtk::TreeModelColumn< float > dBMax
float power_at_bin(uint32_t i) const
ARDOUR::framecnt_t _buffer_size
framecnt_t frame_rate() const
AudioBuffer & get_audio(size_t i)
#define ENSURE_GUI_THREAD(obj, method,...)
virtual framecnt_t signal_latency() const =0
virtual int connect_and_run(BufferSet &bufs, ChanMapping in, ChanMapping out, pframes_t nframes, framecnt_t offset)
void redraw_analysis_area()
cairo_surface_t * _analysis_scale_surface
void plot_signal_amplitude_difference(Gtk::Widget *, cairo_t *)
sigc::connection _window_unmap_connection
void draw_scales_phase(Gtk::Widget *, cairo_t *)
GTKArdour::FFT * _impulse_fft
void draw_scales_power(Gtk::Widget *, cairo_t *)
ChanCount output_streams() const
ARDOUR::Session * the_session()
sigc::connection _update_connection
Gtk::TreeModelColumn< float > dBStep
ChanCount input_streams() const
Gtk::CheckButton * _phase_button
sigc::connection _window_map_connection
void set_buffer_size(uint32_t, uint32_t)
static ChanCount max(const ChanCount &a, const ChanCount &b)
#define ADD_DB_ROW(MIN, MAX, STEP, NAME)
Gtk::ComboBox * dBScaleCombo
PluginInfoPtr get_info() const
virtual void activate()=0
void plot_impulse_phase(Gtk::Widget *, cairo_t *)
PBD::Signal2< void, BufferSet *, BufferSet * > AnalysisDataGathered
Gtk::TreeModelColumn< float > dBMin
uint32_t get(DataType t) const
void signal_collect_callback(ARDOUR::BufferSet *, ARDOUR::BufferSet *)
void plot_impulse_amplitude(Gtk::Widget *, cairo_t *)
boost::shared_ptr< ARDOUR::PluginInsert > _plugin_insert
virtual void deactivate()=0
Gtk::TreeModelColumn< std::string > name
void analyze(ARDOUR::Sample *, WindowingType w=NONE)
Gtk::DrawingArea * _analysis_area
GTKArdour::FFT * _signal_output_fft
PBD::ScopedConnection analysis_connection
const Sample * data(framecnt_t offset=0) const
ARDOUR::BufferSet _collect_bufferset
void drop_process_buffers()
void draw_analysis_scales(cairo_t *)
bool expose_analysis_area(GdkEventExpose *)
dBSelectionColumns dBColumns
float power_to_dB(float a)
void get_process_buffers()
boost::shared_ptr< Plugin > get_impulse_analysis_plugin()
LIBARDOUR_API PBD::PropertyDescriptor< framecnt_t > length
GTKArdour::FFT * _signal_input_fft