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());
583 AudioPlaylist::restore_state (StateManager::State& state)
586 RegionLock rlock (this);
587 State* apstate = dynamic_cast<State*> (&state);
591 regions = apstate->regions;
593 for (list<UndoAction>::iterator s = apstate->region_states.begin(); s != apstate->region_states.end(); ++s) {
597 _crossfades = apstate->crossfades;
599 for (list<UndoAction>::iterator s = apstate->crossfade_states.begin(); s != apstate->crossfade_states.end(); ++s) {
603 in_set_state = false;
606 notify_length_changed ();
611 AudioPlaylist::get_memento () const
613 return sigc::bind (mem_fun (*(const_cast<AudioPlaylist*> (this)), &StateManager::use_state), _current_state_id);
617 AudioPlaylist::clear (bool with_delete, bool with_save)
620 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
625 _crossfades.clear ();
627 Playlist::clear (with_delete, with_save);
631 AudioPlaylist::state (bool full_state)
633 XMLNode& node = Playlist::state (full_state);
636 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
637 node.add_child_nocopy ((*i)->get_state());
645 AudioPlaylist::dump () const
650 cerr << "Playlist \"" << _name << "\" " << endl
651 << regions.size() << " regions "
652 << _crossfades.size() << " crossfades"
655 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
657 cerr << " " << r->name() << " @ " << r << " ["
658 << r->start() << "+" << r->length()
666 for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
677 << (x->active() ? "yes" : "no")
683 AudioPlaylist::destroy_region (Region* region)
685 AudioRegion* r = dynamic_cast<AudioRegion*> (region);
686 bool changed = false;
687 Crossfades::iterator c, ctmp;
688 set<Crossfade*> unique_xfades;
691 fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
698 RegionLock rlock (this);
699 RegionList::iterator i;
700 RegionList::iterator tmp;
702 for (i = regions.begin(); i != regions.end(); ) {
707 if ((*i) == region) {
708 (*i)->unlock_sources ();
717 for (c = _crossfades.begin(); c != _crossfades.end(); ) {
721 if ((*c)->involves (*r)) {
722 unique_xfades.insert (*c);
723 _crossfades.erase (c);
729 for (StateMap::iterator s = states.begin(); s != states.end(); ) {
730 StateMap::iterator tmp;
735 State* astate = dynamic_cast<State*> (*s);
737 for (c = astate->crossfades.begin(); c != astate->crossfades.end(); ) {
742 if ((*c)->involves (*r)) {
743 unique_xfades.insert (*c);
744 _crossfades.erase (c);
750 list<UndoAction>::iterator rsi, rsitmp;
751 RegionList::iterator ri, ritmp;
753 for (ri = astate->regions.begin(), rsi = astate->region_states.begin();
754 ri != astate->regions.end() && rsi != astate->region_states.end();) {
763 if (region == (*ri)) {
764 astate->regions.erase (ri);
765 astate->region_states.erase (rsi);
775 for (set<Crossfade*>::iterator c = unique_xfades.begin(); c != unique_xfades.end(); ++c) {
780 /* overload this, it normally means "removed", not destroyed */
781 notify_region_removed (region);
788 AudioPlaylist::crossfade_changed (Change ignored)
794 /* XXX is there a loop here? can an xfade change not happen
795 due to a playlist change? well, sure activation would
796 be an example. maybe we should check the type of change
800 maybe_save_state (_("xfade change"));
805 AudioPlaylist::get_equivalent_regions (const AudioRegion& other, vector<AudioRegion*>& results)
807 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
809 AudioRegion* ar = dynamic_cast<AudioRegion*> (*i);
811 if (ar && ar->equivalent (other)) {
812 results.push_back (ar);
818 AudioPlaylist::get_region_list_equivalent_regions (const AudioRegion& other, vector<AudioRegion*>& results)
820 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
822 AudioRegion* ar = dynamic_cast<AudioRegion*> (*i);
824 if (ar && ar->region_list_equivalent (other)) {
825 results.push_back (ar);
831 AudioPlaylist::region_changed (Change what_changed, Region* region)
833 if (in_flush || in_set_state) {
837 Change our_interests = Change (AudioRegion::FadeInChanged|
838 AudioRegion::FadeOutChanged|
839 AudioRegion::FadeInActiveChanged|
840 AudioRegion::FadeOutActiveChanged|
841 AudioRegion::EnvelopeActiveChanged|
842 AudioRegion::ScaleAmplitudeChanged|
843 AudioRegion::EnvelopeChanged);
844 bool parent_wants_notify;
846 parent_wants_notify = Playlist::region_changed (what_changed, region);
848 maybe_save_state (_("region modified"));
850 if (parent_wants_notify || (what_changed & our_interests)) {
858 AudioPlaylist::crossfades_at (jack_nframes_t frame, Crossfades& clist)
860 RegionLock rlock (this);
862 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
863 jack_nframes_t start, end;
865 start = (*i)->position();
866 end = start + (*i)->overlap_length(); // not length(), important difference
868 if (frame >= start && frame <= end) {
869 clist.push_back (*i);