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, 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 // FIXME: Should be vector<AudioRegion*>
247 vector<Region*>& r (relevant_regions[*l]);
248 vector<Crossfade*>& x (relevant_xfades[*l]);
250 for (vector<Region*>::iterator i = r.begin(); i != r.end(); ++i) {
251 AudioRegion* const ar = dynamic_cast<AudioRegion*>(*i);
253 ar->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n, read_frames, skip_frames);
254 _read_data_count += ar->read_data_count();
257 for (vector<Crossfade*>::iterator i = x.begin(); i != x.end(); ++i) {
258 (*i)->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n);
260 /* don't JACK up _read_data_count, since its the same data as we just
261 read from the regions, and the OS should handle that for us.
271 AudioPlaylist::remove_dependents (Region& region)
273 Crossfades::iterator i, tmp;
274 AudioRegion* r = dynamic_cast<AudioRegion*> (®ion);
277 fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
282 for (i = _crossfades.begin(); i != _crossfades.end(); ) {
286 if ((*i)->involves (*r)) {
287 /* do not delete crossfades */
288 _crossfades.erase (i);
297 AudioPlaylist::flush_notifications ()
299 Playlist::flush_notifications();
307 Crossfades::iterator a;
308 for (a = _pending_xfade_adds.begin(); a != _pending_xfade_adds.end(); ++a) {
309 NewCrossfade (*a); /* EMIT SIGNAL */
312 _pending_xfade_adds.clear ();
318 AudioPlaylist::refresh_dependents (Region& r)
320 AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
321 set<Crossfade*> updated;
327 for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) {
329 Crossfades::iterator tmp;
334 /* only update them once */
336 if ((*x)->involves (*ar)) {
338 if (find (updated.begin(), updated.end(), *x) == updated.end()) {
339 if ((*x)->refresh ()) {
340 /* not invalidated by the refresh */
351 AudioPlaylist::finalize_split_region (Region *o, Region *l, Region *r)
353 AudioRegion *orig = dynamic_cast<AudioRegion*>(o);
354 AudioRegion *left = dynamic_cast<AudioRegion*>(l);
355 AudioRegion *right = dynamic_cast<AudioRegion*>(r);
357 for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) {
358 Crossfades::iterator tmp;
364 if ((*x)->_in == orig) {
365 if (! (*x)->covers(right->position())) {
366 fade = new Crossfade( *(*x), left, (*x)->_out);
368 // Overlap, the crossfade is copied on the left side of the right region instead
369 fade = new Crossfade( *(*x), right, (*x)->_out);
373 if ((*x)->_out == orig) {
374 if (! (*x)->covers(right->position())) {
375 fade = new Crossfade( *(*x), (*x)->_in, right);
377 // Overlap, the crossfade is copied on the right side of the left region instead
378 fade = new Crossfade( *(*x), (*x)->_in, left);
383 _crossfades.remove( (*x) );
384 add_crossfade (*fade);
391 AudioPlaylist::check_dependents (Region& r, bool norefresh)
399 if (in_set_state || in_partition) {
403 if ((region = dynamic_cast<AudioRegion*> (&r)) == 0) {
404 fatal << _("programming error: non-audio Region tested for overlap in audio playlist")
410 refresh_dependents (r);
413 if (!Config->get_auto_xfade()) {
417 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
419 other = dynamic_cast<AudioRegion*> (*i);
421 if (other == region) {
425 if (other->muted() || region->muted()) {
429 if (other->layer() < region->layer()) {
439 if (top->coverage (bottom->position(), bottom->last_frame()) != OverlapNone) {
441 /* check if the upper region is within the lower region */
443 if (top->first_frame() > bottom->first_frame() &&
444 top->last_frame() < bottom->last_frame()) {
447 /* [ -------- top ------- ]
448 * {=========== bottom =============}
451 /* to avoid discontinuities at the region boundaries of an internal
452 overlap (this region is completely within another), we create
453 two hidden crossfades at each boundary. this is not dependent
454 on the auto-xfade option, because we require it as basic
458 jack_nframes_t xfade_length = min ((jack_nframes_t) 720, top->length());
461 xfade = new Crossfade (*top, *bottom, xfade_length, top->first_frame(), StartOfIn);
462 add_crossfade (*xfade);
463 xfade = new Crossfade (*bottom, *top, xfade_length, top->last_frame() - xfade_length, EndOfOut);
464 add_crossfade (*xfade);
468 xfade = new Crossfade (*other, *region, _session.get_xfade_model(), _session.get_crossfades_active());
469 add_crossfade (*xfade);
474 catch (failed_constructor& err) {
478 catch (Crossfade::NoCrossfadeHere& err) {
486 AudioPlaylist::add_crossfade (Crossfade& xfade)
488 Crossfades::iterator ci;
490 for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) {
491 if (*(*ci) == xfade) { // Crossfade::operator==()
496 if (ci != _crossfades.end()) {
499 _crossfades.push_back (&xfade);
501 xfade.Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
502 xfade.StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
504 notify_crossfade_added (&xfade);
508 void AudioPlaylist::notify_crossfade_added (Crossfade *x)
510 if (g_atomic_int_get(&block_notifications)) {
511 _pending_xfade_adds.insert (_pending_xfade_adds.end(), x);
513 NewCrossfade (x); /* EMIT SIGNAL */
518 AudioPlaylist::crossfade_invalidated (Crossfade* xfade)
520 Crossfades::iterator i;
522 xfade->in().resume_fade_in ();
523 xfade->out().resume_fade_out ();
525 if ((i = find (_crossfades.begin(), _crossfades.end(), xfade)) != _crossfades.end()) {
526 _crossfades.erase (i);
531 AudioPlaylist::set_state (const XMLNode& node)
535 XMLNodeConstIterator niter;
538 Playlist::set_state (node);
541 nlist = node.children();
543 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
547 if (child->name() == "Crossfade") {
552 xfade = new Crossfade (*((const Playlist *)this), *child);
555 catch (failed_constructor& err) {
556 // cout << string_compose (_("could not create crossfade object in playlist %1"),
562 Crossfades::iterator ci;
564 for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) {
565 if (*(*ci) == *xfade) {
570 if (ci == _crossfades.end()) {
571 _crossfades.push_back (xfade);
572 xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
573 xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
574 /* no need to notify here */
586 AudioPlaylist::drop_all_states ()
588 set<Crossfade*> all_xfades;
589 set<Region*> all_regions;
591 /* find every region we've ever used, and add it to the set of
592 all regions. same for xfades;
595 for (StateMap::iterator i = states.begin(); i != states.end(); ++i) {
597 AudioPlaylist::State* apstate = dynamic_cast<AudioPlaylist::State*> (*i);
599 for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
600 all_regions.insert (*r);
602 for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
603 all_xfades.insert (*xf);
607 /* now remove from the "all" lists every region that is in the current list. */
609 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
610 set<Region*>::iterator x = all_regions.find (*i);
611 if (x != all_regions.end()) {
612 all_regions.erase (x);
616 /* ditto for every crossfade */
618 for (list<Crossfade*>::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
619 set<Crossfade*>::iterator x = all_xfades.find (*i);
620 if (x != all_xfades.end()) {
621 all_xfades.erase (x);
625 /* delete every region that is left - these are all things that are part of our "history" */
627 for (set<Region *>::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
628 (*ar)->unlock_sources ();
632 /* delete every crossfade that is left (ditto as per regions) */
634 for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) {
638 /* Now do the generic thing ... */
640 StateManager::drop_all_states ();
644 AudioPlaylist::state_factory (std::string why) const
646 State* state = new State (why);
648 state->regions = regions;
649 state->region_states.clear ();
650 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
651 state->region_states.push_back ((*i)->get_memento());
654 state->crossfades = _crossfades;
655 state->crossfade_states.clear ();
656 for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
657 state->crossfade_states.push_back ((*i)->get_memento());
663 AudioPlaylist::restore_state (StateManager::State& state)
666 RegionLock rlock (this);
667 State* apstate = dynamic_cast<State*> (&state);
671 regions = apstate->regions;
673 for (list<UndoAction>::iterator s = apstate->region_states.begin(); s != apstate->region_states.end(); ++s) {
677 _crossfades = apstate->crossfades;
679 for (list<UndoAction>::iterator s = apstate->crossfade_states.begin(); s != apstate->crossfade_states.end(); ++s) {
683 in_set_state = false;
686 notify_length_changed ();
691 AudioPlaylist::get_memento () const
693 return sigc::bind (mem_fun (*(const_cast<AudioPlaylist*> (this)), &StateManager::use_state), _current_state_id);
697 AudioPlaylist::clear (bool with_delete, bool with_save)
700 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
705 _crossfades.clear ();
707 Playlist::clear (with_delete, with_save);
711 AudioPlaylist::state (bool full_state)
713 XMLNode& node = Playlist::state (full_state);
716 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
717 node.add_child_nocopy ((*i)->get_state());
725 AudioPlaylist::dump () const
730 cerr << "Playlist \"" << _name << "\" " << endl
731 << regions.size() << " regions "
732 << _crossfades.size() << " crossfades"
735 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
737 cerr << " " << r->name() << " @ " << r << " ["
738 << r->start() << "+" << r->length()
746 for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
757 << (x->active() ? "yes" : "no")
763 AudioPlaylist::destroy_region (Region* region)
765 AudioRegion* r = dynamic_cast<AudioRegion*> (region);
766 bool changed = false;
767 Crossfades::iterator c, ctmp;
768 set<Crossfade*> unique_xfades;
771 fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
778 RegionLock rlock (this);
779 RegionList::iterator i;
780 RegionList::iterator tmp;
782 for (i = regions.begin(); i != regions.end(); ) {
787 if ((*i) == region) {
788 (*i)->unlock_sources ();
797 for (c = _crossfades.begin(); c != _crossfades.end(); ) {
801 if ((*c)->involves (*r)) {
802 unique_xfades.insert (*c);
803 _crossfades.erase (c);
809 for (StateMap::iterator s = states.begin(); s != states.end(); ) {
810 StateMap::iterator tmp;
815 State* astate = dynamic_cast<State*> (*s);
817 for (c = astate->crossfades.begin(); c != astate->crossfades.end(); ) {
822 if ((*c)->involves (*r)) {
823 unique_xfades.insert (*c);
824 _crossfades.erase (c);
830 list<UndoAction>::iterator rsi, rsitmp;
831 RegionList::iterator ri, ritmp;
833 for (ri = astate->regions.begin(), rsi = astate->region_states.begin();
834 ri != astate->regions.end() && rsi != astate->region_states.end();) {
843 if (region == (*ri)) {
844 astate->regions.erase (ri);
845 astate->region_states.erase (rsi);
855 for (set<Crossfade*>::iterator c = unique_xfades.begin(); c != unique_xfades.end(); ++c) {
860 /* overload this, it normally means "removed", not destroyed */
861 notify_region_removed (region);
868 AudioPlaylist::crossfade_changed (Change ignored)
870 if (in_flush || in_set_state) {
874 /* XXX is there a loop here? can an xfade change not happen
875 due to a playlist change? well, sure activation would
876 be an example. maybe we should check the type of change
880 maybe_save_state (_("xfade change"));
886 AudioPlaylist::region_changed (Change what_changed, Region* region)
888 if (in_flush || in_set_state) {
892 Change our_interests = Change (AudioRegion::FadeInChanged|
893 AudioRegion::FadeOutChanged|
894 AudioRegion::FadeInActiveChanged|
895 AudioRegion::FadeOutActiveChanged|
896 AudioRegion::EnvelopeActiveChanged|
897 AudioRegion::ScaleAmplitudeChanged|
898 AudioRegion::EnvelopeChanged);
899 bool parent_wants_notify;
901 parent_wants_notify = Playlist::region_changed (what_changed, region);
903 maybe_save_state (_("region modified"));
905 if ((parent_wants_notify || (what_changed & our_interests))) {
913 AudioPlaylist::crossfades_at (jack_nframes_t frame, Crossfades& clist)
915 RegionLock rlock (this);
917 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
918 jack_nframes_t start, end;
920 start = (*i)->position();
921 end = start + (*i)->overlap_length(); // not length(), important difference
923 if (frame >= start && frame <= end) {
924 clist.push_back (*i);