Merged with trunk R1304
[ardour.git] / libs / ardour / ardour / crossfade.h
1 /*
2     Copyright (C) 2000 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18     $Id$
19 */
20
21 #ifndef __ardour_overlap_h__
22 #define __ardour_overlap_h__
23
24 #include <vector>
25 #include <algorithm>
26 #include <boost/shared_ptr.hpp>
27 #include <boost/enable_shared_from_this.hpp>
28
29 #include <sigc++/signal.h>
30
31 #include <pbd/undo.h>
32 #include <pbd/statefuldestructible.h> 
33
34 #include <ardour/ardour.h>
35 #include <ardour/curve.h>
36 #include <ardour/audioregion.h>
37 #include <ardour/crossfade_compare.h>
38
39 namespace ARDOUR {
40
41 class AudioRegion;
42 class Playlist;
43
44 class Crossfade : public PBD::StatefulDestructible, public boost::enable_shared_from_this<ARDOUR::Crossfade>
45 {
46   public:
47
48         class NoCrossfadeHere: std::exception {
49           public:
50                 virtual const char *what() const throw() { return "no crossfade should be constructed here"; }
51         };
52         
53         /* constructor for "fixed" xfades at each end of an internal overlap */
54
55         Crossfade (boost::shared_ptr<ARDOUR::AudioRegion> in, boost::shared_ptr<ARDOUR::AudioRegion> out,
56                    nframes_t position,
57                    nframes_t initial_length,
58                    AnchorPoint);
59
60         /* constructor for xfade between two regions that are overlapped in any way
61            except the "internal" case.
62         */
63         
64         Crossfade (boost::shared_ptr<ARDOUR::AudioRegion> in, boost::shared_ptr<ARDOUR::AudioRegion> out, CrossfadeModel, bool active);
65
66
67         /* copy constructor to copy a crossfade with new regions. used (for example)
68            when a playlist copy is made 
69         */
70         Crossfade (const Crossfade &, boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>);
71         
72         /* the usual XML constructor */
73
74         Crossfade (const Playlist&, XMLNode&);
75         virtual ~Crossfade();
76
77         bool operator== (const ARDOUR::Crossfade&);
78
79         XMLNode& get_state (void);
80         int set_state (const XMLNode&);
81
82         boost::shared_ptr<ARDOUR::AudioRegion> in() const { return _in; }
83         boost::shared_ptr<ARDOUR::AudioRegion> out() const { return _out; }
84         
85         nframes_t read_at (Sample *buf, Sample *mixdown_buffer, 
86                                 float *gain_buffer, nframes_t position, nframes_t cnt, 
87                                 uint32_t chan_n,
88                                 nframes_t read_frames = 0,
89                                 nframes_t skip_frames = 0);
90         
91         bool refresh ();
92
93         uint32_t upper_layer () const {
94                 return std::max (_in->layer(), _out->layer());
95         }
96
97         uint32_t lower_layer () const {
98                 return std::min (_in->layer(), _out->layer());
99         }
100
101         bool involves (boost::shared_ptr<ARDOUR::AudioRegion> region) const {
102                 return _in == region || _out == region;
103         }
104
105         bool involves (boost::shared_ptr<ARDOUR::AudioRegion> a, boost::shared_ptr<ARDOUR::AudioRegion> b) const {
106                 return (_in == a && _out == b) || (_in == b && _out == a);
107         }
108
109         nframes_t length() const { return _length; }
110         nframes_t overlap_length() const;
111         nframes_t position() const { return _position; }
112
113         void invalidate();
114
115         sigc::signal<void,boost::shared_ptr<Crossfade> > Invalidated;
116         sigc::signal<void,Change>     StateChanged;
117
118         bool covers (nframes_t frame) const {
119                 return _position <= frame && frame < _position + _length;
120         }
121
122         OverlapType coverage (nframes_t start, nframes_t end) const;
123
124         static void set_buffer_size (nframes_t);
125
126         bool active () const { return _active; }
127         void set_active (bool yn);
128
129         bool following_overlap() const { return _follow_overlap; }
130         bool can_follow_overlap() const;
131         void set_follow_overlap (bool yn);
132
133         Curve& fade_in() { return _fade_in; } 
134         Curve& fade_out() { return _fade_out; }
135
136         nframes_t set_length (nframes_t);
137         
138         static nframes_t short_xfade_length() { return _short_xfade_length; }
139         static void set_short_xfade_length (nframes_t n);
140
141         static Change ActiveChanged;
142         static Change FollowOverlapChanged;
143
144   private:
145         friend struct CrossfadeComparePtr;
146         friend class AudioPlaylist;
147
148         static nframes_t _short_xfade_length;
149
150         boost::shared_ptr<ARDOUR::AudioRegion> _in;
151         boost::shared_ptr<ARDOUR::AudioRegion> _out;
152         bool                 _active;
153         bool                 _in_update;
154         OverlapType           overlap_type;
155         nframes_t       _length;
156         nframes_t       _position;
157         AnchorPoint          _anchor_point;
158         bool                 _follow_overlap;
159         bool                 _fixed;
160         Curve _fade_in;
161         Curve _fade_out;
162
163         static Sample* crossfade_buffer_out;
164         static Sample* crossfade_buffer_in;
165
166         void initialize ();
167         int  compute (boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>, CrossfadeModel);
168         bool update (bool force);
169
170         void member_changed (ARDOUR::Change);
171 };
172
173
174 } // namespace ARDOUR
175
176 #endif /* __ardour_overlap_h__ */