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);
98 cerr << "Here we go!" << endl;
105 // cerr << "HUH!? second region in the crossfade not found!" << endl;
117 PlaylistCreated (this); /* EMIT SIGNAL */
121 AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden)
122 : Playlist (other, start, cnt, name, hidden)
124 save_state (_("initial state"));
126 /* this constructor does NOT notify others (session) */
129 AudioPlaylist::~AudioPlaylist ()
131 set<Crossfade*> all_xfades;
132 set<Region*> all_regions;
136 /* find every region we've ever used, and add it to the set of
137 all regions. same for xfades;
140 for (RegionList::iterator x = regions.begin(); x != regions.end(); ++x) {
141 all_regions.insert (*x);
144 for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end(); ++x) {
145 all_xfades.insert (*x);
148 for (StateMap::iterator i = states.begin(); i != states.end(); ++i) {
150 AudioPlaylist::State* apstate = dynamic_cast<AudioPlaylist::State*> (*i);
152 for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
153 all_regions.insert (*r);
155 for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
156 all_xfades.insert (*xf);
162 /* delete every region */
164 for (set<Region *>::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
165 (*ar)->unlock_sources ();
169 /* delete every crossfade */
171 for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) {
176 struct RegionSortByLayer {
177 bool operator() (Region *a, Region *b) {
178 return a->layer() < b->layer();
183 AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, char * workbuf, jack_nframes_t start,
184 jack_nframes_t cnt, unsigned chan_n)
186 jack_nframes_t ret = cnt;
188 jack_nframes_t read_frames;
189 jack_nframes_t skip_frames;
191 /* optimizing this memset() away involves a lot of conditionals
192 that may well cause more of a hit due to cache misses
193 and related stuff than just doing this here.
195 it would be great if someone could measure this
198 one way or another, parts of the requested area
199 that are not written to by Region::region_at()
200 for all Regions that cover the area need to be
204 memset (buf, 0, sizeof (Sample) * cnt);
206 /* this function is never called from a realtime thread, so
207 its OK to block (for short intervals).
210 LockMonitor rm (region_lock, __LINE__, __FILE__);
212 end = start + cnt - 1;
216 _read_data_count = 0;
218 map<uint32_t,vector<Region*> > relevant_regions;
219 map<uint32_t,vector<Crossfade*> > relevant_xfades;
220 vector<uint32_t> relevant_layers;
222 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
223 if ((*i)->coverage (start, end) != OverlapNone) {
225 relevant_regions[(*i)->layer()].push_back (*i);
226 relevant_layers.push_back ((*i)->layer());
230 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
231 if ((*i)->coverage (start, end) != OverlapNone) {
232 relevant_xfades[(*i)->upper_layer()].push_back (*i);
236 // RegionSortByLayer layer_cmp;
237 // relevant_regions.sort (layer_cmp);
239 /* XXX this whole per-layer approach is a hack that
240 should be removed once Crossfades become
241 CrossfadeRegions and we just grab a list of relevant
242 regions and call read_at() on all of them.
245 sort (relevant_layers.begin(), relevant_layers.end());
247 for (vector<uint32_t>::iterator l = relevant_layers.begin(); l != relevant_layers.end(); ++l) {
249 vector<Region*>& r (relevant_regions[*l]);
250 vector<Crossfade*>& x (relevant_xfades[*l]);
252 for (vector<Region*>::iterator i = r.begin(); i != r.end(); ++i) {
253 (*i)->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n, read_frames, skip_frames);
254 _read_data_count += (*i)->read_data_count();
257 for (vector<Crossfade*>::iterator i = x.begin(); i != x.end(); ++i) {
259 (*i)->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n);
261 /* don't JACK up _read_data_count, since its the same data as we just
262 read from the regions, and the OS should handle that for us.
272 AudioPlaylist::remove_dependents (Region& region)
274 Crossfades::iterator i, tmp;
275 AudioRegion* r = dynamic_cast<AudioRegion*> (®ion);
278 fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
283 for (i = _crossfades.begin(); i != _crossfades.end(); ) {
287 if ((*i)->involves (*r)) {
288 /* do not delete crossfades */
289 _crossfades.erase (i);
298 AudioPlaylist::flush_notifications ()
300 Playlist::flush_notifications();
308 Crossfades::iterator a;
309 for (a = _pending_xfade_adds.begin(); a != _pending_xfade_adds.end(); ++a) {
310 NewCrossfade (*a); /* EMIT SIGNAL */
313 _pending_xfade_adds.clear ();
319 AudioPlaylist::refresh_dependents (Region& r)
321 AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
322 set<Crossfade*> updated;
328 for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) {
330 Crossfades::iterator tmp;
335 /* only update them once */
337 if ((*x)->involves (*ar)) {
339 if (find (updated.begin(), updated.end(), *x) == updated.end()) {
340 if ((*x)->refresh ()) {
341 /* not invalidated by the refresh */
352 AudioPlaylist::check_dependents (Region& r, bool norefresh)
360 if (in_set_state || in_partition) {
364 if ((region = dynamic_cast<AudioRegion*> (&r)) == 0) {
365 fatal << _("programming error: non-audio Region tested for overlap in audio playlist")
371 refresh_dependents (r);
374 if (!Config->get_auto_xfade()) {
378 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
380 other = dynamic_cast<AudioRegion*> (*i);
382 if (other == region) {
386 if (other->muted() || region->muted()) {
390 if (other->layer() < region->layer()) {
400 if (top->coverage (bottom->position(), bottom->last_frame()) != OverlapNone) {
402 /* check if the upper region is within the lower region */
404 if (top->first_frame() > bottom->first_frame() &&
405 top->last_frame() < bottom->last_frame()) {
408 /* [ -------- top ------- ]
409 * {=========== bottom =============}
412 /* to avoid discontinuities at the region boundaries of an internal
413 overlap (this region is completely within another), we create
414 two hidden crossfades at each boundary. this is not dependent
415 on the auto-xfade option, because we require it as basic
419 jack_nframes_t xfade_length = min ((jack_nframes_t) 720, top->length());
422 xfade = new Crossfade (*top, *bottom, xfade_length, top->first_frame(), StartOfIn);
423 add_crossfade (*xfade);
424 xfade = new Crossfade (*bottom, *top, xfade_length, top->last_frame() - xfade_length, EndOfOut);
425 add_crossfade (*xfade);
429 xfade = new Crossfade (*other, *region, _session.get_xfade_model(), _session.get_crossfades_active());
430 add_crossfade (*xfade);
435 catch (failed_constructor& err) {
439 catch (Crossfade::NoCrossfadeHere& err) {
447 AudioPlaylist::add_crossfade (Crossfade& xfade)
449 Crossfades::iterator ci;
451 for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) {
452 if (*(*ci) == xfade) { // Crossfade::operator==()
457 if (ci != _crossfades.end()) {
460 _crossfades.push_back (&xfade);
462 xfade.Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
463 xfade.StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
465 notify_crossfade_added (&xfade);
469 void AudioPlaylist::notify_crossfade_added (Crossfade *x)
471 if (atomic_read(&block_notifications)) {
472 _pending_xfade_adds.insert (_pending_xfade_adds.end(), x);
474 NewCrossfade (x); /* EMIT SIGNAL */
479 AudioPlaylist::crossfade_invalidated (Crossfade* xfade)
481 Crossfades::iterator i;
483 xfade->in().resume_fade_in ();
484 xfade->out().resume_fade_out ();
486 if ((i = find (_crossfades.begin(), _crossfades.end(), xfade)) != _crossfades.end()) {
487 _crossfades.erase (i);
492 AudioPlaylist::set_state (const XMLNode& node)
496 XMLNodeConstIterator niter;
499 Playlist::set_state (node);
502 nlist = node.children();
504 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
508 if (child->name() == "Crossfade") {
513 xfade = new Crossfade (*((const Playlist *)this), *child);
516 catch (failed_constructor& err) {
517 // cout << string_compose (_("could not create crossfade object in playlist %1"),
523 Crossfades::iterator ci;
525 for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) {
526 if (*(*ci) == *xfade) {
531 if (ci == _crossfades.end()) {
532 _crossfades.push_back (xfade);
533 xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
534 xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
535 /* no need to notify here */
547 AudioPlaylist::drop_all_states ()
549 set<Crossfade*> all_xfades;
550 set<Region*> all_regions;
552 /* find every region we've ever used, and add it to the set of
553 all regions. same for xfades;
556 for (StateMap::iterator i = states.begin(); i != states.end(); ++i) {
558 AudioPlaylist::State* apstate = dynamic_cast<AudioPlaylist::State*> (*i);
560 for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
561 all_regions.insert (*r);
563 for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
564 all_xfades.insert (*xf);
568 /* now remove from the "all" lists every region that is in the current list. */
570 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
571 set<Region*>::iterator x = all_regions.find (*i);
572 if (x != all_regions.end()) {
573 all_regions.erase (x);
577 /* ditto for every crossfade */
579 for (list<Crossfade*>::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
580 set<Crossfade*>::iterator x = all_xfades.find (*i);
581 if (x != all_xfades.end()) {
582 all_xfades.erase (x);
586 /* delete every region that is left - these are all things that are part of our "history" */
588 for (set<Region *>::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
589 (*ar)->unlock_sources ();
593 /* delete every crossfade that is left (ditto as per regions) */
595 for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) {
599 /* Now do the generic thing ... */
601 StateManager::drop_all_states ();
605 AudioPlaylist::state_factory (std::string why) const
607 State* state = new State (why);
609 state->regions = regions;
610 state->region_states.clear ();
611 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
612 state->region_states.push_back ((*i)->get_memento());
615 state->crossfades = _crossfades;
616 state->crossfade_states.clear ();
617 for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
618 state->crossfade_states.push_back ((*i)->get_memento());
624 AudioPlaylist::restore_state (StateManager::State& state)
627 RegionLock rlock (this);
628 State* apstate = dynamic_cast<State*> (&state);
632 regions = apstate->regions;
634 for (list<UndoAction>::iterator s = apstate->region_states.begin(); s != apstate->region_states.end(); ++s) {
638 _crossfades = apstate->crossfades;
640 for (list<UndoAction>::iterator s = apstate->crossfade_states.begin(); s != apstate->crossfade_states.end(); ++s) {
644 in_set_state = false;
647 notify_length_changed ();
652 AudioPlaylist::get_memento () const
654 return sigc::bind (mem_fun (*(const_cast<AudioPlaylist*> (this)), &StateManager::use_state), _current_state_id);
658 AudioPlaylist::clear (bool with_delete, bool with_save)
661 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
666 _crossfades.clear ();
668 Playlist::clear (with_delete, with_save);
672 AudioPlaylist::state (bool full_state)
674 XMLNode& node = Playlist::state (full_state);
677 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
678 node.add_child_nocopy ((*i)->get_state());
686 AudioPlaylist::dump () const
691 cerr << "Playlist \"" << _name << "\" " << endl
692 << regions.size() << " regions "
693 << _crossfades.size() << " crossfades"
696 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
698 cerr << " " << r->name() << " @ " << r << " ["
699 << r->start() << "+" << r->length()
707 for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
718 << (x->active() ? "yes" : "no")
724 AudioPlaylist::destroy_region (Region* region)
726 AudioRegion* r = dynamic_cast<AudioRegion*> (region);
727 bool changed = false;
728 Crossfades::iterator c, ctmp;
729 set<Crossfade*> unique_xfades;
732 fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
739 RegionLock rlock (this);
740 RegionList::iterator i;
741 RegionList::iterator tmp;
743 for (i = regions.begin(); i != regions.end(); ) {
748 if ((*i) == region) {
749 (*i)->unlock_sources ();
758 for (c = _crossfades.begin(); c != _crossfades.end(); ) {
762 if ((*c)->involves (*r)) {
763 unique_xfades.insert (*c);
764 _crossfades.erase (c);
770 for (StateMap::iterator s = states.begin(); s != states.end(); ) {
771 StateMap::iterator tmp;
776 State* astate = dynamic_cast<State*> (*s);
778 for (c = astate->crossfades.begin(); c != astate->crossfades.end(); ) {
783 if ((*c)->involves (*r)) {
784 unique_xfades.insert (*c);
785 _crossfades.erase (c);
791 list<UndoAction>::iterator rsi, rsitmp;
792 RegionList::iterator ri, ritmp;
794 for (ri = astate->regions.begin(), rsi = astate->region_states.begin();
795 ri != astate->regions.end() && rsi != astate->region_states.end();) {
804 if (region == (*ri)) {
805 astate->regions.erase (ri);
806 astate->region_states.erase (rsi);
816 for (set<Crossfade*>::iterator c = unique_xfades.begin(); c != unique_xfades.end(); ++c) {
821 /* overload this, it normally means "removed", not destroyed */
822 notify_region_removed (region);
829 AudioPlaylist::crossfade_changed (Change ignored)
831 if (in_flush || in_set_state) {
835 /* XXX is there a loop here? can an xfade change not happen
836 due to a playlist change? well, sure activation would
837 be an example. maybe we should check the type of change
841 maybe_save_state (_("xfade change"));
847 AudioPlaylist::get_equivalent_regions (const AudioRegion& other, vector<AudioRegion*>& results)
849 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
851 AudioRegion* ar = dynamic_cast<AudioRegion*> (*i);
853 if (ar && ar->equivalent (other)) {
854 results.push_back (ar);
860 AudioPlaylist::get_region_list_equivalent_regions (const AudioRegion& other, vector<AudioRegion*>& results)
862 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
864 AudioRegion* ar = dynamic_cast<AudioRegion*> (*i);
866 if (ar && ar->region_list_equivalent (other)) {
867 results.push_back (ar);
873 AudioPlaylist::region_changed (Change what_changed, Region* region)
875 if (in_flush || in_set_state) {
879 Change our_interests = Change (AudioRegion::FadeInChanged|
880 AudioRegion::FadeOutChanged|
881 AudioRegion::FadeInActiveChanged|
882 AudioRegion::FadeOutActiveChanged|
883 AudioRegion::EnvelopeActiveChanged|
884 AudioRegion::ScaleAmplitudeChanged|
885 AudioRegion::EnvelopeChanged);
886 bool parent_wants_notify;
888 parent_wants_notify = Playlist::region_changed (what_changed, region);
890 maybe_save_state (_("region modified"));
892 if ((parent_wants_notify || (what_changed & our_interests))) {
900 AudioPlaylist::crossfades_at (jack_nframes_t frame, Crossfades& clist)
902 RegionLock rlock (this);
904 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
905 jack_nframes_t start, end;
907 start = (*i)->position();
908 end = start + (*i)->overlap_length(); // not length(), important difference
910 if (frame >= start && frame <= end) {
911 clist.push_back (*i);