mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-21 06:06:25 +01:00
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:
parent
aef355525f
commit
156f5e4a42
10 changed files with 89 additions and 15 deletions
|
|
@ -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 ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue