fix xfade logic and use shared_ptr for xfades
authorPaul Davis <paul@linuxaudiosystems.com>
Wed, 10 Jan 2007 16:19:13 +0000 (16:19 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Wed, 10 Jan 2007 16:19:13 +0000 (16:19 +0000)
git-svn-id: svn://localhost/ardour2/trunk@1297 d708f5d6-7413-0410-9779-e7cbd77b26cf

15 files changed:
gtk2_ardour/ardev
gtk2_ardour/audio_streamview.cc
gtk2_ardour/audio_streamview.h
gtk2_ardour/crossfade_edit.cc
gtk2_ardour/crossfade_edit.h
gtk2_ardour/crossfade_view.cc
gtk2_ardour/crossfade_view.h
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
libs/ardour/ardour/audioplaylist.h
libs/ardour/ardour/crossfade.h
libs/ardour/ardour/playlist_templates.h
libs/ardour/audio_playlist.cc
libs/ardour/crossfade.cc
libs/ardour/globals.cc

index 3b65b2ec7938180c3f7ca179831ce2171cb71e9b..ff68e11fbe1713f42e710163e2f644018b3857ca 100755 (executable)
@@ -1,3 +1,3 @@
 #!/bin/sh
 . `dirname "$0"`/ardev_common.sh
-exec $EXECUTABLE "$*"
+exec $EXECUTABLE $*
index 89d6d394c42d1778f7ed3cb212f1661c383eb443..349f472e6eac3aef9dca3343b42544028062e433 100644 (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 ();
                }
        }
index 295e02d96a11384d5c9082e3883898a0c05456a3..893622116f02ae6f289d7a05f8a8fb6fc0a0646d 100644 (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);
        
index f6f26c76d55f09ff69180e748d36bf9a6a824141..94e167282c1a0bcef2b62ad469104cb7cda6501d 100644 (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);
index ad0661c0369b27c37a0ced0c386509483c6e5057..3c9a6a13c10a9f3248cc22c72dded9fd17222bf9 100644 (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;
-
-    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;
+       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 vpacker2;
+       Gtk::VBox vpacker2;
 
-    Gtk::Button clear_button;
-    Gtk::Button revert_button;
+       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 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::ToggleButton preroll_button;
+       Gtk::ToggleButton postroll_button;
 
-    Gtk::HBox roll_box;
+       Gtk::HBox roll_box;
 
-    gint event_handler (GdkEvent*);
+       gint event_handler (GdkEvent*);
 
-    bool canvas_event (GdkEvent* event);
-    bool point_event (GdkEvent* event, Point*);
-    bool curve_event (GdkEvent* event);
+       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 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 xfade_changed (ARDOUR::Change);
-
-    void dump ();
+       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_both ();
+       void audition_left_dry ();
+       void audition_left ();
+       void audition_right_dry ();
+       void audition_right ();
+
+       void xfade_changed (ARDOUR::Change);
+
+       void dump ();
 };
 
 #endif /* __gtk_ardour_xfade_edit_h__ */
index 3c3ef4ff91315b910d098a310e9546d6c2313532..b56cedd08a8526c7906d57e19b936f27298fe9f6 100644 (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];
index adbd74b42027da577d37d5857ace317eac45fbb9..730813f78cfb099633ecf1378eca463a30132afb 100644 (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;
 
index 5c2acc8a2a42243db8800cf83d24d81c74995699..ebcf4ecad3e54cd023ca839ca5db65cb6081dac1 100644 (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);
        
index 68b5bd256ed2ded1d2b970840eca9493589e0a69..8ee9c45ed111426b21b5aba7cae65d9075ba0877 100644 (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 ();
 
index 2f1b127c5a7ee62c1c5485a2abd49c4cebbbde6f..586bf6ccc670494418ae641bbbd3ec62222c5270 100644 (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);
 };
index 0422698c5e5afd525f776347680c364fc24b57fe..946d35b8e02d18cdbc64f279f025e1ee8791f368 100644 (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 {
index 7ce6c1818cc033c337d193be58163665cbbd1b43..603e0bef376c34006f0c3beb3ed9b337abbf982b 100644 (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);
index 0c35599332187b6d97daf3392f2d4464c128697d..06060061e0599f76629f5bf3b12a65e318842329 100644 (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);
index 9e36702705fde55d598336e66fecfab1d62e77fa..d2d04f8dc7de1ea79e98b004a5911719f1f31f1e 100644 (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 */
 }
index 3f47b30c1f8ca1333205648557be4b8e0df2dec8..41fc3db16128530bd4561a3e284139b66da6b716 100644 (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