2 Copyright (C) 2000-2006 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/audiofilesource.h>
44 #include <ardour/region_factory.h>
45 #include <ardour/runtime_functions.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();
68 _scale_amplitude = 1.0;
71 set_default_envelope ();
73 listen_to_my_curves ();
74 listen_to_my_sources ();
77 /* constructor for use by derived types only */
78 AudioRegion::AudioRegion (Session& s, nframes_t start, nframes_t length, string name)
79 : Region (s, start, length, name, DataType::AUDIO)
81 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
82 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
83 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
88 /** Basic AudioRegion constructor (one channel) */
89 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length)
90 : Region (src, start, length, PBD::basename_nosuffix(src->name()), DataType::AUDIO, 0, Region::Flag(Region::DefaultFlags|Region::External))
91 , _automatable(src->session())
92 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
93 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
94 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
96 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
98 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
104 /* Basic AudioRegion constructor (one channel) */
105 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
106 : Region (src, start, length, name, DataType::AUDIO, layer, flags)
107 , _automatable(src->session())
108 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
109 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
110 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
112 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
114 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
120 /* Basic AudioRegion constructor (many channels) */
121 AudioRegion::AudioRegion (const SourceList& srcs, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
122 : Region (srcs, start, length, name, DataType::AUDIO, layer, flags)
123 , _automatable(srcs[0]->session())
124 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
125 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
126 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
129 listen_to_my_sources ();
132 /** Create a new AudioRegion, that is part of an existing one */
133 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags)
134 : Region (other, offset, length, name, layer, flags)
135 , _automatable(other->session())
136 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
137 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
138 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
140 set<boost::shared_ptr<Source> > unique_srcs;
142 for (SourceList::const_iterator i= other->_sources.begin(); i != other->_sources.end(); ++i) {
143 _sources.push_back (*i);
145 pair<set<boost::shared_ptr<Source> >::iterator,bool> result;
147 result = unique_srcs.insert (*i);
150 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
152 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
157 /* return to default fades if the existing ones are too long */
160 if (_flags & LeftOfSplit) {
161 if (_fade_in->back()->when >= _length) {
162 set_default_fade_in ();
164 _fade_in_disabled = other->_fade_in_disabled;
166 set_default_fade_out ();
167 _flags = Flag (_flags & ~Region::LeftOfSplit);
170 if (_flags & RightOfSplit) {
171 if (_fade_out->back()->when >= _length) {
172 set_default_fade_out ();
174 _fade_out_disabled = other->_fade_out_disabled;
176 set_default_fade_in ();
177 _flags = Flag (_flags & ~Region::RightOfSplit);
180 _scale_amplitude = other->_scale_amplitude;
182 assert(_type == DataType::AUDIO);
183 listen_to_my_sources ();
186 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
188 , _automatable(other->session())
189 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
190 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
191 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
193 assert(_type == DataType::AUDIO);
194 _scale_amplitude = other->_scale_amplitude;
195 _envelope = other->_envelope;
197 set_default_fades ();
199 listen_to_my_curves ();
200 listen_to_my_sources ();
203 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node)
205 , _automatable(src->session())
206 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
207 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
208 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
210 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
212 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
217 if (set_state (node)) {
218 throw failed_constructor();
221 assert(_type == DataType::AUDIO);
222 listen_to_my_sources ();
225 AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
226 : Region (srcs, node)
227 , _automatable(srcs[0]->session())
228 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
229 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
230 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
234 if (set_state (node)) {
235 throw failed_constructor();
238 assert(_type == DataType::AUDIO);
239 listen_to_my_sources ();
242 AudioRegion::~AudioRegion ()
247 AudioRegion::listen_to_my_sources ()
249 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
250 (*i)->AnalysisChanged.connect (mem_fun (*this, &AudioRegion::invalidate_transients));
255 AudioRegion::listen_to_my_curves ()
257 _envelope->StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
258 _fade_in->StateChanged.connect (mem_fun (*this, &AudioRegion::fade_in_changed));
259 _fade_out->StateChanged.connect (mem_fun (*this, &AudioRegion::fade_out_changed));
263 AudioRegion::set_envelope_active (bool yn)
265 if (envelope_active() != yn) {
268 snprintf (buf, sizeof (buf), "envelope active");
269 _flags = Flag (_flags|EnvelopeActive);
271 snprintf (buf, sizeof (buf), "envelope off");
272 _flags = Flag (_flags & ~EnvelopeActive);
274 send_change (EnvelopeActiveChanged);
279 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
281 if (chan_n >= _sources.size()) {
285 if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
288 if (_scale_amplitude != 1.0) {
289 for (nframes_t n = 0; n < npeaks; ++n) {
290 buf[n].max *= _scale_amplitude;
291 buf[n].min *= _scale_amplitude;
299 AudioRegion::read (Sample* buf, nframes64_t position, nframes64_t cnt, int channel) const
301 /* raw read, no fades, no gain, nada */
302 return _read_at (_sources, _length, buf, 0, 0, _position + position, cnt, channel, 0, 0, true);
306 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position,
308 uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames) const
310 /* regular diskstream/butler read complete with fades etc */
311 return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, read_frames, skip_frames, false);
315 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position,
316 nframes_t cnt, uint32_t chan_n) const
318 return _read_at (_master_sources, _master_sources.front()->length(), buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0);
322 AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
323 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
324 nframes_t position, nframes_t cnt,
326 nframes_t read_frames,
327 nframes_t skip_frames,
330 nframes_t internal_offset;
331 nframes_t buf_offset;
334 if (muted() && !raw) {
335 return 0; /* read nothing */
338 /* precondition: caller has verified that we cover the desired section */
340 if (position < _position) {
342 buf_offset = _position - position;
345 internal_offset = position - _position;
349 if (internal_offset >= limit) {
350 return 0; /* read nothing */
353 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
354 return 0; /* read nothing */
357 if (opaque() || raw) {
358 /* overwrite whatever is there */
359 mixdown_buffer = buf + buf_offset;
361 mixdown_buffer += buf_offset;
365 _read_data_count = 0;
368 if (chan_n < n_channels()) {
370 boost::shared_ptr<AudioSource> src = audio_source(chan_n);
371 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
372 return 0; /* "read nothing" */
376 _read_data_count += src->read_data_count();
381 /* track is N-channel, this region has less channels; silence the ones
385 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
387 /* no fades required */
398 if ((_flags & FadeIn) && Config->get_use_region_fades()) {
400 nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
402 /* see if this read is within the fade in */
404 if (internal_offset < fade_in_length) {
408 fi_limit = min (to_read, fade_in_length - internal_offset);
410 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
412 for (nframes_t n = 0; n < fi_limit; ++n) {
413 mixdown_buffer[n] *= gain_buffer[n];
420 if ((_flags & FadeOut) && Config->get_use_region_fades()) {
422 /* see if some part of this read is within the fade out */
424 /* ................. >| REGION
430 limit - fade_out_length
433 ^internal_offset + to_read
435 we need the intersection of [internal_offset,internal_offset+to_read] with
436 [limit - fade_out_length, limit]
441 nframes_t fade_out_length = (nframes_t) _fade_out->back()->when;
442 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
443 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
445 if (fade_interval_end > fade_interval_start) {
446 /* (part of the) the fade out is in this buffer */
448 nframes_t fo_limit = fade_interval_end - fade_interval_start;
449 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
450 nframes_t fade_offset = fade_interval_start - internal_offset;
452 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
454 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
455 mixdown_buffer[m] *= gain_buffer[n];
461 /* Regular gain curves */
463 if (envelope_active()) {
464 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
466 if (_scale_amplitude != 1.0f) {
467 for (nframes_t n = 0; n < to_read; ++n) {
468 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
471 for (nframes_t n = 0; n < to_read; ++n) {
472 mixdown_buffer[n] *= gain_buffer[n];
475 } else if (_scale_amplitude != 1.0f) {
476 apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
483 /* gack. the things we do for users.
488 for (nframes_t n = 0; n < to_read; ++n) {
489 buf[n] += mixdown_buffer[n];
498 AudioRegion::state (bool full)
500 XMLNode& node (Region::state (full));
504 LocaleGuard lg (X_("POSIX"));
506 node.add_property ("flags", enum_2_string (_flags));
508 snprintf (buf, sizeof(buf), "%.12g", _scale_amplitude);
509 node.add_property ("scale-gain", buf);
511 // XXX these should move into Region
513 for (uint32_t n=0; n < _sources.size(); ++n) {
514 snprintf (buf2, sizeof(buf2), "source-%d", n);
515 _sources[n]->id().print (buf, sizeof (buf));
516 node.add_property (buf2, buf);
519 for (uint32_t n=0; n < _master_sources.size(); ++n) {
520 snprintf (buf2, sizeof(buf2), "master-source-%d", n);
521 _master_sources[n]->id().print (buf, sizeof (buf));
522 node.add_property (buf2, buf);
525 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
526 node.add_property ("channels", buf);
530 child = node.add_child (X_("FadeIn"));
532 if ((_flags & DefaultFadeIn)) {
533 child->add_property (X_("default"), X_("yes"));
535 child->add_child_nocopy (_fade_in->get_state ());
538 child->add_property (X_("active"), _fade_in_disabled ? X_("no") : X_("yes"));
540 child = node.add_child (X_("FadeOut"));
542 if ((_flags & DefaultFadeOut)) {
543 child->add_property (X_("default"), X_("yes"));
545 child->add_child_nocopy (_fade_out->get_state ());
548 child->add_property (X_("active"), _fade_out_disabled ? X_("no") : X_("yes"));
551 child = node.add_child ("Envelope");
554 bool default_env = false;
556 // If there are only two points, the points are in the start of the region and the end of the region
557 // so, if they are both at 1.0f, that means the default region.
559 if (_envelope->size() == 2 &&
560 _envelope->front()->value == 1.0f &&
561 _envelope->back()->value==1.0f) {
562 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
568 child->add_property ("default", "yes");
570 child->add_child_nocopy (_envelope->get_state ());
574 child->add_property ("default", "yes");
577 if (full && _extra_xml) {
578 node.add_child_copy (*_extra_xml);
585 AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool send)
587 const XMLNodeList& nlist = node.children();
588 const XMLProperty *prop;
589 LocaleGuard lg (X_("POSIX"));
591 Region::set_live_state (node, what_changed, false);
593 uint32_t old_flags = _flags;
595 if ((prop = node.property ("flags")) != 0) {
596 _flags = Flag (string_2_enum (prop->value(), _flags));
598 //_flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16));
600 _flags = Flag (_flags & ~Region::LeftOfSplit);
601 _flags = Flag (_flags & ~Region::RightOfSplit);
604 if ((old_flags ^ _flags) & Muted) {
605 what_changed = Change (what_changed|MuteChanged);
607 if ((old_flags ^ _flags) & Opaque) {
608 what_changed = Change (what_changed|OpacityChanged);
610 if ((old_flags ^ _flags) & Locked) {
611 what_changed = Change (what_changed|LockChanged);
614 if ((prop = node.property ("scale-gain")) != 0) {
615 _scale_amplitude = atof (prop->value().c_str());
616 what_changed = Change (what_changed|ScaleAmplitudeChanged);
618 _scale_amplitude = 1.0;
621 /* Now find envelope description and other misc child items */
623 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
630 if (child->name() == "Envelope") {
634 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child)) {
635 set_default_envelope ();
638 _envelope->set_max_xval (_length);
639 _envelope->truncate_end (_length);
641 } else if (child->name() == "FadeIn") {
645 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
646 set_default_fade_in ();
648 XMLNode* grandchild = child->child ("AutomationList");
650 _fade_in->set_state (*grandchild);
654 if ((prop = child->property ("active")) != 0) {
655 if (prop->value() == "yes") {
656 set_fade_in_active (true);
658 set_fade_in_active (true);
662 } else if (child->name() == "FadeOut") {
666 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
667 set_default_fade_out ();
669 XMLNode* grandchild = child->child ("AutomationList");
671 _fade_out->set_state (*grandchild);
675 if ((prop = child->property ("active")) != 0) {
676 if (prop->value() == "yes") {
677 set_fade_out_active (true);
679 set_fade_out_active (false);
687 send_change (what_changed);
694 AudioRegion::set_state (const XMLNode& node)
696 /* Region::set_state() calls the virtual set_live_state(),
697 which will get us back to AudioRegion::set_live_state()
698 to handle the relevant stuff.
701 return Region::set_state (node);
705 AudioRegion::set_fade_in_shape (FadeShape shape)
707 set_fade_in (shape, (nframes_t) _fade_in->back()->when);
711 AudioRegion::set_fade_out_shape (FadeShape shape)
713 set_fade_out (shape, (nframes_t) _fade_out->back()->when);
717 AudioRegion::set_fade_in (FadeShape shape, nframes_t len)
724 _fade_in->fast_simple_add (0.0, 0.0);
725 _fade_in->fast_simple_add (len, 1.0);
729 _fade_in->fast_simple_add (0, 0);
730 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
731 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
732 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
733 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
734 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
735 _fade_in->fast_simple_add (len, 1);
739 _fade_in->fast_simple_add (0, 0);
740 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
741 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
742 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
743 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
744 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
745 _fade_in->fast_simple_add (len * 0.767281, 1);
746 _fade_in->fast_simple_add (len, 1);
750 _fade_in->fast_simple_add (0, 0);
751 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
752 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
753 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
754 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
755 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
756 _fade_in->fast_simple_add (len, 1);
760 _fade_in->fast_simple_add (0, 0);
761 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
762 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
763 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
764 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
765 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
766 _fade_in->fast_simple_add (len, 1);
771 _fade_in_shape = shape;
773 send_change (FadeInChanged);
777 AudioRegion::set_fade_out (FadeShape shape, nframes_t len)
779 _fade_out->freeze ();
784 _fade_out->fast_simple_add (len * 0, 1);
785 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
786 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
787 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
788 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
789 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
790 _fade_out->fast_simple_add (len * 1, 0);
794 _fade_out->fast_simple_add (len * 0, 1);
795 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
796 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
797 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
798 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
799 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
800 _fade_out->fast_simple_add (len * 1, 0);
804 _fade_out->fast_simple_add (len * 0, 1);
805 _fade_out->fast_simple_add (len * 0.305556, 1);
806 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
807 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
808 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
809 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
810 _fade_out->fast_simple_add (len * 1, 0);
814 _fade_out->fast_simple_add (len * 0, 1);
815 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
816 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
817 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
818 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
819 _fade_out->fast_simple_add (len * 1, 0);
823 _fade_out->fast_simple_add (len * 0, 1);
824 _fade_out->fast_simple_add (len * 1, 0);
829 _fade_out_shape = shape;
831 send_change (FadeOutChanged);
835 AudioRegion::set_fade_in_length (nframes_t len)
841 bool changed = _fade_in->extend_to (len);
844 _flags = Flag (_flags & ~DefaultFadeIn);
845 send_change (FadeInChanged);
850 AudioRegion::set_fade_out_length (nframes_t len)
856 bool changed = _fade_out->extend_to (len);
859 _flags = Flag (_flags & ~DefaultFadeOut);
860 send_change (FadeOutChanged);
865 AudioRegion::set_fade_in_active (bool yn)
867 if (yn == (_flags & FadeIn)) {
871 _flags = Flag (_flags|FadeIn);
873 _flags = Flag (_flags & ~FadeIn);
876 send_change (FadeInActiveChanged);
880 AudioRegion::set_fade_out_active (bool yn)
882 if (yn == (_flags & FadeOut)) {
886 _flags = Flag (_flags | FadeOut);
888 _flags = Flag (_flags & ~FadeOut);
891 send_change (FadeOutActiveChanged);
895 AudioRegion::fade_in_is_default () const
897 return _fade_in_shape == Linear && _fade_in->back()->when == 64;
901 AudioRegion::fade_out_is_default () const
903 return _fade_out_shape == Linear && _fade_out->back()->when == 64;
907 AudioRegion::set_default_fade_in ()
909 set_fade_in (Linear, 64);
913 AudioRegion::set_default_fade_out ()
915 set_fade_out (Linear, 64);
919 AudioRegion::set_default_fades ()
921 _fade_in_disabled = 0;
922 _fade_out_disabled = 0;
923 set_default_fade_in ();
924 set_default_fade_out ();
928 AudioRegion::set_default_envelope ()
930 _envelope->freeze ();
932 _envelope->fast_simple_add (0, 1.0f);
933 _envelope->fast_simple_add (_length, 1.0f);
938 AudioRegion::recompute_at_end ()
940 /* our length has changed. recompute a new final point by interpolating
941 based on the the existing curve.
944 _envelope->freeze ();
945 _envelope->truncate_end (_length);
946 _envelope->set_max_xval (_length);
949 if (_fade_in->back()->when > _length) {
950 _fade_in->extend_to (_length);
951 send_change (FadeInChanged);
954 if (_fade_out->back()->when > _length) {
955 _fade_out->extend_to (_length);
956 send_change (FadeOutChanged);
961 AudioRegion::recompute_at_start ()
963 /* as above, but the shift was from the front */
965 _envelope->truncate_start (_length);
967 if (_fade_in->back()->when > _length) {
968 _fade_in->extend_to (_length);
969 send_change (FadeInChanged);
972 if (_fade_out->back()->when > _length) {
973 _fade_out->extend_to (_length);
974 send_change (FadeOutChanged);
979 AudioRegion::separate_by_channel (Session& session, vector<boost::shared_ptr<AudioRegion> >& v) const
985 if (_sources.size() < 2) {
991 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
998 if (_sources.size() == 2) {
1006 new_name += ('0' + n + 1);
1009 /* create a copy with just one source. prevent if from being thought of as "whole file" even if
1010 it covers the entire source file(s).
1013 Flag f = Flag (_flags & ~WholeFile);
1015 boost::shared_ptr<Region> r = RegionFactory::create (srcs, _start, _length, new_name, _layer, f);
1016 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (r);
1027 AudioRegion::read_raw_internal (Sample* buf, nframes_t pos, nframes_t cnt) const
1029 return audio_source()->read (buf, pos, cnt);
1033 AudioRegion::exportme (Session& session, ARDOUR::ExportSpecification& spec)
1036 // const nframes_t blocksize = 4096;
1037 // nframes_t to_read;
1040 // spec.channels = _sources.size();
1042 // if (spec.prepare (blocksize, session.frame_rate())) {
1047 // spec.total_frames = _length;
1049 // while (spec.pos < _length && !spec.stop) {
1052 // /* step 1: interleave */
1054 // to_read = min (_length - spec.pos, blocksize);
1056 // if (spec.channels == 1) {
1058 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1064 // Sample buf[blocksize];
1066 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1068 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1072 // for (nframes_t x = 0; x < to_read; ++x) {
1073 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1078 // if (spec.process (to_read)) {
1082 // spec.pos += to_read;
1083 // spec.progress = (double) spec.pos /_length;
1090 // spec.running = false;
1091 // spec.status = status;
1099 AudioRegion::set_scale_amplitude (gain_t g)
1101 boost::shared_ptr<Playlist> pl (playlist());
1103 _scale_amplitude = g;
1105 /* tell the diskstream we're in */
1111 /* tell everybody else */
1113 send_change (ScaleAmplitudeChanged);
1117 AudioRegion::normalize_to (float target_dB)
1119 const nframes_t blocksize = 64 * 1024;
1120 Sample buf[blocksize];
1125 gain_t target = dB_to_coefficient (target_dB);
1127 if (target == 1.0f) {
1128 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1129 that we may have clipped.
1131 target -= FLT_EPSILON;
1135 fend = _start + _length;
1137 /* first pass: find max amplitude */
1139 while (fpos < fend) {
1143 to_read = min (fend - fpos, blocksize);
1145 for (n = 0; n < n_channels(); ++n) {
1149 if (read_raw_internal (buf, fpos, to_read) != to_read) {
1153 maxamp = compute_peak (buf, to_read, maxamp);
1159 if (maxamp == 0.0f) {
1160 /* don't even try */
1164 if (maxamp == target) {
1165 /* we can't do anything useful */
1169 /* compute scale factor */
1171 _scale_amplitude = target/maxamp;
1173 /* tell the diskstream we're in */
1175 boost::shared_ptr<Playlist> pl (playlist());
1181 /* tell everybody else */
1183 send_change (ScaleAmplitudeChanged);
1187 AudioRegion::fade_in_changed ()
1189 send_change (FadeInChanged);
1193 AudioRegion::fade_out_changed ()
1195 send_change (FadeOutChanged);
1199 AudioRegion::envelope_changed ()
1201 send_change (EnvelopeChanged);
1205 AudioRegion::suspend_fade_in ()
1207 if (++_fade_in_disabled == 1) {
1208 if (fade_in_is_default()) {
1209 set_fade_in_active (false);
1215 AudioRegion::resume_fade_in ()
1217 if (--_fade_in_disabled == 0 && _fade_in_disabled) {
1218 set_fade_in_active (true);
1223 AudioRegion::suspend_fade_out ()
1225 if (++_fade_out_disabled == 1) {
1226 if (fade_out_is_default()) {
1227 set_fade_out_active (false);
1233 AudioRegion::resume_fade_out ()
1235 if (--_fade_out_disabled == 0 &&_fade_out_disabled) {
1236 set_fade_out_active (true);
1241 AudioRegion::speed_mismatch (float sr) const
1243 if (_sources.empty()) {
1244 /* impossible, but ... */
1248 float fsr = audio_source()->sample_rate();
1254 AudioRegion::source_offset_changed ()
1256 /* XXX this fixes a crash that should not occur. It does occur
1257 becauses regions are not being deleted when a session
1258 is unloaded. That bug must be fixed.
1261 if (_sources.empty()) {
1265 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1267 if (afs && afs->destructive()) {
1268 // set_start (source()->natural_position(), this);
1269 set_position (source()->natural_position(), this);
1273 boost::shared_ptr<AudioSource>
1274 AudioRegion::audio_source (uint32_t n) const
1276 // Guaranteed to succeed (use a static cast for speed?)
1277 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1281 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1283 boost::shared_ptr<Playlist> pl = playlist();
1289 if (_valid_transients && !force_new) {
1290 results = _transients;
1294 SourceList::iterator s;
1296 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1297 if (!(*s)->has_been_analysed()) {
1298 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1303 if (s == _sources.end()) {
1304 /* all sources are analyzed, merge data from each one */
1306 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1308 /* find the set of transients within the bounds of this region */
1310 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1311 (*s)->transients.end(),
1314 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1315 (*s)->transients.end(),
1320 results.insert (results.end(), low, high);
1323 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1325 /* translate all transients to current position */
1327 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1332 _transients = results;
1333 _valid_transients = true;
1338 /* no existing/complete transient info */
1340 if (!Config->get_auto_analyse_audio()) {
1341 pl->session().Dialog (_("\
1342 You have requested an operation that requires audio analysis.\n\n\
1343 You currently have \"auto-analyse-audio\" disabled, which means\n\
1344 that transient data must be generated every time it is required.\n\n\
1345 If you are doing work that will require transient data on a\n\
1346 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1347 then quit ardour and restart."));
1350 TransientDetector t (pl->session().frame_rate());
1351 bool existing_results = !results.empty();
1353 _transients.clear ();
1354 _valid_transients = false;
1356 for (uint32_t i = 0; i < n_channels(); ++i) {
1358 AnalysisFeatureList these_results;
1362 if (t.run ("", this, i, these_results)) {
1366 /* translate all transients to give absolute position */
1368 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1374 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1377 if (!results.empty()) {
1378 if (existing_results) {
1380 /* merge our transients into the existing ones, then clean up
1384 results.insert (results.end(), _transients.begin(), _transients.end());
1385 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1388 /* make sure ours are clean too */
1390 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1394 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1395 results = _transients;
1398 _valid_transients = true;
1405 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)
1407 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (nframes_t) npeaks, (nframes_t) start, (nframes_t) cnt, n_chan,samples_per_unit);
1410 uint32_t region_length_from_c (void *arg)
1413 return ((AudioRegion *) arg)->length();
1416 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1418 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;