diff options
-rw-r--r-- | gtk2_ardour/ardour3_ui_default.conf | 2 | ||||
-rw-r--r-- | gtk2_ardour/audio_region_view.cc | 69 | ||||
-rw-r--r-- | gtk2_ardour/audio_region_view.h | 1 | ||||
-rw-r--r-- | gtk2_ardour/theme_manager.cc | 11 | ||||
-rw-r--r-- | gtk2_ardour/theme_manager.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/ui_config_vars.h | 1 | ||||
-rw-r--r-- | libs/canvas/canvas/wave_view.h | 2 | ||||
-rw-r--r-- | libs/canvas/wave_view.cc | 82 |
8 files changed, 105 insertions, 65 deletions
diff --git a/gtk2_ardour/ardour3_ui_default.conf b/gtk2_ardour/ardour3_ui_default.conf index e6c4367e80..88970cbbd7 100644 --- a/gtk2_ardour/ardour3_ui_default.conf +++ b/gtk2_ardour/ardour3_ui_default.conf @@ -141,7 +141,7 @@ <Option name="video timeline bar" value="303030ff"/> <Option name="region base" value="99a7b5a0"/> <Option name="region area covered by another region" value="505050b0"/> - <Option name="waveform fill" value="3d4753dc"/> + <Option name="waveform fill" value="ffffffff"/> <Option name="clipped waveform" value="ff0000e5"/> <Option name="waveform fill" value="bde7b9dc"/> <Option name="zero line" value="b5b5b525"/> diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc index 71f9466b00..0159022f87 100644 --- a/gtk2_ardour/audio_region_view.cc +++ b/gtk2_ardour/audio_region_view.cc @@ -233,7 +233,6 @@ AudioRegionView::init (Gdk::Color const & basic_color, bool wfd) setup_waveform_visibility (); setup_waveform_shape (); - setup_waveform_scale (); if (frame_handle_start) { frame_handle_start->raise_to_top (); @@ -1323,6 +1322,12 @@ AudioRegionView::setup_waveform_scale () WaveView::set_global_logscaled (Config->get_waveform_scale() == Logarithmic); } +void +AudioRegionView::setup_waveform_clipping () +{ + WaveView::set_global_show_waveform_clipping (ARDOUR_UI::config()->get_show_waveform_clipping()); +} + GhostRegion* AudioRegionView::add_ghost (TimeAxisView& tv) { @@ -1433,46 +1438,38 @@ AudioRegionView::set_one_waveform_color (ArdourCanvas::WaveView* wave) { ArdourCanvas::Color fill; ArdourCanvas::Color outline; + + if (_selected) { + if (_region->muted()) { + outline = UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->get_canvasvar_SelectedWaveForm(), MUTED_ALPHA); + } else { + outline = ARDOUR_UI::config()->get_canvasvar_SelectedWaveForm(); + } + fill = ARDOUR_UI::config()->get_canvasvar_SelectedWaveFormFill(); + } else { + if (_recregion) { + outline = ARDOUR_UI::config()->get_canvasvar_RecWaveForm(); + fill = ARDOUR_UI::config()->get_canvasvar_RecWaveFormFill(); + } else { + if (_region->muted()) { + outline = UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->get_canvasvar_WaveForm(), MUTED_ALPHA); + } else { + outline = ARDOUR_UI::config()->get_canvasvar_WaveForm(); + } + fill = ARDOUR_UI::config()->get_canvasvar_WaveFormFill(); + } + } if (ARDOUR_UI::config()->get_color_regions_using_track_color()) { - /* wave color is a saturated, whiter version of the frame's - * fill color + /* just use a slightly transparent version of the selected + * color so that some of the track color bleeds through */ - ArdourCanvas::Color c = frame->fill_color (); - double h, s, v; - ArdourCanvas::color_to_hsv (c, h, s, v); - - /* full saturate */ - s = 0.45; - /* head towards white */ - v = 0.97; + double r, g, b, a; + ArdourCanvas::color_to_rgba (fill, r, g, b, a); + fill = ArdourCanvas::rgba_to_color (r, g, b, 0.85); /* magic number, not user controllable */ - fill = ArdourCanvas::hsv_to_color (h, s, v, _region->muted() ? MUTED_ALPHA : 1.0); - - } else { - - if (_selected) { - if (_region->muted()) { - outline = UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->get_canvasvar_SelectedWaveForm(), MUTED_ALPHA); - } else { - outline = ARDOUR_UI::config()->get_canvasvar_SelectedWaveForm(); - } - fill = ARDOUR_UI::config()->get_canvasvar_SelectedWaveFormFill(); - } else { - if (_recregion) { - outline = ARDOUR_UI::config()->get_canvasvar_RecWaveForm(); - fill = ARDOUR_UI::config()->get_canvasvar_RecWaveFormFill(); - } else { - if (_region->muted()) { - outline = UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->get_canvasvar_WaveForm(), MUTED_ALPHA); - } else { - outline = ARDOUR_UI::config()->get_canvasvar_WaveForm(); - } - fill = ARDOUR_UI::config()->get_canvasvar_WaveFormFill(); - } - } } wave->set_fill_color (fill); @@ -1688,5 +1685,7 @@ AudioRegionView::parameter_changed (string const & p) setup_waveform_scale (); } else if (p == "waveform-shape") { setup_waveform_shape (); + } else if (p == "show-waveform-clipping") { + setup_waveform_clipping (); } } diff --git a/gtk2_ardour/audio_region_view.h b/gtk2_ardour/audio_region_view.h index 02de3edbb1..353d0dc937 100644 --- a/gtk2_ardour/audio_region_view.h +++ b/gtk2_ardour/audio_region_view.h @@ -208,6 +208,7 @@ private: void setup_waveform_visibility (); void setup_waveform_shape (); void setup_waveform_scale (); + void setup_waveform_clipping (); /** A ScopedConnection for each PeaksReady callback (one per channel). Each member * may be 0 if no connection exists. diff --git a/gtk2_ardour/theme_manager.cc b/gtk2_ardour/theme_manager.cc index ff37c315cf..3514d918bd 100644 --- a/gtk2_ardour/theme_manager.cc +++ b/gtk2_ardour/theme_manager.cc @@ -60,6 +60,7 @@ ThemeManager::ThemeManager() , reset_button (_("Restore Defaults")) , flat_buttons (_("Draw \"flat\" buttons")) , region_color_button (_("Color regions using their track's color")) + , show_clipping_button (_("Show waveform clipping")) , waveform_gradient_depth (0, 1.0, 0.05) , waveform_gradient_depth_label (_("Waveforms color gradient depth")) , timeline_item_gradient_depth (0, 1.0, 0.05) @@ -104,6 +105,7 @@ ThemeManager::ThemeManager() #endif vbox->pack_start (flat_buttons, PACK_SHRINK); vbox->pack_start (region_color_button, PACK_SHRINK); + vbox->pack_start (show_clipping_button, PACK_SHRINK); Gtk::HBox* hbox = Gtk::manage (new Gtk::HBox()); hbox->set_spacing (6); @@ -133,6 +135,7 @@ ThemeManager::ThemeManager() flat_buttons.set_active (ARDOUR_UI::config()->get_flat_buttons()); region_color_button.set_active (ARDOUR_UI::config()->get_color_regions_using_track_color()); + show_clipping_button.set_active (ARDOUR_UI::config()->get_show_waveform_clipping()); color_dialog.get_ok_button()->signal_clicked().connect (sigc::bind (sigc::mem_fun (color_dialog, &Gtk::Dialog::response), RESPONSE_ACCEPT)); color_dialog.get_cancel_button()->signal_clicked().connect (sigc::bind (sigc::mem_fun (color_dialog, &Gtk::Dialog::response), RESPONSE_CANCEL)); @@ -141,6 +144,7 @@ ThemeManager::ThemeManager() reset_button.signal_clicked().connect (sigc::mem_fun (*this, &ThemeManager::reset_canvas_colors)); flat_buttons.signal_toggled().connect (sigc::mem_fun (*this, &ThemeManager::on_flat_buttons_toggled)); region_color_button.signal_toggled().connect (sigc::mem_fun (*this, &ThemeManager::on_region_color_toggled)); + show_clipping_button.signal_toggled().connect (sigc::mem_fun (*this, &ThemeManager::on_show_clip_toggled)); waveform_gradient_depth.signal_value_changed().connect (sigc::mem_fun (*this, &ThemeManager::on_waveform_gradient_depth_change)); timeline_item_gradient_depth.signal_value_changed().connect (sigc::mem_fun (*this, &ThemeManager::on_timeline_item_gradient_depth_change)); all_dialogs.signal_toggled().connect (sigc::mem_fun (*this, &ThemeManager::on_all_dialogs_toggled)); @@ -293,6 +297,13 @@ ThemeManager::on_region_color_toggled () } void +ThemeManager::on_show_clip_toggled () +{ + ARDOUR_UI::config()->set_show_waveform_clipping (show_clipping_button.get_active()); + ARDOUR_UI::config()->set_dirty (); +} + +void ThemeManager::on_all_dialogs_toggled () { ARDOUR_UI::config()->set_all_floating_windows_are_dialogs (all_dialogs.get_active()); diff --git a/gtk2_ardour/theme_manager.h b/gtk2_ardour/theme_manager.h index c0d6cf8f74..7c8d81fef9 100644 --- a/gtk2_ardour/theme_manager.h +++ b/gtk2_ardour/theme_manager.h @@ -45,6 +45,7 @@ class ThemeManager : public ArdourWindow void on_light_theme_button_toggled (); void on_flat_buttons_toggled (); void on_region_color_toggled (); + void on_show_clip_toggled (); void on_waveform_gradient_depth_change (); void on_timeline_item_gradient_depth_change (); void on_all_dialogs_toggled (); @@ -75,6 +76,7 @@ class ThemeManager : public ArdourWindow Gtk::Button reset_button; Gtk::CheckButton flat_buttons; Gtk::CheckButton region_color_button; + Gtk::CheckButton show_clipping_button; Gtk::HScale waveform_gradient_depth; Gtk::Label waveform_gradient_depth_label; Gtk::HScale timeline_item_gradient_depth; diff --git a/gtk2_ardour/ui_config_vars.h b/gtk2_ardour/ui_config_vars.h index 84f293649f..18bda55457 100644 --- a/gtk2_ardour/ui_config_vars.h +++ b/gtk2_ardour/ui_config_vars.h @@ -23,4 +23,5 @@ UI_CONFIG_VARIABLE(float, waveform_gradient_depth, "waveform-gradient-depth", 0. UI_CONFIG_VARIABLE(float, timeline_item_gradient_depth, "timeline-item-gradient-depth", 1.3) UI_CONFIG_VARIABLE(bool, all_floating_windows_are_dialogs, "all-floating-windows-are-dialogs", false) UI_CONFIG_VARIABLE (bool, color_regions_using_track_color, "color-regions-using-track-color", false) +UI_CONFIG_VARIABLE (bool, show_waveform_clipping, "show-waveform-clipping", true) diff --git a/libs/canvas/canvas/wave_view.h b/libs/canvas/canvas/wave_view.h index 250eeb3b94..fc39d7e555 100644 --- a/libs/canvas/canvas/wave_view.h +++ b/libs/canvas/canvas/wave_view.h @@ -106,6 +106,7 @@ public: static void set_global_gradient_depth (double); static void set_global_logscaled (bool); static void set_global_shape (Shape); + static void set_global_show_waveform_clipping (bool); static double global_gradient_depth() { return _global_gradient_depth; } static bool global_logscaled() { return _global_logscaled; } @@ -161,6 +162,7 @@ private: static double _global_gradient_depth; static bool _global_logscaled; static Shape _global_shape; + static bool _global_show_waveform_clipping; static PBD::Signal0<void> VisualPropertiesChanged; diff --git a/libs/canvas/wave_view.cc b/libs/canvas/wave_view.cc index ce5c87ccfd..4ea9ff9fd3 100644 --- a/libs/canvas/wave_view.cc +++ b/libs/canvas/wave_view.cc @@ -44,6 +44,7 @@ using namespace ArdourCanvas; double WaveView::_global_gradient_depth = 0.6; bool WaveView::_global_logscaled = false; WaveView::Shape WaveView::_global_shape = WaveView::Normal; +bool WaveView::_global_show_waveform_clipping = true; PBD::Signal0<void> WaveView::VisualPropertiesChanged; @@ -177,7 +178,18 @@ WaveView::draw_image (PeakData* _peaks, int n_peaks) const Cairo::RefPtr<Cairo::Context> context = Cairo::Context::create (_image); boost::scoped_array<LineTips> tips (new LineTips[n_peaks]); - const double clip_level = 1.0; + + /* Clip level nominally set to -0.9dBFS to account for inter-sample + interpolation possibly clipping (value may be too low). + + We adjust by the region's own gain (but note: not by any gain + automation or its gain envelope) so that clip indicators are closer + to providing data about on-disk data. This multiplication is + needed because the data we get from AudioRegion::read_peaks() + has been scaled by scale_amplitude() already. + */ + + const double clip_level = 0.98853 * _region->scale_amplitude(); if (_shape == WaveView::Rectified) { @@ -328,40 +340,43 @@ WaveView::draw_image (PeakData* _peaks, int n_peaks) const * modelled on pyramix, except that we add clipping indicators. */ - context->set_source_rgba (0, 0, 0, 1.0); - - /* the height of the clip-indicator should be at most 7 pixels, - or 5% of the height of the waveview item. - */ - const double clip_height = min (7.0, ceil (_height * 0.05)); - - for (int i = 0; i < n_peaks; ++i) { - context->move_to (i, tips[i].top); - - bool show_top_clip = (_shape == WaveView::Rectified && (tips[i].clip_max || tips[i].clip_min)) || - tips[i].clip_max; - - if (show_top_clip) { - context->set_source_rgba (1.0, 0, 0, 1.0); - context->rel_line_to (0, clip_height); - context->stroke (); - context->set_source_rgba (0.0, 0, 0, 1.0); - } else { - context->rel_line_to (0, 1.0); - context->stroke (); - } - - if (_shape != WaveView::Rectified) { - context->move_to (i, tips[i].bot); - if (tips[i].clip_min) { + if (_global_show_waveform_clipping) { + + context->set_source_rgba (0, 0, 0, 1.0); + + /* the height of the clip-indicator should be at most 7 pixels, + or 5% of the height of the waveview item. + */ + const double clip_height = min (7.0, ceil (_height * 0.05)); + + for (int i = 0; i < n_peaks; ++i) { + context->move_to (i, tips[i].top); + + bool show_top_clip = (_shape == WaveView::Rectified && (tips[i].clip_max || tips[i].clip_min)) || + tips[i].clip_max; + + if (show_top_clip) { context->set_source_rgba (1.0, 0, 0, 1.0); - context->rel_line_to (0, -clip_height); + context->rel_line_to (0, clip_height); context->stroke (); context->set_source_rgba (0.0, 0, 0, 1.0); } else { - context->rel_line_to (0, -1.0); + context->rel_line_to (0, 1.0); context->stroke (); } + + if (_shape != WaveView::Rectified) { + context->move_to (i, tips[i].bot); + if (tips[i].clip_min) { + context->set_source_rgba (1.0, 0, 0, 1.0); + context->rel_line_to (0, -clip_height); + context->stroke (); + context->set_source_rgba (0.0, 0, 0, 1.0); + } else { + context->rel_line_to (0, -1.0); + context->stroke (); + } + } } } @@ -662,3 +677,12 @@ WaveView::set_global_gradient_depth (double depth) VisualPropertiesChanged (); /* EMIT SIGNAL */ } } + +void +WaveView::set_global_show_waveform_clipping (bool yn) +{ + if (_global_show_waveform_clipping != yn) { + _global_show_waveform_clipping = yn; + VisualPropertiesChanged (); /* EMIT SIGNAL */ + } +} |