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;
41 AudioPlaylist::State::~State ()
45 AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden)
46 : Playlist (session, node, hidden)
52 save_state (_("initial state"));
55 PlaylistCreated (this); /* EMIT SIGNAL */
59 AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden)
60 : Playlist (session, name, hidden)
62 save_state (_("initial state"));
65 PlaylistCreated (this); /* EMIT SIGNAL */
70 AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, string name, bool hidden)
71 : Playlist (other, name, hidden)
73 save_state (_("initial state"));
75 list<Region*>::const_iterator in_o = other.regions.begin();
76 list<Region*>::iterator in_n = regions.begin();
78 while (in_o != other.regions.end()) {
79 AudioRegion *ar = dynamic_cast<AudioRegion *>( (*in_o) );
81 // We look only for crossfades which begin with the current region, so we don't get doubles
82 for (list<Crossfade *>::const_iterator xfades = other._crossfades.begin(); xfades != other._crossfades.end(); ++xfades) {
83 if ( &(*xfades)->in() == ar) {
84 // We found one! Now copy it!
86 list<Region*>::const_iterator out_o = other.regions.begin();
87 list<Region*>::const_iterator out_n = regions.begin();
89 while (out_o != other.regions.end()) {
91 AudioRegion *ar2 = dynamic_cast<AudioRegion *>( (*out_o) );
93 if ( &(*xfades)->out() == ar2) {
94 AudioRegion *in = dynamic_cast<AudioRegion*>( (*in_n) );
95 AudioRegion *out = dynamic_cast<AudioRegion*>( (*out_n) );
96 Crossfade *new_fade = new Crossfade( *(*xfades), in, out);
97 add_crossfade(*new_fade);
104 // cerr << "HUH!? second region in the crossfade not found!" << endl;
113 PlaylistCreated (this); /* EMIT SIGNAL */
117 AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden)
118 : Playlist (other, start, cnt, name, hidden)
120 save_state (_("initial state"));
122 /* this constructor does NOT notify others (session) */
125 AudioPlaylist::~AudioPlaylist ()
127 set<Crossfade*> all_xfades;
128 set<Region*> all_regions;
132 /* find every region we've ever used, and add it to the set of
133 all regions. same for xfades;
136 for (RegionList::iterator x = regions.begin(); x != regions.end(); ++x) {
137 all_regions.insert (*x);
140 for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end(); ++x) {
141 all_xfades.insert (*x);
144 for (StateMap::iterator i = states.begin(); i != states.end(); ++i) {
146 AudioPlaylist::State* apstate = dynamic_cast<AudioPlaylist::State*> (*i);
148 for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
149 all_regions.insert (*r);
151 for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
152 all_xfades.insert (*xf);
158 /* delete every region */
160 for (set<Region *>::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
161 (*ar)->unlock_sources ();
165 /* delete every crossfade */
167 for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) {
172 struct RegionSortByLayer {
173 bool operator() (Region *a, Region *b) {
174 return a->layer() < b->layer();
179 AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, char * workbuf, jack_nframes_t start,
180 jack_nframes_t cnt, unsigned chan_n)
182 jack_nframes_t ret = cnt;
184 jack_nframes_t read_frames;
185 jack_nframes_t skip_frames;
187 /* optimizing this memset() away involves a lot of conditionals
188 that may well cause more of a hit due to cache misses
189 and related stuff than just doing this here.
191 it would be great if someone could measure this
194 one way or another, parts of the requested area
195 that are not written to by Region::region_at()
196 for all Regions that cover the area need to be
200 memset (buf, 0, sizeof (Sample) * cnt);
202 /* this function is never called from a realtime thread, so
203 its OK to block (for short intervals).
206 LockMonitor rm (region_lock, __LINE__, __FILE__);
208 end = start + cnt - 1;
212 _read_data_count = 0;
214 map<uint32_t,vector<Region*> > relevant_regions;
215 map<uint32_t,vector<Crossfade*> > relevant_xfades;
216 vector<uint32_t> relevant_layers;
218 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
219 if ((*i)->coverage (start, end) != OverlapNone) {
221 relevant_regions[(*i)->layer()].push_back (*i);
222 relevant_layers.push_back ((*i)->layer());
226 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
227 if ((*i)->coverage (start, end) != OverlapNone) {
228 relevant_xfades[(*i)->upper_layer()].push_back (*i);
232 // RegionSortByLayer layer_cmp;
233 // relevant_regions.sort (layer_cmp);
235 /* XXX this whole per-layer approach is a hack that
236 should be removed once Crossfades become
237 CrossfadeRegions and we just grab a list of relevant
238 regions and call read_at() on all of them.
241 sort (relevant_layers.begin(), relevant_layers.end());
243 for (vector<uint32_t>::iterator l = relevant_layers.begin(); l != relevant_layers.end(); ++l) {
245 vector<Region*>& r (relevant_regions[*l]);
246 vector<Crossfade*>& x (relevant_xfades[*l]);
248 for (vector<Region*>::iterator i = r.begin(); i != r.end(); ++i) {
249 (*i)->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n, read_frames, skip_frames);
250 _read_data_count += (*i)->read_data_count();
253 for (vector<Crossfade*>::iterator i = x.begin(); i != x.end(); ++i) {
255 (*i)->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n);
257 /* don't JACK up _read_data_count, since its the same data as we just
258 read from the regions, and the OS should handle that for us.
268 AudioPlaylist::remove_dependents (Region& region)
270 Crossfades::iterator i, tmp;
271 AudioRegion* r = dynamic_cast<AudioRegion*> (®ion);
274 fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
279 for (i = _crossfades.begin(); i != _crossfades.end(); ) {
283 if ((*i)->involves (*r)) {
284 /* do not delete crossfades */
285 _crossfades.erase (i);
294 AudioPlaylist::flush_notifications ()
296 Playlist::flush_notifications();
304 Crossfades::iterator a;
305 for (a = _pending_xfade_adds.begin(); a != _pending_xfade_adds.end(); ++a) {
306 NewCrossfade (*a); /* EMIT SIGNAL */
309 _pending_xfade_adds.clear ();
315 AudioPlaylist::refresh_dependents (Region& r)
317 AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
318 set<Crossfade*> updated;
324 for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) {
326 Crossfades::iterator tmp;
331 /* only update them once */
333 if ((*x)->involves (*ar)) {
335 if (find (updated.begin(), updated.end(), *x) == updated.end()) {
336 if ((*x)->refresh ()) {
337 /* not invalidated by the refresh */
348 AudioPlaylist::finalize_split_region (Region *o, Region *l, Region *r)
350 AudioRegion *orig = dynamic_cast<AudioRegion*>(o);
351 AudioRegion *left = dynamic_cast<AudioRegion*>(l);
352 AudioRegion *right = dynamic_cast<AudioRegion*>(r);
354 for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) {
355 Crossfades::iterator tmp;
361 if ((*x)->_in == orig) {
362 if (! (*x)->covers(right->position())) {
363 fade = new Crossfade( *(*x), left, (*x)->_out);
365 // Overlap, the crossfade is copied on the left side of the right region instead
366 fade = new Crossfade( *(*x), right, (*x)->_out);
370 if ((*x)->_out == orig) {
371 if (! (*x)->covers(right->position())) {
372 fade = new Crossfade( *(*x), (*x)->_in, right);
374 // Overlap, the crossfade is copied on the right side of the left region instead
375 fade = new Crossfade( *(*x), (*x)->_in, left);
380 _crossfades.remove( (*x) );
381 add_crossfade (*fade);
388 AudioPlaylist::check_dependents (Region& r, bool norefresh)
396 if (in_set_state || in_partition) {
400 if ((region = dynamic_cast<AudioRegion*> (&r)) == 0) {
401 fatal << _("programming error: non-audio Region tested for overlap in audio playlist")
407 refresh_dependents (r);
410 if (!Config->get_auto_xfade()) {
414 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
416 other = dynamic_cast<AudioRegion*> (*i);
418 if (other == region) {
422 if (other->muted() || region->muted()) {
426 if (other->layer() < region->layer()) {
436 if (top->coverage (bottom->position(), bottom->last_frame()) != OverlapNone) {
438 /* check if the upper region is within the lower region */
440 if (top->first_frame() > bottom->first_frame() &&
441 top->last_frame() < bottom->last_frame()) {
444 /* [ -------- top ------- ]
445 * {=========== bottom =============}
448 /* to avoid discontinuities at the region boundaries of an internal
449 overlap (this region is completely within another), we create
450 two hidden crossfades at each boundary. this is not dependent
451 on the auto-xfade option, because we require it as basic
455 jack_nframes_t xfade_length = min ((jack_nframes_t) 720, top->length());
458 xfade = new Crossfade (*top, *bottom, xfade_length, top->first_frame(), StartOfIn);
459 add_crossfade (*xfade);
460 xfade = new Crossfade (*bottom, *top, xfade_length, top->last_frame() - xfade_length, EndOfOut);
461 add_crossfade (*xfade);
465 xfade = new Crossfade (*other, *region, _session.get_xfade_model(), _session.get_crossfades_active());
466 add_crossfade (*xfade);
471 catch (failed_constructor& err) {
475 catch (Crossfade::NoCrossfadeHere& err) {
483 AudioPlaylist::add_crossfade (Crossfade& xfade)
485 Crossfades::iterator ci;
487 for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) {
488 if (*(*ci) == xfade) { // Crossfade::operator==()
493 if (ci != _crossfades.end()) {
496 _crossfades.push_back (&xfade);
498 xfade.Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
499 xfade.StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
501 notify_crossfade_added (&xfade);
505 void AudioPlaylist::notify_crossfade_added (Crossfade *x)
507 if (atomic_read(&block_notifications)) {
508 _pending_xfade_adds.insert (_pending_xfade_adds.end(), x);
510 NewCrossfade (x); /* EMIT SIGNAL */
515 AudioPlaylist::crossfade_invalidated (Crossfade* xfade)
517 Crossfades::iterator i;
519 xfade->in().resume_fade_in ();
520 xfade->out().resume_fade_out ();
522 if ((i = find (_crossfades.begin(), _crossfades.end(), xfade)) != _crossfades.end()) {
523 _crossfades.erase (i);
528 AudioPlaylist::set_state (const XMLNode& node)
532 XMLNodeConstIterator niter;
535 Playlist::set_state (node);
538 nlist = node.children();
540 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
544 if (child->name() == "Crossfade") {
549 xfade = new Crossfade (*((const Playlist *)this), *child);
552 catch (failed_constructor& err) {
553 // cout << string_compose (_("could not create crossfade object in playlist %1"),
559 Crossfades::iterator ci;
561 for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) {
562 if (*(*ci) == *xfade) {
567 if (ci == _crossfades.end()) {
568 _crossfades.push_back (xfade);
569 xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
570 xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
571 /* no need to notify here */
583 AudioPlaylist::drop_all_states ()
585 set<Crossfade*> all_xfades;
586 set<Region*> all_regions;
588 /* find every region we've ever used, and add it to the set of
589 all regions. same for xfades;
592 for (StateMap::iterator i = states.begin(); i != states.end(); ++i) {
594 AudioPlaylist::State* apstate = dynamic_cast<AudioPlaylist::State*> (*i);
596 for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
597 all_regions.insert (*r);
599 for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
600 all_xfades.insert (*xf);
604 /* now remove from the "all" lists every region that is in the current list. */
606 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
607 set<Region*>::iterator x = all_regions.find (*i);
608 if (x != all_regions.end()) {
609 all_regions.erase (x);
613 /* ditto for every crossfade */
615 for (list<Crossfade*>::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
616 set<Crossfade*>::iterator x = all_xfades.find (*i);
617 if (x != all_xfades.end()) {
618 all_xfades.erase (x);
622 /* delete every region that is left - these are all things that are part of our "history" */
624 for (set<Region *>::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
625 (*ar)->unlock_sources ();
629 /* delete every crossfade that is left (ditto as per regions) */
631 for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) {
635 /* Now do the generic thing ... */
637 StateManager::drop_all_states ();
641 AudioPlaylist::state_factory (std::string why) const
643 State* state = new State (why);
645 state->regions = regions;
646 state->region_states.clear ();
647 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
648 state->region_states.push_back ((*i)->get_memento());
651 state->crossfades = _crossfades;
652 state->crossfade_states.clear ();
653 for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
654 state->crossfade_states.push_back ((*i)->get_memento());
660 AudioPlaylist::restore_state (StateManager::State& state)
663 RegionLock rlock (this);
664 State* apstate = dynamic_cast<State*> (&state);
668 regions = apstate->regions;
670 for (list<UndoAction>::iterator s = apstate->region_states.begin(); s != apstate->region_states.end(); ++s) {
674 _crossfades = apstate->crossfades;
676 for (list<UndoAction>::iterator s = apstate->crossfade_states.begin(); s != apstate->crossfade_states.end(); ++s) {
680 in_set_state = false;
683 notify_length_changed ();
688 AudioPlaylist::get_memento () const
690 return sigc::bind (mem_fun (*(const_cast<AudioPlaylist*> (this)), &StateManager::use_state), _current_state_id);
694 AudioPlaylist::clear (bool with_delete, bool with_save)
697 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
702 _crossfades.clear ();
704 Playlist::clear (with_delete, with_save);
708 AudioPlaylist::state (bool full_state)
710 XMLNode& node = Playlist::state (full_state);
713 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
714 node.add_child_nocopy ((*i)->get_state());
722 AudioPlaylist::dump () const
727 cerr << "Playlist \"" << _name << "\" " << endl
728 << regions.size() << " regions "
729 << _crossfades.size() << " crossfades"
732 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
734 cerr << " " << r->name() << " @ " << r << " ["
735 << r->start() << "+" << r->length()
743 for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
754 << (x->active() ? "yes" : "no")
760 AudioPlaylist::destroy_region (Region* region)
762 AudioRegion* r = dynamic_cast<AudioRegion*> (region);
763 bool changed = false;
764 Crossfades::iterator c, ctmp;
765 set<Crossfade*> unique_xfades;
768 fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
775 RegionLock rlock (this);
776 RegionList::iterator i;
777 RegionList::iterator tmp;
779 for (i = regions.begin(); i != regions.end(); ) {
784 if ((*i) == region) {
785 (*i)->unlock_sources ();
794 for (c = _crossfades.begin(); c != _crossfades.end(); ) {
798 if ((*c)->involves (*r)) {
799 unique_xfades.insert (*c);
800 _crossfades.erase (c);
806 for (StateMap::iterator s = states.begin(); s != states.end(); ) {
807 StateMap::iterator tmp;
812 State* astate = dynamic_cast<State*> (*s);
814 for (c = astate->crossfades.begin(); c != astate->crossfades.end(); ) {
819 if ((*c)->involves (*r)) {
820 unique_xfades.insert (*c);
821 _crossfades.erase (c);
827 list<UndoAction>::iterator rsi, rsitmp;
828 RegionList::iterator ri, ritmp;
830 for (ri = astate->regions.begin(), rsi = astate->region_states.begin();
831 ri != astate->regions.end() && rsi != astate->region_states.end();) {
840 if (region == (*ri)) {
841 astate->regions.erase (ri);
842 astate->region_states.erase (rsi);
852 for (set<Crossfade*>::iterator c = unique_xfades.begin(); c != unique_xfades.end(); ++c) {
857 /* overload this, it normally means "removed", not destroyed */
858 notify_region_removed (region);
865 AudioPlaylist::crossfade_changed (Change ignored)
867 if (in_flush || in_set_state) {
871 /* XXX is there a loop here? can an xfade change not happen
872 due to a playlist change? well, sure activation would
873 be an example. maybe we should check the type of change
877 maybe_save_state (_("xfade change"));
883 AudioPlaylist::get_equivalent_regions (const AudioRegion& other, vector<AudioRegion*>& results)
885 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
887 AudioRegion* ar = dynamic_cast<AudioRegion*> (*i);
889 if (ar && ar->equivalent (other)) {
890 results.push_back (ar);
896 AudioPlaylist::get_region_list_equivalent_regions (const AudioRegion& other, vector<AudioRegion*>& results)
898 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
900 AudioRegion* ar = dynamic_cast<AudioRegion*> (*i);
902 if (ar && ar->region_list_equivalent (other)) {
903 results.push_back (ar);
909 AudioPlaylist::region_changed (Change what_changed, Region* region)
911 if (in_flush || in_set_state) {
915 Change our_interests = Change (AudioRegion::FadeInChanged|
916 AudioRegion::FadeOutChanged|
917 AudioRegion::FadeInActiveChanged|
918 AudioRegion::FadeOutActiveChanged|
919 AudioRegion::EnvelopeActiveChanged|
920 AudioRegion::ScaleAmplitudeChanged|
921 AudioRegion::EnvelopeChanged);
922 bool parent_wants_notify;
924 parent_wants_notify = Playlist::region_changed (what_changed, region);
926 maybe_save_state (_("region modified"));
928 if ((parent_wants_notify || (what_changed & our_interests))) {
936 AudioPlaylist::crossfades_at (jack_nframes_t frame, Crossfades& clist)
938 RegionLock rlock (this);
940 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
941 jack_nframes_t start, end;
943 start = (*i)->position();
944 end = start + (*i)->overlap_length(); // not length(), important difference
946 if (frame >= start && frame <= end) {
947 clist.push_back (*i);