2 Copyright (C) 2000-2001 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.
27 #include <sigc++/bind.h>
28 #include <sigc++/class_slot.h>
30 #include <glibmm/thread.h>
32 #include <pbd/basename.h>
33 #include <pbd/xml++.h>
34 #include <pbd/stacktrace.h>
35 #include <pbd/enumwriter.h>
36 #include <pbd/convert.h>
38 #include <ardour/audioregion.h>
39 #include <ardour/session.h>
40 #include <ardour/gain.h>
41 #include <ardour/dB.h>
42 #include <ardour/playlist.h>
43 #include <ardour/audiofilter.h>
44 #include <ardour/audiofilesource.h>
45 #include <ardour/region_factory.h>
46 #include <ardour/transient_detector.h>
52 using namespace ARDOUR;
55 /* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
57 Change AudioRegion::FadeInChanged = ARDOUR::new_change();
58 Change AudioRegion::FadeOutChanged = ARDOUR::new_change();
59 Change AudioRegion::FadeInActiveChanged = ARDOUR::new_change();
60 Change AudioRegion::FadeOutActiveChanged = ARDOUR::new_change();
61 Change AudioRegion::EnvelopeActiveChanged = ARDOUR::new_change();
62 Change AudioRegion::ScaleAmplitudeChanged = ARDOUR::new_change();
63 Change AudioRegion::EnvelopeChanged = ARDOUR::new_change();
65 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length)
66 : Region (start, length, PBD::basename_nosuffix(src->name()), 0, Region::Flag(Region::DefaultFlags|Region::External)),
67 _fade_in (0.0, 2.0, 1.0, false),
68 _fade_out (0.0, 2.0, 1.0, false),
69 _envelope (0.0, 2.0, 1.0, false)
71 /* basic AudioRegion constructor */
73 sources.push_back (src);
74 master_sources.push_back (src);
75 src->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
77 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
79 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
82 _scale_amplitude = 1.0;
85 set_default_envelope ();
87 listen_to_my_curves ();
88 listen_to_my_sources ();
91 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
92 : Region (start, length, name, layer, flags),
93 _fade_in (0.0, 2.0, 1.0, false),
94 _fade_out (0.0, 2.0, 1.0, false),
95 _envelope (0.0, 2.0, 1.0, false)
97 /* basic AudioRegion constructor */
99 sources.push_back (src);
100 master_sources.push_back (src);
101 src->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
103 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
105 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
108 _scale_amplitude = 1.0;
110 set_default_fades ();
111 set_default_envelope ();
113 listen_to_my_curves ();
114 listen_to_my_sources ();
117 AudioRegion::AudioRegion (const SourceList& srcs, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
118 : Region (start, length, name, layer, flags),
119 _fade_in (0.0, 2.0, 1.0, false),
120 _fade_out (0.0, 2.0, 1.0, false),
121 _envelope (0.0, 2.0, 1.0, false)
123 /* basic AudioRegion constructor */
125 for (SourceList::const_iterator i=srcs.begin(); i != srcs.end(); ++i) {
126 sources.push_back (*i);
127 master_sources.push_back (*i);
128 (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
130 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> ((*i));
132 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
136 _scale_amplitude = 1.0;
138 set_default_fades ();
139 set_default_envelope ();
141 listen_to_my_curves ();
142 listen_to_my_sources ();
146 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags)
147 : Region (other, offset, length, name, layer, flags),
148 _fade_in (other->_fade_in),
149 _fade_out (other->_fade_out),
150 _envelope (other->_envelope, (double) offset, (double) offset + length)
152 /* create a new AudioRegion, that is part of an existing one */
154 set<boost::shared_ptr<AudioSource> > unique_srcs;
156 for (SourceList::const_iterator i= other->sources.begin(); i != other->sources.end(); ++i) {
157 sources.push_back (*i);
158 (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
160 pair<set<boost::shared_ptr<AudioSource> >::iterator,bool> result;
162 result = unique_srcs.insert (*i);
165 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
167 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
172 for (SourceList::const_iterator i = other->master_sources.begin(); i != other->master_sources.end(); ++i) {
173 if (unique_srcs.find (*i) == unique_srcs.end()) {
174 (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
176 master_sources.push_back (*i);
180 /* return to default fades if the existing ones are too long */
181 _fade_in_disabled = 0;
182 _fade_out_disabled = 0;
185 if (_flags & LeftOfSplit) {
186 if (_fade_in.back()->when >= _length) {
187 set_default_fade_in ();
189 _fade_in_disabled = other->_fade_in_disabled;
191 set_default_fade_out ();
192 _flags = Flag (_flags & ~Region::LeftOfSplit);
195 if (_flags & RightOfSplit) {
196 if (_fade_out.back()->when >= _length) {
197 set_default_fade_out ();
199 _fade_out_disabled = other->_fade_out_disabled;
201 set_default_fade_in ();
202 _flags = Flag (_flags & ~Region::RightOfSplit);
205 _scale_amplitude = other->_scale_amplitude;
207 listen_to_my_curves ();
208 listen_to_my_sources ();
211 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
213 _fade_in (other->_fade_in),
214 _fade_out (other->_fade_out),
215 _envelope (other->_envelope)
218 /* Pure copy constructor */
220 set<boost::shared_ptr<AudioSource> > unique_srcs;
222 for (SourceList::const_iterator i = other->sources.begin(); i != other->sources.end(); ++i) {
223 sources.push_back (*i);
224 (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
225 pair<set<boost::shared_ptr<AudioSource> >::iterator,bool> result;
227 result = unique_srcs.insert (*i);
230 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
232 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
237 for (SourceList::const_iterator i = other->master_sources.begin(); i != other->master_sources.end(); ++i) {
238 master_sources.push_back (*i);
239 if (unique_srcs.find (*i) == unique_srcs.end()) {
240 (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
244 _scale_amplitude = other->_scale_amplitude;
246 _fade_in_disabled = 0;
247 _fade_out_disabled = 0;
249 listen_to_my_curves ();
250 listen_to_my_sources ();
253 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& srcs,
254 nframes_t length, const string& name, layer_t layer, Flag flags)
255 : Region (other, length, name, layer, flags),
256 _fade_in (other->_fade_in),
257 _fade_out (other->_fade_out),
258 _envelope (other->_envelope)
261 /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
263 set<boost::shared_ptr<AudioSource> > unique_srcs;
265 for (SourceList::const_iterator i=srcs.begin(); i != srcs.end(); ++i) {
266 sources.push_back (*i);
267 master_sources.push_back (*i);
268 (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
270 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> ((*i));
272 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
276 _scale_amplitude = other->_scale_amplitude;
278 _fade_in_disabled = 0;
279 _fade_out_disabled = 0;
281 listen_to_my_curves ();
282 listen_to_my_sources ();
285 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node)
287 _fade_in (0.0, 2.0, 1.0, false),
288 _fade_out (0.0, 2.0, 1.0, false),
289 _envelope (0.0, 2.0, 1.0, false)
291 sources.push_back (src);
292 master_sources.push_back (src);
293 src->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
295 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
297 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
300 set_default_fades ();
302 if (set_state (node)) {
303 throw failed_constructor();
306 listen_to_my_curves ();
307 listen_to_my_sources ();
310 AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
312 _fade_in (0.0, 2.0, 1.0, false),
313 _fade_out (0.0, 2.0, 1.0, false),
314 _envelope (0.0, 2.0, 1.0, false)
316 set<boost::shared_ptr<AudioSource> > unique_srcs;
318 for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) {
319 sources.push_back (*i);
320 (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
321 pair<set<boost::shared_ptr<AudioSource> >::iterator,bool> result;
323 result = unique_srcs.insert (*i);
326 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
328 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
333 for (SourceList::iterator i = srcs.begin(); i != srcs.end(); ++i) {
334 master_sources.push_back (*i);
335 if (unique_srcs.find (*i) == unique_srcs.end()) {
336 (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
340 set_default_fades ();
341 _scale_amplitude = 1.0;
343 if (set_state (node)) {
344 throw failed_constructor();
347 listen_to_my_curves ();
348 listen_to_my_sources ();
351 AudioRegion::~AudioRegion ()
353 boost::shared_ptr<Playlist> pl (playlist());
356 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
357 (*i)->remove_playlist (pl);
359 for (SourceList::const_iterator i = master_sources.begin(); i != master_sources.end(); ++i) {
360 (*i)->remove_playlist (pl);
365 GoingAway (); /* EMIT SIGNAL */
369 AudioRegion::listen_to_my_sources ()
371 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
372 (*i)->AnalysisChanged.connect (mem_fun (*this, &AudioRegion::invalidate_transients));
377 AudioRegion::listen_to_my_curves ()
379 _envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
380 _fade_in.StateChanged.connect (mem_fun (*this, &AudioRegion::fade_in_changed));
381 _fade_out.StateChanged.connect (mem_fun (*this, &AudioRegion::fade_out_changed));
385 AudioRegion::verify_length (nframes_t& len)
387 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(source());
389 if (afs && afs->destructive()) {
393 nframes_t maxlen = 0;
395 for (uint32_t n=0; n < sources.size(); ++n) {
396 maxlen = max (maxlen, sources[n]->length() - _start);
399 len = min (len, maxlen);
405 AudioRegion::verify_start_and_length (nframes_t new_start, nframes_t& new_length)
407 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(source());
409 if (afs && afs->destructive()) {
413 nframes_t maxlen = 0;
415 for (uint32_t n=0; n < sources.size(); ++n) {
416 maxlen = max (maxlen, sources[n]->length() - new_start);
419 new_length = min (new_length, maxlen);
425 AudioRegion::verify_start (nframes_t pos)
427 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(source());
429 if (afs && afs->destructive()) {
433 for (uint32_t n=0; n < sources.size(); ++n) {
434 if (pos > sources[n]->length() - _length) {
442 AudioRegion::verify_start_mutable (nframes_t& new_start)
444 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(source());
446 if (afs && afs->destructive()) {
450 for (uint32_t n=0; n < sources.size(); ++n) {
451 if (new_start > sources[n]->length() - _length) {
452 new_start = sources[n]->length() - _length;
458 AudioRegion::set_envelope_active (bool yn)
460 if (envelope_active() != yn) {
463 snprintf (buf, sizeof (buf), "envelope active");
464 _flags = Flag (_flags|EnvelopeActive);
466 snprintf (buf, sizeof (buf), "envelope off");
467 _flags = Flag (_flags & ~EnvelopeActive);
469 send_change (EnvelopeActiveChanged);
474 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
476 if (chan_n >= sources.size()) {
480 if (sources[chan_n]->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
483 if (_scale_amplitude != 1.0) {
484 for (nframes_t n = 0; n < npeaks; ++n) {
485 buf[n].max *= _scale_amplitude;
486 buf[n].min *= _scale_amplitude;
494 AudioRegion::read (Sample* buf, nframes64_t timeline_position, nframes64_t cnt, int channel) const
496 /* raw read, no fades, no gain, nada */
497 return _read_at (sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
501 AudioRegion::read_with_ops (Sample* buf, nframes64_t file_position, nframes64_t cnt, int channel, ReadOps rops) const
503 return _read_at (sources, _length, buf, 0, 0, file_position, cnt, channel, 0, 0, rops);
507 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t file_position,
509 uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames) const
511 /* regular diskstream/butler read complete with fades etc */
512 return _read_at (sources, _length, buf, mixdown_buffer, gain_buffer, file_position, cnt,
513 chan_n, read_frames, skip_frames, ReadOps (~0));
517 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position,
518 nframes_t cnt, uint32_t chan_n) const
520 /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
522 return _read_at (master_sources, master_sources.front()->length(), buf, mixdown_buffer,
523 gain_buffer, position, cnt, chan_n, 0, 0, ReadOps (0));
527 AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
528 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
529 nframes_t position, nframes_t cnt,
531 nframes_t read_frames,
532 nframes_t skip_frames,
535 nframes_t internal_offset;
536 nframes_t buf_offset;
538 bool raw = (rops == ReadOpsNone);
540 if (muted() && !raw) {
541 return 0; /* read nothing */
544 /* precondition: caller has verified that we cover the desired section */
546 if (position < _position) {
548 buf_offset = _position - position;
551 internal_offset = position - _position;
555 if (internal_offset >= limit) {
556 return 0; /* read nothing */
559 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
560 return 0; /* read nothing */
563 if (opaque() || raw) {
564 /* overwrite whatever is there */
565 mixdown_buffer = buf + buf_offset;
567 mixdown_buffer += buf_offset;
570 if (rops & ReadOpsCount) {
571 _read_data_count = 0;
574 if (chan_n < n_channels()) {
576 if (srcs[chan_n]->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
577 return 0; /* "read nothing" */
580 if (rops & ReadOpsCount) {
581 _read_data_count += srcs[chan_n]->read_data_count();
586 /* track is N-channel, this region has less channels; silence the ones
590 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
593 if (rops & ReadOpsFades) {
597 if ((_flags & FadeIn) && Config->get_use_region_fades()) {
599 nframes_t fade_in_length = (nframes_t) _fade_in.back()->when;
601 /* see if this read is within the fade in */
603 if (internal_offset < fade_in_length) {
607 fi_limit = min (to_read, fade_in_length - internal_offset);
609 _fade_in.get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
611 for (nframes_t n = 0; n < fi_limit; ++n) {
612 mixdown_buffer[n] *= gain_buffer[n];
619 if ((_flags & FadeOut) && Config->get_use_region_fades()) {
621 /* see if some part of this read is within the fade out */
623 /* ................. >| REGION
629 limit - fade_out_length
632 ^internal_offset + to_read
634 we need the intersection of [internal_offset,internal_offset+to_read] with
635 [limit - fade_out_length, limit]
640 nframes_t fade_out_length = (nframes_t) _fade_out.back()->when;
641 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
642 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
644 if (fade_interval_end > fade_interval_start) {
645 /* (part of the) the fade out is in this buffer */
647 nframes_t fo_limit = fade_interval_end - fade_interval_start;
648 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
649 nframes_t fade_offset = fade_interval_start - internal_offset;
651 _fade_out.get_vector (curve_offset,curve_offset+fo_limit, gain_buffer, fo_limit);
653 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
654 mixdown_buffer[m] *= gain_buffer[n];
661 /* Regular gain curves and scaling */
663 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
664 _envelope.get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
666 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
667 for (nframes_t n = 0; n < to_read; ++n) {
668 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
671 for (nframes_t n = 0; n < to_read; ++n) {
672 mixdown_buffer[n] *= gain_buffer[n];
675 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
676 Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
681 /* gack. the things we do for users.
686 for (nframes_t n = 0; n < to_read; ++n) {
687 buf[n] += mixdown_buffer[n];
695 AudioRegion::state (bool full)
697 XMLNode& node (Region::state (full));
701 LocaleGuard lg (X_("POSIX"));
703 node.add_property ("flags", enum_2_string (_flags));
705 snprintf (buf, sizeof(buf), "%.12g", _scale_amplitude);
706 node.add_property ("scale-gain", buf);
708 for (uint32_t n=0; n < sources.size(); ++n) {
709 snprintf (buf2, sizeof(buf2), "source-%d", n);
710 sources[n]->id().print (buf, sizeof (buf));
711 node.add_property (buf2, buf);
714 snprintf (buf, sizeof (buf), "%u", (uint32_t) sources.size());
715 node.add_property ("channels", buf);
719 child = node.add_child (X_("FadeIn"));
721 if ((_flags & DefaultFadeIn)) {
722 child->add_property (X_("default"), X_("yes"));
724 child->add_child_nocopy (_fade_in.get_state ());
727 child->add_property (X_("active"), _fade_in_disabled ? X_("no") : X_("yes"));
729 child = node.add_child (X_("FadeOut"));
731 if ((_flags & DefaultFadeOut)) {
732 child->add_property (X_("default"), X_("yes"));
734 child->add_child_nocopy (_fade_out.get_state ());
737 child->add_property (X_("active"), _fade_out_disabled ? X_("no") : X_("yes"));
740 child = node.add_child ("Envelope");
743 bool default_env = false;
745 // If there are only two points, the points are in the start of the region and the end of the region
746 // so, if they are both at 1.0f, that means the default region.
748 if (_envelope.size() == 2 &&
749 _envelope.front()->value == 1.0f &&
750 _envelope.back()->value==1.0f) {
751 if (_envelope.front()->when == 0 && _envelope.back()->when == _length) {
757 child->add_property ("default", "yes");
759 child->add_child_nocopy (_envelope.get_state ());
763 child->add_property ("default", "yes");
766 for (uint32_t n=0; n < master_sources.size(); ++n) {
767 snprintf (buf2, sizeof(buf2), "master-source-%d", n);
768 master_sources[n]->id().print (buf, sizeof (buf));
769 node.add_property (buf2, buf);
772 if (full && _extra_xml) {
773 node.add_child_copy (*_extra_xml);
780 AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool send)
782 const XMLNodeList& nlist = node.children();
783 const XMLProperty *prop;
784 LocaleGuard lg (X_("POSIX"));
786 Region::set_live_state (node, what_changed, false);
788 uint32_t old_flags = _flags;
790 if ((prop = node.property ("flags")) != 0) {
791 _flags = Flag (string_2_enum (prop->value(), _flags));
793 //_flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16));
795 _flags = Flag (_flags & ~Region::LeftOfSplit);
796 _flags = Flag (_flags & ~Region::RightOfSplit);
799 if ((old_flags ^ _flags) & Muted) {
800 what_changed = Change (what_changed|MuteChanged);
802 if ((old_flags ^ _flags) & Opaque) {
803 what_changed = Change (what_changed|OpacityChanged);
805 if ((old_flags ^ _flags) & Locked) {
806 what_changed = Change (what_changed|LockChanged);
809 if ((prop = node.property ("scale-gain")) != 0) {
810 _scale_amplitude = atof (prop->value().c_str());
811 what_changed = Change (what_changed|ScaleAmplitudeChanged);
813 _scale_amplitude = 1.0;
816 /* Now find envelope description and other misc child items */
818 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
825 if (child->name() == "Envelope") {
829 if ((prop = child->property ("default")) != 0 || _envelope.set_state (*child)) {
830 set_default_envelope ();
833 _envelope.set_max_xval (_length);
834 _envelope.truncate_end (_length);
836 } else if (child->name() == "FadeIn") {
840 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
841 set_default_fade_in ();
843 XMLNode* grandchild = child->child ("AutomationList");
845 _fade_in.set_state (*grandchild);
849 if ((prop = child->property ("active")) != 0) {
850 if (prop->value() == "yes") {
851 set_fade_in_active (true);
853 set_fade_in_active (true);
857 } else if (child->name() == "FadeOut") {
861 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
862 set_default_fade_out ();
864 XMLNode* grandchild = child->child ("AutomationList");
866 _fade_out.set_state (*grandchild);
870 if ((prop = child->property ("active")) != 0) {
871 if (prop->value() == "yes") {
872 set_fade_out_active (true);
874 set_fade_out_active (false);
882 send_change (what_changed);
889 AudioRegion::set_state (const XMLNode& node)
891 /* Region::set_state() calls the virtual set_live_state(),
892 which will get us back to AudioRegion::set_live_state()
893 to handle the relevant stuff.
896 return Region::set_state (node);
900 AudioRegion::set_fade_in_shape (FadeShape shape)
902 set_fade_in (shape, (nframes_t) _fade_in.back()->when);
906 AudioRegion::set_fade_out_shape (FadeShape shape)
908 set_fade_out (shape, (nframes_t) _fade_out.back()->when);
912 AudioRegion::set_fade_in (FadeShape shape, nframes_t len)
919 _fade_in.fast_simple_add (0.0, 0.0);
920 _fade_in.fast_simple_add (len, 1.0);
924 _fade_in.fast_simple_add (0, 0);
925 _fade_in.fast_simple_add (len * 0.389401, 0.0333333);
926 _fade_in.fast_simple_add (len * 0.629032, 0.0861111);
927 _fade_in.fast_simple_add (len * 0.829493, 0.233333);
928 _fade_in.fast_simple_add (len * 0.9447, 0.483333);
929 _fade_in.fast_simple_add (len * 0.976959, 0.697222);
930 _fade_in.fast_simple_add (len, 1);
934 _fade_in.fast_simple_add (0, 0);
935 _fade_in.fast_simple_add (len * 0.0207373, 0.197222);
936 _fade_in.fast_simple_add (len * 0.0645161, 0.525);
937 _fade_in.fast_simple_add (len * 0.152074, 0.802778);
938 _fade_in.fast_simple_add (len * 0.276498, 0.919444);
939 _fade_in.fast_simple_add (len * 0.481567, 0.980556);
940 _fade_in.fast_simple_add (len * 0.767281, 1);
941 _fade_in.fast_simple_add (len, 1);
945 _fade_in.fast_simple_add (0, 0);
946 _fade_in.fast_simple_add (len * 0.0737327, 0.308333);
947 _fade_in.fast_simple_add (len * 0.246544, 0.658333);
948 _fade_in.fast_simple_add (len * 0.470046, 0.886111);
949 _fade_in.fast_simple_add (len * 0.652074, 0.972222);
950 _fade_in.fast_simple_add (len * 0.771889, 0.988889);
951 _fade_in.fast_simple_add (len, 1);
955 _fade_in.fast_simple_add (0, 0);
956 _fade_in.fast_simple_add (len * 0.304147, 0.0694444);
957 _fade_in.fast_simple_add (len * 0.529954, 0.152778);
958 _fade_in.fast_simple_add (len * 0.725806, 0.333333);
959 _fade_in.fast_simple_add (len * 0.847926, 0.558333);
960 _fade_in.fast_simple_add (len * 0.919355, 0.730556);
961 _fade_in.fast_simple_add (len, 1);
966 _fade_in_shape = shape;
968 send_change (FadeInChanged);
972 AudioRegion::set_fade_out (FadeShape shape, nframes_t len)
979 _fade_out.fast_simple_add (len * 0, 1);
980 _fade_out.fast_simple_add (len * 0.023041, 0.697222);
981 _fade_out.fast_simple_add (len * 0.0553, 0.483333);
982 _fade_out.fast_simple_add (len * 0.170507, 0.233333);
983 _fade_out.fast_simple_add (len * 0.370968, 0.0861111);
984 _fade_out.fast_simple_add (len * 0.610599, 0.0333333);
985 _fade_out.fast_simple_add (len * 1, 0);
989 _fade_out.fast_simple_add (len * 0, 1);
990 _fade_out.fast_simple_add (len * 0.228111, 0.988889);
991 _fade_out.fast_simple_add (len * 0.347926, 0.972222);
992 _fade_out.fast_simple_add (len * 0.529954, 0.886111);
993 _fade_out.fast_simple_add (len * 0.753456, 0.658333);
994 _fade_out.fast_simple_add (len * 0.9262673, 0.308333);
995 _fade_out.fast_simple_add (len * 1, 0);
999 _fade_out.fast_simple_add (len * 0, 1);
1000 _fade_out.fast_simple_add (len * 0.305556, 1);
1001 _fade_out.fast_simple_add (len * 0.548611, 0.991736);
1002 _fade_out.fast_simple_add (len * 0.759259, 0.931129);
1003 _fade_out.fast_simple_add (len * 0.918981, 0.68595);
1004 _fade_out.fast_simple_add (len * 0.976852, 0.22865);
1005 _fade_out.fast_simple_add (len * 1, 0);
1009 _fade_out.fast_simple_add (len * 0, 1);
1010 _fade_out.fast_simple_add (len * 0.080645, 0.730556);
1011 _fade_out.fast_simple_add (len * 0.277778, 0.289256);
1012 _fade_out.fast_simple_add (len * 0.470046, 0.152778);
1013 _fade_out.fast_simple_add (len * 0.695853, 0.0694444);
1014 _fade_out.fast_simple_add (len * 1, 0);
1018 _fade_out.fast_simple_add (len * 0, 1);
1019 _fade_out.fast_simple_add (len * 1, 0);
1024 _fade_out_shape = shape;
1026 send_change (FadeOutChanged);
1030 AudioRegion::set_fade_in_length (nframes_t len)
1032 if (len > _length) {
1036 bool changed = _fade_in.extend_to (len);
1039 _flags = Flag (_flags & ~DefaultFadeIn);
1040 send_change (FadeInChanged);
1045 AudioRegion::set_fade_out_length (nframes_t len)
1047 if (len > _length) {
1051 bool changed = _fade_out.extend_to (len);
1054 _flags = Flag (_flags & ~DefaultFadeOut);
1055 send_change (FadeOutChanged);
1060 AudioRegion::set_fade_in_active (bool yn)
1062 if (yn == (_flags & FadeIn)) {
1066 _flags = Flag (_flags|FadeIn);
1068 _flags = Flag (_flags & ~FadeIn);
1071 send_change (FadeInActiveChanged);
1075 AudioRegion::set_fade_out_active (bool yn)
1077 if (yn == (_flags & FadeOut)) {
1081 _flags = Flag (_flags | FadeOut);
1083 _flags = Flag (_flags & ~FadeOut);
1086 send_change (FadeOutActiveChanged);
1090 AudioRegion::fade_in_is_default () const
1092 return _fade_in_shape == Linear && _fade_in.back()->when == 64;
1096 AudioRegion::fade_out_is_default () const
1098 return _fade_out_shape == Linear && _fade_out.back()->when == 64;
1102 AudioRegion::set_default_fade_in ()
1104 set_fade_in (Linear, 64);
1108 AudioRegion::set_default_fade_out ()
1110 set_fade_out (Linear, 64);
1114 AudioRegion::set_default_fades ()
1116 _fade_in_disabled = 0;
1117 _fade_out_disabled = 0;
1118 set_default_fade_in ();
1119 set_default_fade_out ();
1123 AudioRegion::set_default_envelope ()
1125 _envelope.freeze ();
1127 _envelope.fast_simple_add (0, 1.0f);
1128 _envelope.fast_simple_add (_length, 1.0f);
1133 AudioRegion::recompute_at_end ()
1135 /* our length has changed. recompute a new final point by interpolating
1136 based on the the existing curve.
1139 _envelope.freeze ();
1140 _envelope.truncate_end (_length);
1141 _envelope.set_max_xval (_length);
1144 if (_fade_in.back()->when > _length) {
1145 _fade_in.extend_to (_length);
1146 send_change (FadeInChanged);
1149 if (_fade_out.back()->when > _length) {
1150 _fade_out.extend_to (_length);
1151 send_change (FadeOutChanged);
1156 AudioRegion::recompute_at_start ()
1158 /* as above, but the shift was from the front */
1160 _envelope.truncate_start (_length);
1162 if (_fade_in.back()->when > _length) {
1163 _fade_in.extend_to (_length);
1164 send_change (FadeInChanged);
1167 if (_fade_out.back()->when > _length) {
1168 _fade_out.extend_to (_length);
1169 send_change (FadeOutChanged);
1174 AudioRegion::separate_by_channel (Session& session, vector<boost::shared_ptr<AudioRegion> >& v) const
1180 if (sources.size() < 2) {
1186 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
1189 srcs.push_back (*i);
1193 if (sources.size() == 2) {
1201 new_name += ('0' + n + 1);
1204 /* create a copy with just one source. prevent if from being thought of as "whole file" even if
1205 it covers the entire source file(s).
1208 Flag f = Flag (_flags & ~WholeFile);
1210 boost::shared_ptr<Region> r = RegionFactory::create (srcs, _start, _length, new_name, _layer, f);
1211 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (r);
1222 AudioRegion::source_deleted ()
1229 AudioRegion::master_source_names ()
1231 SourceList::iterator i;
1233 vector<string> names;
1234 for (i = master_sources.begin(); i != master_sources.end(); ++i) {
1235 names.push_back((*i)->name());
1242 AudioRegion::set_master_sources (const SourceList& srcs)
1244 master_sources = srcs;
1248 AudioRegion::source_equivalent (boost::shared_ptr<const Region> o) const
1250 boost::shared_ptr<const AudioRegion> other = boost::dynamic_pointer_cast<const AudioRegion>(o);
1255 SourceList::const_iterator i;
1256 SourceList::const_iterator io;
1258 for (i = sources.begin(), io = other->sources.begin(); i != sources.end() && io != other->sources.end(); ++i, ++io) {
1259 if ((*i)->id() != (*io)->id()) {
1264 for (i = master_sources.begin(), io = other->master_sources.begin(); i != master_sources.end() && io != other->master_sources.end(); ++i, ++io) {
1265 if ((*i)->id() != (*io)->id()) {
1274 AudioRegion::apply (AudioFilter& filter)
1276 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (shared_from_this());
1277 return filter.run (ar);
1281 AudioRegion::exportme (Session& session, AudioExportSpecification& spec)
1283 const nframes_t blocksize = 4096;
1287 spec.channels = sources.size();
1289 if (spec.prepare (blocksize, session.frame_rate())) {
1294 spec.total_frames = _length;
1296 while (spec.pos < _length && !spec.stop) {
1299 /* step 1: interleave */
1301 to_read = min (_length - spec.pos, blocksize);
1303 if (spec.channels == 1) {
1305 if (sources.front()->read (spec.dataF, _start + spec.pos, to_read) != to_read) {
1311 Sample buf[blocksize];
1313 for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1315 if (sources[chan]->read (buf, _start + spec.pos, to_read) != to_read) {
1319 for (nframes_t x = 0; x < to_read; ++x) {
1320 spec.dataF[chan+(x*spec.channels)] = buf[x];
1325 if (spec.process (to_read)) {
1329 spec.pos += to_read;
1330 spec.progress = (double) spec.pos /_length;
1337 spec.running = false;
1338 spec.status = status;
1344 boost::shared_ptr<Region>
1345 AudioRegion::get_parent() const
1347 boost::shared_ptr<Playlist> pl (playlist());
1350 boost::shared_ptr<AudioRegion> ar;
1351 boost::shared_ptr<AudioRegion const> grrr2 = boost::dynamic_pointer_cast<AudioRegion const> (shared_from_this());
1353 if (grrr2 && (ar = pl->session().find_whole_file_parent (grrr2))) {
1354 return boost::static_pointer_cast<Region> (ar);
1358 return boost::shared_ptr<Region>();
1362 AudioRegion::set_scale_amplitude (gain_t g)
1364 boost::shared_ptr<Playlist> pl (playlist());
1366 _scale_amplitude = g;
1368 /* tell the diskstream we're in */
1374 /* tell everybody else */
1376 send_change (ScaleAmplitudeChanged);
1380 AudioRegion::normalize_to (float target_dB)
1382 const nframes_t blocksize = 64 * 1024;
1383 Sample buf[blocksize];
1388 gain_t target = dB_to_coefficient (target_dB);
1390 if (target == 1.0f) {
1391 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1392 that we may have clipped.
1394 target -= FLT_EPSILON;
1398 fend = _start + _length;
1400 /* first pass: find max amplitude */
1402 while (fpos < fend) {
1406 to_read = min (fend - fpos, blocksize);
1408 for (n = 0; n < n_channels(); ++n) {
1412 if (source (n)->read (buf, fpos, to_read) != to_read) {
1416 maxamp = Session::compute_peak (buf, to_read, maxamp);
1422 if (maxamp == 0.0f) {
1423 /* don't even try */
1427 if (maxamp == target) {
1428 /* we can't do anything useful */
1432 /* compute scale factor */
1434 _scale_amplitude = target/maxamp;
1436 /* tell the diskstream we're in */
1438 boost::shared_ptr<Playlist> pl (playlist());
1444 /* tell everybody else */
1446 send_change (ScaleAmplitudeChanged);
1450 AudioRegion::fade_in_changed ()
1452 send_change (FadeInChanged);
1456 AudioRegion::fade_out_changed ()
1458 send_change (FadeOutChanged);
1462 AudioRegion::envelope_changed ()
1464 send_change (EnvelopeChanged);
1468 AudioRegion::suspend_fade_in ()
1470 if (++_fade_in_disabled == 1) {
1471 if (fade_in_is_default()) {
1472 set_fade_in_active (false);
1478 AudioRegion::resume_fade_in ()
1480 if (--_fade_in_disabled == 0 && _fade_in_disabled) {
1481 set_fade_in_active (true);
1486 AudioRegion::suspend_fade_out ()
1488 if (++_fade_out_disabled == 1) {
1489 if (fade_out_is_default()) {
1490 set_fade_out_active (false);
1496 AudioRegion::resume_fade_out ()
1498 if (--_fade_out_disabled == 0 &&_fade_out_disabled) {
1499 set_fade_out_active (true);
1504 AudioRegion::speed_mismatch (float sr) const
1506 if (sources.empty()) {
1507 /* impossible, but ... */
1511 float fsr = sources.front()->sample_rate();
1517 AudioRegion::source_offset_changed ()
1519 /* XXX this fixes a crash that should not occur. It does occur
1520 becauses regions are not being deleted when a session
1521 is unloaded. That bug must be fixed.
1524 if (sources.empty()) {
1528 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(sources.front());
1530 if (afs && afs->destructive()) {
1531 // set_start (source()->natural_position(), this);
1532 set_position (source()->natural_position(), this);
1537 AudioRegion::set_playlist (boost::weak_ptr<Playlist> wpl)
1539 boost::shared_ptr<Playlist> old_playlist = (_playlist.lock());
1541 boost::shared_ptr<Playlist> pl (wpl.lock());
1543 if (old_playlist == pl) {
1547 Region::set_playlist (wpl);
1551 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
1552 (*i)->remove_playlist (_playlist);
1553 (*i)->add_playlist (pl);
1555 for (SourceList::const_iterator i = master_sources.begin(); i != master_sources.end(); ++i) {
1556 (*i)->remove_playlist (_playlist);
1557 (*i)->add_playlist (pl);
1560 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
1561 (*i)->add_playlist (pl);
1563 for (SourceList::const_iterator i = master_sources.begin(); i != master_sources.end(); ++i) {
1564 (*i)->add_playlist (pl);
1569 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
1570 (*i)->remove_playlist (old_playlist);
1572 for (SourceList::const_iterator i = master_sources.begin(); i != master_sources.end(); ++i) {
1573 (*i)->remove_playlist (old_playlist);
1580 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1582 boost::shared_ptr<Playlist> pl = playlist();
1588 if (valid_transients && !force_new) {
1589 results = _transients;
1593 SourceList::iterator s;
1595 for (s = sources.begin() ; s != sources.end(); ++s) {
1596 if (!(*s)->has_been_analysed()) {
1597 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1602 if (s == sources.end()) {
1603 /* all sources are analyzed, merge data from each one */
1605 for (s = sources.begin() ; s != sources.end(); ++s) {
1607 /* find the set of transients within the bounds of this region */
1609 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1610 (*s)->transients.end(),
1613 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1614 (*s)->transients.end(),
1619 results.insert (results.end(), low, high);
1622 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1624 /* translate all transients to current position */
1626 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1631 _transients = results;
1632 valid_transients = true;
1637 /* no existing/complete transient info */
1639 if (!Config->get_auto_analyse_audio()) {
1640 pl->session().Dialog (_("\
1641 You have requested an operation that requires audio analysis.\n\n\
1642 You currently have \"auto-analyse-audio\" disabled, which means\n\
1643 that transient data must be generated every time it is required.\n\n\
1644 If you are doing work that will require transient data on a\n\
1645 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1646 then quit ardour and restart."));
1649 TransientDetector t (pl->session().frame_rate());
1650 bool existing_results = !results.empty();
1652 _transients.clear ();
1653 valid_transients = false;
1655 for (uint32_t i = 0; i < n_channels(); ++i) {
1657 AnalysisFeatureList these_results;
1661 if (t.run ("", this, i, these_results)) {
1665 /* translate all transients to give absolute position */
1667 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1673 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1676 if (!results.empty()) {
1677 if (existing_results) {
1679 /* merge our transients into the existing ones, then clean up
1683 results.insert (results.end(), _transients.begin(), _transients.end());
1684 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1687 /* make sure ours are clean too */
1689 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1693 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1694 results = _transients;
1697 valid_transients = true;
1704 int region_read_peaks_from_c (void *arg, uint32_t npeaks, uint32_t start, uint32_t cnt, intptr_t data, uint32_t n_chan, double samples_per_unit)
1706 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (nframes_t) npeaks, (nframes_t) start, (nframes_t) cnt, n_chan,samples_per_unit);
1709 uint32_t region_length_from_c (void *arg)
1712 return ((AudioRegion *) arg)->length();
1715 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1717 return ( (AudioRegion *) arg)->source()->available_peaks (zoom_factor) ;