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 _fade_in_disabled = 0;
245 _fade_out_disabled = 0;
247 listen_to_my_curves ();
248 listen_to_my_sources ();
251 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node)
253 _fade_in (0.0, 2.0, 1.0, false),
254 _fade_out (0.0, 2.0, 1.0, false),
255 _envelope (0.0, 2.0, 1.0, false)
257 sources.push_back (src);
258 master_sources.push_back (src);
259 src->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
261 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
263 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
266 set_default_fades ();
268 if (set_state (node)) {
269 throw failed_constructor();
272 listen_to_my_curves ();
273 listen_to_my_sources ();
276 AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
278 _fade_in (0.0, 2.0, 1.0, false),
279 _fade_out (0.0, 2.0, 1.0, false),
280 _envelope (0.0, 2.0, 1.0, false)
282 set<boost::shared_ptr<AudioSource> > unique_srcs;
284 for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) {
285 sources.push_back (*i);
286 (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
287 pair<set<boost::shared_ptr<AudioSource> >::iterator,bool> result;
289 result = unique_srcs.insert (*i);
292 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
294 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
299 for (SourceList::iterator i = srcs.begin(); i != srcs.end(); ++i) {
300 master_sources.push_back (*i);
301 if (unique_srcs.find (*i) == unique_srcs.end()) {
302 (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
306 set_default_fades ();
307 _scale_amplitude = 1.0;
309 if (set_state (node)) {
310 throw failed_constructor();
313 listen_to_my_curves ();
314 listen_to_my_sources ();
317 AudioRegion::~AudioRegion ()
319 boost::shared_ptr<Playlist> pl (playlist());
322 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
323 (*i)->remove_playlist (pl);
325 for (SourceList::const_iterator i = master_sources.begin(); i != master_sources.end(); ++i) {
326 (*i)->remove_playlist (pl);
331 GoingAway (); /* EMIT SIGNAL */
335 AudioRegion::listen_to_my_sources ()
337 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
338 (*i)->AnalysisChanged.connect (mem_fun (*this, &AudioRegion::invalidate_transients));
343 AudioRegion::listen_to_my_curves ()
345 _envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
346 _fade_in.StateChanged.connect (mem_fun (*this, &AudioRegion::fade_in_changed));
347 _fade_out.StateChanged.connect (mem_fun (*this, &AudioRegion::fade_out_changed));
351 AudioRegion::copy_settings (boost::shared_ptr<const AudioRegion> other)
353 _fade_in = other->_fade_in;
354 _fade_out = other->_fade_out;
355 _envelope = other->_envelope;
356 _flags = other->_flags;
357 _scale_amplitude = other->_scale_amplitude;
358 _fade_in_disabled = other->_fade_in_disabled;
359 _fade_out_disabled = other->_fade_out_disabled;
361 if (_length != other->length()) {
362 _envelope.extend_to (_length);
367 AudioRegion::verify_length (nframes_t& len)
369 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(source());
371 if (afs && afs->destructive()) {
375 nframes_t maxlen = 0;
377 for (uint32_t n=0; n < sources.size(); ++n) {
378 maxlen = max (maxlen, sources[n]->length() - _start);
381 len = min (len, maxlen);
387 AudioRegion::verify_start_and_length (nframes_t new_start, nframes_t& new_length)
389 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(source());
391 if (afs && afs->destructive()) {
395 nframes_t maxlen = 0;
397 for (uint32_t n=0; n < sources.size(); ++n) {
398 maxlen = max (maxlen, sources[n]->length() - new_start);
401 new_length = min (new_length, maxlen);
407 AudioRegion::verify_start (nframes_t pos)
409 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(source());
411 if (afs && afs->destructive()) {
415 for (uint32_t n=0; n < sources.size(); ++n) {
416 if (pos > sources[n]->length() - _length) {
424 AudioRegion::verify_start_mutable (nframes_t& new_start)
426 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(source());
428 if (afs && afs->destructive()) {
432 for (uint32_t n=0; n < sources.size(); ++n) {
433 if (new_start > sources[n]->length() - _length) {
434 new_start = sources[n]->length() - _length;
440 AudioRegion::set_envelope_active (bool yn)
442 if (envelope_active() != yn) {
445 snprintf (buf, sizeof (buf), "envelope active");
446 _flags = Flag (_flags|EnvelopeActive);
448 snprintf (buf, sizeof (buf), "envelope off");
449 _flags = Flag (_flags & ~EnvelopeActive);
451 send_change (EnvelopeActiveChanged);
456 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
458 if (chan_n >= sources.size()) {
462 if (sources[chan_n]->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
465 if (_scale_amplitude != 1.0) {
466 for (nframes_t n = 0; n < npeaks; ++n) {
467 buf[n].max *= _scale_amplitude;
468 buf[n].min *= _scale_amplitude;
476 AudioRegion::read (Sample* buf, nframes64_t position, nframes64_t cnt, int channel) const
478 /* raw read, no fades, no gain, nada */
479 return _read_at (sources, _length, buf, 0, 0, _position + position, cnt, channel, 0, 0, ReadOps (0));
483 AudioRegion::read_with_ops (Sample* buf, nframes64_t position, nframes64_t cnt, int channel, ReadOps rops) const
485 return _read_at (sources, _length, buf, 0, 0, _position + position, cnt, channel, 0, 0, rops);
489 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position,
491 uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames) const
493 /* regular diskstream/butler read complete with fades etc */
494 return _read_at (sources, _length, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
498 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position,
499 nframes_t cnt, uint32_t chan_n) const
501 return _read_at (master_sources, master_sources.front()->length(), buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0);
505 AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
506 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
507 nframes_t position, nframes_t cnt,
509 nframes_t read_frames,
510 nframes_t skip_frames,
513 nframes_t internal_offset;
514 nframes_t buf_offset;
516 bool raw = (rops == ReadOpsNone);
518 if (muted() && !raw) {
519 return 0; /* read nothing */
522 /* precondition: caller has verified that we cover the desired section */
524 if (position < _position) {
526 buf_offset = _position - position;
529 internal_offset = position - _position;
533 if (internal_offset >= limit) {
534 return 0; /* read nothing */
537 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
538 return 0; /* read nothing */
541 if (opaque() || raw) {
542 /* overwrite whatever is there */
543 mixdown_buffer = buf + buf_offset;
545 mixdown_buffer += buf_offset;
548 if (rops & ReadOpsCount) {
549 _read_data_count = 0;
552 if (chan_n < n_channels()) {
554 if (srcs[chan_n]->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
555 return 0; /* "read nothing" */
558 if (rops & ReadOpsCount) {
559 _read_data_count += srcs[chan_n]->read_data_count();
564 /* track is N-channel, this region has less channels; silence the ones
568 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
571 if (rops & ReadOpsFades) {
575 if ((_flags & FadeIn) && Config->get_use_region_fades()) {
577 nframes_t fade_in_length = (nframes_t) _fade_in.back()->when;
579 /* see if this read is within the fade in */
581 if (internal_offset < fade_in_length) {
585 fi_limit = min (to_read, fade_in_length - internal_offset);
587 _fade_in.get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
589 for (nframes_t n = 0; n < fi_limit; ++n) {
590 mixdown_buffer[n] *= gain_buffer[n];
597 if ((_flags & FadeOut) && Config->get_use_region_fades()) {
599 /* see if some part of this read is within the fade out */
601 /* ................. >| REGION
607 limit - fade_out_length
610 ^internal_offset + to_read
612 we need the intersection of [internal_offset,internal_offset+to_read] with
613 [limit - fade_out_length, limit]
618 nframes_t fade_out_length = (nframes_t) _fade_out.back()->when;
619 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
620 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
622 if (fade_interval_end > fade_interval_start) {
623 /* (part of the) the fade out is in this buffer */
625 nframes_t fo_limit = fade_interval_end - fade_interval_start;
626 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
627 nframes_t fade_offset = fade_interval_start - internal_offset;
629 _fade_out.get_vector (curve_offset,curve_offset+fo_limit, gain_buffer, fo_limit);
631 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
632 mixdown_buffer[m] *= gain_buffer[n];
639 /* Regular gain curves and scaling */
641 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
642 _envelope.get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
644 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
645 for (nframes_t n = 0; n < to_read; ++n) {
646 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
649 for (nframes_t n = 0; n < to_read; ++n) {
650 mixdown_buffer[n] *= gain_buffer[n];
653 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
654 Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
659 /* gack. the things we do for users.
664 for (nframes_t n = 0; n < to_read; ++n) {
665 buf[n] += mixdown_buffer[n];
673 AudioRegion::state (bool full)
675 XMLNode& node (Region::state (full));
679 LocaleGuard lg (X_("POSIX"));
681 node.add_property ("flags", enum_2_string (_flags));
683 snprintf (buf, sizeof(buf), "%.12g", _scale_amplitude);
684 node.add_property ("scale-gain", buf);
686 for (uint32_t n=0; n < sources.size(); ++n) {
687 snprintf (buf2, sizeof(buf2), "source-%d", n);
688 sources[n]->id().print (buf, sizeof (buf));
689 node.add_property (buf2, buf);
692 snprintf (buf, sizeof (buf), "%u", (uint32_t) sources.size());
693 node.add_property ("channels", buf);
697 child = node.add_child (X_("FadeIn"));
699 if ((_flags & DefaultFadeIn)) {
700 child->add_property (X_("default"), X_("yes"));
702 child->add_child_nocopy (_fade_in.get_state ());
705 child->add_property (X_("active"), _fade_in_disabled ? X_("no") : X_("yes"));
707 child = node.add_child (X_("FadeOut"));
709 if ((_flags & DefaultFadeOut)) {
710 child->add_property (X_("default"), X_("yes"));
712 child->add_child_nocopy (_fade_out.get_state ());
715 child->add_property (X_("active"), _fade_out_disabled ? X_("no") : X_("yes"));
718 child = node.add_child ("Envelope");
721 bool default_env = false;
723 // If there are only two points, the points are in the start of the region and the end of the region
724 // so, if they are both at 1.0f, that means the default region.
726 if (_envelope.size() == 2 &&
727 _envelope.front()->value == 1.0f &&
728 _envelope.back()->value==1.0f) {
729 if (_envelope.front()->when == 0 && _envelope.back()->when == _length) {
735 child->add_property ("default", "yes");
737 child->add_child_nocopy (_envelope.get_state ());
741 child->add_property ("default", "yes");
744 for (uint32_t n=0; n < master_sources.size(); ++n) {
745 snprintf (buf2, sizeof(buf2), "master-source-%d", n);
746 master_sources[n]->id().print (buf, sizeof (buf));
747 node.add_property (buf2, buf);
750 if (full && _extra_xml) {
751 node.add_child_copy (*_extra_xml);
758 AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool send)
760 const XMLNodeList& nlist = node.children();
761 const XMLProperty *prop;
762 LocaleGuard lg (X_("POSIX"));
764 Region::set_live_state (node, what_changed, false);
766 uint32_t old_flags = _flags;
768 if ((prop = node.property ("flags")) != 0) {
769 _flags = Flag (string_2_enum (prop->value(), _flags));
771 //_flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16));
773 _flags = Flag (_flags & ~Region::LeftOfSplit);
774 _flags = Flag (_flags & ~Region::RightOfSplit);
777 if ((old_flags ^ _flags) & Muted) {
778 what_changed = Change (what_changed|MuteChanged);
780 if ((old_flags ^ _flags) & Opaque) {
781 what_changed = Change (what_changed|OpacityChanged);
783 if ((old_flags ^ _flags) & Locked) {
784 what_changed = Change (what_changed|LockChanged);
787 if ((prop = node.property ("scale-gain")) != 0) {
788 _scale_amplitude = atof (prop->value().c_str());
789 what_changed = Change (what_changed|ScaleAmplitudeChanged);
791 _scale_amplitude = 1.0;
794 /* Now find envelope description and other misc child items */
796 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
803 if (child->name() == "Envelope") {
807 if ((prop = child->property ("default")) != 0 || _envelope.set_state (*child)) {
808 set_default_envelope ();
811 _envelope.set_max_xval (_length);
812 _envelope.truncate_end (_length);
814 } else if (child->name() == "FadeIn") {
818 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
819 set_default_fade_in ();
821 XMLNode* grandchild = child->child ("AutomationList");
823 _fade_in.set_state (*grandchild);
827 if ((prop = child->property ("active")) != 0) {
828 if (prop->value() == "yes") {
829 set_fade_in_active (true);
831 set_fade_in_active (true);
835 } else if (child->name() == "FadeOut") {
839 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
840 set_default_fade_out ();
842 XMLNode* grandchild = child->child ("AutomationList");
844 _fade_out.set_state (*grandchild);
848 if ((prop = child->property ("active")) != 0) {
849 if (prop->value() == "yes") {
850 set_fade_out_active (true);
852 set_fade_out_active (false);
860 send_change (what_changed);
867 AudioRegion::set_state (const XMLNode& node)
869 /* Region::set_state() calls the virtual set_live_state(),
870 which will get us back to AudioRegion::set_live_state()
871 to handle the relevant stuff.
874 return Region::set_state (node);
878 AudioRegion::set_fade_in_shape (FadeShape shape)
880 set_fade_in (shape, (nframes_t) _fade_in.back()->when);
884 AudioRegion::set_fade_out_shape (FadeShape shape)
886 set_fade_out (shape, (nframes_t) _fade_out.back()->when);
890 AudioRegion::set_fade_in (FadeShape shape, nframes_t len)
897 _fade_in.fast_simple_add (0.0, 0.0);
898 _fade_in.fast_simple_add (len, 1.0);
902 _fade_in.fast_simple_add (0, 0);
903 _fade_in.fast_simple_add (len * 0.389401, 0.0333333);
904 _fade_in.fast_simple_add (len * 0.629032, 0.0861111);
905 _fade_in.fast_simple_add (len * 0.829493, 0.233333);
906 _fade_in.fast_simple_add (len * 0.9447, 0.483333);
907 _fade_in.fast_simple_add (len * 0.976959, 0.697222);
908 _fade_in.fast_simple_add (len, 1);
912 _fade_in.fast_simple_add (0, 0);
913 _fade_in.fast_simple_add (len * 0.0207373, 0.197222);
914 _fade_in.fast_simple_add (len * 0.0645161, 0.525);
915 _fade_in.fast_simple_add (len * 0.152074, 0.802778);
916 _fade_in.fast_simple_add (len * 0.276498, 0.919444);
917 _fade_in.fast_simple_add (len * 0.481567, 0.980556);
918 _fade_in.fast_simple_add (len * 0.767281, 1);
919 _fade_in.fast_simple_add (len, 1);
923 _fade_in.fast_simple_add (0, 0);
924 _fade_in.fast_simple_add (len * 0.0737327, 0.308333);
925 _fade_in.fast_simple_add (len * 0.246544, 0.658333);
926 _fade_in.fast_simple_add (len * 0.470046, 0.886111);
927 _fade_in.fast_simple_add (len * 0.652074, 0.972222);
928 _fade_in.fast_simple_add (len * 0.771889, 0.988889);
929 _fade_in.fast_simple_add (len, 1);
933 _fade_in.fast_simple_add (0, 0);
934 _fade_in.fast_simple_add (len * 0.304147, 0.0694444);
935 _fade_in.fast_simple_add (len * 0.529954, 0.152778);
936 _fade_in.fast_simple_add (len * 0.725806, 0.333333);
937 _fade_in.fast_simple_add (len * 0.847926, 0.558333);
938 _fade_in.fast_simple_add (len * 0.919355, 0.730556);
939 _fade_in.fast_simple_add (len, 1);
944 _fade_in_shape = shape;
946 send_change (FadeInChanged);
950 AudioRegion::set_fade_out (FadeShape shape, nframes_t len)
957 _fade_out.fast_simple_add (len * 0, 1);
958 _fade_out.fast_simple_add (len * 0.023041, 0.697222);
959 _fade_out.fast_simple_add (len * 0.0553, 0.483333);
960 _fade_out.fast_simple_add (len * 0.170507, 0.233333);
961 _fade_out.fast_simple_add (len * 0.370968, 0.0861111);
962 _fade_out.fast_simple_add (len * 0.610599, 0.0333333);
963 _fade_out.fast_simple_add (len * 1, 0);
967 _fade_out.fast_simple_add (len * 0, 1);
968 _fade_out.fast_simple_add (len * 0.228111, 0.988889);
969 _fade_out.fast_simple_add (len * 0.347926, 0.972222);
970 _fade_out.fast_simple_add (len * 0.529954, 0.886111);
971 _fade_out.fast_simple_add (len * 0.753456, 0.658333);
972 _fade_out.fast_simple_add (len * 0.9262673, 0.308333);
973 _fade_out.fast_simple_add (len * 1, 0);
977 _fade_out.fast_simple_add (len * 0, 1);
978 _fade_out.fast_simple_add (len * 0.305556, 1);
979 _fade_out.fast_simple_add (len * 0.548611, 0.991736);
980 _fade_out.fast_simple_add (len * 0.759259, 0.931129);
981 _fade_out.fast_simple_add (len * 0.918981, 0.68595);
982 _fade_out.fast_simple_add (len * 0.976852, 0.22865);
983 _fade_out.fast_simple_add (len * 1, 0);
987 _fade_out.fast_simple_add (len * 0, 1);
988 _fade_out.fast_simple_add (len * 0.080645, 0.730556);
989 _fade_out.fast_simple_add (len * 0.277778, 0.289256);
990 _fade_out.fast_simple_add (len * 0.470046, 0.152778);
991 _fade_out.fast_simple_add (len * 0.695853, 0.0694444);
992 _fade_out.fast_simple_add (len * 1, 0);
996 _fade_out.fast_simple_add (len * 0, 1);
997 _fade_out.fast_simple_add (len * 1, 0);
1002 _fade_out_shape = shape;
1004 send_change (FadeOutChanged);
1008 AudioRegion::set_fade_in_length (nframes_t len)
1010 if (len > _length) {
1014 bool changed = _fade_in.extend_to (len);
1017 _flags = Flag (_flags & ~DefaultFadeIn);
1018 send_change (FadeInChanged);
1023 AudioRegion::set_fade_out_length (nframes_t len)
1025 if (len > _length) {
1029 bool changed = _fade_out.extend_to (len);
1032 _flags = Flag (_flags & ~DefaultFadeOut);
1033 send_change (FadeOutChanged);
1038 AudioRegion::set_fade_in_active (bool yn)
1040 if (yn == (_flags & FadeIn)) {
1044 _flags = Flag (_flags|FadeIn);
1046 _flags = Flag (_flags & ~FadeIn);
1049 send_change (FadeInActiveChanged);
1053 AudioRegion::set_fade_out_active (bool yn)
1055 if (yn == (_flags & FadeOut)) {
1059 _flags = Flag (_flags | FadeOut);
1061 _flags = Flag (_flags & ~FadeOut);
1064 send_change (FadeOutActiveChanged);
1068 AudioRegion::fade_in_is_default () const
1070 return _fade_in_shape == Linear && _fade_in.back()->when == 64;
1074 AudioRegion::fade_out_is_default () const
1076 return _fade_out_shape == Linear && _fade_out.back()->when == 64;
1080 AudioRegion::set_default_fade_in ()
1082 set_fade_in (Linear, 64);
1086 AudioRegion::set_default_fade_out ()
1088 set_fade_out (Linear, 64);
1092 AudioRegion::set_default_fades ()
1094 _fade_in_disabled = 0;
1095 _fade_out_disabled = 0;
1096 set_default_fade_in ();
1097 set_default_fade_out ();
1101 AudioRegion::set_default_envelope ()
1103 _envelope.freeze ();
1105 _envelope.fast_simple_add (0, 1.0f);
1106 _envelope.fast_simple_add (_length, 1.0f);
1111 AudioRegion::recompute_at_end ()
1113 /* our length has changed. recompute a new final point by interpolating
1114 based on the the existing curve.
1117 _envelope.freeze ();
1118 _envelope.truncate_end (_length);
1119 _envelope.set_max_xval (_length);
1122 if (_fade_in.back()->when > _length) {
1123 _fade_in.extend_to (_length);
1124 send_change (FadeInChanged);
1127 if (_fade_out.back()->when > _length) {
1128 _fade_out.extend_to (_length);
1129 send_change (FadeOutChanged);
1134 AudioRegion::recompute_at_start ()
1136 /* as above, but the shift was from the front */
1138 _envelope.truncate_start (_length);
1140 if (_fade_in.back()->when > _length) {
1141 _fade_in.extend_to (_length);
1142 send_change (FadeInChanged);
1145 if (_fade_out.back()->when > _length) {
1146 _fade_out.extend_to (_length);
1147 send_change (FadeOutChanged);
1152 AudioRegion::separate_by_channel (Session& session, vector<boost::shared_ptr<AudioRegion> >& v) const
1158 if (sources.size() < 2) {
1164 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
1167 srcs.push_back (*i);
1171 if (sources.size() == 2) {
1179 new_name += ('0' + n + 1);
1182 /* create a copy with just one source. prevent if from being thought of as "whole file" even if
1183 it covers the entire source file(s).
1186 Flag f = Flag (_flags & ~WholeFile);
1188 boost::shared_ptr<Region> r = RegionFactory::create (srcs, _start, _length, new_name, _layer, f);
1189 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (r);
1200 AudioRegion::source_deleted ()
1207 AudioRegion::master_source_names ()
1209 SourceList::iterator i;
1211 vector<string> names;
1212 for (i = master_sources.begin(); i != master_sources.end(); ++i) {
1213 names.push_back((*i)->name());
1220 AudioRegion::set_master_sources (const SourceList& srcs)
1222 master_sources = srcs;
1226 AudioRegion::source_equivalent (boost::shared_ptr<const Region> o) const
1228 boost::shared_ptr<const AudioRegion> other = boost::dynamic_pointer_cast<const AudioRegion>(o);
1233 SourceList::const_iterator i;
1234 SourceList::const_iterator io;
1236 for (i = sources.begin(), io = other->sources.begin(); i != sources.end() && io != other->sources.end(); ++i, ++io) {
1237 if ((*i)->id() != (*io)->id()) {
1242 for (i = master_sources.begin(), io = other->master_sources.begin(); i != master_sources.end() && io != other->master_sources.end(); ++i, ++io) {
1243 if ((*i)->id() != (*io)->id()) {
1252 AudioRegion::apply (AudioFilter& filter)
1254 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (shared_from_this());
1255 return filter.run (ar);
1259 AudioRegion::exportme (Session& session, AudioExportSpecification& spec)
1261 const nframes_t blocksize = 4096;
1265 spec.channels = sources.size();
1267 if (spec.prepare (blocksize, session.frame_rate())) {
1272 spec.total_frames = _length;
1274 while (spec.pos < _length && !spec.stop) {
1277 /* step 1: interleave */
1279 to_read = min (_length - spec.pos, blocksize);
1281 if (spec.channels == 1) {
1283 if (sources.front()->read (spec.dataF, _start + spec.pos, to_read) != to_read) {
1289 Sample buf[blocksize];
1291 for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1293 if (sources[chan]->read (buf, _start + spec.pos, to_read) != to_read) {
1297 for (nframes_t x = 0; x < to_read; ++x) {
1298 spec.dataF[chan+(x*spec.channels)] = buf[x];
1303 if (spec.process (to_read)) {
1307 spec.pos += to_read;
1308 spec.progress = (double) spec.pos /_length;
1315 spec.running = false;
1316 spec.status = status;
1322 boost::shared_ptr<Region>
1323 AudioRegion::get_parent() const
1325 boost::shared_ptr<Playlist> pl (playlist());
1328 boost::shared_ptr<AudioRegion> ar;
1329 boost::shared_ptr<AudioRegion const> grrr2 = boost::dynamic_pointer_cast<AudioRegion const> (shared_from_this());
1331 if (grrr2 && (ar = pl->session().find_whole_file_parent (grrr2))) {
1332 return boost::static_pointer_cast<Region> (ar);
1336 return boost::shared_ptr<Region>();
1340 AudioRegion::set_scale_amplitude (gain_t g)
1342 boost::shared_ptr<Playlist> pl (playlist());
1344 _scale_amplitude = g;
1346 /* tell the diskstream we're in */
1352 /* tell everybody else */
1354 send_change (ScaleAmplitudeChanged);
1358 AudioRegion::normalize_to (float target_dB)
1360 const nframes_t blocksize = 64 * 1024;
1361 Sample buf[blocksize];
1366 gain_t target = dB_to_coefficient (target_dB);
1368 if (target == 1.0f) {
1369 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1370 that we may have clipped.
1372 target -= FLT_EPSILON;
1376 fend = _start + _length;
1378 /* first pass: find max amplitude */
1380 while (fpos < fend) {
1384 to_read = min (fend - fpos, blocksize);
1386 for (n = 0; n < n_channels(); ++n) {
1390 if (source (n)->read (buf, fpos, to_read) != to_read) {
1394 maxamp = Session::compute_peak (buf, to_read, maxamp);
1400 if (maxamp == 0.0f) {
1401 /* don't even try */
1405 if (maxamp == target) {
1406 /* we can't do anything useful */
1410 /* compute scale factor */
1412 _scale_amplitude = target/maxamp;
1414 /* tell the diskstream we're in */
1416 boost::shared_ptr<Playlist> pl (playlist());
1422 /* tell everybody else */
1424 send_change (ScaleAmplitudeChanged);
1428 AudioRegion::fade_in_changed ()
1430 send_change (FadeInChanged);
1434 AudioRegion::fade_out_changed ()
1436 send_change (FadeOutChanged);
1440 AudioRegion::envelope_changed ()
1442 send_change (EnvelopeChanged);
1446 AudioRegion::suspend_fade_in ()
1448 if (++_fade_in_disabled == 1) {
1449 if (fade_in_is_default()) {
1450 set_fade_in_active (false);
1456 AudioRegion::resume_fade_in ()
1458 if (--_fade_in_disabled == 0 && _fade_in_disabled) {
1459 set_fade_in_active (true);
1464 AudioRegion::suspend_fade_out ()
1466 if (++_fade_out_disabled == 1) {
1467 if (fade_out_is_default()) {
1468 set_fade_out_active (false);
1474 AudioRegion::resume_fade_out ()
1476 if (--_fade_out_disabled == 0 &&_fade_out_disabled) {
1477 set_fade_out_active (true);
1482 AudioRegion::speed_mismatch (float sr) const
1484 if (sources.empty()) {
1485 /* impossible, but ... */
1489 float fsr = sources.front()->sample_rate();
1495 AudioRegion::source_offset_changed ()
1497 /* XXX this fixes a crash that should not occur. It does occur
1498 becauses regions are not being deleted when a session
1499 is unloaded. That bug must be fixed.
1502 if (sources.empty()) {
1506 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(sources.front());
1508 if (afs && afs->destructive()) {
1509 // set_start (source()->natural_position(), this);
1510 set_position (source()->natural_position(), this);
1515 AudioRegion::set_playlist (boost::weak_ptr<Playlist> wpl)
1517 boost::shared_ptr<Playlist> old_playlist = (_playlist.lock());
1519 boost::shared_ptr<Playlist> pl (wpl.lock());
1521 if (old_playlist == pl) {
1525 Region::set_playlist (wpl);
1529 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
1530 (*i)->remove_playlist (_playlist);
1531 (*i)->add_playlist (pl);
1533 for (SourceList::const_iterator i = master_sources.begin(); i != master_sources.end(); ++i) {
1534 (*i)->remove_playlist (_playlist);
1535 (*i)->add_playlist (pl);
1538 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
1539 (*i)->add_playlist (pl);
1541 for (SourceList::const_iterator i = master_sources.begin(); i != master_sources.end(); ++i) {
1542 (*i)->add_playlist (pl);
1547 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
1548 (*i)->remove_playlist (old_playlist);
1550 for (SourceList::const_iterator i = master_sources.begin(); i != master_sources.end(); ++i) {
1551 (*i)->remove_playlist (old_playlist);
1558 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1560 boost::shared_ptr<Playlist> pl = playlist();
1566 if (valid_transients && !force_new) {
1567 results = _transients;
1571 SourceList::iterator s;
1573 for (s = sources.begin() ; s != sources.end(); ++s) {
1574 if (!(*s)->has_been_analysed()) {
1575 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1580 if (s == sources.end()) {
1581 /* all sources are analyzed, merge data from each one */
1583 for (s = sources.begin() ; s != sources.end(); ++s) {
1585 /* find the set of transients within the bounds of this region */
1587 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1588 (*s)->transients.end(),
1591 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1592 (*s)->transients.end(),
1597 results.insert (results.end(), low, high);
1600 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1602 /* translate all transients to current position */
1604 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1609 _transients = results;
1610 valid_transients = true;
1615 /* no existing/complete transient info */
1617 if (!Config->get_auto_analyse_audio()) {
1618 pl->session().Dialog (_("\
1619 You have requested an operation that requires audio analysis.\n\n\
1620 You currently have \"auto-analyse-audio\" disabled, which means\n\
1621 that transient data must be generated every time it is required.\n\n\
1622 If you are doing work that will require transient data on a\n\
1623 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1624 then quit ardour and restart."));
1627 TransientDetector t (pl->session().frame_rate());
1628 bool existing_results = !results.empty();
1630 _transients.clear ();
1631 valid_transients = false;
1633 for (uint32_t i = 0; i < n_channels(); ++i) {
1635 AnalysisFeatureList these_results;
1639 if (t.run ("", this, i, these_results)) {
1643 /* translate all transients to give absolute position */
1645 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1651 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1654 if (!results.empty()) {
1655 if (existing_results) {
1657 /* merge our transients into the existing ones, then clean up
1661 results.insert (results.end(), _transients.begin(), _transients.end());
1662 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1665 /* make sure ours are clean too */
1667 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1671 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1672 results = _transients;
1675 valid_transients = true;
1682 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)
1684 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (nframes_t) npeaks, (nframes_t) start, (nframes_t) cnt, n_chan,samples_per_unit);
1687 uint32_t region_length_from_c (void *arg)
1690 return ((AudioRegion *) arg)->length();
1693 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1695 return ( (AudioRegion *) arg)->source()->available_peaks (zoom_factor) ;