Only compute and render the visible portion of crossfades. Fixes #3498.

git-svn-id: svn://localhost/ardour2/branches/3.0@7901 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Carl Hetherington 2010-10-17 23:35:05 +00:00
parent aef355525f
commit 156f5e4a42
10 changed files with 89 additions and 15 deletions

View file

@ -826,3 +826,14 @@ AudioStreamView::parameter_changed (string const & p)
set_waveform_shape (Config->get_waveform_shape ());
}
}
void
AudioStreamView::horizontal_position_changed ()
{
/* we only `draw' the bit of the curve that is visible, so we need to update here */
for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
i->second->horizontal_position_changed ();
}
}

View file

@ -57,6 +57,7 @@ class AudioStreamView : public StreamView
~AudioStreamView ();
int set_samples_per_unit (gdouble spp);
void horizontal_position_changed ();
int set_amplitude_above_axis (gdouble app);
gdouble get_amplitude_above_axis () { return _amplitude_above_axis; }

View file

@ -55,7 +55,8 @@ CrossfadeView::CrossfadeView (ArdourCanvas::Group *parent,
xf->length(), false, false, TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowFrame)),
crossfade (xf),
left_view (lview),
right_view (rview)
right_view (rview),
_all_in_view (false)
{
_valid = true;
_visible = true;
@ -144,13 +145,12 @@ CrossfadeView::crossfade_changed (const PropertyChange& what_changed)
}
}
/** Set up our fade_in and fade_out curves to contain points for the currently visible portion
* of the crossfade.
*/
void
CrossfadeView::redraw_curves ()
{
Points* points;
int32_t npoints;
float* vec;
if (!crossfade->following_overlap()) {
/* curves should not be visible */
fade_in->hide ();
@ -163,8 +163,21 @@ CrossfadeView::redraw_curves ()
return;
}
npoints = get_time_axis_view().editor().frame_to_pixel (crossfade->length());
// npoints = std::min (gdk_screen_width(), npoints);
PublicEditor& editor = get_time_axis_view().editor ();
framepos_t const editor_left = editor.leftmost_position ();
framepos_t const editor_right = editor_left + editor.current_page_frames ();
framepos_t const xfade_left = crossfade->position ();
framepos_t const xfade_right = xfade_left + crossfade->length ();
/* Work out the range of our frames that are visible */
framepos_t const min_frames = std::max (editor_left, xfade_left);
framepos_t const max_frames = std::min (editor_right, xfade_right);
_all_in_view = (editor_left <= xfade_left && editor_right >= xfade_right);
/* Hence the number of points that we will render */
int32_t const npoints = editor.frame_to_pixel (max_frames - min_frames);
if (!_visible || !crossfade->active() || npoints < 3) {
fade_in->hide();
@ -175,24 +188,30 @@ CrossfadeView::redraw_curves ()
fade_out->show();
}
points = get_canvas_points ("xfade edit redraw", npoints);
vec = new float[npoints];
Points* points = get_canvas_points ("xfade edit redraw", npoints);
float* vec = new float[npoints];
crossfade->fade_in().curve().get_vector (0, crossfade->length(), vec, npoints);
crossfade->fade_in().curve().get_vector (min_frames - crossfade->position(), max_frames - crossfade->position(), vec, npoints);
/* Work out the offset from the start of the crossfade to the visible part, in pixels */
double xoff = 0;
if (crossfade->position() < editor.leftmost_position()) {
xoff = editor.frame_to_pixel (min_frames) - editor.frame_to_pixel (crossfade->position ());
}
for (int i = 0, pci = 0; i < npoints; ++i) {
Art::Point &p = (*points)[pci++];
p.set_x (i + 1);
p.set_x (xoff + i + 1);
p.set_y (_height - ((_height - 2) * vec[i]));
}
fade_in->property_points() = *points;
crossfade->fade_out().curve().get_vector (0, crossfade->length(), vec, npoints);
crossfade->fade_out().curve().get_vector (min_frames - crossfade->position(), max_frames - crossfade->position(), vec, npoints);
for (int i = 0, pci = 0; i < npoints; ++i) {
Art::Point &p = (*points)[pci++];
p.set_x (i + 1);
p.set_x (xoff + i + 1);
p.set_y (_height - ((_height - 2) * vec[i]));
}
@ -269,3 +288,17 @@ CrossfadeView::crossfade_fades_changed ()
{
redraw_curves ();
}
void
CrossfadeView::horizontal_position_changed ()
{
/* If the crossfade curves are entirely within the editor's visible space, there is
no need to redraw them here as they will be completely drawn (as distinct from
the other case where the horizontal position change will uncover `undrawn'
sections).
*/
if (!_all_in_view) {
redraw_curves ();
}
}

View file

@ -59,6 +59,7 @@ struct CrossfadeView : public TimeAxisViewItem
void fake_hide ();
void hide ();
void show ();
void horizontal_position_changed ();
protected:
void reset_width_dependent_items (double pixel_width);
@ -66,6 +67,7 @@ struct CrossfadeView : public TimeAxisViewItem
private:
bool _valid;
bool _visible;
bool _all_in_view;
ArdourCanvas::Line *fade_in;
ArdourCanvas::Line *fade_out;

View file

@ -4691,7 +4691,19 @@ Editor::idle_visual_changer ()
VisualChange::Type p = pending_visual_change.pending;
pending_visual_change.pending = (VisualChange::Type) 0;
double last_time_origin = horizontal_position ();
double const last_time_origin = horizontal_position ();
if (p & VisualChange::TimeOrigin) {
/* This is a bit of a hack, but set_frames_per_unit
below will (if called) end up with the
CrossfadeViews looking at Editor::leftmost_frame,
and if we're changing origin and zoom in the same
operation it will be the wrong value unless we
update it here.
*/
leftmost_frame = pending_visual_change.time_origin;
}
if (p & VisualChange::ZoomLevel) {
set_frames_per_unit (pending_visual_change.frames_per_unit);

View file

@ -792,6 +792,8 @@ Editor::set_horizontal_position (double p)
_summary->set_overlays_dirty ();
}
HorizontalPositionChanged (); /* EMIT SIGNAL */
#ifndef GTKOSX
if (!autoscroll_active && !_stationary_playhead) {
/* force rulers and canvas to move in lock step */

View file

@ -284,6 +284,8 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible {
sigc::signal<void> ZoomFocusChanged;
sigc::signal<void> ZoomChanged;
/** Emitted when the horizontal position of the editor view changes */
sigc::signal<void> HorizontalPositionChanged;
sigc::signal<void> Resized;
sigc::signal<void> Realized;
sigc::signal<void,framepos_t> UpdateAllTransportClocks;

View file

@ -225,6 +225,7 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session* sess, boost::sh
}
_editor.ZoomChanged.connect (sigc::mem_fun(*this, &RouteTimeAxisView::reset_samples_per_unit));
_editor.HorizontalPositionChanged.connect (sigc::mem_fun (*this, &RouteTimeAxisView::horizontal_position_changed));
ColorsChanged.connect (sigc::mem_fun (*this, &RouteTimeAxisView::color_handler));
PropertyList* plist = new PropertyList();
@ -871,6 +872,14 @@ RouteTimeAxisView::reset_samples_per_unit ()
set_samples_per_unit (_editor.get_current_zoom());
}
void
RouteTimeAxisView::horizontal_position_changed ()
{
if (_view) {
_view->horizontal_position_changed ();
}
}
void
RouteTimeAxisView::set_samples_per_unit (double spu)
{

View file

@ -210,6 +210,7 @@ protected:
void set_route_group_from_menu (ARDOUR::RouteGroup *);
void reset_samples_per_unit ();
void horizontal_position_changed ();
void select_track_color();

View file

@ -72,6 +72,7 @@ public:
virtual int set_samples_per_unit (gdouble spp);
gdouble get_samples_per_unit () { return _samples_per_unit; }
virtual void horizontal_position_changed () {}
void set_layer_display (LayerDisplay);
LayerDisplay layer_display () const { return _layer_display; }