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)
217 /* Pure copy constructor */
219 set<boost::shared_ptr<AudioSource> > unique_srcs;
221 for (SourceList::const_iterator i = other->sources.begin(); i != other->sources.end(); ++i) {
222 sources.push_back (*i);
223 (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
224 pair<set<boost::shared_ptr<AudioSource> >::iterator,bool> result;
226 result = unique_srcs.insert (*i);
229 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
231 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
236 for (SourceList::const_iterator i = other->master_sources.begin(); i != other->master_sources.end(); ++i) {
237 master_sources.push_back (*i);
238 if (unique_srcs.find (*i) == unique_srcs.end()) {
239 (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
243 _scale_amplitude = other->_scale_amplitude;
244 _envelope = other->_envelope;
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<AudioSource> src, const XMLNode& node)
255 _fade_in (0.0, 2.0, 1.0, false),
256 _fade_out (0.0, 2.0, 1.0, false),
257 _envelope (0.0, 2.0, 1.0, false)
259 sources.push_back (src);
260 master_sources.push_back (src);
261 src->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
263 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
265 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
268 set_default_fades ();
270 if (set_state (node)) {
271 throw failed_constructor();
274 listen_to_my_curves ();
275 listen_to_my_sources ();
278 AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
280 _fade_in (0.0, 2.0, 1.0, false),
281 _fade_out (0.0, 2.0, 1.0, false),
282 _envelope (0.0, 2.0, 1.0, false)
284 set<boost::shared_ptr<AudioSource> > unique_srcs;
286 for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) {
287 sources.push_back (*i);
288 (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
289 pair<set<boost::shared_ptr<AudioSource> >::iterator,bool> result;
291 result = unique_srcs.insert (*i);
294 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
296 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
301 for (SourceList::iterator i = srcs.begin(); i != srcs.end(); ++i) {
302 master_sources.push_back (*i);
303 if (unique_srcs.find (*i) == unique_srcs.end()) {
304 (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
308 set_default_fades ();
309 _scale_amplitude = 1.0;
311 if (set_state (node)) {
312 throw failed_constructor();
315 listen_to_my_curves ();
316 listen_to_my_sources ();
319 AudioRegion::~AudioRegion ()
321 boost::shared_ptr<Playlist> pl (playlist());
324 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
325 (*i)->remove_playlist (pl);
327 for (SourceList::const_iterator i = master_sources.begin(); i != master_sources.end(); ++i) {
328 (*i)->remove_playlist (pl);
333 GoingAway (); /* EMIT SIGNAL */
337 AudioRegion::listen_to_my_sources ()
339 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
340 (*i)->AnalysisChanged.connect (mem_fun (*this, &AudioRegion::invalidate_transients));
345 AudioRegion::listen_to_my_curves ()
347 _envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
348 _fade_in.StateChanged.connect (mem_fun (*this, &AudioRegion::fade_in_changed));
349 _fade_out.StateChanged.connect (mem_fun (*this, &AudioRegion::fade_out_changed));
353 AudioRegion::verify_length (nframes_t& len)
355 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(source());
357 if (afs && afs->destructive()) {
361 nframes_t maxlen = 0;
363 for (uint32_t n=0; n < sources.size(); ++n) {
364 maxlen = max (maxlen, sources[n]->length() - _start);
367 len = min (len, maxlen);
373 AudioRegion::verify_start_and_length (nframes_t new_start, nframes_t& new_length)
375 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(source());
377 if (afs && afs->destructive()) {
381 nframes_t maxlen = 0;
383 for (uint32_t n=0; n < sources.size(); ++n) {
384 maxlen = max (maxlen, sources[n]->length() - new_start);
387 new_length = min (new_length, maxlen);
392 AudioRegion::verify_start (nframes_t pos)
394 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(source());
396 if (afs && afs->destructive()) {
400 for (uint32_t n=0; n < sources.size(); ++n) {
401 if (pos > sources[n]->length() - _length) {
409 AudioRegion::verify_start_mutable (nframes_t& new_start)
411 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(source());
413 if (afs && afs->destructive()) {
417 for (uint32_t n=0; n < sources.size(); ++n) {
418 if (new_start > sources[n]->length() - _length) {
419 new_start = sources[n]->length() - _length;
425 AudioRegion::set_envelope_active (bool yn)
427 if (envelope_active() != yn) {
430 snprintf (buf, sizeof (buf), "envelope active");
431 _flags = Flag (_flags|EnvelopeActive);
433 snprintf (buf, sizeof (buf), "envelope off");
434 _flags = Flag (_flags & ~EnvelopeActive);
436 send_change (EnvelopeActiveChanged);
441 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
443 if (chan_n >= sources.size()) {
447 if (sources[chan_n]->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
450 if (_scale_amplitude != 1.0) {
451 for (nframes_t n = 0; n < npeaks; ++n) {
452 buf[n].max *= _scale_amplitude;
453 buf[n].min *= _scale_amplitude;
461 AudioRegion::read (Sample* buf, nframes64_t position, nframes64_t cnt, int channel) const
463 /* raw read, no fades, no gain, nada */
464 return _read_at (sources, _length, buf, 0, 0, _position + position, cnt, channel, 0, 0, true);
468 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position,
470 uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames) const
472 /* regular diskstream/butler read complete with fades etc */
473 return _read_at (sources, _length, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, read_frames, skip_frames, false);
477 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position,
478 nframes_t cnt, uint32_t chan_n) const
480 return _read_at (master_sources, master_sources.front()->length(), buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0);
484 AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
485 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
486 nframes_t position, nframes_t cnt,
488 nframes_t read_frames,
489 nframes_t skip_frames,
492 nframes_t internal_offset;
493 nframes_t buf_offset;
496 if (muted() && !raw) {
497 return 0; /* read nothing */
500 /* precondition: caller has verified that we cover the desired section */
502 if (position < _position) {
504 buf_offset = _position - position;
507 internal_offset = position - _position;
511 if (internal_offset >= limit) {
512 return 0; /* read nothing */
515 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
516 return 0; /* read nothing */
519 if (opaque() || raw) {
520 /* overwrite whatever is there */
521 mixdown_buffer = buf + buf_offset;
523 mixdown_buffer += buf_offset;
527 _read_data_count = 0;
530 if (chan_n < n_channels()) {
532 if (srcs[chan_n]->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
534 return 0; /* "read nothing" */
538 _read_data_count += srcs[chan_n]->read_data_count();
543 /* track is N-channel, this region has less channels; silence the ones
547 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
549 /* no fades required */
560 if (_flags & FadeIn) {
562 nframes_t fade_in_length = (nframes_t) _fade_in.back()->when;
564 /* see if this read is within the fade in */
566 if (internal_offset < fade_in_length) {
570 limit = min (to_read, fade_in_length - internal_offset);
572 _fade_in.get_vector (internal_offset, internal_offset+limit, gain_buffer, limit);
574 for (nframes_t n = 0; n < limit; ++n) {
575 mixdown_buffer[n] *= gain_buffer[n];
582 if (_flags & FadeOut) {
584 /* see if some part of this read is within the fade out */
586 /* ................. >| REGION
592 limit - fade_out_length
595 ^internal_offset + to_read
597 we need the intersection of [internal_offset,internal_offset+to_read] with
598 [limit - fade_out_length, limit]
603 nframes_t fade_out_length = (nframes_t) _fade_out.back()->when;
604 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
605 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
607 if (fade_interval_end > fade_interval_start) {
608 /* (part of the) the fade out is in this buffer */
610 nframes_t fo_limit = fade_interval_end - fade_interval_start;
611 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
612 nframes_t fade_offset = fade_interval_start - internal_offset;
614 _fade_out.get_vector (curve_offset,curve_offset+fo_limit, gain_buffer, fo_limit);
616 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
617 mixdown_buffer[m] *= gain_buffer[n];
623 /* Regular gain curves */
625 if (envelope_active()) {
626 _envelope.get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
628 if (_scale_amplitude != 1.0f) {
629 for (nframes_t n = 0; n < to_read; ++n) {
630 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
633 for (nframes_t n = 0; n < to_read; ++n) {
634 mixdown_buffer[n] *= gain_buffer[n];
637 } else if (_scale_amplitude != 1.0f) {
638 Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
645 /* gack. the things we do for users.
650 for (nframes_t n = 0; n < to_read; ++n) {
651 buf[n] += mixdown_buffer[n];
660 AudioRegion::state (bool full)
662 XMLNode& node (Region::state (full));
666 LocaleGuard lg (X_("POSIX"));
668 node.add_property ("flags", enum_2_string (_flags));
670 snprintf (buf, sizeof(buf), "%.12g", _scale_amplitude);
671 node.add_property ("scale-gain", buf);
673 for (uint32_t n=0; n < sources.size(); ++n) {
674 snprintf (buf2, sizeof(buf2), "source-%d", n);
675 sources[n]->id().print (buf, sizeof (buf));
676 node.add_property (buf2, buf);
679 snprintf (buf, sizeof (buf), "%u", (uint32_t) sources.size());
680 node.add_property ("channels", buf);
684 child = node.add_child (X_("FadeIn"));
686 if ((_flags & DefaultFadeIn)) {
687 child->add_property (X_("default"), X_("yes"));
689 child->add_child_nocopy (_fade_in.get_state ());
692 child->add_property (X_("active"), _fade_in_disabled ? X_("no") : X_("yes"));
694 child = node.add_child (X_("FadeOut"));
696 if ((_flags & DefaultFadeOut)) {
697 child->add_property (X_("default"), X_("yes"));
699 child->add_child_nocopy (_fade_out.get_state ());
702 child->add_property (X_("active"), _fade_out_disabled ? X_("no") : X_("yes"));
705 child = node.add_child ("Envelope");
708 bool default_env = false;
710 // If there are only two points, the points are in the start of the region and the end of the region
711 // so, if they are both at 1.0f, that means the default region.
713 if (_envelope.size() == 2 &&
714 _envelope.front()->value == 1.0f &&
715 _envelope.back()->value==1.0f) {
716 if (_envelope.front()->when == 0 && _envelope.back()->when == _length) {
722 child->add_property ("default", "yes");
724 child->add_child_nocopy (_envelope.get_state ());
728 child->add_property ("default", "yes");
731 for (uint32_t n=0; n < master_sources.size(); ++n) {
732 snprintf (buf2, sizeof(buf2), "master-source-%d", n);
733 master_sources[n]->id().print (buf, sizeof (buf));
734 node.add_property (buf2, buf);
737 if (full && _extra_xml) {
738 node.add_child_copy (*_extra_xml);
745 AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool send)
747 const XMLNodeList& nlist = node.children();
748 const XMLProperty *prop;
749 LocaleGuard lg (X_("POSIX"));
751 Region::set_live_state (node, what_changed, false);
753 uint32_t old_flags = _flags;
755 if ((prop = node.property ("flags")) != 0) {
756 _flags = Flag (string_2_enum (prop->value(), _flags));
758 //_flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16));
760 _flags = Flag (_flags & ~Region::LeftOfSplit);
761 _flags = Flag (_flags & ~Region::RightOfSplit);
764 if ((old_flags ^ _flags) & Muted) {
765 what_changed = Change (what_changed|MuteChanged);
767 if ((old_flags ^ _flags) & Opaque) {
768 what_changed = Change (what_changed|OpacityChanged);
770 if ((old_flags ^ _flags) & Locked) {
771 what_changed = Change (what_changed|LockChanged);
774 if ((prop = node.property ("scale-gain")) != 0) {
775 _scale_amplitude = atof (prop->value().c_str());
776 what_changed = Change (what_changed|ScaleAmplitudeChanged);
778 _scale_amplitude = 1.0;
781 /* Now find envelope description and other misc child items */
783 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
790 if (child->name() == "Envelope") {
794 if ((prop = child->property ("default")) != 0 || _envelope.set_state (*child)) {
795 set_default_envelope ();
798 _envelope.set_max_xval (_length);
799 _envelope.truncate_end (_length);
801 } else if (child->name() == "FadeIn") {
805 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
806 set_default_fade_in ();
808 XMLNode* grandchild = child->child ("AutomationList");
810 _fade_in.set_state (*grandchild);
814 if ((prop = child->property ("active")) != 0) {
815 if (prop->value() == "yes") {
816 set_fade_in_active (true);
818 set_fade_in_active (true);
822 } else if (child->name() == "FadeOut") {
826 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
827 set_default_fade_out ();
829 XMLNode* grandchild = child->child ("AutomationList");
831 _fade_out.set_state (*grandchild);
835 if ((prop = child->property ("active")) != 0) {
836 if (prop->value() == "yes") {
837 set_fade_out_active (true);
839 set_fade_out_active (false);
847 send_change (what_changed);
854 AudioRegion::set_state (const XMLNode& node)
856 /* Region::set_state() calls the virtual set_live_state(),
857 which will get us back to AudioRegion::set_live_state()
858 to handle the relevant stuff.
861 return Region::set_state (node);
865 AudioRegion::set_fade_in_shape (FadeShape shape)
867 set_fade_in (shape, (nframes_t) _fade_in.back()->when);
871 AudioRegion::set_fade_out_shape (FadeShape shape)
873 set_fade_out (shape, (nframes_t) _fade_out.back()->when);
877 AudioRegion::set_fade_in (FadeShape shape, nframes_t len)
884 _fade_in.fast_simple_add (0.0, 0.0);
885 _fade_in.fast_simple_add (len, 1.0);
889 _fade_in.fast_simple_add (0, 0);
890 _fade_in.fast_simple_add (len * 0.389401, 0.0333333);
891 _fade_in.fast_simple_add (len * 0.629032, 0.0861111);
892 _fade_in.fast_simple_add (len * 0.829493, 0.233333);
893 _fade_in.fast_simple_add (len * 0.9447, 0.483333);
894 _fade_in.fast_simple_add (len * 0.976959, 0.697222);
895 _fade_in.fast_simple_add (len, 1);
899 _fade_in.fast_simple_add (0, 0);
900 _fade_in.fast_simple_add (len * 0.0207373, 0.197222);
901 _fade_in.fast_simple_add (len * 0.0645161, 0.525);
902 _fade_in.fast_simple_add (len * 0.152074, 0.802778);
903 _fade_in.fast_simple_add (len * 0.276498, 0.919444);
904 _fade_in.fast_simple_add (len * 0.481567, 0.980556);
905 _fade_in.fast_simple_add (len * 0.767281, 1);
906 _fade_in.fast_simple_add (len, 1);
910 _fade_in.fast_simple_add (0, 0);
911 _fade_in.fast_simple_add (len * 0.0737327, 0.308333);
912 _fade_in.fast_simple_add (len * 0.246544, 0.658333);
913 _fade_in.fast_simple_add (len * 0.470046, 0.886111);
914 _fade_in.fast_simple_add (len * 0.652074, 0.972222);
915 _fade_in.fast_simple_add (len * 0.771889, 0.988889);
916 _fade_in.fast_simple_add (len, 1);
920 _fade_in.fast_simple_add (0, 0);
921 _fade_in.fast_simple_add (len * 0.304147, 0.0694444);
922 _fade_in.fast_simple_add (len * 0.529954, 0.152778);
923 _fade_in.fast_simple_add (len * 0.725806, 0.333333);
924 _fade_in.fast_simple_add (len * 0.847926, 0.558333);
925 _fade_in.fast_simple_add (len * 0.919355, 0.730556);
926 _fade_in.fast_simple_add (len, 1);
931 _fade_in_shape = shape;
933 send_change (FadeInChanged);
937 AudioRegion::set_fade_out (FadeShape shape, nframes_t len)
944 _fade_out.fast_simple_add (len * 0, 1);
945 _fade_out.fast_simple_add (len * 0.023041, 0.697222);
946 _fade_out.fast_simple_add (len * 0.0553, 0.483333);
947 _fade_out.fast_simple_add (len * 0.170507, 0.233333);
948 _fade_out.fast_simple_add (len * 0.370968, 0.0861111);
949 _fade_out.fast_simple_add (len * 0.610599, 0.0333333);
950 _fade_out.fast_simple_add (len * 1, 0);
954 _fade_out.fast_simple_add (len * 0, 1);
955 _fade_out.fast_simple_add (len * 0.228111, 0.988889);
956 _fade_out.fast_simple_add (len * 0.347926, 0.972222);
957 _fade_out.fast_simple_add (len * 0.529954, 0.886111);
958 _fade_out.fast_simple_add (len * 0.753456, 0.658333);
959 _fade_out.fast_simple_add (len * 0.9262673, 0.308333);
960 _fade_out.fast_simple_add (len * 1, 0);
964 _fade_out.fast_simple_add (len * 0, 1);
965 _fade_out.fast_simple_add (len * 0.305556, 1);
966 _fade_out.fast_simple_add (len * 0.548611, 0.991736);
967 _fade_out.fast_simple_add (len * 0.759259, 0.931129);
968 _fade_out.fast_simple_add (len * 0.918981, 0.68595);
969 _fade_out.fast_simple_add (len * 0.976852, 0.22865);
970 _fade_out.fast_simple_add (len * 1, 0);
974 _fade_out.fast_simple_add (len * 0, 1);
975 _fade_out.fast_simple_add (len * 0.080645, 0.730556);
976 _fade_out.fast_simple_add (len * 0.277778, 0.289256);
977 _fade_out.fast_simple_add (len * 0.470046, 0.152778);
978 _fade_out.fast_simple_add (len * 0.695853, 0.0694444);
979 _fade_out.fast_simple_add (len * 1, 0);
983 _fade_out.fast_simple_add (len * 0, 1);
984 _fade_out.fast_simple_add (len * 1, 0);
989 _fade_out_shape = shape;
991 send_change (FadeOutChanged);
995 AudioRegion::set_fade_in_length (nframes_t len)
1001 bool changed = _fade_in.extend_to (len);
1004 _flags = Flag (_flags & ~DefaultFadeIn);
1005 send_change (FadeInChanged);
1010 AudioRegion::set_fade_out_length (nframes_t len)
1012 if (len > _length) {
1016 bool changed = _fade_out.extend_to (len);
1019 _flags = Flag (_flags & ~DefaultFadeOut);
1020 send_change (FadeOutChanged);
1025 AudioRegion::set_fade_in_active (bool yn)
1027 if (yn == (_flags & FadeIn)) {
1031 _flags = Flag (_flags|FadeIn);
1033 _flags = Flag (_flags & ~FadeIn);
1036 send_change (FadeInActiveChanged);
1040 AudioRegion::set_fade_out_active (bool yn)
1042 if (yn == (_flags & FadeOut)) {
1046 _flags = Flag (_flags | FadeOut);
1048 _flags = Flag (_flags & ~FadeOut);
1051 send_change (FadeOutActiveChanged);
1055 AudioRegion::fade_in_is_default () const
1057 return _fade_in_shape == Linear && _fade_in.back()->when == 64;
1061 AudioRegion::fade_out_is_default () const
1063 return _fade_out_shape == Linear && _fade_out.back()->when == 64;
1067 AudioRegion::set_default_fade_in ()
1069 set_fade_in (Linear, 64);
1073 AudioRegion::set_default_fade_out ()
1075 set_fade_out (Linear, 64);
1079 AudioRegion::set_default_fades ()
1081 _fade_in_disabled = 0;
1082 _fade_out_disabled = 0;
1083 set_default_fade_in ();
1084 set_default_fade_out ();
1088 AudioRegion::set_default_envelope ()
1090 _envelope.freeze ();
1092 _envelope.fast_simple_add (0, 1.0f);
1093 _envelope.fast_simple_add (_length, 1.0f);
1098 AudioRegion::recompute_at_end ()
1100 /* our length has changed. recompute a new final point by interpolating
1101 based on the the existing curve.
1104 _envelope.freeze ();
1105 _envelope.truncate_end (_length);
1106 _envelope.set_max_xval (_length);
1109 if (_fade_in.back()->when > _length) {
1110 _fade_in.extend_to (_length);
1111 send_change (FadeInChanged);
1114 if (_fade_out.back()->when > _length) {
1115 _fade_out.extend_to (_length);
1116 send_change (FadeOutChanged);
1121 AudioRegion::recompute_at_start ()
1123 /* as above, but the shift was from the front */
1125 _envelope.truncate_start (_length);
1127 if (_fade_in.back()->when > _length) {
1128 _fade_in.extend_to (_length);
1129 send_change (FadeInChanged);
1132 if (_fade_out.back()->when > _length) {
1133 _fade_out.extend_to (_length);
1134 send_change (FadeOutChanged);
1139 AudioRegion::separate_by_channel (Session& session, vector<boost::shared_ptr<AudioRegion> >& v) const
1145 if (sources.size() < 2) {
1151 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
1154 srcs.push_back (*i);
1158 if (sources.size() == 2) {
1166 new_name += ('0' + n + 1);
1169 /* create a copy with just one source. prevent if from being thought of as "whole file" even if
1170 it covers the entire source file(s).
1173 Flag f = Flag (_flags & ~WholeFile);
1175 boost::shared_ptr<Region> r = RegionFactory::create (srcs, _start, _length, new_name, _layer, f);
1176 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (r);
1187 AudioRegion::source_deleted ()
1194 AudioRegion::master_source_names ()
1196 SourceList::iterator i;
1198 vector<string> names;
1199 for (i = master_sources.begin(); i != master_sources.end(); ++i) {
1200 names.push_back((*i)->name());
1207 AudioRegion::set_master_sources (const SourceList& srcs)
1209 master_sources = srcs;
1213 AudioRegion::source_equivalent (boost::shared_ptr<const Region> o) const
1215 boost::shared_ptr<const AudioRegion> other = boost::dynamic_pointer_cast<const AudioRegion>(o);
1220 SourceList::const_iterator i;
1221 SourceList::const_iterator io;
1223 for (i = sources.begin(), io = other->sources.begin(); i != sources.end() && io != other->sources.end(); ++i, ++io) {
1224 if ((*i)->id() != (*io)->id()) {
1229 for (i = master_sources.begin(), io = other->master_sources.begin(); i != master_sources.end() && io != other->master_sources.end(); ++i, ++io) {
1230 if ((*i)->id() != (*io)->id()) {
1239 AudioRegion::apply (AudioFilter& filter)
1241 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (shared_from_this());
1242 return filter.run (ar);
1246 AudioRegion::exportme (Session& session, AudioExportSpecification& spec)
1248 const nframes_t blocksize = 4096;
1252 spec.channels = sources.size();
1254 if (spec.prepare (blocksize, session.frame_rate())) {
1259 spec.total_frames = _length;
1261 while (spec.pos < _length && !spec.stop) {
1264 /* step 1: interleave */
1266 to_read = min (_length - spec.pos, blocksize);
1268 if (spec.channels == 1) {
1270 if (sources.front()->read (spec.dataF, _start + spec.pos, to_read) != to_read) {
1276 Sample buf[blocksize];
1278 for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1280 if (sources[chan]->read (buf, _start + spec.pos, to_read) != to_read) {
1284 for (nframes_t x = 0; x < to_read; ++x) {
1285 spec.dataF[chan+(x*spec.channels)] = buf[x];
1290 if (spec.process (to_read)) {
1294 spec.pos += to_read;
1295 spec.progress = (double) spec.pos /_length;
1302 spec.running = false;
1303 spec.status = status;
1309 boost::shared_ptr<Region>
1310 AudioRegion::get_parent() const
1312 boost::shared_ptr<Playlist> pl (playlist());
1315 boost::shared_ptr<AudioRegion> ar;
1316 boost::shared_ptr<AudioRegion const> grrr2 = boost::dynamic_pointer_cast<AudioRegion const> (shared_from_this());
1318 if (grrr2 && (ar = pl->session().find_whole_file_parent (grrr2))) {
1319 return boost::static_pointer_cast<Region> (ar);
1323 return boost::shared_ptr<Region>();
1327 AudioRegion::set_scale_amplitude (gain_t g)
1329 boost::shared_ptr<Playlist> pl (playlist());
1331 _scale_amplitude = g;
1333 /* tell the diskstream we're in */
1339 /* tell everybody else */
1341 send_change (ScaleAmplitudeChanged);
1345 AudioRegion::normalize_to (float target_dB)
1347 const nframes_t blocksize = 64 * 1024;
1348 Sample buf[blocksize];
1353 gain_t target = dB_to_coefficient (target_dB);
1355 if (target == 1.0f) {
1356 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1357 that we may have clipped.
1359 target -= FLT_EPSILON;
1363 fend = _start + _length;
1365 /* first pass: find max amplitude */
1367 while (fpos < fend) {
1371 to_read = min (fend - fpos, blocksize);
1373 for (n = 0; n < n_channels(); ++n) {
1377 if (source (n)->read (buf, fpos, to_read) != to_read) {
1381 maxamp = Session::compute_peak (buf, to_read, maxamp);
1387 if (maxamp == 0.0f) {
1388 /* don't even try */
1392 if (maxamp == target) {
1393 /* we can't do anything useful */
1397 /* compute scale factor */
1399 _scale_amplitude = target/maxamp;
1401 /* tell the diskstream we're in */
1403 boost::shared_ptr<Playlist> pl (playlist());
1409 /* tell everybody else */
1411 send_change (ScaleAmplitudeChanged);
1415 AudioRegion::fade_in_changed ()
1417 send_change (FadeInChanged);
1421 AudioRegion::fade_out_changed ()
1423 send_change (FadeOutChanged);
1427 AudioRegion::envelope_changed ()
1429 send_change (EnvelopeChanged);
1433 AudioRegion::suspend_fade_in ()
1435 if (++_fade_in_disabled == 1) {
1436 if (fade_in_is_default()) {
1437 set_fade_in_active (false);
1443 AudioRegion::resume_fade_in ()
1445 if (--_fade_in_disabled == 0 && _fade_in_disabled) {
1446 set_fade_in_active (true);
1451 AudioRegion::suspend_fade_out ()
1453 if (++_fade_out_disabled == 1) {
1454 if (fade_out_is_default()) {
1455 set_fade_out_active (false);
1461 AudioRegion::resume_fade_out ()
1463 if (--_fade_out_disabled == 0 &&_fade_out_disabled) {
1464 set_fade_out_active (true);
1469 AudioRegion::speed_mismatch (float sr) const
1471 if (sources.empty()) {
1472 /* impossible, but ... */
1476 float fsr = sources.front()->sample_rate();
1482 AudioRegion::source_offset_changed ()
1484 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(sources.front());
1486 if (afs && afs->destructive()) {
1487 // set_start (source()->natural_position(), this);
1488 set_position (source()->natural_position(), this);
1493 AudioRegion::set_playlist (boost::weak_ptr<Playlist> wpl)
1495 boost::shared_ptr<Playlist> old_playlist = (_playlist.lock());
1497 boost::shared_ptr<Playlist> pl (wpl.lock());
1499 if (old_playlist == pl) {
1503 Region::set_playlist (wpl);
1507 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
1508 (*i)->remove_playlist (_playlist);
1509 (*i)->add_playlist (pl);
1511 for (SourceList::const_iterator i = master_sources.begin(); i != master_sources.end(); ++i) {
1512 (*i)->remove_playlist (_playlist);
1513 (*i)->add_playlist (pl);
1516 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
1517 (*i)->add_playlist (pl);
1519 for (SourceList::const_iterator i = master_sources.begin(); i != master_sources.end(); ++i) {
1520 (*i)->add_playlist (pl);
1525 for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
1526 (*i)->remove_playlist (old_playlist);
1528 for (SourceList::const_iterator i = master_sources.begin(); i != master_sources.end(); ++i) {
1529 (*i)->remove_playlist (old_playlist);
1536 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1538 boost::shared_ptr<Playlist> pl = playlist();
1544 if (valid_transients && !force_new) {
1545 results = _transients;
1549 SourceList::iterator s;
1551 for (s = sources.begin() ; s != sources.end(); ++s) {
1552 if (!(*s)->has_been_analysed()) {
1553 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1558 if (s == sources.end()) {
1559 /* all sources are analyzed, merge data from each one */
1561 for (s = sources.begin() ; s != sources.end(); ++s) {
1563 /* find the set of transients within the bounds of this region */
1565 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1566 (*s)->transients.end(),
1569 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1570 (*s)->transients.end(),
1575 results.insert (results.end(), low, high);
1578 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1580 /* translate all transients to current position */
1582 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1587 _transients = results;
1588 valid_transients = true;
1593 /* no existing/complete transient info */
1595 if (!Config->get_auto_analyse_audio()) {
1596 pl->session().Dialog (_("\
1597 You have requested an operation that requires audio analysis.\n\n\
1598 You currently have \"auto-analyse-audio\" disabled, which means\n\
1599 that transient data must be generated every time it is required.\n\n\
1600 If you are doing work that will require transient data on a\n\
1601 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1602 then quit ardour and restart."));
1605 TransientDetector t (pl->session().frame_rate());
1606 bool existing_results = !results.empty();
1608 _transients.clear ();
1609 valid_transients = false;
1611 for (uint32_t i = 0; i < n_channels(); ++i) {
1613 AnalysisFeatureList these_results;
1617 if (t.run ("", this, i, these_results)) {
1621 /* translate all transients to give absolute position */
1623 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1629 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1632 if (!results.empty()) {
1633 if (existing_results) {
1635 /* merge our transients into the existing ones, then clean up
1639 results.insert (results.end(), _transients.begin(), _transients.end());
1640 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1643 /* make sure ours are clean too */
1645 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1649 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1650 results = _transients;
1653 valid_transients = true;
1660 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)
1662 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (nframes_t) npeaks, (nframes_t) start, (nframes_t) cnt, n_chan,samples_per_unit);
1665 uint32_t region_length_from_c (void *arg)
1668 return ((AudioRegion *) arg)->length();
1671 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1673 return ( (AudioRegion *) arg)->source()->available_peaks (zoom_factor) ;