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.
28 #include <glibmm/thread.h>
30 #include "pbd/basename.h"
31 #include "pbd/xml++.h"
32 #include "pbd/stacktrace.h"
33 #include "pbd/enumwriter.h"
34 #include "pbd/convert.h"
36 #include "evoral/Curve.hpp"
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 = PBD::new_change();
58 Change AudioRegion::FadeOutChanged = PBD::new_change();
59 Change AudioRegion::FadeInActiveChanged = PBD::new_change();
60 Change AudioRegion::FadeOutActiveChanged = PBD::new_change();
61 Change AudioRegion::EnvelopeActiveChanged = PBD::new_change();
62 Change AudioRegion::ScaleAmplitudeChanged = PBD::new_change();
63 Change AudioRegion::EnvelopeChanged = PBD::new_change();
68 _scale_amplitude = 1.0;
71 set_default_envelope ();
73 listen_to_my_curves ();
74 connect_to_analysis_changed ();
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)))
86 assert (_sources.size() == _master_sources.size());
89 /** Basic AudioRegion constructor (one channel) */
90 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length)
91 : Region (src, start, length, PBD::basename_nosuffix(src->name()), DataType::AUDIO, 0, Region::Flag(Region::DefaultFlags|Region::External))
92 , _automatable(src->session())
93 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
94 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
95 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
97 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
99 afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
103 assert (_sources.size() == _master_sources.size());
106 /* Basic AudioRegion constructor (one channel) */
107 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
108 : Region (src, start, length, name, DataType::AUDIO, layer, flags)
109 , _automatable(src->session())
110 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
111 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
112 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
114 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
116 afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
120 assert (_sources.size() == _master_sources.size());
123 /** Basic AudioRegion constructor (many channels) */
124 AudioRegion::AudioRegion (const SourceList& srcs, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
125 : Region (srcs, start, length, name, DataType::AUDIO, layer, flags)
126 , _automatable(srcs[0]->session())
127 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
128 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
129 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
132 connect_to_analysis_changed ();
133 assert (_sources.size() == _master_sources.size());
136 /** Create a new AudioRegion, that is part of an existing one */
137 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags)
138 : Region (other, offset, length, name, layer, flags)
139 , _automatable(other->session())
140 , _fade_in (new AutomationList(*other->_fade_in))
141 , _fade_out (new AutomationList(*other->_fade_out))
142 , _envelope (new AutomationList(*other->_envelope, offset, offset + length))
144 connect_to_header_position_offset_changed ();
146 /* return to default fades if the existing ones are too long */
148 if (_flags & LeftOfSplit) {
149 if (_fade_in->back()->when >= _length) {
150 set_default_fade_in ();
152 _fade_in_disabled = other->_fade_in_disabled;
154 set_default_fade_out ();
155 _flags = Flag (_flags & ~Region::LeftOfSplit);
158 if (_flags & RightOfSplit) {
159 if (_fade_out->back()->when >= _length) {
160 set_default_fade_out ();
162 _fade_out_disabled = other->_fade_out_disabled;
164 set_default_fade_in ();
165 _flags = Flag (_flags & ~Region::RightOfSplit);
168 _scale_amplitude = other->_scale_amplitude;
170 assert(_type == DataType::AUDIO);
172 listen_to_my_curves ();
173 connect_to_analysis_changed ();
175 assert (_sources.size() == _master_sources.size());
178 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
180 , _automatable (other->session())
181 , _fade_in (new AutomationList (*other->_fade_in))
182 , _fade_out (new AutomationList (*other->_fade_out))
183 , _envelope (new AutomationList (*other->_envelope))
185 assert(_type == DataType::AUDIO);
186 _scale_amplitude = other->_scale_amplitude;
188 listen_to_my_curves ();
189 connect_to_analysis_changed ();
191 assert (_sources.size() == _master_sources.size());
194 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& /*srcs*/,
195 nframes_t length, const string& name, layer_t layer, Flag flags)
196 : Region (other, length, name, layer, flags)
197 , _automatable (other->session())
198 , _fade_in (new AutomationList (*other->_fade_in))
199 , _fade_out (new AutomationList (*other->_fade_out))
200 , _envelope (new AutomationList (*other->_envelope))
202 /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
204 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
206 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> ((*i));
208 afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
212 _scale_amplitude = other->_scale_amplitude;
214 _fade_in_disabled = 0;
215 _fade_out_disabled = 0;
217 listen_to_my_curves ();
218 connect_to_analysis_changed ();
220 assert (_sources.size() == _master_sources.size());
223 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node)
225 , _automatable(src->session())
226 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
227 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
228 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
230 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
232 afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
237 if (set_state (node, Stateful::loading_state_version)) {
238 throw failed_constructor();
241 assert(_type == DataType::AUDIO);
242 connect_to_analysis_changed ();
244 assert (_sources.size() == _master_sources.size());
247 AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
248 : Region (srcs, node)
249 , _automatable(srcs[0]->session())
250 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
251 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
252 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
256 if (set_state (node, Stateful::loading_state_version)) {
257 throw failed_constructor();
260 assert(_type == DataType::AUDIO);
261 connect_to_analysis_changed ();
262 assert (_sources.size() == _master_sources.size());
265 AudioRegion::~AudioRegion ()
270 AudioRegion::connect_to_analysis_changed ()
272 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
273 (*i)->AnalysisChanged.connect_same_thread (*this, boost::bind (&AudioRegion::invalidate_transients, this));
278 AudioRegion::connect_to_header_position_offset_changed ()
280 set<boost::shared_ptr<Source> > unique_srcs;
282 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
284 if (unique_srcs.find (*i) == unique_srcs.end ()) {
285 unique_srcs.insert (*i);
286 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
288 afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
295 AudioRegion::listen_to_my_curves ()
297 cerr << _name << ": listeing my own curves\n";
299 _envelope->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::envelope_changed, this));
300 _fade_in->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_in_changed, this));
301 _fade_out->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_out_changed, this));
305 AudioRegion::set_envelope_active (bool yn)
307 if (envelope_active() != yn) {
309 _flags = Flag (_flags|EnvelopeActive);
311 _flags = Flag (_flags & ~EnvelopeActive);
313 send_change (EnvelopeActiveChanged);
318 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
320 if (chan_n >= _sources.size()) {
324 if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
327 if (_scale_amplitude != 1.0) {
328 for (nframes_t n = 0; n < npeaks; ++n) {
329 buf[n].max *= _scale_amplitude;
330 buf[n].min *= _scale_amplitude;
338 AudioRegion::read (Sample* buf, sframes_t timeline_position, nframes_t cnt, int channel) const
340 /* raw read, no fades, no gain, nada */
341 return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
345 AudioRegion::read_with_ops (Sample* buf, sframes_t file_position, nframes_t cnt, int channel, ReadOps rops) const
347 return _read_at (_sources, _length, buf, 0, 0, file_position, cnt, channel, 0, 0, rops);
351 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
352 sframes_t file_position, nframes_t cnt, uint32_t chan_n,
353 nframes_t read_frames, nframes_t skip_frames) const
355 /* regular diskstream/butler read complete with fades etc */
356 return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer,
357 file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
361 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
362 sframes_t position, nframes_t cnt, uint32_t chan_n) const
364 /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
366 return _read_at (_master_sources, _master_sources.front()->length(_master_sources.front()->timeline_position()),
367 buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0, ReadOps (0));
371 AudioRegion::_read_at (const SourceList& /*srcs*/, nframes_t limit,
372 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
373 sframes_t position, nframes_t cnt,
375 nframes_t /*read_frames*/,
376 nframes_t /*skip_frames*/,
379 nframes_t internal_offset;
380 nframes_t buf_offset;
382 bool raw = (rops == ReadOpsNone);
384 if (muted() && !raw) {
385 return 0; /* read nothing */
388 /* precondition: caller has verified that we cover the desired section */
390 if (position < _position) {
392 buf_offset = _position - position;
395 internal_offset = position - _position;
399 if (internal_offset >= limit) {
400 return 0; /* read nothing */
403 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
404 return 0; /* read nothing */
407 if (opaque() || raw) {
408 /* overwrite whatever is there */
409 mixdown_buffer = buf + buf_offset;
411 mixdown_buffer += buf_offset;
414 if (rops & ReadOpsCount) {
415 _read_data_count = 0;
418 if (chan_n < n_channels()) {
420 boost::shared_ptr<AudioSource> src = audio_source(chan_n);
421 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
422 return 0; /* "read nothing" */
425 if (rops & ReadOpsCount) {
426 _read_data_count += src->read_data_count();
431 /* track is N-channel, this region has less channels; silence the ones
435 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
438 if (rops & ReadOpsFades) {
442 if ((_flags & FadeIn) && _session.config.get_use_region_fades()) {
444 nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
446 /* see if this read is within the fade in */
448 if (internal_offset < fade_in_length) {
452 fi_limit = min (to_read, fade_in_length - internal_offset);
455 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
457 for (nframes_t n = 0; n < fi_limit; ++n) {
458 mixdown_buffer[n] *= gain_buffer[n];
465 if ((_flags & FadeOut) && _session.config.get_use_region_fades()) {
467 /* see if some part of this read is within the fade out */
469 /* ................. >| REGION
475 limit - fade_out_length
478 ^internal_offset + to_read
480 we need the intersection of [internal_offset,internal_offset+to_read] with
481 [limit - fade_out_length, limit]
486 nframes_t fade_out_length = (nframes_t) _fade_out->back()->when;
487 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
488 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
490 if (fade_interval_end > fade_interval_start) {
491 /* (part of the) the fade out is in this buffer */
493 nframes_t fo_limit = fade_interval_end - fade_interval_start;
494 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
495 nframes_t fade_offset = fade_interval_start - internal_offset;
497 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
499 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
500 mixdown_buffer[m] *= gain_buffer[n];
507 /* Regular gain curves and scaling */
509 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
510 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
512 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
513 for (nframes_t n = 0; n < to_read; ++n) {
514 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
517 for (nframes_t n = 0; n < to_read; ++n) {
518 mixdown_buffer[n] *= gain_buffer[n];
521 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
523 // XXX this should be using what in 2.0 would have been:
524 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
526 for (nframes_t n = 0; n < to_read; ++n) {
527 mixdown_buffer[n] *= _scale_amplitude;
533 /* gack. the things we do for users.
538 for (nframes_t n = 0; n < to_read; ++n) {
539 buf[n] += mixdown_buffer[n];
547 AudioRegion::state (bool full)
549 XMLNode& node (Region::state (full));
553 LocaleGuard lg (X_("POSIX"));
555 node.add_property ("flags", enum_2_string (_flags));
557 snprintf (buf, sizeof(buf), "%.12g", _scale_amplitude);
558 node.add_property ("scale-gain", buf);
560 // XXX these should move into Region
562 for (uint32_t n=0; n < _sources.size(); ++n) {
563 snprintf (buf2, sizeof(buf2), "source-%d", n);
564 _sources[n]->id().print (buf, sizeof (buf));
565 node.add_property (buf2, buf);
568 for (uint32_t n=0; n < _master_sources.size(); ++n) {
569 snprintf (buf2, sizeof(buf2), "master-source-%d", n);
570 _master_sources[n]->id().print (buf, sizeof (buf));
571 node.add_property (buf2, buf);
574 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
575 node.add_property ("channels", buf);
579 child = node.add_child (X_("FadeIn"));
581 if ((_flags & DefaultFadeIn)) {
582 child->add_property (X_("default"), X_("yes"));
584 child->add_child_nocopy (_fade_in->get_state ());
587 child->add_property (X_("active"), fade_in_active () ? X_("yes") : X_("no"));
589 child = node.add_child (X_("FadeOut"));
591 if ((_flags & DefaultFadeOut)) {
592 child->add_property (X_("default"), X_("yes"));
594 child->add_child_nocopy (_fade_out->get_state ());
597 child->add_property (X_("active"), fade_out_active () ? X_("yes") : X_("no"));
600 child = node.add_child ("Envelope");
603 bool default_env = false;
605 // If there are only two points, the points are in the start of the region and the end of the region
606 // so, if they are both at 1.0f, that means the default region.
608 if (_envelope->size() == 2 &&
609 _envelope->front()->value == 1.0f &&
610 _envelope->back()->value==1.0f) {
611 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
617 child->add_property ("default", "yes");
619 child->add_child_nocopy (_envelope->get_state ());
623 child->add_property ("default", "yes");
626 if (full && _extra_xml) {
627 node.add_child_copy (*_extra_xml);
634 AudioRegion::set_live_state (const XMLNode& node, int version, Change& what_changed, bool send)
636 const XMLNodeList& nlist = node.children();
637 const XMLProperty *prop;
638 LocaleGuard lg (X_("POSIX"));
639 boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
643 the_playlist->freeze ();
646 Region::set_live_state (node, version, what_changed, false);
647 cerr << "After region SLS, wc = " << what_changed << endl;
649 uint32_t old_flags = _flags;
651 if ((prop = node.property ("flags")) != 0) {
652 _flags = Flag (string_2_enum (prop->value(), _flags));
654 //_flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16));
656 _flags = Flag (_flags & ~Region::LeftOfSplit);
657 _flags = Flag (_flags & ~Region::RightOfSplit);
660 /* leave this flag setting in place, no matter what */
662 if ((old_flags & DoNotSendPropertyChanges)) {
663 _flags = Flag (_flags | DoNotSendPropertyChanges);
666 /* find out if any flags changed that we signal about */
668 if ((old_flags ^ _flags) & Muted) {
669 what_changed = Change (what_changed|MuteChanged);
670 cerr << _name << " mute changed\n";
672 if ((old_flags ^ _flags) & Opaque) {
673 what_changed = Change (what_changed|OpacityChanged);
674 cerr << _name << " opacity changed\n";
676 if ((old_flags ^ _flags) & Locked) {
677 what_changed = Change (what_changed|LockChanged);
678 cerr << _name << " lock changed\n";
681 if ((prop = node.property ("scale-gain")) != 0) {
682 float a = atof (prop->value().c_str());
683 if (a != _scale_amplitude) {
684 _scale_amplitude = a;
685 what_changed = Change (what_changed|ScaleAmplitudeChanged);
686 cerr << _name << " amp changed\n";
690 /* Now find envelope description and other misc child items */
692 _envelope->freeze ();
694 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
701 if (child->name() == "Envelope") {
705 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child, version)) {
706 set_default_envelope ();
709 _envelope->set_max_xval (_length);
710 _envelope->truncate_end (_length);
712 cerr << _name << " envelope changd\n";
715 } else if (child->name() == "FadeIn") {
719 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
720 set_default_fade_in ();
722 XMLNode* grandchild = child->child ("AutomationList");
724 _fade_in->set_state (*grandchild, version);
728 if ((prop = child->property ("active")) != 0) {
729 if (string_is_affirmative (prop->value())) {
730 set_fade_in_active (true);
732 set_fade_in_active (false);
735 cerr << _name << " fadein changd\n";
737 } else if (child->name() == "FadeOut") {
741 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
742 set_default_fade_out ();
744 XMLNode* grandchild = child->child ("AutomationList");
746 _fade_out->set_state (*grandchild, version);
750 if ((prop = child->property ("active")) != 0) {
751 if (string_is_affirmative (prop->value())) {
752 set_fade_out_active (true);
754 set_fade_out_active (false);
757 cerr << _name << " fadeout changd\n";
767 cerr << _name << ": audio final change: " << hex << what_changed << dec << endl;
768 send_change (what_changed);
772 the_playlist->thaw ();
779 AudioRegion::set_state (const XMLNode& node, int version)
781 /* Region::set_state() calls the virtual set_live_state(),
782 which will get us back to AudioRegion::set_live_state()
783 to handle the relevant stuff.
786 return Region::set_state (node, version);
790 AudioRegion::set_fade_in_shape (FadeShape shape)
792 set_fade_in (shape, (nframes_t) _fade_in->back()->when);
796 AudioRegion::set_fade_out_shape (FadeShape shape)
798 set_fade_out (shape, (nframes_t) _fade_out->back()->when);
802 AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
808 send_change (FadeInChanged);
812 AudioRegion::set_fade_in (FadeShape shape, nframes_t len)
819 _fade_in->fast_simple_add (0.0, 0.0);
820 _fade_in->fast_simple_add (len, 1.0);
824 _fade_in->fast_simple_add (0, 0);
825 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
826 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
827 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
828 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
829 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
830 _fade_in->fast_simple_add (len, 1);
834 _fade_in->fast_simple_add (0, 0);
835 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
836 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
837 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
838 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
839 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
840 _fade_in->fast_simple_add (len * 0.767281, 1);
841 _fade_in->fast_simple_add (len, 1);
845 _fade_in->fast_simple_add (0, 0);
846 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
847 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
848 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
849 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
850 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
851 _fade_in->fast_simple_add (len, 1);
855 _fade_in->fast_simple_add (0, 0);
856 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
857 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
858 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
859 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
860 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
861 _fade_in->fast_simple_add (len, 1);
869 AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
871 _fade_out->freeze ();
875 send_change (FadeInChanged);
879 AudioRegion::set_fade_out (FadeShape shape, nframes_t len)
881 _fade_out->freeze ();
886 _fade_out->fast_simple_add (len * 0, 1);
887 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
888 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
889 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
890 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
891 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
892 _fade_out->fast_simple_add (len * 1, 0);
896 _fade_out->fast_simple_add (len * 0, 1);
897 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
898 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
899 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
900 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
901 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
902 _fade_out->fast_simple_add (len * 1, 0);
906 _fade_out->fast_simple_add (len * 0, 1);
907 _fade_out->fast_simple_add (len * 0.305556, 1);
908 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
909 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
910 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
911 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
912 _fade_out->fast_simple_add (len * 1, 0);
916 _fade_out->fast_simple_add (len * 0, 1);
917 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
918 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
919 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
920 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
921 _fade_out->fast_simple_add (len * 1, 0);
925 _fade_out->fast_simple_add (len * 0, 1);
926 _fade_out->fast_simple_add (len * 1, 0);
934 AudioRegion::set_fade_in_length (nframes_t len)
940 bool changed = _fade_in->extend_to (len);
943 _flags = Flag (_flags & ~DefaultFadeIn);
944 send_change (FadeInChanged);
949 AudioRegion::set_fade_out_length (nframes_t len)
955 bool changed = _fade_out->extend_to (len);
958 _flags = Flag (_flags & ~DefaultFadeOut);
959 send_change (FadeOutChanged);
964 AudioRegion::set_fade_in_active (bool yn)
966 if (yn == (_flags & FadeIn)) {
970 _flags = Flag (_flags|FadeIn);
972 _flags = Flag (_flags & ~FadeIn);
975 send_change (FadeInActiveChanged);
979 AudioRegion::set_fade_out_active (bool yn)
981 if (yn == (_flags & FadeOut)) {
985 _flags = Flag (_flags | FadeOut);
987 _flags = Flag (_flags & ~FadeOut);
990 send_change (FadeOutActiveChanged);
994 AudioRegion::fade_in_is_default () const
996 return _fade_in->size() == 2 && _fade_in->front()->when == 0 && _fade_in->back()->when == 64;
1000 AudioRegion::fade_out_is_default () const
1002 return _fade_out->size() == 2 && _fade_out->front()->when == 0 && _fade_out->back()->when == 64;
1006 AudioRegion::set_default_fade_in ()
1008 _fade_in_disabled = 0;
1009 set_fade_in (Linear, 64);
1013 AudioRegion::set_default_fade_out ()
1015 _fade_out_disabled = 0;
1016 set_fade_out (Linear, 64);
1020 AudioRegion::set_default_fades ()
1022 set_default_fade_in ();
1023 set_default_fade_out ();
1027 AudioRegion::set_default_envelope ()
1029 _envelope->freeze ();
1030 _envelope->clear ();
1031 _envelope->fast_simple_add (0, 1.0f);
1032 _envelope->fast_simple_add (_length, 1.0f);
1037 AudioRegion::recompute_at_end ()
1039 /* our length has changed. recompute a new final point by interpolating
1040 based on the the existing curve.
1043 _envelope->freeze ();
1044 _envelope->truncate_end (_length);
1045 _envelope->set_max_xval (_length);
1048 if (_fade_in->back()->when > _length) {
1049 _fade_in->extend_to (_length);
1050 send_change (FadeInChanged);
1053 if (_fade_out->back()->when > _length) {
1054 _fade_out->extend_to (_length);
1055 send_change (FadeOutChanged);
1060 AudioRegion::recompute_at_start ()
1062 /* as above, but the shift was from the front */
1064 _envelope->truncate_start (_length);
1066 if (_fade_in->back()->when > _length) {
1067 _fade_in->extend_to (_length);
1068 send_change (FadeInChanged);
1071 if (_fade_out->back()->when > _length) {
1072 _fade_out->extend_to (_length);
1073 send_change (FadeOutChanged);
1078 AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr<Region> >& v) const
1084 if (_sources.size() < 2) {
1088 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
1090 srcs.push_back (*i);
1094 if (_sources.size() == 2) {
1102 new_name += ('0' + n + 1);
1105 /* create a copy with just one source. prevent if from being thought of as
1106 "whole file" even if it covers the entire source file(s).
1109 Flag f = Flag (_flags & ~WholeFile);
1111 v.push_back(RegionFactory::create (srcs, _start, _length, new_name, _layer, f));
1120 AudioRegion::read_raw_internal (Sample* buf, sframes_t pos, nframes_t cnt, int channel) const
1122 return audio_source()->read (buf, pos, cnt, channel);
1126 AudioRegion::exportme (Session& /*session*/, ARDOUR::ExportSpecification& /*spec*/)
1129 // const nframes_t blocksize = 4096;
1130 // nframes_t to_read;
1133 // spec.channels = _sources.size();
1135 // if (spec.prepare (blocksize, session.frame_rate())) {
1140 // spec.total_frames = _length;
1142 // while (spec.pos < _length && !spec.stop) {
1145 // /* step 1: interleave */
1147 // to_read = min (_length - spec.pos, blocksize);
1149 // if (spec.channels == 1) {
1151 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1157 // Sample buf[blocksize];
1159 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1161 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1165 // for (nframes_t x = 0; x < to_read; ++x) {
1166 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1171 // if (spec.process (to_read)) {
1175 // spec.pos += to_read;
1176 // spec.progress = (double) spec.pos /_length;
1183 // spec.running = false;
1184 // spec.status = status;
1192 AudioRegion::set_scale_amplitude (gain_t g)
1194 boost::shared_ptr<Playlist> pl (playlist());
1196 _scale_amplitude = g;
1198 /* tell the diskstream we're in */
1201 pl->ContentsChanged();
1204 /* tell everybody else */
1206 send_change (ScaleAmplitudeChanged);
1210 AudioRegion::normalize_to (float target_dB)
1212 const nframes_t blocksize = 64 * 1024;
1213 Sample buf[blocksize];
1218 gain_t target = dB_to_coefficient (target_dB);
1220 if (target == 1.0f) {
1221 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1222 that we may have clipped.
1224 target -= FLT_EPSILON;
1228 fend = _start + _length;
1230 /* first pass: find max amplitude */
1232 while (fpos < fend) {
1236 to_read = min (fend - fpos, blocksize);
1238 for (n = 0; n < n_channels(); ++n) {
1242 if (read_raw_internal (buf, fpos, to_read, 0) != to_read) {
1246 maxamp = compute_peak (buf, to_read, maxamp);
1252 if (maxamp == 0.0f) {
1253 /* don't even try */
1257 if (maxamp == target) {
1258 /* we can't do anything useful */
1262 /* compute scale factor */
1264 _scale_amplitude = target/maxamp;
1266 /* tell the diskstream we're in */
1268 boost::shared_ptr<Playlist> pl (playlist());
1271 pl->ContentsChanged();
1274 /* tell everybody else */
1276 send_change (ScaleAmplitudeChanged);
1280 AudioRegion::fade_in_changed ()
1282 send_change (FadeInChanged);
1286 AudioRegion::fade_out_changed ()
1288 send_change (FadeOutChanged);
1292 AudioRegion::envelope_changed ()
1294 send_change (EnvelopeChanged);
1298 AudioRegion::suspend_fade_in ()
1300 if (++_fade_in_disabled == 1) {
1301 if (fade_in_is_default()) {
1302 set_fade_in_active (false);
1308 AudioRegion::resume_fade_in ()
1310 if (--_fade_in_disabled == 0 && _fade_in_disabled) {
1311 set_fade_in_active (true);
1316 AudioRegion::suspend_fade_out ()
1318 if (++_fade_out_disabled == 1) {
1319 if (fade_out_is_default()) {
1320 set_fade_out_active (false);
1326 AudioRegion::resume_fade_out ()
1328 if (--_fade_out_disabled == 0 &&_fade_out_disabled) {
1329 set_fade_out_active (true);
1334 AudioRegion::speed_mismatch (float sr) const
1336 if (_sources.empty()) {
1337 /* impossible, but ... */
1341 float fsr = audio_source()->sample_rate();
1347 AudioRegion::source_offset_changed ()
1349 /* XXX this fixes a crash that should not occur. It does occur
1350 becauses regions are not being deleted when a session
1351 is unloaded. That bug must be fixed.
1354 if (_sources.empty()) {
1358 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1360 if (afs && afs->destructive()) {
1361 // set_start (source()->natural_position(), this);
1362 set_position (source()->natural_position(), this);
1366 boost::shared_ptr<AudioSource>
1367 AudioRegion::audio_source (uint32_t n) const
1369 // Guaranteed to succeed (use a static cast for speed?)
1370 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1374 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1376 boost::shared_ptr<Playlist> pl = playlist();
1382 if (_valid_transients && !force_new) {
1383 results = _transients;
1387 SourceList::iterator s;
1389 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1390 if (!(*s)->has_been_analysed()) {
1391 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1396 if (s == _sources.end()) {
1397 /* all sources are analyzed, merge data from each one */
1399 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1401 /* find the set of transients within the bounds of this region */
1403 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1404 (*s)->transients.end(),
1407 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1408 (*s)->transients.end(),
1413 results.insert (results.end(), low, high);
1416 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1418 /* translate all transients to current position */
1420 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1425 _transients = results;
1426 _valid_transients = true;
1431 /* no existing/complete transient info */
1433 if (!Config->get_auto_analyse_audio()) {
1434 pl->session().Dialog (_("\
1435 You have requested an operation that requires audio analysis.\n\n\
1436 You currently have \"auto-analyse-audio\" disabled, which means\n\
1437 that transient data must be generated every time it is required.\n\n\
1438 If you are doing work that will require transient data on a\n\
1439 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1440 then quit ardour and restart."));
1443 TransientDetector t (pl->session().frame_rate());
1444 bool existing_results = !results.empty();
1446 _transients.clear ();
1447 _valid_transients = false;
1449 for (uint32_t i = 0; i < n_channels(); ++i) {
1451 AnalysisFeatureList these_results;
1455 if (t.run ("", this, i, these_results)) {
1459 /* translate all transients to give absolute position */
1461 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1467 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1470 if (!results.empty()) {
1471 if (existing_results) {
1473 /* merge our transients into the existing ones, then clean up
1477 results.insert (results.end(), _transients.begin(), _transients.end());
1478 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1481 /* make sure ours are clean too */
1483 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1487 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1488 results = _transients;
1491 _valid_transients = true;
1496 /** Find areas of `silence' within a region.
1498 * @param threshold Threshold below which signal is considered silence (as a sample value)
1499 * @param min_length Minimum length of silent period to be reported.
1500 * @return Silent periods; first of pair is the offset within the region, second is the length of the period
1503 std::list<std::pair<nframes_t, nframes_t> >
1504 AudioRegion::find_silence (Sample threshold, nframes_t min_length) const
1506 nframes_t const block_size = 64 * 1024;
1507 Sample loudest[block_size];
1508 Sample buf[block_size];
1510 nframes_t pos = _start;
1511 nframes_t const end = _start + _length - 1;
1513 std::list<std::pair<nframes_t, nframes_t> > silent_periods;
1515 bool in_silence = false;
1516 nframes_t silence_start = 0;
1521 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1522 memset (loudest, 0, sizeof (Sample) * block_size);
1523 for (uint32_t n = 0; n < n_channels(); ++n) {
1525 read_raw_internal (buf, pos, block_size, n);
1526 for (nframes_t i = 0; i < block_size; ++i) {
1527 loudest[i] = max (loudest[i], abs (buf[i]));
1531 /* now look for silence */
1532 for (nframes_t i = 0; i < block_size; ++i) {
1533 silence = abs (loudest[i]) < threshold;
1534 if (silence && !in_silence) {
1535 /* non-silence to silence */
1537 silence_start = pos + i;
1538 } else if (!silence && in_silence) {
1539 /* silence to non-silence */
1541 if (pos + i - 1 - silence_start >= min_length) {
1542 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1550 if (in_silence && end - 1 - silence_start >= min_length) {
1551 /* last block was silent, so finish off the last period */
1552 silent_periods.push_back (std::make_pair (silence_start, end));
1555 return silent_periods;
1561 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)
1563 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (nframes_t) npeaks, (nframes_t) start, (nframes_t) cnt, n_chan,samples_per_unit);
1566 uint32_t region_length_from_c (void *arg)
1569 return ((AudioRegion *) arg)->length();
1572 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1574 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;