ardour
playlist.h
Go to the documentation of this file.
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 */
19 
20 #ifndef __ardour_playlist_h__
21 #define __ardour_playlist_h__
22 
23 #include <string>
24 #include <set>
25 #include <map>
26 #include <list>
27 #include <boost/shared_ptr.hpp>
28 #include <boost/enable_shared_from_this.hpp>
29 #include <boost/utility.hpp>
30 
31 #include <sys/stat.h>
32 
33 #include <glib.h>
34 
35 #include "pbd/undo.h"
36 #include "pbd/stateful.h"
38 #include "pbd/sequence_property.h"
39 #include "pbd/stacktrace.h"
40 
41 #include "evoral/types.hpp"
42 
43 #include "ardour/ardour.h"
44 #include "ardour/region.h"
45 #include "ardour/session_object.h"
46 #include "ardour/data_type.h"
47 
48 namespace ARDOUR {
49 
50 class Session;
51 class Playlist;
52 class Crossfade;
53 
54 namespace Properties {
55  /* fake the type, since regions are handled by SequenceProperty which doesn't
56  care about such things.
57  */
59 }
60 
61 class LIBARDOUR_API RegionListProperty : public PBD::SequenceProperty<std::list<boost::shared_ptr<Region> > >
62 {
63  public:
65 
66  RegionListProperty* clone () const;
67  void get_content_as_xml (boost::shared_ptr<Region>, XMLNode &) const;
68  boost::shared_ptr<Region> get_content_from_xml (XMLNode const &) const;
69 
70  private:
71  RegionListProperty* create () const;
72 
73  /* copy construction only by ourselves */
75 
76  friend class Playlist;
77  /* we live and die with our playlist, no lifetime management needed */
79 };
80 
82 {
83 public:
84  static void make_property_quarks ();
85 
86  Playlist (Session&, const XMLNode&, DataType type, bool hidden = false);
87  Playlist (Session&, std::string name, DataType type, bool hidden = false);
88  Playlist (boost::shared_ptr<const Playlist>, std::string name, bool hidden = false);
89  Playlist (boost::shared_ptr<const Playlist>, framepos_t start, framecnt_t cnt, std::string name, bool hidden = false);
90 
91  virtual ~Playlist ();
92 
93  void update (const RegionListProperty::ChangeRecord&);
94  void clear_owned_changes ();
95  void rdiff (std::vector<Command*>&) const;
96 
97  boost::shared_ptr<Region> region_by_id (const PBD::ID&) const;
98 
99  uint32_t max_source_level () const;
100 
101  void set_region_ownership ();
102 
103  virtual void clear (bool with_signals=true);
104  virtual void dump () const;
105 
106  void use();
107  void release();
108  bool used () const { return _refcnt != 0; }
109 
110  bool set_name (const std::string& str);
111  int sort_id() { return _sort_id; }
112 
113  const DataType& data_type() const { return _type; }
114 
115  bool frozen() const { return _frozen; }
116  void set_frozen (bool yn);
117 
118  bool hidden() const { return _hidden; }
119  bool empty() const;
120  uint32_t n_regions() const;
121  bool all_regions_empty() const;
122  std::pair<framepos_t, framepos_t> get_extent () const;
123  std::pair<framepos_t, framepos_t> get_extent_with_endspace() const;
124  layer_t top_layer() const;
125 
126  EditMode get_edit_mode() const { return _edit_mode; }
127  void set_edit_mode (EditMode);
128 
129  /* Editing operations */
130 
131  void add_region (boost::shared_ptr<Region>, framepos_t position, float times = 1, bool auto_partition = false);
132  void remove_region (boost::shared_ptr<Region>);
133  void remove_region_by_source (boost::shared_ptr<Source>);
134  void get_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
135  void get_region_list_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
136  void get_source_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
137  void replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Region> newr, framepos_t pos);
138  void split_region (boost::shared_ptr<Region>, framepos_t position);
139  void split (framepos_t at);
140  void shift (framepos_t at, frameoffset_t distance, bool move_intersected, bool ignore_music_glue);
141  void partition (framepos_t start, framepos_t end, bool cut = false);
142  void duplicate (boost::shared_ptr<Region>, framepos_t position, float times);
143  void nudge_after (framepos_t start, framecnt_t distance, bool forwards);
144  boost::shared_ptr<Region> combine (const RegionList&);
145  void uncombine (boost::shared_ptr<Region>);
146  void fade_range (std::list<AudioRange>&);
147 
148  void shuffle (boost::shared_ptr<Region>, int dir);
149  void ripple (framepos_t at, framecnt_t distance, RegionList *exclude);
150  void ripple (framepos_t at, framecnt_t distance, boost::shared_ptr<Region> exclude) {
151  RegionList el;
152  if (exclude)
153  el.push_back (exclude);
154  ripple (at, distance, &el);
155  }
156 
157  void update_after_tempo_map_change ();
158 
159  boost::shared_ptr<Playlist> cut (std::list<AudioRange>&, bool result_is_hidden = true);
160  boost::shared_ptr<Playlist> copy (std::list<AudioRange>&, bool result_is_hidden = true);
162 
163  const RegionListProperty& region_list () const { return regions; }
164 
165  boost::shared_ptr<RegionList> regions_at (framepos_t frame);
166  uint32_t count_regions_at (framepos_t) const;
167  boost::shared_ptr<RegionList> regions_touched (framepos_t start, framepos_t end);
168  boost::shared_ptr<RegionList> regions_with_start_within (Evoral::Range<framepos_t>);
170  uint32_t region_use_count (boost::shared_ptr<Region>) const;
171  boost::shared_ptr<Region> find_region (const PBD::ID&) const;
172  boost::shared_ptr<Region> top_region_at (framepos_t frame);
173  boost::shared_ptr<Region> top_unmuted_region_at (framepos_t frame);
174  boost::shared_ptr<Region> find_next_region (framepos_t frame, RegionPoint point, int dir);
175  framepos_t find_next_region_boundary (framepos_t frame, int dir);
176  bool region_is_shuffle_constrained (boost::shared_ptr<Region>);
177  bool has_region_at (framepos_t const) const;
178 
179  bool uses_source (boost::shared_ptr<const Source> src) const;
180 
181  framepos_t find_next_transient (framepos_t position, int dir);
182 
183  void foreach_region (boost::function<void (boost::shared_ptr<Region>)>);
184 
185  XMLNode& get_state ();
186  virtual int set_state (const XMLNode&, int version);
187  XMLNode& get_template ();
188 
189  PBD::Signal1<void,bool> InUse;
190  PBD::Signal0<void> ContentsChanged;
191  PBD::Signal1<void,boost::weak_ptr<Region> > RegionAdded;
192  PBD::Signal1<void,boost::weak_ptr<Region> > RegionRemoved;
193  PBD::Signal0<void> NameChanged;
194  PBD::Signal0<void> LayeringChanged;
195 
197  PBD::Signal2<void,std::list< Evoral::RangeMove<framepos_t> > const &, bool> RangesMoved;
198 
202  PBD::Signal1<void,std::list< Evoral::Range<framepos_t> > const &> RegionsExtended;
203 
204  static std::string bump_name (std::string old_name, Session&);
205 
206  void freeze ();
207  void thaw (bool from_undo = false);
208 
209  void raise_region (boost::shared_ptr<Region>);
210  void lower_region (boost::shared_ptr<Region>);
211  void raise_region_to_top (boost::shared_ptr<Region>);
212  void lower_region_to_bottom (boost::shared_ptr<Region>);
213 
214  const PBD::ID& get_orig_track_id () const { return _orig_track_id; }
215  void set_orig_track_id (const PBD::ID& did);
216 
217  /* destructive editing */
218 
219  virtual bool destroy_region (boost::shared_ptr<Region>) = 0;
220 
221  void sync_all_regions_with_regions ();
222 
223  /* special case function used by UI selection objects, which have playlists that actually own the regions
224  within them.
225  */
226 
227  void drop_regions ();
228 
231  }
232 
233  framepos_t find_next_top_layer_position (framepos_t) const;
234  uint32_t combine_ops() const { return _combine_ops; }
235 
236  void set_layer (boost::shared_ptr<Region>, double);
237 
238  void set_capture_insertion_in_progress (bool yn);
239 
240  protected:
241  friend class Session;
242 
243  protected:
244  class RegionReadLock : public Glib::Threads::RWLock::ReaderLock {
245  public:
246  RegionReadLock (Playlist *pl) : Glib::Threads::RWLock::ReaderLock (pl->region_lock) {}
248  };
249 
250  class RegionWriteLock : public Glib::Threads::RWLock::WriterLock {
251  public:
252  RegionWriteLock (Playlist *pl, bool do_block_notify = true)
253  : Glib::Threads::RWLock::WriterLock (pl->region_lock)
254  , playlist (pl)
255  , block_notify (do_block_notify) {
256  if (block_notify) {
257  playlist->delay_notifications();
258  }
259  }
260 
262  Glib::Threads::RWLock::WriterLock::release ();
263  if (block_notify) {
264  playlist->release_notifications ();
265  }
266  }
269  };
270 
271  RegionListProperty regions; /* the current list of regions in the playlist */
272  std::set<boost::shared_ptr<Region> > all_regions; /* all regions ever added to this playlist */
275  int _sort_id;
276  mutable gint block_notifications;
277  mutable gint ignore_state_changes;
278  std::set<boost::shared_ptr<Region> > pending_adds;
279  std::set<boost::shared_ptr<Region> > pending_removes;
283 
288  std::list< Evoral::RangeMove<framepos_t> > pending_range_moves;
290  std::list< Evoral::Range<framepos_t> > pending_region_extensions;
291  uint32_t in_set_state;
292  bool in_undo;
294  bool _hidden;
295  bool _splicing;
296  bool _rippling;
298  bool _nudging;
299  uint32_t _refcnt;
301  bool in_flush;
303  bool _frozen;
305  uint32_t subcnt;
307  uint32_t _combine_ops;
308 
309  void init (bool hide);
310 
311  bool holding_state () const {
312  return g_atomic_int_get (&block_notifications) != 0 ||
313  g_atomic_int_get (&ignore_state_changes) != 0;
314  }
315 
316  void delay_notifications ();
317  void release_notifications (bool from_undo = false);
318  virtual void flush_notifications (bool from_undo = false);
319  void clear_pending ();
320 
321  void _set_sort_id ();
322 
323  boost::shared_ptr<RegionList> regions_touched_locked (framepos_t start, framepos_t end);
324 
325  void notify_region_removed (boost::shared_ptr<Region>);
326  void notify_region_added (boost::shared_ptr<Region>);
327  void notify_layering_changed ();
328  void notify_contents_changed ();
329  void notify_state_changed (const PBD::PropertyChange&);
330  void notify_region_moved (boost::shared_ptr<Region>);
331  void notify_region_start_trimmed (boost::shared_ptr<Region>);
332  void notify_region_end_trimmed (boost::shared_ptr<Region>);
333 
334  void mark_session_dirty();
335 
336  void region_changed_proxy (const PBD::PropertyChange&, boost::weak_ptr<Region>);
337  virtual bool region_changed (const PBD::PropertyChange&, boost::shared_ptr<Region>);
338 
339  void region_bounds_changed (const PBD::PropertyChange&, boost::shared_ptr<Region>);
340  void region_deleted (boost::shared_ptr<Region>);
341 
342  void sort_regions ();
343 
344  void possibly_splice (framepos_t at, framecnt_t distance, boost::shared_ptr<Region> exclude = boost::shared_ptr<Region>());
345  void possibly_splice_unlocked(framepos_t at, framecnt_t distance, boost::shared_ptr<Region> exclude = boost::shared_ptr<Region>());
346 
347  void core_splice (framepos_t at, framecnt_t distance, boost::shared_ptr<Region> exclude);
348  void splice_locked (framepos_t at, framecnt_t distance, boost::shared_ptr<Region> exclude);
349  void splice_unlocked (framepos_t at, framecnt_t distance, boost::shared_ptr<Region> exclude);
350 
351  void core_ripple (framepos_t at, framecnt_t distance, RegionList *exclude);
352  void ripple_locked (framepos_t at, framecnt_t distance, RegionList *exclude);
353  void ripple_unlocked (framepos_t at, framecnt_t distance, RegionList *exclude);
354 
355 
356  virtual void remove_dependents (boost::shared_ptr<Region> /*region*/) {}
357 
358  virtual XMLNode& state (bool);
359 
360  bool add_region_internal (boost::shared_ptr<Region>, framepos_t position);
361 
362  int remove_region_internal (boost::shared_ptr<Region>);
363  void copy_regions (RegionList&) const;
364  void partition_internal (framepos_t start, framepos_t end, bool cutting, RegionList& thawlist);
365 
366  std::pair<framepos_t, framepos_t> _get_extent() const;
367 
369  std::list<AudioRange>& ranges, bool result_is_hidden);
370  boost::shared_ptr<Playlist> cut (framepos_t start, framecnt_t cnt, bool result_is_hidden);
371  boost::shared_ptr<Playlist> copy (framepos_t start, framecnt_t cnt, bool result_is_hidden);
372 
373  void relayer ();
374 
375  void begin_undo ();
376  void end_undo ();
377 
378  void _split_region (boost::shared_ptr<Region>, framepos_t position);
379 
380  typedef std::pair<boost::shared_ptr<Region>, boost::shared_ptr<Region> > TwoRegions;
381 
382  /* this is called before we create a new compound region */
383  virtual void pre_combine (std::vector<boost::shared_ptr<Region> >&) {}
384  /* this is called before we create a new compound region */
386  /* this is called before we remove a compound region and replace it
387  with its constituent regions
388  */
390 
391  private:
392  friend class RegionReadLock;
393  friend class RegionWriteLock;
394  mutable Glib::Threads::RWLock region_lock;
395 
396  private:
397  void setup_layering_indices (RegionList const &);
398  void coalesce_and_check_crossfades (std::list<Evoral::Range<framepos_t> >);
399  boost::shared_ptr<RegionList> find_regions_at (framepos_t);
400 
401  framepos_t _end_space; //this is used when we are pasting a range with extra space at the end
402 };
403 
404 } /* namespace ARDOUR */
405 
406 #endif /* __ardour_playlist_h__ */
407 
408 
virtual void pre_uncombine(std::vector< boost::shared_ptr< Region > > &, boost::shared_ptr< Region >)
Definition: playlist.h:389
bool _capture_insertion_underway
Definition: playlist.h:304
EditMode get_edit_mode() const
Definition: playlist.h:126
framepos_t _end_space
Definition: playlist.h:401
bool frozen() const
Definition: playlist.h:115
bool used() const
Definition: playlist.h:108
LIBARDOUR_API PBD::PropertyDescriptor< bool > hidden
Definition: route_group.h:50
const DataType & data_type() const
Definition: playlist.h:113
LIBPBD_API void split(std::string, std::vector< std::string > &, char)
bool pending_contents_change
Definition: playlist.h:281
PBD::Signal0< void > ContentsChanged
Definition: playlist.h:190
LIBARDOUR_API GQuark paste
Definition: operations.cc:25
bool holding_state() const
Definition: playlist.h:311
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
Definition: region.cc:63
virtual void pre_combine(std::vector< boost::shared_ptr< Region > > &)
Definition: playlist.h:383
Glib::Threads::RWLock region_lock
Definition: playlist.h:394
gint block_notifications
Definition: playlist.h:276
Definition: id.h:32
virtual boost::shared_ptr< Crossfade > find_crossfade(const PBD::ID &) const
Definition: playlist.h:229
uint32_t _refcnt
Definition: playlist.h:299
std::list< Evoral::RangeMove< framepos_t > > pending_range_moves
Definition: playlist.h:288
uint32_t combine_ops() const
Definition: playlist.h:234
int64_t framecnt_t
Definition: types.h:76
PBD::Signal0< void > LayeringChanged
Definition: playlist.h:194
PBD::ID _orig_track_id
Definition: playlist.h:306
const PBD::ID & get_orig_track_id() const
Definition: playlist.h:214
PBD::Signal0< void > NameChanged
Definition: playlist.h:193
bool pending_layering
Definition: playlist.h:282
std::pair< boost::shared_ptr< Region >, boost::shared_ptr< Region > > TwoRegions
Definition: playlist.h:380
std::set< boost::shared_ptr< Region > > all_regions
Definition: playlist.h:272
LIBARDOUR_API PBD::PropertyDescriptor< float > shift
Definition: region.cc:71
RegionList pending_bounds
Definition: playlist.h:280
PBD::Signal1< void, boost::weak_ptr< Region > > RegionRemoved
Definition: playlist.h:192
Definition: amp.h:29
gint ignore_state_changes
Definition: playlist.h:277
PBD::Signal2< void, std::list< Evoral::RangeMove< framepos_t > > const &, bool > RangesMoved
Definition: playlist.h:197
bool hidden() const
Definition: playlist.h:118
bool first_set_state
Definition: playlist.h:293
uint32_t layer_t
Definition: types.h:59
std::set< boost::shared_ptr< Region > > pending_removes
Definition: playlist.h:279
LIBARDOUR_API void make_property_quarks()
int64_t framepos_t
Definition: types.h:66
EditMode
Definition: types.h:351
RegionListProperty regions
Definition: playlist.h:271
int64_t frameoffset_t
Definition: types.h:71
EditMode _edit_mode
Definition: playlist.h:300
LIBARDOUR_API PBD::PropertyDescriptor< bool > regions
Definition: playlist.cc:51
PBD::Signal1< void, std::list< Evoral::Range< framepos_t > > const & > RegionsExtended
Definition: playlist.h:202
uint32_t _combine_ops
Definition: playlist.h:307
DataType _type
Definition: playlist.h:274
std::list< boost::shared_ptr< Region > > RegionList
Definition: types.h:87
void ripple(framepos_t at, framecnt_t distance, boost::shared_ptr< Region > exclude)
Definition: playlist.h:150
#define LIBARDOUR_API
RegionWriteLock(Playlist *pl, bool do_block_notify=true)
Definition: playlist.h:252
const char * name
PBD::Signal1< void, boost::weak_ptr< Region > > RegionAdded
Definition: playlist.h:191
uint32_t subcnt
Definition: playlist.h:305
const RegionListProperty & region_list() const
Definition: playlist.h:163
Definition: xml++.h:95
virtual void post_combine(std::vector< boost::shared_ptr< Region > > &, boost::shared_ptr< Region >)
Definition: playlist.h:385
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > position
Definition: region.cc:65
uint32_t in_set_state
Definition: playlist.h:291
std::set< boost::shared_ptr< Region > > pending_adds
Definition: playlist.h:278
PBD::Signal1< void, bool > InUse
Definition: playlist.h:189
virtual void remove_dependents(boost::shared_ptr< Region >)
Definition: playlist.h:356
PBD::ScopedConnectionList region_state_changed_connections
Definition: playlist.h:273
std::list< Evoral::Range< framepos_t > > pending_region_extensions
Definition: playlist.h:290
RegionPoint
Definition: types.h:369
LIBARDOUR_API bool init(bool with_vst, bool try_optimization, const char *localedir)
Definition: globals.cc:376