changes to waveform clipping display
* clip level is now -0.9dbFS * display of clipping is optional (see Theme Manager window) * clipping is based on disk data, unscaled by region gain
This commit is contained in:
@@ -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"/>
|
||||
|
||||
@@ -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);
|
||||
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 */
|
||||
|
||||
/* full saturate */
|
||||
s = 0.45;
|
||||
/* head towards white */
|
||||
v = 0.97;
|
||||
|
||||
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 ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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));
|
||||
@@ -292,6 +296,13 @@ ThemeManager::on_region_color_toggled ()
|
||||
ARDOUR_UI::config()->set_dirty ();
|
||||
}
|
||||
|
||||
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 ()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user