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(*other->_fade_in, offset, offset + length))
137 , _fade_out (new AutomationList(*other->_fade_out, offset, offset + length))
138 , _envelope (new AutomationList(*other->_envelope, offset, offset + length))
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 (*other->_fade_in))
190 , _fade_out (new AutomationList (*other->_fade_out))
191 , _envelope (new AutomationList (*other->_envelope))
193 assert(_type == DataType::AUDIO);
194 _scale_amplitude = other->_scale_amplitude;
196 set_default_fades ();
198 listen_to_my_curves ();
199 listen_to_my_sources ();
202 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& srcs,
203 nframes_t length, const string& name, layer_t layer, Flag flags)
204 : Region (other, length, name, layer, flags)
205 , _automatable (other->session())
206 , _fade_in (new AutomationList (*other->_fade_in))
207 , _fade_out (new AutomationList (*other->_fade_out))
208 , _envelope (new AutomationList (*other->_envelope))
210 /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
212 set<boost::shared_ptr<AudioSource> > unique_srcs;
214 for (SourceList::const_iterator i=srcs.begin(); i != srcs.end(); ++i) {
216 _sources.push_back (*i);
217 _master_sources.push_back (*i);
219 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> ((*i));
221 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
225 _scale_amplitude = other->_scale_amplitude;
227 _fade_in_disabled = 0;
228 _fade_out_disabled = 0;
230 listen_to_my_curves ();
231 listen_to_my_sources ();
234 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node)
236 , _automatable(src->session())
237 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
238 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
239 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
241 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
243 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
248 if (set_state (node)) {
249 throw failed_constructor();
252 assert(_type == DataType::AUDIO);
253 listen_to_my_sources ();
256 AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
257 : Region (srcs, node)
258 , _automatable(srcs[0]->session())
259 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
260 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
261 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
265 if (set_state (node)) {
266 throw failed_constructor();
269 assert(_type == DataType::AUDIO);
270 listen_to_my_sources ();
273 AudioRegion::~AudioRegion ()
278 AudioRegion::listen_to_my_sources ()
280 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
281 (*i)->AnalysisChanged.connect (mem_fun (*this, &AudioRegion::invalidate_transients));
286 AudioRegion::listen_to_my_curves ()
288 _envelope->StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
289 _fade_in->StateChanged.connect (mem_fun (*this, &AudioRegion::fade_in_changed));
290 _fade_out->StateChanged.connect (mem_fun (*this, &AudioRegion::fade_out_changed));
294 AudioRegion::set_envelope_active (bool yn)
296 if (envelope_active() != yn) {
299 snprintf (buf, sizeof (buf), "envelope active");
300 _flags = Flag (_flags|EnvelopeActive);
302 snprintf (buf, sizeof (buf), "envelope off");
303 _flags = Flag (_flags & ~EnvelopeActive);
305 send_change (EnvelopeActiveChanged);
310 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
312 if (chan_n >= _sources.size()) {
316 if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
319 if (_scale_amplitude != 1.0) {
320 for (nframes_t n = 0; n < npeaks; ++n) {
321 buf[n].max *= _scale_amplitude;
322 buf[n].min *= _scale_amplitude;
330 AudioRegion::read (Sample* buf, nframes64_t timeline_position, nframes64_t cnt, int channel) const
332 /* raw read, no fades, no gain, nada */
333 return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
337 AudioRegion::read_with_ops (Sample* buf, nframes64_t file_position, nframes64_t cnt, int channel, ReadOps rops) const
339 return _read_at (_sources, _length, buf, 0, 0, file_position, cnt, channel, 0, 0, rops);
343 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t file_position,
345 uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames) const
347 /* regular diskstream/butler read complete with fades etc */
348 return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer, file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
352 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position,
353 nframes_t cnt, uint32_t chan_n) const
355 return _read_at (_master_sources, _master_sources.front()->length(), buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0);
359 AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
360 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
361 nframes_t position, nframes_t cnt,
363 nframes_t read_frames,
364 nframes_t skip_frames,
367 nframes_t internal_offset;
368 nframes_t buf_offset;
370 bool raw = (rops == ReadOpsNone);
372 if (muted() && !raw) {
373 return 0; /* read nothing */
376 /* precondition: caller has verified that we cover the desired section */
378 if (position < _position) {
380 buf_offset = _position - position;
383 internal_offset = position - _position;
387 if (internal_offset >= limit) {
388 return 0; /* read nothing */
391 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
392 return 0; /* read nothing */
395 if (opaque() || raw) {
396 /* overwrite whatever is there */
397 mixdown_buffer = buf + buf_offset;
399 mixdown_buffer += buf_offset;
402 if (rops & ReadOpsCount) {
403 _read_data_count = 0;
406 if (chan_n < n_channels()) {
408 boost::shared_ptr<AudioSource> src = audio_source(chan_n);
409 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
410 return 0; /* "read nothing" */
413 if (rops & ReadOpsCount) {
414 _read_data_count += src->read_data_count();
419 /* track is N-channel, this region has less channels; silence the ones
423 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
426 if (rops & ReadOpsFades) {
430 if ((_flags & FadeIn) && Config->get_use_region_fades()) {
432 nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
434 /* see if this read is within the fade in */
436 if (internal_offset < fade_in_length) {
440 fi_limit = min (to_read, fade_in_length - internal_offset);
443 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
445 for (nframes_t n = 0; n < fi_limit; ++n) {
446 mixdown_buffer[n] *= gain_buffer[n];
453 if ((_flags & FadeOut) && Config->get_use_region_fades()) {
455 /* see if some part of this read is within the fade out */
457 /* ................. >| REGION
463 limit - fade_out_length
466 ^internal_offset + to_read
468 we need the intersection of [internal_offset,internal_offset+to_read] with
469 [limit - fade_out_length, limit]
474 nframes_t fade_out_length = (nframes_t) _fade_out->back()->when;
475 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
476 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
478 if (fade_interval_end > fade_interval_start) {
479 /* (part of the) the fade out is in this buffer */
481 nframes_t fo_limit = fade_interval_end - fade_interval_start;
482 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
483 nframes_t fade_offset = fade_interval_start - internal_offset;
485 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
487 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
488 mixdown_buffer[m] *= gain_buffer[n];
495 /* Regular gain curves and scaling */
497 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
498 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
500 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
501 for (nframes_t n = 0; n < to_read; ++n) {
502 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
505 for (nframes_t n = 0; n < to_read; ++n) {
506 mixdown_buffer[n] *= gain_buffer[n];
509 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
511 // XXX this should be using what in 2.0 would have been:
512 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
514 for (nframes_t n = 0; n < to_read; ++n) {
515 mixdown_buffer[n] *= _scale_amplitude;
521 /* gack. the things we do for users.
526 for (nframes_t n = 0; n < to_read; ++n) {
527 buf[n] += mixdown_buffer[n];
535 AudioRegion::state (bool full)
537 XMLNode& node (Region::state (full));
541 LocaleGuard lg (X_("POSIX"));
543 node.add_property ("flags", enum_2_string (_flags));
545 snprintf (buf, sizeof(buf), "%.12g", _scale_amplitude);
546 node.add_property ("scale-gain", buf);
548 // XXX these should move into Region
550 for (uint32_t n=0; n < _sources.size(); ++n) {
551 snprintf (buf2, sizeof(buf2), "source-%d", n);
552 _sources[n]->id().print (buf, sizeof (buf));
553 node.add_property (buf2, buf);
556 for (uint32_t n=0; n < _master_sources.size(); ++n) {
557 snprintf (buf2, sizeof(buf2), "master-source-%d", n);
558 _master_sources[n]->id().print (buf, sizeof (buf));
559 node.add_property (buf2, buf);
562 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
563 node.add_property ("channels", buf);
567 child = node.add_child (X_("FadeIn"));
569 if ((_flags & DefaultFadeIn)) {
570 child->add_property (X_("default"), X_("yes"));
572 child->add_child_nocopy (_fade_in->get_state ());
575 child->add_property (X_("active"), _fade_in_disabled ? X_("no") : X_("yes"));
577 child = node.add_child (X_("FadeOut"));
579 if ((_flags & DefaultFadeOut)) {
580 child->add_property (X_("default"), X_("yes"));
582 child->add_child_nocopy (_fade_out->get_state ());
585 child->add_property (X_("active"), _fade_out_disabled ? X_("no") : X_("yes"));
588 child = node.add_child ("Envelope");
591 bool default_env = false;
593 // If there are only two points, the points are in the start of the region and the end of the region
594 // so, if they are both at 1.0f, that means the default region.
596 if (_envelope->size() == 2 &&
597 _envelope->front()->value == 1.0f &&
598 _envelope->back()->value==1.0f) {
599 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
605 child->add_property ("default", "yes");
607 child->add_child_nocopy (_envelope->get_state ());
611 child->add_property ("default", "yes");
614 if (full && _extra_xml) {
615 node.add_child_copy (*_extra_xml);
622 AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool send)
624 const XMLNodeList& nlist = node.children();
625 const XMLProperty *prop;
626 LocaleGuard lg (X_("POSIX"));
628 Region::set_live_state (node, what_changed, false);
630 uint32_t old_flags = _flags;
632 if ((prop = node.property ("flags")) != 0) {
633 _flags = Flag (string_2_enum (prop->value(), _flags));
635 //_flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16));
637 _flags = Flag (_flags & ~Region::LeftOfSplit);
638 _flags = Flag (_flags & ~Region::RightOfSplit);
641 if ((old_flags ^ _flags) & Muted) {
642 what_changed = Change (what_changed|MuteChanged);
644 if ((old_flags ^ _flags) & Opaque) {
645 what_changed = Change (what_changed|OpacityChanged);
647 if ((old_flags ^ _flags) & Locked) {
648 what_changed = Change (what_changed|LockChanged);
651 if ((prop = node.property ("scale-gain")) != 0) {
652 _scale_amplitude = atof (prop->value().c_str());
653 what_changed = Change (what_changed|ScaleAmplitudeChanged);
655 _scale_amplitude = 1.0;
658 /* Now find envelope description and other misc child items */
660 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
667 if (child->name() == "Envelope") {
671 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child)) {
672 set_default_envelope ();
675 _envelope->set_max_xval (_length);
676 _envelope->truncate_end (_length);
678 } else if (child->name() == "FadeIn") {
682 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
683 set_default_fade_in ();
685 XMLNode* grandchild = child->child ("AutomationList");
687 _fade_in->set_state (*grandchild);
691 if ((prop = child->property ("active")) != 0) {
692 if (prop->value() == "yes") {
693 set_fade_in_active (true);
695 set_fade_in_active (true);
699 } else if (child->name() == "FadeOut") {
703 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
704 set_default_fade_out ();
706 XMLNode* grandchild = child->child ("AutomationList");
708 _fade_out->set_state (*grandchild);
712 if ((prop = child->property ("active")) != 0) {
713 if (prop->value() == "yes") {
714 set_fade_out_active (true);
716 set_fade_out_active (false);
724 send_change (what_changed);
731 AudioRegion::set_state (const XMLNode& node)
733 /* Region::set_state() calls the virtual set_live_state(),
734 which will get us back to AudioRegion::set_live_state()
735 to handle the relevant stuff.
738 return Region::set_state (node);
742 AudioRegion::set_fade_in_shape (FadeShape shape)
744 set_fade_in (shape, (nframes_t) _fade_in->back()->when);
748 AudioRegion::set_fade_out_shape (FadeShape shape)
750 set_fade_out (shape, (nframes_t) _fade_out->back()->when);
754 AudioRegion::set_fade_in (FadeShape shape, nframes_t len)
761 _fade_in->fast_simple_add (0.0, 0.0);
762 _fade_in->fast_simple_add (len, 1.0);
766 _fade_in->fast_simple_add (0, 0);
767 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
768 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
769 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
770 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
771 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
772 _fade_in->fast_simple_add (len, 1);
776 _fade_in->fast_simple_add (0, 0);
777 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
778 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
779 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
780 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
781 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
782 _fade_in->fast_simple_add (len * 0.767281, 1);
783 _fade_in->fast_simple_add (len, 1);
787 _fade_in->fast_simple_add (0, 0);
788 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
789 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
790 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
791 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
792 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
793 _fade_in->fast_simple_add (len, 1);
797 _fade_in->fast_simple_add (0, 0);
798 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
799 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
800 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
801 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
802 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
803 _fade_in->fast_simple_add (len, 1);
808 _fade_in_shape = shape;
810 send_change (FadeInChanged);
814 AudioRegion::set_fade_out (FadeShape shape, nframes_t len)
816 _fade_out->freeze ();
821 _fade_out->fast_simple_add (len * 0, 1);
822 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
823 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
824 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
825 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
826 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
827 _fade_out->fast_simple_add (len * 1, 0);
831 _fade_out->fast_simple_add (len * 0, 1);
832 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
833 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
834 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
835 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
836 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
837 _fade_out->fast_simple_add (len * 1, 0);
841 _fade_out->fast_simple_add (len * 0, 1);
842 _fade_out->fast_simple_add (len * 0.305556, 1);
843 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
844 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
845 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
846 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
847 _fade_out->fast_simple_add (len * 1, 0);
851 _fade_out->fast_simple_add (len * 0, 1);
852 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
853 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
854 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
855 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
856 _fade_out->fast_simple_add (len * 1, 0);
860 _fade_out->fast_simple_add (len * 0, 1);
861 _fade_out->fast_simple_add (len * 1, 0);
866 _fade_out_shape = shape;
868 send_change (FadeOutChanged);
872 AudioRegion::set_fade_in_length (nframes_t len)
878 bool changed = _fade_in->extend_to (len);
881 _flags = Flag (_flags & ~DefaultFadeIn);
882 send_change (FadeInChanged);
887 AudioRegion::set_fade_out_length (nframes_t len)
893 bool changed = _fade_out->extend_to (len);
896 _flags = Flag (_flags & ~DefaultFadeOut);
897 send_change (FadeOutChanged);
902 AudioRegion::set_fade_in_active (bool yn)
904 if (yn == (_flags & FadeIn)) {
908 _flags = Flag (_flags|FadeIn);
910 _flags = Flag (_flags & ~FadeIn);
913 send_change (FadeInActiveChanged);
917 AudioRegion::set_fade_out_active (bool yn)
919 if (yn == (_flags & FadeOut)) {
923 _flags = Flag (_flags | FadeOut);
925 _flags = Flag (_flags & ~FadeOut);
928 send_change (FadeOutActiveChanged);
932 AudioRegion::fade_in_is_default () const
934 return _fade_in_shape == Linear && _fade_in->back()->when == 64;
938 AudioRegion::fade_out_is_default () const
940 return _fade_out_shape == Linear && _fade_out->back()->when == 64;
944 AudioRegion::set_default_fade_in ()
946 set_fade_in (Linear, 64);
950 AudioRegion::set_default_fade_out ()
952 set_fade_out (Linear, 64);
956 AudioRegion::set_default_fades ()
958 _fade_in_disabled = 0;
959 _fade_out_disabled = 0;
960 set_default_fade_in ();
961 set_default_fade_out ();
965 AudioRegion::set_default_envelope ()
967 _envelope->freeze ();
969 _envelope->fast_simple_add (0, 1.0f);
970 _envelope->fast_simple_add (_length, 1.0f);
975 AudioRegion::recompute_at_end ()
977 /* our length has changed. recompute a new final point by interpolating
978 based on the the existing curve.
981 _envelope->freeze ();
982 _envelope->truncate_end (_length);
983 _envelope->set_max_xval (_length);
986 if (_fade_in->back()->when > _length) {
987 _fade_in->extend_to (_length);
988 send_change (FadeInChanged);
991 if (_fade_out->back()->when > _length) {
992 _fade_out->extend_to (_length);
993 send_change (FadeOutChanged);
998 AudioRegion::recompute_at_start ()
1000 /* as above, but the shift was from the front */
1002 _envelope->truncate_start (_length);
1004 if (_fade_in->back()->when > _length) {
1005 _fade_in->extend_to (_length);
1006 send_change (FadeInChanged);
1009 if (_fade_out->back()->when > _length) {
1010 _fade_out->extend_to (_length);
1011 send_change (FadeOutChanged);
1016 AudioRegion::separate_by_channel (Session& session, vector<boost::shared_ptr<AudioRegion> >& v) const
1022 if (_sources.size() < 2) {
1028 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
1031 srcs.push_back (*i);
1035 if (_sources.size() == 2) {
1043 new_name += ('0' + n + 1);
1046 /* create a copy with just one source. prevent if from being thought of as "whole file" even if
1047 it covers the entire source file(s).
1050 Flag f = Flag (_flags & ~WholeFile);
1052 boost::shared_ptr<Region> r = RegionFactory::create (srcs, _start, _length, new_name, _layer, f);
1053 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (r);
1064 AudioRegion::read_raw_internal (Sample* buf, nframes_t pos, nframes_t cnt) const
1066 return audio_source()->read (buf, pos, cnt);
1070 AudioRegion::exportme (Session& session, ARDOUR::ExportSpecification& spec)
1073 // const nframes_t blocksize = 4096;
1074 // nframes_t to_read;
1077 // spec.channels = _sources.size();
1079 // if (spec.prepare (blocksize, session.frame_rate())) {
1084 // spec.total_frames = _length;
1086 // while (spec.pos < _length && !spec.stop) {
1089 // /* step 1: interleave */
1091 // to_read = min (_length - spec.pos, blocksize);
1093 // if (spec.channels == 1) {
1095 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1101 // Sample buf[blocksize];
1103 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1105 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1109 // for (nframes_t x = 0; x < to_read; ++x) {
1110 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1115 // if (spec.process (to_read)) {
1119 // spec.pos += to_read;
1120 // spec.progress = (double) spec.pos /_length;
1127 // spec.running = false;
1128 // spec.status = status;
1136 AudioRegion::set_scale_amplitude (gain_t g)
1138 boost::shared_ptr<Playlist> pl (playlist());
1140 _scale_amplitude = g;
1142 /* tell the diskstream we're in */
1148 /* tell everybody else */
1150 send_change (ScaleAmplitudeChanged);
1154 AudioRegion::normalize_to (float target_dB)
1156 const nframes_t blocksize = 64 * 1024;
1157 Sample buf[blocksize];
1162 gain_t target = dB_to_coefficient (target_dB);
1164 if (target == 1.0f) {
1165 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1166 that we may have clipped.
1168 target -= FLT_EPSILON;
1172 fend = _start + _length;
1174 /* first pass: find max amplitude */
1176 while (fpos < fend) {
1180 to_read = min (fend - fpos, blocksize);
1182 for (n = 0; n < n_channels(); ++n) {
1186 if (read_raw_internal (buf, fpos, to_read) != to_read) {
1190 maxamp = compute_peak (buf, to_read, maxamp);
1196 if (maxamp == 0.0f) {
1197 /* don't even try */
1201 if (maxamp == target) {
1202 /* we can't do anything useful */
1206 /* compute scale factor */
1208 _scale_amplitude = target/maxamp;
1210 /* tell the diskstream we're in */
1212 boost::shared_ptr<Playlist> pl (playlist());
1218 /* tell everybody else */
1220 send_change (ScaleAmplitudeChanged);
1224 AudioRegion::fade_in_changed ()
1226 send_change (FadeInChanged);
1230 AudioRegion::fade_out_changed ()
1232 send_change (FadeOutChanged);
1236 AudioRegion::envelope_changed ()
1238 send_change (EnvelopeChanged);
1242 AudioRegion::suspend_fade_in ()
1244 if (++_fade_in_disabled == 1) {
1245 if (fade_in_is_default()) {
1246 set_fade_in_active (false);
1252 AudioRegion::resume_fade_in ()
1254 if (--_fade_in_disabled == 0 && _fade_in_disabled) {
1255 set_fade_in_active (true);
1260 AudioRegion::suspend_fade_out ()
1262 if (++_fade_out_disabled == 1) {
1263 if (fade_out_is_default()) {
1264 set_fade_out_active (false);
1270 AudioRegion::resume_fade_out ()
1272 if (--_fade_out_disabled == 0 &&_fade_out_disabled) {
1273 set_fade_out_active (true);
1278 AudioRegion::speed_mismatch (float sr) const
1280 if (_sources.empty()) {
1281 /* impossible, but ... */
1285 float fsr = audio_source()->sample_rate();
1291 AudioRegion::source_offset_changed ()
1293 /* XXX this fixes a crash that should not occur. It does occur
1294 becauses regions are not being deleted when a session
1295 is unloaded. That bug must be fixed.
1298 if (_sources.empty()) {
1302 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1304 if (afs && afs->destructive()) {
1305 // set_start (source()->natural_position(), this);
1306 set_position (source()->natural_position(), this);
1310 boost::shared_ptr<AudioSource>
1311 AudioRegion::audio_source (uint32_t n) const
1313 // Guaranteed to succeed (use a static cast for speed?)
1314 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1318 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1320 boost::shared_ptr<Playlist> pl = playlist();
1326 if (_valid_transients && !force_new) {
1327 results = _transients;
1331 SourceList::iterator s;
1333 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1334 if (!(*s)->has_been_analysed()) {
1335 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1340 if (s == _sources.end()) {
1341 /* all sources are analyzed, merge data from each one */
1343 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1345 /* find the set of transients within the bounds of this region */
1347 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1348 (*s)->transients.end(),
1351 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1352 (*s)->transients.end(),
1357 results.insert (results.end(), low, high);
1360 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1362 /* translate all transients to current position */
1364 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1369 _transients = results;
1370 _valid_transients = true;
1375 /* no existing/complete transient info */
1377 if (!Config->get_auto_analyse_audio()) {
1378 pl->session().Dialog (_("\
1379 You have requested an operation that requires audio analysis.\n\n\
1380 You currently have \"auto-analyse-audio\" disabled, which means\n\
1381 that transient data must be generated every time it is required.\n\n\
1382 If you are doing work that will require transient data on a\n\
1383 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1384 then quit ardour and restart."));
1387 TransientDetector t (pl->session().frame_rate());
1388 bool existing_results = !results.empty();
1390 _transients.clear ();
1391 _valid_transients = false;
1393 for (uint32_t i = 0; i < n_channels(); ++i) {
1395 AnalysisFeatureList these_results;
1399 if (t.run ("", this, i, these_results)) {
1403 /* translate all transients to give absolute position */
1405 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1411 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1414 if (!results.empty()) {
1415 if (existing_results) {
1417 /* merge our transients into the existing ones, then clean up
1421 results.insert (results.end(), _transients.begin(), _transients.end());
1422 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1425 /* make sure ours are clean too */
1427 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1431 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1432 results = _transients;
1435 _valid_transients = true;
1442 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)
1444 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (nframes_t) npeaks, (nframes_t) start, (nframes_t) cnt, n_chan,samples_per_unit);
1447 uint32_t region_length_from_c (void *arg)
1450 return ((AudioRegion *) arg)->length();
1453 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1455 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;