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"));
76 PlaylistCreated (this); /* EMIT SIGNAL */
80 AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden)
81 : Playlist (other, start, cnt, name, hidden)
83 save_state (_("initial state"));
85 /* this constructor does NOT notify others (session) */
88 AudioPlaylist::~AudioPlaylist ()
90 set<Crossfade*> all_xfades;
91 set<Region*> all_regions;
95 /* find every region we've ever used, and add it to the set of
96 all regions. same for xfades;
99 for (RegionList::iterator x = regions.begin(); x != regions.end(); ++x) {
100 all_regions.insert (*x);
103 for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end(); ++x) {
104 all_xfades.insert (*x);
107 for (StateMap::iterator i = states.begin(); i != states.end(); ++i) {
109 AudioPlaylist::State* apstate = dynamic_cast<AudioPlaylist::State*> (*i);
111 for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
112 all_regions.insert (*r);
114 for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
115 all_xfades.insert (*xf);
121 /* delete every region */
123 for (set<Region *>::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
124 (*ar)->unlock_sources ();
128 /* delete every crossfade */
130 for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) {
135 struct RegionSortByLayer {
136 bool operator() (Region *a, Region *b) {
137 return a->layer() < b->layer();
142 AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, jack_nframes_t start,
143 jack_nframes_t cnt, unsigned chan_n)
145 jack_nframes_t ret = cnt;
147 jack_nframes_t read_frames;
148 jack_nframes_t skip_frames;
150 /* optimizing this memset() away involves a lot of conditionals
151 that may well cause more of a hit due to cache misses
152 and related stuff than just doing this here.
154 it would be great if someone could measure this
157 one way or another, parts of the requested area
158 that are not written to by Region::region_at()
159 for all Regions that cover the area need to be
163 memset (buf, 0, sizeof (Sample) * cnt);
165 /* this function is never called from a realtime thread, so
166 its OK to block (for short intervals).
169 LockMonitor rm (region_lock, __LINE__, __FILE__);
171 end = start + cnt - 1;
175 _read_data_count = 0;
177 map<uint32_t,vector<Region*> > relevant_regions;
178 map<uint32_t,vector<Crossfade*> > relevant_xfades;
179 vector<uint32_t> relevant_layers;
181 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
182 if ((*i)->coverage (start, end) != OverlapNone) {
184 relevant_regions[(*i)->layer()].push_back (*i);
185 relevant_layers.push_back ((*i)->layer());
189 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
190 if ((*i)->coverage (start, end) != OverlapNone) {
191 relevant_xfades[(*i)->upper_layer()].push_back (*i);
195 // RegionSortByLayer layer_cmp;
196 // relevant_regions.sort (layer_cmp);
198 /* XXX this whole per-layer approach is a hack that
199 should be removed once Crossfades become
200 CrossfadeRegions and we just grab a list of relevant
201 regions and call read_at() on all of them.
204 sort (relevant_layers.begin(), relevant_layers.end());
206 for (vector<uint32_t>::iterator l = relevant_layers.begin(); l != relevant_layers.end(); ++l) {
208 vector<Region*>& r (relevant_regions[*l]);
209 vector<Crossfade*>& x (relevant_xfades[*l]);
211 for (vector<Region*>::iterator i = r.begin(); i != r.end(); ++i) {
212 (*i)->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n, read_frames, skip_frames);
213 _read_data_count += (*i)->read_data_count();
216 for (vector<Crossfade*>::iterator i = x.begin(); i != x.end(); ++i) {
218 (*i)->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n);
220 /* don't JACK up _read_data_count, since its the same data as we just
221 read from the regions, and the OS should handle that for us.
231 AudioPlaylist::remove_dependents (Region& region)
233 Crossfades::iterator i, tmp;
234 AudioRegion* r = dynamic_cast<AudioRegion*> (®ion);
237 fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
242 for (i = _crossfades.begin(); i != _crossfades.end(); ) {
246 if ((*i)->involves (*r)) {
247 /* do not delete crossfades */
248 _crossfades.erase (i);
257 AudioPlaylist::flush_notifications ()
259 Playlist::flush_notifications();
267 Crossfades::iterator a;
268 for (a = _pending_xfade_adds.begin(); a != _pending_xfade_adds.end(); ++a) {
269 NewCrossfade (*a); /* EMIT SIGNAL */
272 _pending_xfade_adds.clear ();
278 AudioPlaylist::refresh_dependents (Region& r)
280 AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
281 set<Crossfade*> updated;
287 for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) {
289 Crossfades::iterator tmp;
294 /* only update them once */
296 if ((*x)->involves (*ar)) {
298 if (find (updated.begin(), updated.end(), *x) == updated.end()) {
299 if ((*x)->refresh ()) {
300 /* not invalidated by the refresh */
311 AudioPlaylist::check_dependents (Region& r, bool norefresh)
319 if (in_set_state || in_partition) {
323 if ((region = dynamic_cast<AudioRegion*> (&r)) == 0) {
324 fatal << _("programming error: non-audio Region tested for overlap in audio playlist")
330 refresh_dependents (r);
333 if (!Config->get_auto_xfade()) {
337 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
339 other = dynamic_cast<AudioRegion*> (*i);
341 if (other == region) {
345 if (other->muted() || region->muted()) {
349 if (other->layer() < region->layer()) {
359 if (top->coverage (bottom->position(), bottom->last_frame()) != OverlapNone) {
361 /* check if the upper region is within the lower region */
363 if (top->first_frame() > bottom->first_frame() &&
364 top->last_frame() < bottom->last_frame()) {
367 /* [ -------- top ------- ]
368 * {=========== bottom =============}
371 /* to avoid discontinuities at the region boundaries of an internal
372 overlap (this region is completely within another), we create
373 two hidden crossfades at each boundary. this is not dependent
374 on the auto-xfade option, because we require it as basic
378 jack_nframes_t xfade_length = min ((jack_nframes_t) 720, top->length());
381 xfade = new Crossfade (*top, *bottom, xfade_length, top->first_frame(), StartOfIn);
382 add_crossfade (*xfade);
383 xfade = new Crossfade (*bottom, *top, xfade_length, top->last_frame() - xfade_length, EndOfOut);
384 add_crossfade (*xfade);
388 xfade = new Crossfade (*other, *region, _session.get_xfade_model(), _session.get_crossfades_active());
389 add_crossfade (*xfade);
394 catch (failed_constructor& err) {
398 catch (Crossfade::NoCrossfadeHere& err) {
406 AudioPlaylist::add_crossfade (Crossfade& xfade)
408 Crossfades::iterator ci;
410 for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) {
411 if (*(*ci) == xfade) { // Crossfade::operator==()
416 if (ci != _crossfades.end()) {
419 _crossfades.push_back (&xfade);
421 xfade.Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
422 xfade.StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
424 notify_crossfade_added (&xfade);
428 void AudioPlaylist::notify_crossfade_added (Crossfade *x)
430 if (atomic_read(&block_notifications)) {
431 _pending_xfade_adds.insert (_pending_xfade_adds.end(), x);
433 NewCrossfade (x); /* EMIT SIGNAL */
438 AudioPlaylist::crossfade_invalidated (Crossfade* xfade)
440 Crossfades::iterator i;
442 xfade->in().resume_fade_in ();
443 xfade->out().resume_fade_out ();
445 if ((i = find (_crossfades.begin(), _crossfades.end(), xfade)) != _crossfades.end()) {
446 _crossfades.erase (i);
451 AudioPlaylist::set_state (const XMLNode& node)
455 XMLNodeConstIterator niter;
458 Playlist::set_state (node);
461 nlist = node.children();
463 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
467 if (child->name() == "Crossfade") {
472 xfade = new Crossfade (*((const Playlist *)this), *child);
475 catch (failed_constructor& err) {
476 // cout << string_compose (_("could not create crossfade object in playlist %1"),
482 Crossfades::iterator ci;
484 for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) {
485 if (*(*ci) == *xfade) {
490 if (ci == _crossfades.end()) {
491 _crossfades.push_back (xfade);
492 xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
493 xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
494 /* no need to notify here */
506 AudioPlaylist::drop_all_states ()
508 set<Crossfade*> all_xfades;
509 set<Region*> all_regions;
511 /* find every region we've ever used, and add it to the set of
512 all regions. same for xfades;
515 for (StateMap::iterator i = states.begin(); i != states.end(); ++i) {
517 AudioPlaylist::State* apstate = dynamic_cast<AudioPlaylist::State*> (*i);
519 for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
520 all_regions.insert (*r);
522 for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
523 all_xfades.insert (*xf);
527 /* now remove from the "all" lists every region that is in the current list. */
529 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
530 set<Region*>::iterator x = all_regions.find (*i);
531 if (x != all_regions.end()) {
532 all_regions.erase (x);
536 /* ditto for every crossfade */
538 for (list<Crossfade*>::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
539 set<Crossfade*>::iterator x = all_xfades.find (*i);
540 if (x != all_xfades.end()) {
541 all_xfades.erase (x);
545 /* delete every region that is left - these are all things that are part of our "history" */
547 for (set<Region *>::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
548 (*ar)->unlock_sources ();
552 /* delete every crossfade that is left (ditto as per regions) */
554 for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) {
558 /* Now do the generic thing ... */
560 StateManager::drop_all_states ();
564 AudioPlaylist::state_factory (std::string why) const
566 State* state = new State (why);
568 state->regions = regions;
569 state->region_states.clear ();
570 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
571 state->region_states.push_back ((*i)->get_memento());
574 state->crossfades = _crossfades;
575 state->crossfade_states.clear ();
576 for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
577 state->crossfade_states.push_back ((*i)->get_memento());
584 AudioPlaylist::restore_state (StateManager::State& state)
587 RegionLock rlock (this);
588 State* apstate = dynamic_cast<State*> (&state);
592 regions = apstate->regions;
594 for (list<UndoAction>::iterator s = apstate->region_states.begin(); s != apstate->region_states.end(); ++s) {
598 _crossfades = apstate->crossfades;
600 for (list<UndoAction>::iterator s = apstate->crossfade_states.begin(); s != apstate->crossfade_states.end(); ++s) {
604 in_set_state = false;
607 notify_length_changed ();
612 AudioPlaylist::get_memento () const
614 return sigc::bind (mem_fun (*(const_cast<AudioPlaylist*> (this)), &StateManager::use_state), _current_state_id);
618 AudioPlaylist::clear (bool with_delete, bool with_save)
621 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
626 _crossfades.clear ();
628 Playlist::clear (with_delete, with_save);
632 AudioPlaylist::state (bool full_state)
634 XMLNode& node = Playlist::state (full_state);
637 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
638 node.add_child_nocopy ((*i)->get_state());
646 AudioPlaylist::dump () const
651 cerr << "Playlist \"" << _name << "\" " << endl
652 << regions.size() << " regions "
653 << _crossfades.size() << " crossfades"
656 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
658 cerr << " " << r->name() << " @ " << r << " ["
659 << r->start() << "+" << r->length()
667 for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
678 << (x->active() ? "yes" : "no")
684 AudioPlaylist::destroy_region (Region* region)
686 AudioRegion* r = dynamic_cast<AudioRegion*> (region);
687 bool changed = false;
688 Crossfades::iterator c, ctmp;
689 set<Crossfade*> unique_xfades;
692 fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
699 RegionLock rlock (this);
700 RegionList::iterator i;
701 RegionList::iterator tmp;
703 for (i = regions.begin(); i != regions.end(); ) {
708 if ((*i) == region) {
709 (*i)->unlock_sources ();
718 for (c = _crossfades.begin(); c != _crossfades.end(); ) {
722 if ((*c)->involves (*r)) {
723 unique_xfades.insert (*c);
724 _crossfades.erase (c);
730 for (StateMap::iterator s = states.begin(); s != states.end(); ) {
731 StateMap::iterator tmp;
736 State* astate = dynamic_cast<State*> (*s);
738 for (c = astate->crossfades.begin(); c != astate->crossfades.end(); ) {
743 if ((*c)->involves (*r)) {
744 unique_xfades.insert (*c);
745 _crossfades.erase (c);
751 list<UndoAction>::iterator rsi, rsitmp;
752 RegionList::iterator ri, ritmp;
754 for (ri = astate->regions.begin(), rsi = astate->region_states.begin();
755 ri != astate->regions.end() && rsi != astate->region_states.end();) {
764 if (region == (*ri)) {
765 astate->regions.erase (ri);
766 astate->region_states.erase (rsi);
776 for (set<Crossfade*>::iterator c = unique_xfades.begin(); c != unique_xfades.end(); ++c) {
781 /* overload this, it normally means "removed", not destroyed */
782 notify_region_removed (region);
789 AudioPlaylist::crossfade_changed (Change ignored)
795 /* XXX is there a loop here? can an xfade change not happen
796 due to a playlist change? well, sure activation would
797 be an example. maybe we should check the type of change
801 maybe_save_state (_("xfade change"));
806 AudioPlaylist::get_equivalent_regions (const AudioRegion& other, vector<AudioRegion*>& results)
808 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
810 AudioRegion* ar = dynamic_cast<AudioRegion*> (*i);
812 if (ar && ar->equivalent (other)) {
813 results.push_back (ar);
819 AudioPlaylist::get_region_list_equivalent_regions (const AudioRegion& other, vector<AudioRegion*>& results)
821 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
823 AudioRegion* ar = dynamic_cast<AudioRegion*> (*i);
825 if (ar && ar->region_list_equivalent (other)) {
826 results.push_back (ar);
832 AudioPlaylist::region_changed (Change what_changed, Region* region)
834 if (in_flush || in_set_state) {
838 Change our_interests = Change (AudioRegion::FadeInChanged|
839 AudioRegion::FadeOutChanged|
840 AudioRegion::FadeInActiveChanged|
841 AudioRegion::FadeOutActiveChanged|
842 AudioRegion::EnvelopeActiveChanged|
843 AudioRegion::ScaleAmplitudeChanged|
844 AudioRegion::EnvelopeChanged);
845 bool parent_wants_notify;
847 parent_wants_notify = Playlist::region_changed (what_changed, region);
849 maybe_save_state (_("region modified"));
851 if (parent_wants_notify || (what_changed & our_interests)) {
859 AudioPlaylist::crossfades_at (jack_nframes_t frame, Crossfades& clist)
861 RegionLock rlock (this);
863 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
864 jack_nframes_t start, end;
866 start = (*i)->position();
867 end = start + (*i)->overlap_length(); // not length(), important difference
869 if (frame >= start && frame <= end) {
870 clist.push_back (*i);