2 Copyright (C) 2003 Paul Davis
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.
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.
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.
25 #include <sigc++/bind.h>
27 #include <ardour/types.h>
28 #include <ardour/configuration.h>
29 #include <ardour/audioplaylist.h>
30 #include <ardour/audioregion.h>
31 #include <ardour/crossfade.h>
32 #include <ardour/crossfade_compare.h>
33 #include <ardour/session.h>
37 using namespace ARDOUR;
42 AudioPlaylist::State::~State ()
46 AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden)
47 : Playlist (session, node, hidden)
53 save_state (_("initial state"));
56 PlaylistCreated (this); /* EMIT SIGNAL */
60 AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden)
61 : Playlist (session, name, hidden)
63 save_state (_("initial state"));
66 PlaylistCreated (this); /* EMIT SIGNAL */
71 AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, string name, bool hidden)
72 : Playlist (other, name, hidden)
74 save_state (_("initial state"));
76 list<Region*>::const_iterator in_o = other.regions.begin();
77 list<Region*>::iterator in_n = regions.begin();
79 while (in_o != other.regions.end()) {
80 AudioRegion *ar = dynamic_cast<AudioRegion *>( (*in_o) );
82 // We look only for crossfades which begin with the current region, so we don't get doubles
83 for (list<Crossfade *>::const_iterator xfades = other._crossfades.begin(); xfades != other._crossfades.end(); ++xfades) {
84 if ( &(*xfades)->in() == ar) {
85 // We found one! Now copy it!
87 list<Region*>::const_iterator out_o = other.regions.begin();
88 list<Region*>::const_iterator out_n = regions.begin();
90 while (out_o != other.regions.end()) {
92 AudioRegion *ar2 = dynamic_cast<AudioRegion *>( (*out_o) );
94 if ( &(*xfades)->out() == ar2) {
95 AudioRegion *in = dynamic_cast<AudioRegion*>( (*in_n) );
96 AudioRegion *out = dynamic_cast<AudioRegion*>( (*out_n) );
97 Crossfade *new_fade = new Crossfade( *(*xfades), in, out);
98 add_crossfade(*new_fade);
105 // cerr << "HUH!? second region in the crossfade not found!" << endl;
114 PlaylistCreated (this); /* EMIT SIGNAL */
118 AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden)
119 : Playlist (other, start, cnt, name, hidden)
121 save_state (_("initial state"));
123 /* this constructor does NOT notify others (session) */
126 AudioPlaylist::~AudioPlaylist ()
128 set<Crossfade*> all_xfades;
129 set<Region*> all_regions;
133 /* find every region we've ever used, and add it to the set of
134 all regions. same for xfades;
137 for (RegionList::iterator x = regions.begin(); x != regions.end(); ++x) {
138 all_regions.insert (*x);
141 for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end(); ++x) {
142 all_xfades.insert (*x);
145 for (StateMap::iterator i = states.begin(); i != states.end(); ++i) {
147 AudioPlaylist::State* apstate = dynamic_cast<AudioPlaylist::State*> (*i);
149 for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
150 all_regions.insert (*r);
152 for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
153 all_xfades.insert (*xf);
159 /* delete every region */
161 for (set<Region *>::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
162 (*ar)->unlock_sources ();
166 /* delete every crossfade */
168 for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) {
173 struct RegionSortByLayer {
174 bool operator() (Region *a, Region *b) {
175 return a->layer() < b->layer();
180 AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, char * workbuf, jack_nframes_t start,
181 jack_nframes_t cnt, unsigned chan_n)
183 jack_nframes_t ret = cnt;
185 jack_nframes_t read_frames;
186 jack_nframes_t skip_frames;
188 /* optimizing this memset() away involves a lot of conditionals
189 that may well cause more of a hit due to cache misses
190 and related stuff than just doing this here.
192 it would be great if someone could measure this
195 one way or another, parts of the requested area
196 that are not written to by Region::region_at()
197 for all Regions that cover the area need to be
201 memset (buf, 0, sizeof (Sample) * cnt);
203 /* this function is never called from a realtime thread, so
204 its OK to block (for short intervals).
207 Glib::Mutex::Lock rm (region_lock);
209 end = start + cnt - 1;
213 _read_data_count = 0;
215 map<uint32_t,vector<Region*> > relevant_regions;
216 map<uint32_t,vector<Crossfade*> > relevant_xfades;
217 vector<uint32_t> relevant_layers;
219 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
220 if ((*i)->coverage (start, end) != OverlapNone) {
222 relevant_regions[(*i)->layer()].push_back (*i);
223 relevant_layers.push_back ((*i)->layer());
227 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
228 if ((*i)->coverage (start, end) != OverlapNone) {
229 relevant_xfades[(*i)->upper_layer()].push_back (*i);
233 // RegionSortByLayer layer_cmp;
234 // relevant_regions.sort (layer_cmp);
236 /* XXX this whole per-layer approach is a hack that
237 should be removed once Crossfades become
238 CrossfadeRegions and we just grab a list of relevant
239 regions and call read_at() on all of them.
242 sort (relevant_layers.begin(), relevant_layers.end());
244 for (vector<uint32_t>::iterator l = relevant_layers.begin(); l != relevant_layers.end(); ++l) {
246 vector<Region*>& r (relevant_regions[*l]);
247 vector<Crossfade*>& x (relevant_xfades[*l]);
249 for (vector<Region*>::iterator i = r.begin(); i != r.end(); ++i) {
250 (*i)->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n, read_frames, skip_frames);
251 _read_data_count += (*i)->read_data_count();
254 for (vector<Crossfade*>::iterator i = x.begin(); i != x.end(); ++i) {
256 (*i)->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n);
258 /* don't JACK up _read_data_count, since its the same data as we just
259 read from the regions, and the OS should handle that for us.
269 AudioPlaylist::remove_dependents (Region& region)
271 Crossfades::iterator i, tmp;
272 AudioRegion* r = dynamic_cast<AudioRegion*> (®ion);
275 fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
280 for (i = _crossfades.begin(); i != _crossfades.end(); ) {
284 if ((*i)->involves (*r)) {
285 /* do not delete crossfades */
286 _crossfades.erase (i);
295 AudioPlaylist::flush_notifications ()
297 Playlist::flush_notifications();
305 Crossfades::iterator a;
306 for (a = _pending_xfade_adds.begin(); a != _pending_xfade_adds.end(); ++a) {
307 NewCrossfade (*a); /* EMIT SIGNAL */
310 _pending_xfade_adds.clear ();
316 AudioPlaylist::refresh_dependents (Region& r)
318 AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
319 set<Crossfade*> updated;
325 for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) {
327 Crossfades::iterator tmp;
332 /* only update them once */
334 if ((*x)->involves (*ar)) {
336 if (find (updated.begin(), updated.end(), *x) == updated.end()) {
337 if ((*x)->refresh ()) {
338 /* not invalidated by the refresh */
349 AudioPlaylist::finalize_split_region (Region *o, Region *l, Region *r)
351 AudioRegion *orig = dynamic_cast<AudioRegion*>(o);
352 AudioRegion *left = dynamic_cast<AudioRegion*>(l);
353 AudioRegion *right = dynamic_cast<AudioRegion*>(r);
355 for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) {
356 Crossfades::iterator tmp;
362 if ((*x)->_in == orig) {
363 if (! (*x)->covers(right->position())) {
364 fade = new Crossfade( *(*x), left, (*x)->_out);
366 // Overlap, the crossfade is copied on the left side of the right region instead
367 fade = new Crossfade( *(*x), right, (*x)->_out);
371 if ((*x)->_out == orig) {
372 if (! (*x)->covers(right->position())) {
373 fade = new Crossfade( *(*x), (*x)->_in, right);
375 // Overlap, the crossfade is copied on the right side of the left region instead
376 fade = new Crossfade( *(*x), (*x)->_in, left);
381 _crossfades.remove( (*x) );
382 add_crossfade (*fade);
389 AudioPlaylist::check_dependents (Region& r, bool norefresh)
397 if (in_set_state || in_partition) {
401 if ((region = dynamic_cast<AudioRegion*> (&r)) == 0) {
402 fatal << _("programming error: non-audio Region tested for overlap in audio playlist")
408 refresh_dependents (r);
411 if (!Config->get_auto_xfade()) {
415 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
417 other = dynamic_cast<AudioRegion*> (*i);
419 if (other == region) {
423 if (other->muted() || region->muted()) {
427 if (other->layer() < region->layer()) {
437 if (top->coverage (bottom->position(), bottom->last_frame()) != OverlapNone) {
439 /* check if the upper region is within the lower region */
441 if (top->first_frame() > bottom->first_frame() &&
442 top->last_frame() < bottom->last_frame()) {
445 /* [ -------- top ------- ]
446 * {=========== bottom =============}
449 /* to avoid discontinuities at the region boundaries of an internal
450 overlap (this region is completely within another), we create
451 two hidden crossfades at each boundary. this is not dependent
452 on the auto-xfade option, because we require it as basic
456 jack_nframes_t xfade_length = min ((jack_nframes_t) 720, top->length());
459 xfade = new Crossfade (*top, *bottom, xfade_length, top->first_frame(), StartOfIn);
460 add_crossfade (*xfade);
461 xfade = new Crossfade (*bottom, *top, xfade_length, top->last_frame() - xfade_length, EndOfOut);
462 add_crossfade (*xfade);
466 xfade = new Crossfade (*other, *region, _session.get_xfade_model(), _session.get_crossfades_active());
467 add_crossfade (*xfade);
472 catch (failed_constructor& err) {
476 catch (Crossfade::NoCrossfadeHere& err) {
484 AudioPlaylist::add_crossfade (Crossfade& xfade)
486 Crossfades::iterator ci;
488 for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) {
489 if (*(*ci) == xfade) { // Crossfade::operator==()
494 if (ci != _crossfades.end()) {
497 _crossfades.push_back (&xfade);
499 xfade.Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
500 xfade.StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
502 notify_crossfade_added (&xfade);
506 void AudioPlaylist::notify_crossfade_added (Crossfade *x)
508 if (g_atomic_int_get(&block_notifications)) {
509 _pending_xfade_adds.insert (_pending_xfade_adds.end(), x);
511 NewCrossfade (x); /* EMIT SIGNAL */
516 AudioPlaylist::crossfade_invalidated (Crossfade* xfade)
518 Crossfades::iterator i;
520 xfade->in().resume_fade_in ();
521 xfade->out().resume_fade_out ();
523 if ((i = find (_crossfades.begin(), _crossfades.end(), xfade)) != _crossfades.end()) {
524 _crossfades.erase (i);
529 AudioPlaylist::set_state (const XMLNode& node)
533 XMLNodeConstIterator niter;
536 Playlist::set_state (node);
539 nlist = node.children();
541 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
545 if (child->name() == "Crossfade") {
550 xfade = new Crossfade (*((const Playlist *)this), *child);
553 catch (failed_constructor& err) {
554 // cout << string_compose (_("could not create crossfade object in playlist %1"),
560 Crossfades::iterator ci;
562 for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) {
563 if (*(*ci) == *xfade) {
568 if (ci == _crossfades.end()) {
569 _crossfades.push_back (xfade);
570 xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
571 xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
572 /* no need to notify here */
584 AudioPlaylist::drop_all_states ()
586 set<Crossfade*> all_xfades;
587 set<Region*> all_regions;
589 /* find every region we've ever used, and add it to the set of
590 all regions. same for xfades;
593 for (StateMap::iterator i = states.begin(); i != states.end(); ++i) {
595 AudioPlaylist::State* apstate = dynamic_cast<AudioPlaylist::State*> (*i);
597 for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
598 all_regions.insert (*r);
600 for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
601 all_xfades.insert (*xf);
605 /* now remove from the "all" lists every region that is in the current list. */
607 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
608 set<Region*>::iterator x = all_regions.find (*i);
609 if (x != all_regions.end()) {
610 all_regions.erase (x);
614 /* ditto for every crossfade */
616 for (list<Crossfade*>::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
617 set<Crossfade*>::iterator x = all_xfades.find (*i);
618 if (x != all_xfades.end()) {
619 all_xfades.erase (x);
623 /* delete every region that is left - these are all things that are part of our "history" */
625 for (set<Region *>::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
626 (*ar)->unlock_sources ();
630 /* delete every crossfade that is left (ditto as per regions) */
632 for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) {
636 /* Now do the generic thing ... */
638 StateManager::drop_all_states ();
642 AudioPlaylist::state_factory (std::string why) const
644 State* state = new State (why);
646 state->regions = regions;
647 state->region_states.clear ();
648 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
649 state->region_states.push_back ((*i)->get_memento());
652 state->crossfades = _crossfades;
653 state->crossfade_states.clear ();
654 for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
655 state->crossfade_states.push_back ((*i)->get_memento());
661 AudioPlaylist::restore_state (StateManager::State& state)
664 RegionLock rlock (this);
665 State* apstate = dynamic_cast<State*> (&state);
669 regions = apstate->regions;
671 for (list<UndoAction>::iterator s = apstate->region_states.begin(); s != apstate->region_states.end(); ++s) {
675 _crossfades = apstate->crossfades;
677 for (list<UndoAction>::iterator s = apstate->crossfade_states.begin(); s != apstate->crossfade_states.end(); ++s) {
681 in_set_state = false;
684 notify_length_changed ();
689 AudioPlaylist::get_memento () const
691 return sigc::bind (mem_fun (*(const_cast<AudioPlaylist*> (this)), &StateManager::use_state), _current_state_id);
695 AudioPlaylist::clear (bool with_delete, bool with_save)
698 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
703 _crossfades.clear ();
705 Playlist::clear (with_delete, with_save);
709 AudioPlaylist::state (bool full_state)
711 XMLNode& node = Playlist::state (full_state);
714 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
715 node.add_child_nocopy ((*i)->get_state());
723 AudioPlaylist::dump () const
728 cerr << "Playlist \"" << _name << "\" " << endl
729 << regions.size() << " regions "
730 << _crossfades.size() << " crossfades"
733 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
735 cerr << " " << r->name() << " @ " << r << " ["
736 << r->start() << "+" << r->length()
744 for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
755 << (x->active() ? "yes" : "no")
761 AudioPlaylist::destroy_region (Region* region)
763 AudioRegion* r = dynamic_cast<AudioRegion*> (region);
764 bool changed = false;
765 Crossfades::iterator c, ctmp;
766 set<Crossfade*> unique_xfades;
769 fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
776 RegionLock rlock (this);
777 RegionList::iterator i;
778 RegionList::iterator tmp;
780 for (i = regions.begin(); i != regions.end(); ) {
785 if ((*i) == region) {
786 (*i)->unlock_sources ();
795 for (c = _crossfades.begin(); c != _crossfades.end(); ) {
799 if ((*c)->involves (*r)) {
800 unique_xfades.insert (*c);
801 _crossfades.erase (c);
807 for (StateMap::iterator s = states.begin(); s != states.end(); ) {
808 StateMap::iterator tmp;
813 State* astate = dynamic_cast<State*> (*s);
815 for (c = astate->crossfades.begin(); c != astate->crossfades.end(); ) {
820 if ((*c)->involves (*r)) {
821 unique_xfades.insert (*c);
822 _crossfades.erase (c);
828 list<UndoAction>::iterator rsi, rsitmp;
829 RegionList::iterator ri, ritmp;
831 for (ri = astate->regions.begin(), rsi = astate->region_states.begin();
832 ri != astate->regions.end() && rsi != astate->region_states.end();) {
841 if (region == (*ri)) {
842 astate->regions.erase (ri);
843 astate->region_states.erase (rsi);
853 for (set<Crossfade*>::iterator c = unique_xfades.begin(); c != unique_xfades.end(); ++c) {
858 /* overload this, it normally means "removed", not destroyed */
859 notify_region_removed (region);
866 AudioPlaylist::crossfade_changed (Change ignored)
868 if (in_flush || in_set_state) {
872 /* XXX is there a loop here? can an xfade change not happen
873 due to a playlist change? well, sure activation would
874 be an example. maybe we should check the type of change
878 maybe_save_state (_("xfade change"));
884 AudioPlaylist::get_equivalent_regions (const AudioRegion& other, vector<AudioRegion*>& results)
886 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
888 AudioRegion* ar = dynamic_cast<AudioRegion*> (*i);
891 if (Config->get_use_overlap_equivalency()) {
892 if (ar->overlap_equivalent (other)) {
893 results.push_back (ar);
894 } else if (ar->equivalent (other)) {
895 results.push_back (ar);
903 AudioPlaylist::get_region_list_equivalent_regions (const AudioRegion& other, vector<AudioRegion*>& results)
905 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
907 AudioRegion* ar = dynamic_cast<AudioRegion*> (*i);
909 if (ar && ar->region_list_equivalent (other)) {
910 results.push_back (ar);
916 AudioPlaylist::region_changed (Change what_changed, Region* region)
918 if (in_flush || in_set_state) {
922 Change our_interests = Change (AudioRegion::FadeInChanged|
923 AudioRegion::FadeOutChanged|
924 AudioRegion::FadeInActiveChanged|
925 AudioRegion::FadeOutActiveChanged|
926 AudioRegion::EnvelopeActiveChanged|
927 AudioRegion::ScaleAmplitudeChanged|
928 AudioRegion::EnvelopeChanged);
929 bool parent_wants_notify;
931 parent_wants_notify = Playlist::region_changed (what_changed, region);
933 maybe_save_state (_("region modified"));
935 if ((parent_wants_notify || (what_changed & our_interests))) {
943 AudioPlaylist::crossfades_at (jack_nframes_t frame, Crossfades& clist)
945 RegionLock rlock (this);
947 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
948 jack_nframes_t start, end;
950 start = (*i)->position();
951 end = start + (*i)->overlap_length(); // not length(), important difference
953 if (frame >= start && frame <= end) {
954 clist.push_back (*i);