fix xfade logic and use shared_ptr for xfades

git-svn-id: svn://localhost/ardour2/trunk@1297 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2007-01-10 16:19:13 +00:00
parent c9fd6da8b1
commit 1c167454eb
15 changed files with 343 additions and 326 deletions

View File

@ -1,3 +1,3 @@
#!/bin/sh
. `dirname "$0"`/ardev_common.sh
exec $EXECUTABLE "$*"
exec $EXECUTABLE $*

View File

@ -224,7 +224,7 @@ AudioStreamView::remove_region_view (boost::weak_ptr<Region> weak_r)
++tmp;
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r);
if (ar && (*i)->crossfade.involves (ar)) {
if (ar && (*i)->crossfade->involves (ar)) {
delete *i;
crossfade_views.erase (i);
}
@ -276,17 +276,17 @@ AudioStreamView::playlist_changed (boost::shared_ptr<Diskstream> ds)
}
void
AudioStreamView::add_crossfade (Crossfade *crossfade)
AudioStreamView::add_crossfade (boost::shared_ptr<Crossfade> crossfade)
{
AudioRegionView* lview = 0;
AudioRegionView* rview = 0;
ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::add_crossfade), crossfade));
/* first see if we already have a CrossfadeView for this Crossfade */
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
if ((*i)->crossfade == *crossfade) {
if ((*i)->crossfade == crossfade) {
if (!crossfades_visible) {
(*i)->hide();
} else {
@ -312,7 +312,7 @@ AudioStreamView::add_crossfade (Crossfade *crossfade)
CrossfadeView *cv = new CrossfadeView (_trackview.canvas_display,
_trackview,
*crossfade,
crossfade,
_samples_per_unit,
region_color,
*lview, *rview);
@ -326,12 +326,12 @@ AudioStreamView::add_crossfade (Crossfade *crossfade)
}
void
AudioStreamView::remove_crossfade (Crossfade *xfade)
AudioStreamView::remove_crossfade (boost::shared_ptr<Crossfade> xfade)
{
ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::remove_crossfade), xfade));
for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
if (&(*i)->crossfade == xfade) {
if ((*i)->crossfade == xfade) {
delete *i;
crossfade_views.erase (i);
break;
@ -715,7 +715,7 @@ void
AudioStreamView::hide_xfades_involving (AudioRegionView& rv)
{
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
if ((*i)->crossfade.involves (rv.audio_region())) {
if ((*i)->crossfade->involves (rv.audio_region())) {
(*i)->fake_hide ();
}
}
@ -725,7 +725,7 @@ void
AudioStreamView::reveal_xfades_involving (AudioRegionView& rv)
{
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
if ((*i)->crossfade.involves (rv.audio_region()) && (*i)->visible()) {
if ((*i)->crossfade->involves (rv.audio_region()) && (*i)->visible()) {
(*i)->show ();
}
}

View File

@ -93,8 +93,8 @@ class AudioStreamView : public StreamView
void playlist_modified ();
void playlist_changed (boost::shared_ptr<ARDOUR::Diskstream>);
void add_crossfade (ARDOUR::Crossfade*);
void remove_crossfade (ARDOUR::Crossfade*);
void add_crossfade (boost::shared_ptr<ARDOUR::Crossfade>);
void remove_crossfade (boost::shared_ptr<ARDOUR::Crossfade>);
void color_handler (ColorID id, uint32_t val);

View File

@ -72,7 +72,7 @@ CrossfadeEditor::Half::Half ()
{
}
CrossfadeEditor::CrossfadeEditor (Session& s, Crossfade& xf, double my, double mxy)
CrossfadeEditor::CrossfadeEditor (Session& s, boost::shared_ptr<Crossfade> xf, double my, double mxy)
: ArdourDialog (_("ardour: x-fade edit")),
xfade (xf),
session (s),
@ -279,14 +279,14 @@ CrossfadeEditor::CrossfadeEditor (Session& s, Crossfade& xf, double my, double m
// vpacker.pack_start (*foobut, false, false);
current = In;
set (xfade.fade_in(), In);
set (xfade->fade_in(), In);
current = Out;
set (xfade.fade_out(), Out);
set (xfade->fade_out(), Out);
curve_select_clicked (In);
xfade.StateChanged.connect (mem_fun(*this, &CrossfadeEditor::xfade_changed));
xfade->StateChanged.connect (mem_fun(*this, &CrossfadeEditor::xfade_changed));
session.AuditionActive.connect (mem_fun(*this, &CrossfadeEditor::audition_state_changed));
show_all_children();
@ -577,21 +577,21 @@ CrossfadeEditor::canvas_allocation (Gtk::Allocation& alloc)
redraw ();
current = old_current;
double spu = xfade.length() / (double) effective_width();
double spu = xfade->length() / (double) effective_width();
if (fade[In].waves.empty()) {
make_waves (xfade.in(), In);
make_waves (xfade->in(), In);
}
if (fade[Out].waves.empty()) {
make_waves (xfade.out(), Out);
make_waves (xfade->out(), Out);
}
double ht;
vector<ArdourCanvas::WaveView*>::iterator i;
uint32_t n;
ht = canvas->get_allocation().get_height() / xfade.in()->n_channels();
ht = canvas->get_allocation().get_height() / xfade->in()->n_channels();
for (n = 0, i = fade[In].waves.begin(); i != fade[In].waves.end(); ++i, ++n) {
double yoff;
@ -603,7 +603,7 @@ CrossfadeEditor::canvas_allocation (Gtk::Allocation& alloc)
(*i)->property_samples_per_unit() = spu;
}
ht = canvas->get_allocation().get_height() / xfade.out()->n_channels();
ht = canvas->get_allocation().get_height() / xfade->out()->n_channels();
for (n = 0, i = fade[Out].waves.begin(); i != fade[Out].waves.end(); ++i, ++n) {
double yoff;
@ -621,8 +621,8 @@ CrossfadeEditor::canvas_allocation (Gtk::Allocation& alloc)
void
CrossfadeEditor::xfade_changed (Change ignored)
{
set (xfade.fade_in(), In);
set (xfade.fade_out(), Out);
set (xfade->fade_in(), In);
set (xfade->fade_out(), Out);
}
void
@ -632,7 +632,7 @@ CrossfadeEditor::redraw ()
return;
}
nframes_t len = xfade.length ();
nframes_t len = xfade->length ();
fade[current].normative_curve.clear ();
fade[current].gain_curve.clear ();
@ -741,11 +741,11 @@ CrossfadeEditor::apply_preset (Preset *preset)
void
CrossfadeEditor::apply ()
{
_apply_to (&xfade);
_apply_to (xfade);
}
void
CrossfadeEditor::_apply_to (Crossfade* xf)
CrossfadeEditor::_apply_to (boost::shared_ptr<Crossfade> xf)
{
ARDOUR::Curve& in (xf->fade_in());
ARDOUR::Curve& out (xf->fade_out());
@ -796,7 +796,7 @@ CrossfadeEditor::_apply_to (Crossfade* xf)
}
void
CrossfadeEditor::setup (Crossfade* xfade)
CrossfadeEditor::setup (boost::shared_ptr<Crossfade> xfade)
{
_apply_to (xfade);
xfade->set_active (true);
@ -819,8 +819,8 @@ CrossfadeEditor::clear ()
void
CrossfadeEditor::reset ()
{
set (xfade.fade_in(), In);
set (xfade.fade_out(), Out);
set (xfade->fade_in(), In);
set (xfade->fade_out(), Out);
}
void
@ -1028,7 +1028,7 @@ CrossfadeEditor::make_waves (boost::shared_ptr<AudioRegion> region, WhichFade wh
}
ht = canvas->get_allocation().get_height() / (double) nchans;
spu = xfade.length() / (double) effective_width();
spu = xfade->length() / (double) effective_width();
for (uint32_t n = 0; n < nchans; ++n) {
@ -1096,25 +1096,25 @@ CrossfadeEditor::audition_both ()
postroll = 0;
}
if ((left_start_offset = xfade.out()->length() - xfade.length()) >= preroll) {
if ((left_start_offset = xfade->out()->length() - xfade->length()) >= preroll) {
left_start_offset -= preroll;
}
length = 0;
if ((left_length = xfade.length()) < xfade.out()->length() - left_start_offset) {
if ((left_length = xfade->length()) < xfade->out()->length() - left_start_offset) {
length += postroll;
}
right_length = xfade.length();
right_length = xfade->length();
if (xfade.in()->length() - right_length < postroll) {
if (xfade->in()->length() - right_length < postroll) {
right_length += postroll;
}
boost::shared_ptr<AudioRegion> left (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade.out(), left_start_offset, left_length, "xfade out",
boost::shared_ptr<AudioRegion> left (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade->out(), left_start_offset, left_length, "xfade out",
0, Region::DefaultFlags, false)));
boost::shared_ptr<AudioRegion> right (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade.in(), 0, right_length, "xfade in",
boost::shared_ptr<AudioRegion> right (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade->in(), 0, right_length, "xfade in",
0, Region::DefaultFlags, false)));
pl.add_region (left, 0);
@ -1130,7 +1130,7 @@ CrossfadeEditor::audition_both ()
void
CrossfadeEditor::audition_left_dry ()
{
boost::shared_ptr<AudioRegion> left (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade.out(), xfade.out()->length() - xfade.length(), xfade.length(), "xfade left",
boost::shared_ptr<AudioRegion> left (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade->out(), xfade->out()->length() - xfade->length(), xfade->length(), "xfade left",
0, Region::DefaultFlags, false)));
session.audition_region (left);
@ -1141,9 +1141,9 @@ CrossfadeEditor::audition_left ()
{
AudioPlaylist& pl (session.the_auditioner()->prepare_playlist());
boost::shared_ptr<AudioRegion> left (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade.out(), xfade.out()->length() - xfade.length(), xfade.length(), "xfade left",
boost::shared_ptr<AudioRegion> left (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade->out(), xfade->out()->length() - xfade->length(), xfade->length(), "xfade left",
0, Region::DefaultFlags, false)));
boost::shared_ptr<AudioRegion> right (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade.in(), 0, xfade.length(), "xfade in",
boost::shared_ptr<AudioRegion> right (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade->in(), 0, xfade->length(), "xfade in",
0, Region::DefaultFlags, false)));
pl.add_region (left, 0);
@ -1163,7 +1163,7 @@ CrossfadeEditor::audition_left ()
void
CrossfadeEditor::audition_right_dry ()
{
boost::shared_ptr<AudioRegion> right (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade.in(), 0, xfade.length(), "xfade in",
boost::shared_ptr<AudioRegion> right (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade->in(), 0, xfade->length(), "xfade in",
0, Region::DefaultFlags, false)));
session.audition_region (right);
}
@ -1173,9 +1173,9 @@ CrossfadeEditor::audition_right ()
{
AudioPlaylist& pl (session.the_auditioner()->prepare_playlist());
boost::shared_ptr<AudioRegion> left (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade.out(), xfade.out()->length() - xfade.length(), xfade.length(), "xfade out",
boost::shared_ptr<AudioRegion> left (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade->out(), xfade->out()->length() - xfade->length(), xfade->length(), "xfade out",
0, Region::DefaultFlags, false)));
boost::shared_ptr<AudioRegion> right (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade.out(), 0, xfade.length(), "xfade out",
boost::shared_ptr<AudioRegion> right (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (xfade->out(), 0, xfade->length(), "xfade out",
0, Region::DefaultFlags, false)));
pl.add_region (left, 0);

View File

@ -21,170 +21,170 @@ namespace ARDOUR
class CrossfadeEditor : public ArdourDialog
{
public:
CrossfadeEditor (ARDOUR::Session&, ARDOUR::Crossfade&, double miny, double maxy);
~CrossfadeEditor ();
void apply ();
static const double canvas_border;
/* these are public so that a caller/subclass can make them do the right thing.
*/
Gtk::Button* cancel_button;
Gtk::Button* ok_button;
struct PresetPoint {
double x;
double y;
PresetPoint (double a, double b)
: x (a), y (b) {}
};
struct Preset : public list<PresetPoint> {
string xpm;
CrossfadeEditor (ARDOUR::Session&, boost::shared_ptr<ARDOUR::Crossfade>, double miny, double maxy);
~CrossfadeEditor ();
void apply ();
static const double canvas_border;
/* these are public so that a caller/subclass can make them do the right thing.
*/
Gtk::Button* cancel_button;
Gtk::Button* ok_button;
struct PresetPoint {
double x;
double y;
PresetPoint (double a, double b)
: x (a), y (b) {}
};
struct Preset : public list<PresetPoint> {
string xpm;
Preset (string x)
: xpm (x) {}
};
typedef list<Preset*> Presets;
static Presets* fade_in_presets;
static Presets* fade_out_presets;
Preset (string x)
: xpm (x) {}
};
typedef list<Preset*> Presets;
static Presets* fade_in_presets;
static Presets* fade_out_presets;
private:
ARDOUR::Crossfade& xfade;
ARDOUR::Session& session;
boost::shared_ptr<ARDOUR::Crossfade> xfade;
ARDOUR::Session& session;
Gtk::VBox vpacker;
struct Point {
~Point();
ArdourCanvas::SimpleRect* box;
ArdourCanvas::Line* curve;
double x;
double y;
static const int32_t size;
void move_to (double x, double y, double xfract, double yfract);
};
struct PointSorter
{
bool operator() (const CrossfadeEditor::Point* a, const CrossfadeEditor::Point *b) {
return a->x < b->x;
}
};
ArdourCanvas::SimpleRect* toplevel;
ArdourCanvas::Canvas* canvas;
struct Half {
ArdourCanvas::Line* line;
ArdourCanvas::Polygon* shading;
list<Point*> points;
ARDOUR::Curve normative_curve; /* 0 - 1.0, linear */
ARDOUR::Curve gain_curve; /* 0 - 2.0, gain mapping */
vector<ArdourCanvas::WaveView*> waves;
Half();
};
enum WhichFade {
In = 0,
Out = 1
};
Half fade[2];
WhichFade current;
bool point_grabbed;
vector<Gtk::Button*> fade_out_buttons;
vector<Gtk::Button*> fade_in_buttons;
Gtk::VBox vpacker;
Gtk::VBox vpacker2;
struct Point {
~Point();
Gtk::Button clear_button;
Gtk::Button revert_button;
ArdourCanvas::SimpleRect* box;
ArdourCanvas::Line* curve;
double x;
double y;
Gtk::ToggleButton audition_both_button;
Gtk::ToggleButton audition_left_dry_button;
Gtk::ToggleButton audition_left_button;
Gtk::ToggleButton audition_right_dry_button;
Gtk::ToggleButton audition_right_button;
static const int32_t size;
Gtk::ToggleButton preroll_button;
Gtk::ToggleButton postroll_button;
void move_to (double x, double y, double xfract, double yfract);
};
Gtk::HBox roll_box;
struct PointSorter
{
bool operator() (const CrossfadeEditor::Point* a, const CrossfadeEditor::Point *b) {
return a->x < b->x;
}
};
gint event_handler (GdkEvent*);
ArdourCanvas::SimpleRect* toplevel;
ArdourCanvas::Canvas* canvas;
bool canvas_event (GdkEvent* event);
bool point_event (GdkEvent* event, Point*);
bool curve_event (GdkEvent* event);
struct Half {
ArdourCanvas::Line* line;
ArdourCanvas::Polygon* shading;
list<Point*> points;
ARDOUR::Curve normative_curve; /* 0 - 1.0, linear */
ARDOUR::Curve gain_curve; /* 0 - 2.0, gain mapping */
vector<ArdourCanvas::WaveView*> waves;
Half();
};
enum WhichFade {
In = 0,
Out = 1
};
Half fade[2];
WhichFade current;
bool point_grabbed;
vector<Gtk::Button*> fade_out_buttons;
vector<Gtk::Button*> fade_in_buttons;
Gtk::VBox vpacker2;
Gtk::Button clear_button;
Gtk::Button revert_button;
Gtk::ToggleButton audition_both_button;
Gtk::ToggleButton audition_left_dry_button;
Gtk::ToggleButton audition_left_button;
Gtk::ToggleButton audition_right_dry_button;
Gtk::ToggleButton audition_right_button;
Gtk::ToggleButton preroll_button;
Gtk::ToggleButton postroll_button;
Gtk::HBox roll_box;
gint event_handler (GdkEvent*);
bool canvas_event (GdkEvent* event);
bool point_event (GdkEvent* event, Point*);
bool curve_event (GdkEvent* event);
void canvas_allocation (Gtk::Allocation&);
void add_control_point (double x, double y);
Point* make_point ();
void redraw ();
void canvas_allocation (Gtk::Allocation&);
void add_control_point (double x, double y);
Point* make_point ();
void redraw ();
double effective_width () const { return canvas->get_allocation().get_width() - (2.0 * canvas_border); }
double effective_height () const { return canvas->get_allocation().get_height() - (2.0 * canvas_border); }
double effective_width () const { return canvas->get_allocation().get_width() - (2.0 * canvas_border); }
double effective_height () const { return canvas->get_allocation().get_height() - (2.0 * canvas_border); }
void clear ();
void reset ();
void clear ();
void reset ();
double miny;
double maxy;
double miny;
double maxy;
Gtk::Table fade_in_table;
Gtk::Table fade_out_table;
Gtk::Table fade_in_table;
Gtk::Table fade_out_table;
void build_presets ();
void apply_preset (Preset*);
void build_presets ();
void apply_preset (Preset*);
Gtk::RadioButton select_in_button;
Gtk::RadioButton select_out_button;
Gtk::HBox curve_button_box;
Gtk::HBox audition_box;
Gtk::RadioButton select_in_button;
Gtk::RadioButton select_out_button;
Gtk::HBox curve_button_box;
Gtk::HBox audition_box;
void curve_select_clicked (WhichFade);
void curve_select_clicked (WhichFade);
double x_coordinate (double& xfract) const;
double y_coordinate (double& yfract) const;
double x_coordinate (double& xfract) const;
double y_coordinate (double& yfract) const;
void set (const ARDOUR::Curve& alist, WhichFade);
void set (const ARDOUR::Curve& alist, WhichFade);
sigc::connection peaks_ready_connection;
sigc::connection peaks_ready_connection;
void make_waves (boost::shared_ptr<ARDOUR::AudioRegion>, WhichFade);
void peaks_ready (boost::shared_ptr<ARDOUR::AudioRegion> r, WhichFade);
void make_waves (boost::shared_ptr<ARDOUR::AudioRegion>, WhichFade);
void peaks_ready (boost::shared_ptr<ARDOUR::AudioRegion> r, WhichFade);
void _apply_to (ARDOUR::Crossfade* xf);
void setup (ARDOUR::Crossfade*);
void cancel_audition ();
void audition_state_changed (bool);
void _apply_to (boost::shared_ptr<ARDOUR::Crossfade> xf);
void setup (boost::shared_ptr<ARDOUR::Crossfade>);
void cancel_audition ();
void audition_state_changed (bool);
void audition_toggled ();
void audition_right_toggled ();
void audition_right_dry_toggled ();
void audition_left_toggled ();
void audition_left_dry_toggled ();
void audition_toggled ();
void audition_right_toggled ();
void audition_right_dry_toggled ();
void audition_left_toggled ();
void audition_left_dry_toggled ();
void audition_both ();
void audition_left_dry ();
void audition_left ();
void audition_right_dry ();
void audition_right ();
void audition_both ();
void audition_left_dry ();
void audition_left ();
void audition_right_dry ();
void audition_right ();
void xfade_changed (ARDOUR::Change);
void xfade_changed (ARDOUR::Change);
void dump ();
void dump ();
};
#endif /* __gtk_ardour_xfade_edit_h__ */

View File

@ -44,15 +44,15 @@ sigc::signal<void,CrossfadeView*> CrossfadeView::GoingAway;
CrossfadeView::CrossfadeView (ArdourCanvas::Group *parent,
RouteTimeAxisView &tv,
Crossfade& xf,
boost::shared_ptr<Crossfade> xf,
double spu,
Gdk::Color& basic_color,
AudioRegionView& lview,
AudioRegionView& rview)
: TimeAxisViewItem ("xfade" /*xf.name()*/, *parent, tv, spu, basic_color, xf.position(),
xf.length(), TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowFrame)),
: TimeAxisViewItem ("xfade" /*xf.name()*/, *parent, tv, spu, basic_color, xf->position(),
xf->length(), TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowFrame)),
crossfade (xf),
left_view (lview),
right_view (rview)
@ -84,7 +84,7 @@ CrossfadeView::CrossfadeView (ArdourCanvas::Group *parent,
crossfade_changed (Change (~0));
crossfade.StateChanged.connect (mem_fun(*this, &CrossfadeView::crossfade_changed));
crossfade->StateChanged.connect (mem_fun(*this, &CrossfadeView::crossfade_changed));
}
CrossfadeView::~CrossfadeView ()
@ -123,8 +123,8 @@ CrossfadeView::crossfade_changed (Change what_changed)
bool need_redraw_curves = false;
if (what_changed & BoundsChanged) {
set_position (crossfade.position(), this);
set_duration (crossfade.length(), this);
set_position (crossfade->position(), this);
set_duration (crossfade->length(), this);
need_redraw_curves = true;
}
@ -148,7 +148,7 @@ CrossfadeView::redraw_curves ()
float* vec;
double h;
if (!crossfade.following_overlap()) {
if (!crossfade->following_overlap()) {
/* curves should not be visible */
fade_in->hide ();
fade_out->hide ();
@ -172,10 +172,10 @@ CrossfadeView::redraw_curves ()
return;
}
npoints = get_time_axis_view().editor.frame_to_pixel (crossfade.length());
npoints = get_time_axis_view().editor.frame_to_pixel (crossfade->length());
npoints = std::min (gdk_screen_width(), npoints);
if (!_visible || !crossfade.active() || npoints < 3) {
if (!_visible || !crossfade->active() || npoints < 3) {
fade_in->hide();
fade_out->hide();
return;
@ -187,7 +187,7 @@ CrossfadeView::redraw_curves ()
points = get_canvas_points ("xfade edit redraw", npoints);
vec = new float[npoints];
crossfade.fade_in().get_vector (0, crossfade.length(), vec, npoints);
crossfade->fade_in().get_vector (0, crossfade->length(), vec, npoints);
for (int i = 0, pci = 0; i < npoints; ++i) {
Art::Point &p = (*points)[pci++];
p.set_x(i);
@ -195,7 +195,7 @@ CrossfadeView::redraw_curves ()
}
fade_in->property_points() = *points;
crossfade.fade_out().get_vector (0, crossfade.length(), vec, npoints);
crossfade->fade_out().get_vector (0, crossfade->length(), vec, npoints);
for (int i = 0, pci = 0; i < npoints; ++i) {
Art::Point &p = (*points)[pci++];
p.set_x(i);
@ -217,7 +217,7 @@ CrossfadeView::redraw_curves ()
void
CrossfadeView::active_changed ()
{
if (crossfade.active()) {
if (crossfade->active()) {
frame->property_fill_color_rgba() = color_map[cActiveCrossfade];
} else {
frame->property_fill_color_rgba() = color_map[cInactiveCrossfade];

View File

@ -35,14 +35,15 @@ struct CrossfadeView : public TimeAxisViewItem
{
CrossfadeView (ArdourCanvas::Group*,
RouteTimeAxisView&,
ARDOUR::Crossfade&,
boost::shared_ptr<ARDOUR::Crossfade>,
double initial_samples_per_unit,
Gdk::Color& basic_color,
AudioRegionView& leftview,
AudioRegionView& rightview);
~CrossfadeView ();
ARDOUR::Crossfade& crossfade; // ok, let 'em have it
boost::shared_ptr<ARDOUR::Crossfade> crossfade; // ok, let 'em have it
AudioRegionView& left_view; // and these too
AudioRegionView& right_view;

View File

@ -1649,7 +1649,7 @@ Editor::build_track_selection_context_menu (nframes_t ignored)
}
void
Editor::add_crossfade_context_items (AudioStreamView* view, Crossfade* xfade, Menu_Helpers::MenuList& edit_items, bool many)
Editor::add_crossfade_context_items (AudioStreamView* view, boost::shared_ptr<Crossfade> xfade, Menu_Helpers::MenuList& edit_items, bool many)
{
using namespace Menu_Helpers;
Menu *xfade_menu = manage (new Menu);
@ -1663,8 +1663,8 @@ Editor::add_crossfade_context_items (AudioStreamView* view, Crossfade* xfade, Me
str = _("Unmute");
}
items.push_back (MenuElem (str, bind (mem_fun(*this, &Editor::toggle_xfade_active), xfade)));
items.push_back (MenuElem (_("Edit"), bind (mem_fun(*this, &Editor::edit_xfade), xfade)));
items.push_back (MenuElem (str, bind (mem_fun(*this, &Editor::toggle_xfade_active), boost::weak_ptr<Crossfade> (xfade))));
items.push_back (MenuElem (_("Edit"), bind (mem_fun(*this, &Editor::edit_xfade), boost::weak_ptr<Crossfade> (xfade))));
if (xfade->can_follow_overlap()) {
@ -3900,21 +3900,33 @@ Editor::set_follow_playhead (bool yn)
}
void
Editor::toggle_xfade_active (Crossfade* xfade)
Editor::toggle_xfade_active (boost::weak_ptr<Crossfade> wxfade)
{
xfade->set_active (!xfade->active());
boost::shared_ptr<Crossfade> xfade (wxfade.lock());
if (xfade) {
xfade->set_active (!xfade->active());
}
}
void
Editor::toggle_xfade_length (Crossfade* xfade)
Editor::toggle_xfade_length (boost::weak_ptr<Crossfade> wxfade)
{
xfade->set_follow_overlap (!xfade->following_overlap());
boost::shared_ptr<Crossfade> xfade (wxfade.lock());
if (xfade) {
xfade->set_follow_overlap (!xfade->following_overlap());
}
}
void
Editor::edit_xfade (Crossfade* xfade)
Editor::edit_xfade (boost::weak_ptr<Crossfade> wxfade)
{
CrossfadeEditor cew (*session, *xfade, xfade->fade_in().get_min_y(), 1.0);
boost::shared_ptr<Crossfade> xfade (wxfade.lock());
if (!xfade) {
return;
}
CrossfadeEditor cew (*session, xfade, xfade->fade_in().get_min_y(), 1.0);
ensure_float (cew);

View File

@ -464,7 +464,7 @@ class Editor : public PublicEditor
void add_dstream_context_items (Gtk::Menu_Helpers::MenuList&);
void add_bus_context_items (Gtk::Menu_Helpers::MenuList&);
void add_region_context_items (AudioStreamView*, boost::shared_ptr<ARDOUR::Region>, Gtk::Menu_Helpers::MenuList&);
void add_crossfade_context_items (AudioStreamView*, ARDOUR::Crossfade*, Gtk::Menu_Helpers::MenuList&, bool many);
void add_crossfade_context_items (AudioStreamView*, boost::shared_ptr<ARDOUR::Crossfade>, Gtk::Menu_Helpers::MenuList&, bool many);
void add_selection_context_items (Gtk::Menu_Helpers::MenuList&);
void handle_new_route (ARDOUR::Session::RouteList&);
@ -1734,9 +1734,9 @@ class Editor : public PublicEditor
ImageFrameSocketHandler* image_socket_listener ;
/* </CMT Additions> */
void toggle_xfade_active (ARDOUR::Crossfade*);
void toggle_xfade_length (ARDOUR::Crossfade*);
void edit_xfade (ARDOUR::Crossfade*);
void toggle_xfade_active (boost::weak_ptr<ARDOUR::Crossfade>);
void toggle_xfade_length (boost::weak_ptr<ARDOUR::Crossfade>);
void edit_xfade (boost::weak_ptr<ARDOUR::Crossfade>);
void xfade_edit_left_region ();
void xfade_edit_right_region ();

View File

@ -37,7 +37,7 @@ class Source;
class AudioPlaylist : public ARDOUR::Playlist
{
public:
typedef std::list<Crossfade*> Crossfades;
typedef std::list<boost::shared_ptr<Crossfade> > Crossfades;
public:
AudioPlaylist (Session&, const XMLNode&, bool hidden = false);
@ -53,9 +53,9 @@ class AudioPlaylist : public ARDOUR::Playlist
int set_state (const XMLNode&);
sigc::signal<void,Crossfade *> NewCrossfade;
sigc::signal<void,boost::shared_ptr<Crossfade> > NewCrossfade;
template<class T> void foreach_crossfade (T *t, void (T::*func)(Crossfade *));
template<class T> void foreach_crossfade (T *t, void (T::*func)(boost::shared_ptr<Crossfade>));
void crossfades_at (nframes_t frame, Crossfades&);
bool destroy_region (boost::shared_ptr<Region>);
@ -63,7 +63,7 @@ class AudioPlaylist : public ARDOUR::Playlist
protected:
/* playlist "callbacks" */
void notify_crossfade_added (Crossfade *);
void notify_crossfade_added (boost::shared_ptr<Crossfade>);
void flush_notifications ();
void finalize_split_region (boost::shared_ptr<Region> orig, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right);
@ -73,16 +73,16 @@ class AudioPlaylist : public ARDOUR::Playlist
void remove_dependents (boost::shared_ptr<Region> region);
private:
Crossfades _crossfades; /* xfades currently in use */
Crossfades _crossfades;
Crossfades _pending_xfade_adds;
void crossfade_invalidated (Crossfade*);
void crossfade_invalidated (boost::shared_ptr<Crossfade>);
XMLNode& state (bool full_state);
void dump () const;
bool region_changed (Change, boost::shared_ptr<Region>);
void crossfade_changed (Change);
void add_crossfade (Crossfade&);
void add_crossfade (boost::shared_ptr<Crossfade>);
void source_offset_changed (boost::shared_ptr<AudioRegion> region);
};

View File

@ -24,6 +24,7 @@
#include <vector>
#include <algorithm>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <sigc++/signal.h>
@ -40,7 +41,7 @@ namespace ARDOUR {
class AudioRegion;
class Playlist;
class Crossfade : public PBD::StatefulDestructible
class Crossfade : public PBD::StatefulDestructible, public boost::enable_shared_from_this<ARDOUR::Crossfade>
{
public:
@ -111,7 +112,7 @@ class Crossfade : public PBD::StatefulDestructible
void invalidate();
sigc::signal<void,Crossfade*> Invalidated;
sigc::signal<void,boost::shared_ptr<Crossfade> > Invalidated;
sigc::signal<void,Change> StateChanged;
bool covers (nframes_t frame) const {

View File

@ -23,7 +23,7 @@
namespace ARDOUR {
template<class T> void AudioPlaylist::foreach_crossfade (T *t, void (T::*func)(Crossfade *)) {
template<class T> void AudioPlaylist::foreach_crossfade (T *t, void (T::*func)(boost::shared_ptr<Crossfade>)) {
RegionLock rlock (this, false);
for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); i++) {
(t->*func) (*i);

View File

@ -62,7 +62,7 @@ AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, stri
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*in_o);
// We look only for crossfades which begin with the current region, so we don't get doubles
for (list<Crossfade *>::const_iterator xfades = other->_crossfades.begin(); xfades != other->_crossfades.end(); ++xfades) {
for (Crossfades::const_iterator xfades = other->_crossfades.begin(); xfades != other->_crossfades.end(); ++xfades) {
if ((*xfades)->in() == ar) {
// We found one! Now copy it!
@ -76,8 +76,8 @@ AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, stri
if ((*xfades)->out() == ar2) {
boost::shared_ptr<AudioRegion>in = boost::dynamic_pointer_cast<AudioRegion>(*in_n);
boost::shared_ptr<AudioRegion>out = boost::dynamic_pointer_cast<AudioRegion>(*out_n);
Crossfade *new_fade = new Crossfade (*(*xfades), in, out);
add_crossfade(*new_fade);
boost::shared_ptr<Crossfade> new_fade = boost::shared_ptr<Crossfade> (new Crossfade (*(*xfades), in, out));
add_crossfade(new_fade);
break;
}
@ -101,24 +101,13 @@ AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, nfra
AudioPlaylist::~AudioPlaylist ()
{
set<Crossfade*> all_xfades;
GoingAway (); /* EMIT SIGNAL */
/* drop connections to signals */
notify_callbacks ();
for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end(); ) {
Crossfades::iterator tmp;
tmp = x;
++tmp;
delete *x;
x = tmp;
}
_crossfades.clear ();
}
struct RegionSortByLayer {
@ -164,7 +153,7 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nf
_read_data_count = 0;
map<uint32_t,vector<boost::shared_ptr<Region> > > relevant_regions;
map<uint32_t,vector<Crossfade*> > relevant_xfades;
map<uint32_t,vector<boost::shared_ptr<Crossfade> > > relevant_xfades;
vector<uint32_t> relevant_layers;
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
@ -194,7 +183,7 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nf
for (vector<uint32_t>::iterator l = relevant_layers.begin(); l != relevant_layers.end(); ++l) {
vector<boost::shared_ptr<Region> > r (relevant_regions[*l]);
vector<Crossfade*>& x (relevant_xfades[*l]);
vector<boost::shared_ptr<Crossfade> >& x (relevant_xfades[*l]);
for (vector<boost::shared_ptr<Region> >::iterator i = r.begin(); i != r.end(); ++i) {
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*i);
@ -203,7 +192,7 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nf
_read_data_count += ar->read_data_count();
}
for (vector<Crossfade*>::iterator i = x.begin(); i != x.end(); ++i) {
for (vector<boost::shared_ptr<Crossfade> >::iterator i = x.begin(); i != x.end(); ++i) {
(*i)->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n);
/* don't JACK up _read_data_count, since its the same data as we just
@ -219,7 +208,6 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nf
void
AudioPlaylist::remove_dependents (boost::shared_ptr<Region> region)
{
Crossfades::iterator i, tmp;
boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region);
if (in_set_state) {
@ -232,16 +220,13 @@ AudioPlaylist::remove_dependents (boost::shared_ptr<Region> region)
return;
}
for (i = _crossfades.begin(); i != _crossfades.end(); ) {
tmp = i;
tmp++;
for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ) {
if ((*i)->involves (r)) {
delete *i;
i = _crossfades.erase (i);
} else {
++i;
}
i = tmp;
}
}
@ -271,7 +256,7 @@ void
AudioPlaylist::refresh_dependents (boost::shared_ptr<Region> r)
{
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r);
set<Crossfade*> updated;
set<boost::shared_ptr<Crossfade> > updated;
if (ar == 0) {
return;
@ -312,29 +297,29 @@ AudioPlaylist::finalize_split_region (boost::shared_ptr<Region> o, boost::shared
tmp = x;
++tmp;
Crossfade *fade = 0;
boost::shared_ptr<Crossfade> fade;
if ((*x)->_in == orig) {
if (! (*x)->covers(right->position())) {
fade = new Crossfade (**x, left, (*x)->_out);
fade = boost::shared_ptr<Crossfade> (new Crossfade (**x, left, (*x)->_out));
} else {
// Overlap, the crossfade is copied on the left side of the right region instead
fade = new Crossfade (**x, right, (*x)->_out);
fade = boost::shared_ptr<Crossfade> (new Crossfade (**x, right, (*x)->_out));
}
}
if ((*x)->_out == orig) {
if (! (*x)->covers(right->position())) {
fade = new Crossfade (**x, (*x)->_in, right);
fade = boost::shared_ptr<Crossfade> (new Crossfade (**x, (*x)->_in, right));
} else {
// Overlap, the crossfade is copied on the right side of the left region instead
fade = new Crossfade (**x, (*x)->_in, left);
fade = boost::shared_ptr<Crossfade> (new Crossfade (**x, (*x)->_in, left));
}
}
if (fade) {
_crossfades.remove (*x);
add_crossfade (*fade);
add_crossfade (fade);
}
x = tmp;
}
@ -347,7 +332,7 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
boost::shared_ptr<AudioRegion> region;
boost::shared_ptr<AudioRegion> top;
boost::shared_ptr<AudioRegion> bottom;
Crossfade* xfade;
boost::shared_ptr<Crossfade> xfade;
if (in_set_state || in_partition) {
return;
@ -369,6 +354,8 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
nframes_t xfade_length;
other = boost::dynamic_pointer_cast<AudioRegion> (*i);
if (other == region) {
@ -378,6 +365,7 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
if (other->muted() || region->muted()) {
continue;
}
if (other->layer() < region->layer()) {
top = region;
@ -387,50 +375,55 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
bottom = region;
}
OverlapType c = top->coverage (bottom->position(), bottom->last_frame());
try {
switch (c) {
case OverlapNone:
break;
case OverlapInternal:
/* {=============== top =============}
* [ ----- bottom ------- ]
*/
break;
case OverlapExternal:
/* [ -------- top ------- ]
* {=========== bottom =============}
*/
if (top->coverage (bottom->position(), bottom->last_frame()) != OverlapNone) {
/* to avoid discontinuities at the region boundaries of an internal
overlap (this region is completely within another), we create
two hidden crossfades at each boundary. this is not dependent
on the auto-xfade option, because we require it as basic
audio engineering.
*/
/* check if the upper region is within the lower region */
xfade_length = min ((nframes_t) 720, top->length());
if (top->first_frame() > bottom->first_frame() &&
top->last_frame() < bottom->last_frame()) {
/* [ -------- top ------- ]
* {=========== bottom =============}
*/
/* to avoid discontinuities at the region boundaries of an internal
overlap (this region is completely within another), we create
two hidden crossfades at each boundary. this is not dependent
on the auto-xfade option, because we require it as basic
audio engineering.
xfade = boost::shared_ptr<Crossfade> (new Crossfade (top, bottom, xfade_length, top->first_frame(), StartOfIn));
add_crossfade (xfade);
if (top_region_at (top->last_frame() - 1) == top) {
/*
only add a fade out if there is no region on top of the end of 'top' (which
would cover it).
*/
nframes_t xfade_length = min ((nframes_t) 720, top->length());
/* in, out */
xfade = new Crossfade (top, bottom, xfade_length, top->first_frame(), StartOfIn);
add_crossfade (*xfade);
if (top_region_at (top->last_frame() - 1) == top) {
/*
only add a fade out if there is no region on top of the end of 'top' (which
would cover it).
*/
xfade = new Crossfade (bottom, top, xfade_length, top->last_frame() - xfade_length, EndOfOut);
add_crossfade (*xfade);
}
} else {
xfade = new Crossfade (other, region, Config->get_xfade_model(), Config->get_xfades_active());
add_crossfade (*xfade);
xfade = boost::shared_ptr<Crossfade> (new Crossfade (bottom, top, xfade_length, top->last_frame() - xfade_length, EndOfOut));
add_crossfade (xfade);
}
}
break;
default:
xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other, Config->get_xfade_model(), Config->get_xfades_active()));
add_crossfade (xfade);
}
}
catch (failed_constructor& err) {
continue;
}
@ -443,29 +436,29 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
}
void
AudioPlaylist::add_crossfade (Crossfade& xfade)
AudioPlaylist::add_crossfade (boost::shared_ptr<Crossfade> xfade)
{
Crossfades::iterator ci;
for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) {
if (*(*ci) == xfade) { // Crossfade::operator==()
if (*(*ci) == *xfade) { // Crossfade::operator==()
break;
}
}
if (ci != _crossfades.end()) {
delete &xfade;
// it will just go away
} else {
_crossfades.push_back (&xfade);
_crossfades.push_back (xfade);
xfade.Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
xfade.StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
notify_crossfade_added (&xfade);
notify_crossfade_added (xfade);
}
}
void AudioPlaylist::notify_crossfade_added (Crossfade *x)
void AudioPlaylist::notify_crossfade_added (boost::shared_ptr<Crossfade> x)
{
if (g_atomic_int_get(&block_notifications)) {
_pending_xfade_adds.insert (_pending_xfade_adds.end(), x);
@ -475,7 +468,7 @@ void AudioPlaylist::notify_crossfade_added (Crossfade *x)
}
void
AudioPlaylist::crossfade_invalidated (Crossfade* xfade)
AudioPlaylist::crossfade_invalidated (boost::shared_ptr<Crossfade> xfade)
{
Crossfades::iterator i;
@ -510,7 +503,7 @@ AudioPlaylist::set_state (const XMLNode& node)
}
try {
Crossfade* xfade = new Crossfade (*((const Playlist *)this), *child);
boost::shared_ptr<Crossfade> xfade = boost::shared_ptr<Crossfade> (new Crossfade (*((const Playlist *)this), *child));
_crossfades.push_back (xfade);
xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
@ -534,19 +527,7 @@ AudioPlaylist::set_state (const XMLNode& node)
void
AudioPlaylist::clear (bool with_signals)
{
for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ) {
Crossfades::iterator tmp;
tmp = i;
++tmp;
delete *i;
i = tmp;
}
_crossfades.clear ();
Playlist::clear (with_signals);
}
@ -568,7 +549,7 @@ void
AudioPlaylist::dump () const
{
boost::shared_ptr<Region>r;
Crossfade *x;
boost::shared_ptr<Crossfade> x;
cerr << "Playlist \"" << _name << "\" " << endl
<< regions.size() << " regions "
@ -608,7 +589,7 @@ AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region);
bool changed = false;
Crossfades::iterator c, ctmp;
set<Crossfade*> unique_xfades;
set<boost::shared_ptr<Crossfade> > unique_xfades;
if (r == 0) {
fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
@ -661,10 +642,6 @@ AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
c = ctmp;
}
for (set<Crossfade*>::iterator c = unique_xfades.begin(); c != unique_xfades.end(); ++c) {
delete *c;
}
if (changed) {
/* overload this, it normally means "removed", not destroyed */
notify_region_removed (region);

View File

@ -20,6 +20,8 @@
#include <sigc++/bind.h>
#include <pbd/stacktrace.h>
#include <ardour/types.h>
#include <ardour/crossfade.h>
#include <ardour/crossfade_compare.h>
@ -80,6 +82,7 @@ Crossfade::Crossfade (boost::shared_ptr<AudioRegion> in, boost::shared_ptr<Audio
{
_in = in;
_out = out;
_length = length;
_position = position;
_anchor_point = ap;
@ -199,7 +202,8 @@ Crossfade::Crossfade (const Crossfade &orig, boost::shared_ptr<AudioRegion> newi
Crossfade::~Crossfade ()
{
Invalidated (this);
cerr << "Crossfade deleted\n";
notify_callbacks ();
}
void
@ -256,6 +260,8 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
/* first check for matching ends */
if (top->first_frame() == bottom->first_frame()) {
cerr << "same start\n";
/* Both regions start at the same point */
@ -297,6 +303,8 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
} else if (top->last_frame() == bottom->last_frame()) {
cerr << "same end\n";
/* Both regions end at the same point */
if (top->first_frame() > bottom->first_frame()) {
@ -335,17 +343,21 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
OverlapType ot = top->coverage (bottom->first_frame(), bottom->last_frame());
cerr << "ot = " << ot << endl;
switch (ot) {
case OverlapNone:
/* should be NOTREACHED as a precondition of creating
a new crossfade, but we need to handle it here.
*/
cerr << "no sir\n";
throw NoCrossfadeHere();
break;
case OverlapInternal:
case OverlapExternal:
/* should be NOTREACHED because of tests above */
cerr << "nu-uh\n";
throw NoCrossfadeHere();
break;
@ -357,15 +369,16 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
_in = bottom;
_out = top;
_position = bottom->first_frame();
_anchor_point = StartOfIn;
if (model == FullCrossfade) {
_position = bottom->first_frame(); // "{"
_length = _out->first_frame() + _out->length() - _in->first_frame();
/* leave active alone */
_follow_overlap = true;
} else {
_length = min (short_xfade_length, top->length());
_position = top->last_frame() - _length; // "]" - length
_active = true;
_follow_overlap = false;
@ -499,7 +512,13 @@ Crossfade::refresh ()
/* crossfades must be between non-muted regions */
if (_out->muted() || _in->muted()) {
Invalidated (this);
Invalidated (shared_from_this());
return false;
}
if (_in->layer() < _out->layer()) {
cerr << "layer change, invalidated\n";
Invalidated (shared_from_this());
return false;
}
@ -508,11 +527,11 @@ Crossfade::refresh ()
OverlapType ot;
ot = _in->coverage (_out->first_frame(), _out->last_frame());
switch (ot) {
case OverlapNone:
case OverlapInternal:
Invalidated (this);
Invalidated (shared_from_this());
return false;
default:
@ -522,7 +541,7 @@ Crossfade::refresh ()
/* overlap type must not have altered */
if (ot != overlap_type) {
Invalidated (this);
Invalidated (shared_from_this());
return false;
}
@ -543,7 +562,7 @@ Crossfade::update (bool force)
}
if (newlen == 0) {
Invalidated (this);
Invalidated (shared_from_this());
return false;
}
@ -563,7 +582,13 @@ Crossfade::update (bool force)
switch (_anchor_point) {
case StartOfIn:
if (_position != _in->first_frame()) {
_position = _in->first_frame();
if (_length > _short_xfade_length) {
/* assume FullCrossfade */
_position = _in->first_frame();
} else {
/* assume short xfade */
_position = _out->last_frame() - _length;
}
}
break;
@ -865,5 +890,5 @@ Crossfade::set_short_xfade_length (nframes_t n)
void
Crossfade::invalidate ()
{
Invalidated (this); /* EMIT SIGNAL */
Invalidated (shared_from_this()); /* EMIT SIGNAL */
}

View File

@ -196,6 +196,7 @@ setup_hardware_optimization (bool try_optimization)
{
bool generic_mix_functions = true;
if (try_optimization) {
#if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
@ -216,14 +217,14 @@ setup_hardware_optimization (bool try_optimization)
#else
asm (
"movq $1, %%rax\n"
"pushq %%rbx\n"
"movq $1, %%rax\n"
"cpuid\n"
"movq %%rdx, %0\n"
"popq %%rbx\n"
: "=l" (use_sse)
:
: "%rax", "%rcx", "%rdx", "memory");
: "%rax", "%rcx", "%rdx", "memory");
#endif /* USE_X86_64_ASM */
use_sse &= (1 << 25); // bit 25 = SSE support