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)
80 , _fade_in (new AutomationList(Parameter(FadeInAutomation)))
81 , _fade_out (new AutomationList(Parameter(FadeOutAutomation)))
82 , _envelope (new AutomationList(Parameter(EnvelopeAutomation)))
87 /** Basic AudioRegion constructor (one channel) */
88 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length)
89 : Region (src, start, length, PBD::basename_nosuffix(src->name()), DataType::AUDIO, 0, Region::Flag(Region::DefaultFlags|Region::External))
90 , _fade_in (new AutomationList(Parameter(FadeInAutomation)))
91 , _fade_out (new AutomationList(Parameter(FadeOutAutomation)))
92 , _envelope (new AutomationList(Parameter(EnvelopeAutomation)))
94 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
96 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
102 /* Basic AudioRegion constructor (one channel) */
103 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
104 : Region (src, start, length, name, DataType::AUDIO, layer, flags)
105 , _fade_in (new AutomationList(Parameter(FadeInAutomation)))
106 , _fade_out (new AutomationList(Parameter(FadeOutAutomation)))
107 , _envelope (new AutomationList(Parameter(EnvelopeAutomation)))
109 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
111 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
117 /* Basic AudioRegion constructor (many channels) */
118 AudioRegion::AudioRegion (const SourceList& srcs, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
119 : Region (srcs, start, length, name, DataType::AUDIO, layer, flags)
120 , _fade_in (new AutomationList(Parameter(FadeInAutomation)))
121 , _fade_out (new AutomationList(Parameter(FadeOutAutomation)))
122 , _envelope (new AutomationList(Parameter(EnvelopeAutomation)))
125 listen_to_my_sources ();
128 /** Create a new AudioRegion, that is part of an existing one */
129 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags)
130 : Region (other, offset, length, name, layer, flags)
131 , _fade_in (new AutomationList(Parameter(FadeInAutomation)))
132 , _fade_out (new AutomationList(Parameter(FadeOutAutomation)))
133 , _envelope (new AutomationList(Parameter(EnvelopeAutomation)))
135 set<boost::shared_ptr<Source> > unique_srcs;
137 for (SourceList::const_iterator i= other->_sources.begin(); i != other->_sources.end(); ++i) {
138 _sources.push_back (*i);
140 pair<set<boost::shared_ptr<Source> >::iterator,bool> result;
142 result = unique_srcs.insert (*i);
145 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
147 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
152 /* return to default fades if the existing ones are too long */
155 if (_flags & LeftOfSplit) {
156 if (_fade_in->back()->when >= _length) {
157 set_default_fade_in ();
159 _fade_in_disabled = other->_fade_in_disabled;
161 set_default_fade_out ();
162 _flags = Flag (_flags & ~Region::LeftOfSplit);
165 if (_flags & RightOfSplit) {
166 if (_fade_out->back()->when >= _length) {
167 set_default_fade_out ();
169 _fade_out_disabled = other->_fade_out_disabled;
171 set_default_fade_in ();
172 _flags = Flag (_flags & ~Region::RightOfSplit);
175 _scale_amplitude = other->_scale_amplitude;
177 assert(_type == DataType::AUDIO);
178 listen_to_my_sources ();
181 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
183 , _fade_in (new AutomationList(Parameter(FadeInAutomation)))
184 , _fade_out (new AutomationList(Parameter(FadeOutAutomation)))
185 , _envelope (new AutomationList(Parameter(EnvelopeAutomation)))
187 assert(_type == DataType::AUDIO);
188 _scale_amplitude = other->_scale_amplitude;
189 _envelope = other->_envelope;
191 set_default_fades ();
193 listen_to_my_curves ();
194 listen_to_my_sources ();
197 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node)
199 , _fade_in (new AutomationList(Parameter(FadeInAutomation)))
200 , _fade_out (new AutomationList(Parameter(FadeOutAutomation)))
201 , _envelope (new AutomationList(Parameter(EnvelopeAutomation)))
203 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
205 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
210 if (set_state (node)) {
211 throw failed_constructor();
214 assert(_type == DataType::AUDIO);
215 listen_to_my_sources ();
218 AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
219 : Region (srcs, node)
220 , _fade_in (new AutomationList(Parameter(FadeInAutomation)))
221 , _fade_out (new AutomationList(Parameter(FadeOutAutomation)))
222 , _envelope (new AutomationList(Parameter(EnvelopeAutomation)))
226 if (set_state (node)) {
227 throw failed_constructor();
230 assert(_type == DataType::AUDIO);
231 listen_to_my_sources ();
234 AudioRegion::~AudioRegion ()
239 AudioRegion::listen_to_my_sources ()
241 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
242 (*i)->AnalysisChanged.connect (mem_fun (*this, &AudioRegion::invalidate_transients));
247 AudioRegion::listen_to_my_curves ()
249 _envelope->StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
250 _fade_in->StateChanged.connect (mem_fun (*this, &AudioRegion::fade_in_changed));
251 _fade_out->StateChanged.connect (mem_fun (*this, &AudioRegion::fade_out_changed));
255 AudioRegion::set_envelope_active (bool yn)
257 if (envelope_active() != yn) {
260 snprintf (buf, sizeof (buf), "envelope active");
261 _flags = Flag (_flags|EnvelopeActive);
263 snprintf (buf, sizeof (buf), "envelope off");
264 _flags = Flag (_flags & ~EnvelopeActive);
266 send_change (EnvelopeActiveChanged);
271 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
273 if (chan_n >= _sources.size()) {
277 if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
280 if (_scale_amplitude != 1.0) {
281 for (nframes_t n = 0; n < npeaks; ++n) {
282 buf[n].max *= _scale_amplitude;
283 buf[n].min *= _scale_amplitude;
291 AudioRegion::read (Sample* buf, nframes64_t position, nframes64_t cnt, int channel) const
293 /* raw read, no fades, no gain, nada */
294 return _read_at (_sources, _length, buf, 0, 0, _position + position, cnt, channel, 0, 0, true);
298 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position,
300 uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames) const
302 /* regular diskstream/butler read complete with fades etc */
303 return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, read_frames, skip_frames, false);
307 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position,
308 nframes_t cnt, uint32_t chan_n) const
310 return _read_at (_master_sources, _master_sources.front()->length(), buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0);
314 AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
315 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
316 nframes_t position, nframes_t cnt,
318 nframes_t read_frames,
319 nframes_t skip_frames,
322 nframes_t internal_offset;
323 nframes_t buf_offset;
326 if (muted() && !raw) {
327 return 0; /* read nothing */
330 /* precondition: caller has verified that we cover the desired section */
332 if (position < _position) {
334 buf_offset = _position - position;
337 internal_offset = position - _position;
341 if (internal_offset >= limit) {
342 return 0; /* read nothing */
345 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
346 return 0; /* read nothing */
349 if (opaque() || raw) {
350 /* overwrite whatever is there */
351 mixdown_buffer = buf + buf_offset;
353 mixdown_buffer += buf_offset;
357 _read_data_count = 0;
360 if (chan_n < n_channels()) {
362 boost::shared_ptr<AudioSource> src = audio_source(chan_n);
363 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
364 return 0; /* "read nothing" */
368 _read_data_count += src->read_data_count();
373 /* track is N-channel, this region has less channels; silence the ones
377 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
379 /* no fades required */
390 if (_flags & FadeIn) {
392 nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
394 /* see if this read is within the fade in */
396 if (internal_offset < fade_in_length) {
400 fi_limit = min (to_read, fade_in_length - internal_offset);
402 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
404 for (nframes_t n = 0; n < fi_limit; ++n) {
405 mixdown_buffer[n] *= gain_buffer[n];
412 if (_flags & FadeOut) {
414 /* see if some part of this read is within the fade out */
416 /* ................. >| REGION
422 limit - fade_out_length
425 ^internal_offset + to_read
427 we need the intersection of [internal_offset,internal_offset+to_read] with
428 [limit - fade_out_length, limit]
433 nframes_t fade_out_length = (nframes_t) _fade_out->back()->when;
434 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
435 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
437 if (fade_interval_end > fade_interval_start) {
438 /* (part of the) the fade out is in this buffer */
440 nframes_t fo_limit = fade_interval_end - fade_interval_start;
441 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
442 nframes_t fade_offset = fade_interval_start - internal_offset;
444 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
446 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
447 mixdown_buffer[m] *= gain_buffer[n];
453 /* Regular gain curves */
455 if (envelope_active()) {
456 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
458 if (_scale_amplitude != 1.0f) {
459 for (nframes_t n = 0; n < to_read; ++n) {
460 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
463 for (nframes_t n = 0; n < to_read; ++n) {
464 mixdown_buffer[n] *= gain_buffer[n];
467 } else if (_scale_amplitude != 1.0f) {
468 Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
475 /* gack. the things we do for users.
480 for (nframes_t n = 0; n < to_read; ++n) {
481 buf[n] += mixdown_buffer[n];
490 AudioRegion::state (bool full)
492 XMLNode& node (Region::state (full));
496 LocaleGuard lg (X_("POSIX"));
498 node.add_property ("flags", enum_2_string (_flags));
500 snprintf (buf, sizeof(buf), "%.12g", _scale_amplitude);
501 node.add_property ("scale-gain", buf);
503 // XXX these should move into Region
505 for (uint32_t n=0; n < _sources.size(); ++n) {
506 snprintf (buf2, sizeof(buf2), "source-%d", n);
507 _sources[n]->id().print (buf, sizeof (buf));
508 node.add_property (buf2, buf);
511 for (uint32_t n=0; n < _master_sources.size(); ++n) {
512 snprintf (buf2, sizeof(buf2), "master-source-%d", n);
513 _master_sources[n]->id().print (buf, sizeof (buf));
514 node.add_property (buf2, buf);
517 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
518 node.add_property ("channels", buf);
522 child = node.add_child (X_("FadeIn"));
524 if ((_flags & DefaultFadeIn)) {
525 child->add_property (X_("default"), X_("yes"));
527 child->add_child_nocopy (_fade_in->get_state ());
530 child->add_property (X_("active"), _fade_in_disabled ? X_("no") : X_("yes"));
532 child = node.add_child (X_("FadeOut"));
534 if ((_flags & DefaultFadeOut)) {
535 child->add_property (X_("default"), X_("yes"));
537 child->add_child_nocopy (_fade_out->get_state ());
540 child->add_property (X_("active"), _fade_out_disabled ? X_("no") : X_("yes"));
543 child = node.add_child ("Envelope");
546 bool default_env = false;
548 // If there are only two points, the points are in the start of the region and the end of the region
549 // so, if they are both at 1.0f, that means the default region.
551 if (_envelope->size() == 2 &&
552 _envelope->front()->value == 1.0f &&
553 _envelope->back()->value==1.0f) {
554 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
560 child->add_property ("default", "yes");
562 child->add_child_nocopy (_envelope->get_state ());
566 child->add_property ("default", "yes");
569 if (full && _extra_xml) {
570 node.add_child_copy (*_extra_xml);
577 AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool send)
579 const XMLNodeList& nlist = node.children();
580 const XMLProperty *prop;
581 LocaleGuard lg (X_("POSIX"));
583 Region::set_live_state (node, what_changed, false);
585 uint32_t old_flags = _flags;
587 if ((prop = node.property ("flags")) != 0) {
588 _flags = Flag (string_2_enum (prop->value(), _flags));
590 //_flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16));
592 _flags = Flag (_flags & ~Region::LeftOfSplit);
593 _flags = Flag (_flags & ~Region::RightOfSplit);
596 if ((old_flags ^ _flags) & Muted) {
597 what_changed = Change (what_changed|MuteChanged);
599 if ((old_flags ^ _flags) & Opaque) {
600 what_changed = Change (what_changed|OpacityChanged);
602 if ((old_flags ^ _flags) & Locked) {
603 what_changed = Change (what_changed|LockChanged);
606 if ((prop = node.property ("scale-gain")) != 0) {
607 _scale_amplitude = atof (prop->value().c_str());
608 what_changed = Change (what_changed|ScaleAmplitudeChanged);
610 _scale_amplitude = 1.0;
613 /* Now find envelope description and other misc child items */
615 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
622 if (child->name() == "Envelope") {
626 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child)) {
627 set_default_envelope ();
630 _envelope->set_max_xval (_length);
631 _envelope->truncate_end (_length);
633 } else if (child->name() == "FadeIn") {
637 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
638 set_default_fade_in ();
640 XMLNode* grandchild = child->child ("AutomationList");
642 _fade_in->set_state (*grandchild);
646 if ((prop = child->property ("active")) != 0) {
647 if (prop->value() == "yes") {
648 set_fade_in_active (true);
650 set_fade_in_active (true);
654 } else if (child->name() == "FadeOut") {
658 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
659 set_default_fade_out ();
661 XMLNode* grandchild = child->child ("AutomationList");
663 _fade_out->set_state (*grandchild);
667 if ((prop = child->property ("active")) != 0) {
668 if (prop->value() == "yes") {
669 set_fade_out_active (true);
671 set_fade_out_active (false);
679 send_change (what_changed);
686 AudioRegion::set_state (const XMLNode& node)
688 /* Region::set_state() calls the virtual set_live_state(),
689 which will get us back to AudioRegion::set_live_state()
690 to handle the relevant stuff.
693 return Region::set_state (node);
697 AudioRegion::set_fade_in_shape (FadeShape shape)
699 set_fade_in (shape, (nframes_t) _fade_in->back()->when);
703 AudioRegion::set_fade_out_shape (FadeShape shape)
705 set_fade_out (shape, (nframes_t) _fade_out->back()->when);
709 AudioRegion::set_fade_in (FadeShape shape, nframes_t len)
716 _fade_in->fast_simple_add (0.0, 0.0);
717 _fade_in->fast_simple_add (len, 1.0);
721 _fade_in->fast_simple_add (0, 0);
722 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
723 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
724 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
725 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
726 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
727 _fade_in->fast_simple_add (len, 1);
731 _fade_in->fast_simple_add (0, 0);
732 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
733 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
734 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
735 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
736 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
737 _fade_in->fast_simple_add (len * 0.767281, 1);
738 _fade_in->fast_simple_add (len, 1);
742 _fade_in->fast_simple_add (0, 0);
743 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
744 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
745 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
746 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
747 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
748 _fade_in->fast_simple_add (len, 1);
752 _fade_in->fast_simple_add (0, 0);
753 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
754 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
755 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
756 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
757 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
758 _fade_in->fast_simple_add (len, 1);
763 _fade_in_shape = shape;
765 send_change (FadeInChanged);
769 AudioRegion::set_fade_out (FadeShape shape, nframes_t len)
771 _fade_out->freeze ();
776 _fade_out->fast_simple_add (len * 0, 1);
777 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
778 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
779 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
780 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
781 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
782 _fade_out->fast_simple_add (len * 1, 0);
786 _fade_out->fast_simple_add (len * 0, 1);
787 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
788 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
789 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
790 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
791 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
792 _fade_out->fast_simple_add (len * 1, 0);
796 _fade_out->fast_simple_add (len * 0, 1);
797 _fade_out->fast_simple_add (len * 0.305556, 1);
798 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
799 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
800 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
801 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
802 _fade_out->fast_simple_add (len * 1, 0);
806 _fade_out->fast_simple_add (len * 0, 1);
807 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
808 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
809 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
810 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
811 _fade_out->fast_simple_add (len * 1, 0);
815 _fade_out->fast_simple_add (len * 0, 1);
816 _fade_out->fast_simple_add (len * 1, 0);
821 _fade_out_shape = shape;
823 send_change (FadeOutChanged);
827 AudioRegion::set_fade_in_length (nframes_t len)
833 bool changed = _fade_in->extend_to (len);
836 _flags = Flag (_flags & ~DefaultFadeIn);
837 send_change (FadeInChanged);
842 AudioRegion::set_fade_out_length (nframes_t len)
848 bool changed = _fade_out->extend_to (len);
851 _flags = Flag (_flags & ~DefaultFadeOut);
852 send_change (FadeOutChanged);
857 AudioRegion::set_fade_in_active (bool yn)
859 if (yn == (_flags & FadeIn)) {
863 _flags = Flag (_flags|FadeIn);
865 _flags = Flag (_flags & ~FadeIn);
868 send_change (FadeInActiveChanged);
872 AudioRegion::set_fade_out_active (bool yn)
874 if (yn == (_flags & FadeOut)) {
878 _flags = Flag (_flags | FadeOut);
880 _flags = Flag (_flags & ~FadeOut);
883 send_change (FadeOutActiveChanged);
887 AudioRegion::fade_in_is_default () const
889 return _fade_in_shape == Linear && _fade_in->back()->when == 64;
893 AudioRegion::fade_out_is_default () const
895 return _fade_out_shape == Linear && _fade_out->back()->when == 64;
899 AudioRegion::set_default_fade_in ()
901 set_fade_in (Linear, 64);
905 AudioRegion::set_default_fade_out ()
907 set_fade_out (Linear, 64);
911 AudioRegion::set_default_fades ()
913 _fade_in_disabled = 0;
914 _fade_out_disabled = 0;
915 set_default_fade_in ();
916 set_default_fade_out ();
920 AudioRegion::set_default_envelope ()
922 _envelope->freeze ();
924 _envelope->fast_simple_add (0, 1.0f);
925 _envelope->fast_simple_add (_length, 1.0f);
930 AudioRegion::recompute_at_end ()
932 /* our length has changed. recompute a new final point by interpolating
933 based on the the existing curve.
936 _envelope->freeze ();
937 _envelope->truncate_end (_length);
938 _envelope->set_max_xval (_length);
941 if (_fade_in->back()->when > _length) {
942 _fade_in->extend_to (_length);
943 send_change (FadeInChanged);
946 if (_fade_out->back()->when > _length) {
947 _fade_out->extend_to (_length);
948 send_change (FadeOutChanged);
953 AudioRegion::recompute_at_start ()
955 /* as above, but the shift was from the front */
957 _envelope->truncate_start (_length);
959 if (_fade_in->back()->when > _length) {
960 _fade_in->extend_to (_length);
961 send_change (FadeInChanged);
964 if (_fade_out->back()->when > _length) {
965 _fade_out->extend_to (_length);
966 send_change (FadeOutChanged);
971 AudioRegion::separate_by_channel (Session& session, vector<boost::shared_ptr<AudioRegion> >& v) const
977 if (_sources.size() < 2) {
983 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
990 if (_sources.size() == 2) {
998 new_name += ('0' + n + 1);
1001 /* create a copy with just one source. prevent if from being thought of as "whole file" even if
1002 it covers the entire source file(s).
1005 Flag f = Flag (_flags & ~WholeFile);
1007 boost::shared_ptr<Region> r = RegionFactory::create (srcs, _start, _length, new_name, _layer, f);
1008 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (r);
1019 AudioRegion::read_raw_internal (Sample* buf, nframes_t pos, nframes_t cnt) const
1021 return audio_source()->read (buf, pos, cnt);
1025 AudioRegion::exportme (Session& session, ARDOUR::ExportSpecification& spec)
1028 // const nframes_t blocksize = 4096;
1029 // nframes_t to_read;
1032 // spec.channels = _sources.size();
1034 // if (spec.prepare (blocksize, session.frame_rate())) {
1039 // spec.total_frames = _length;
1041 // while (spec.pos < _length && !spec.stop) {
1044 // /* step 1: interleave */
1046 // to_read = min (_length - spec.pos, blocksize);
1048 // if (spec.channels == 1) {
1050 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1056 // Sample buf[blocksize];
1058 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1060 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1064 // for (nframes_t x = 0; x < to_read; ++x) {
1065 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1070 // if (spec.process (to_read)) {
1074 // spec.pos += to_read;
1075 // spec.progress = (double) spec.pos /_length;
1082 // spec.running = false;
1083 // spec.status = status;
1091 AudioRegion::set_scale_amplitude (gain_t g)
1093 boost::shared_ptr<Playlist> pl (playlist());
1095 _scale_amplitude = g;
1097 /* tell the diskstream we're in */
1103 /* tell everybody else */
1105 send_change (ScaleAmplitudeChanged);
1109 AudioRegion::normalize_to (float target_dB)
1111 const nframes_t blocksize = 64 * 1024;
1112 Sample buf[blocksize];
1117 gain_t target = dB_to_coefficient (target_dB);
1119 if (target == 1.0f) {
1120 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1121 that we may have clipped.
1123 target -= FLT_EPSILON;
1127 fend = _start + _length;
1129 /* first pass: find max amplitude */
1131 while (fpos < fend) {
1135 to_read = min (fend - fpos, blocksize);
1137 for (n = 0; n < n_channels(); ++n) {
1141 if (read_raw_internal (buf, fpos, to_read) != to_read) {
1145 maxamp = compute_peak (buf, to_read, maxamp);
1151 if (maxamp == 0.0f) {
1152 /* don't even try */
1156 if (maxamp == target) {
1157 /* we can't do anything useful */
1161 /* compute scale factor */
1163 _scale_amplitude = target/maxamp;
1165 /* tell the diskstream we're in */
1167 boost::shared_ptr<Playlist> pl (playlist());
1173 /* tell everybody else */
1175 send_change (ScaleAmplitudeChanged);
1179 AudioRegion::fade_in_changed ()
1181 send_change (FadeInChanged);
1185 AudioRegion::fade_out_changed ()
1187 send_change (FadeOutChanged);
1191 AudioRegion::envelope_changed ()
1193 send_change (EnvelopeChanged);
1197 AudioRegion::suspend_fade_in ()
1199 if (++_fade_in_disabled == 1) {
1200 if (fade_in_is_default()) {
1201 set_fade_in_active (false);
1207 AudioRegion::resume_fade_in ()
1209 if (--_fade_in_disabled == 0 && _fade_in_disabled) {
1210 set_fade_in_active (true);
1215 AudioRegion::suspend_fade_out ()
1217 if (++_fade_out_disabled == 1) {
1218 if (fade_out_is_default()) {
1219 set_fade_out_active (false);
1225 AudioRegion::resume_fade_out ()
1227 if (--_fade_out_disabled == 0 &&_fade_out_disabled) {
1228 set_fade_out_active (true);
1233 AudioRegion::speed_mismatch (float sr) const
1235 if (_sources.empty()) {
1236 /* impossible, but ... */
1240 float fsr = audio_source()->sample_rate();
1246 AudioRegion::source_offset_changed ()
1248 /* XXX this fixes a crash that should not occur. It does occur
1249 becauses regions are not being deleted when a session
1250 is unloaded. That bug must be fixed.
1253 if (_sources.empty()) {
1257 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1259 if (afs && afs->destructive()) {
1260 // set_start (source()->natural_position(), this);
1261 set_position (source()->natural_position(), this);
1265 boost::shared_ptr<AudioSource>
1266 AudioRegion::audio_source (uint32_t n) const
1268 // Guaranteed to succeed (use a static cast for speed?)
1269 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1273 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1275 boost::shared_ptr<Playlist> pl = playlist();
1281 if (_valid_transients && !force_new) {
1282 results = _transients;
1286 SourceList::iterator s;
1288 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1289 if (!(*s)->has_been_analysed()) {
1290 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1295 if (s == _sources.end()) {
1296 /* all sources are analyzed, merge data from each one */
1298 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1300 /* find the set of transients within the bounds of this region */
1302 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1303 (*s)->transients.end(),
1306 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1307 (*s)->transients.end(),
1312 results.insert (results.end(), low, high);
1315 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1317 /* translate all transients to current position */
1319 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1324 _transients = results;
1325 _valid_transients = true;
1330 /* no existing/complete transient info */
1332 if (!Config->get_auto_analyse_audio()) {
1333 pl->session().Dialog (_("\
1334 You have requested an operation that requires audio analysis.\n\n\
1335 You currently have \"auto-analyse-audio\" disabled, which means\n\
1336 that transient data must be generated every time it is required.\n\n\
1337 If you are doing work that will require transient data on a\n\
1338 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1339 then quit ardour and restart."));
1342 TransientDetector t (pl->session().frame_rate());
1343 bool existing_results = !results.empty();
1345 _transients.clear ();
1346 _valid_transients = false;
1348 for (uint32_t i = 0; i < n_channels(); ++i) {
1350 AnalysisFeatureList these_results;
1354 if (t.run ("", this, i, these_results)) {
1358 /* translate all transients to give absolute position */
1360 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1366 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1369 if (!results.empty()) {
1370 if (existing_results) {
1372 /* merge our transients into the existing ones, then clean up
1376 results.insert (results.end(), _transients.begin(), _transients.end());
1377 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1380 /* make sure ours are clean too */
1382 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1386 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1387 results = _transients;
1390 _valid_transients = true;
1397 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)
1399 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (nframes_t) npeaks, (nframes_t) start, (nframes_t) cnt, n_chan,samples_per_unit);
1402 uint32_t region_length_from_c (void *arg)
1405 return ((AudioRegion *) arg)->length();
1408 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1410 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;