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 <boost/scoped_array.hpp>
29 #include <glibmm/thread.h>
31 #include "pbd/basename.h"
32 #include "pbd/xml++.h"
33 #include "pbd/stacktrace.h"
34 #include "pbd/enumwriter.h"
35 #include "pbd/convert.h"
37 #include "evoral/Curve.hpp"
39 #include "ardour/audioregion.h"
40 #include "ardour/debug.h"
41 #include "ardour/session.h"
42 #include "ardour/dB.h"
43 #include "ardour/playlist.h"
44 #include "ardour/audiofilesource.h"
45 #include "ardour/region_factory.h"
46 #include "ardour/runtime_functions.h"
47 #include "ardour/transient_detector.h"
48 #include "ardour/progress.h"
54 using namespace ARDOUR;
58 namespace Properties {
59 PBD::PropertyDescriptor<bool> envelope_active;
60 PBD::PropertyDescriptor<bool> default_fade_in;
61 PBD::PropertyDescriptor<bool> default_fade_out;
62 PBD::PropertyDescriptor<bool> fade_in_active;
63 PBD::PropertyDescriptor<bool> fade_out_active;
64 PBD::PropertyDescriptor<float> scale_amplitude;
69 AudioRegion::make_property_quarks ()
71 Properties::envelope_active.property_id = g_quark_from_static_string (X_("envelope-active"));
72 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for envelope-active = %1\n", Properties::envelope_active.property_id));
73 Properties::default_fade_in.property_id = g_quark_from_static_string (X_("default-fade-in"));
74 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for default-fade-in = %1\n", Properties::default_fade_in.property_id));
75 Properties::default_fade_out.property_id = g_quark_from_static_string (X_("default-fade-out"));
76 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for default-fade-out = %1\n", Properties::default_fade_out.property_id));
77 Properties::fade_in_active.property_id = g_quark_from_static_string (X_("fade-in-active"));
78 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for fade-in-active = %1\n", Properties::fade_in_active.property_id));
79 Properties::fade_out_active.property_id = g_quark_from_static_string (X_("fade-out-active"));
80 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for fade-out-active = %1\n", Properties::fade_out_active.property_id));
81 Properties::scale_amplitude.property_id = g_quark_from_static_string (X_("scale-amplitude"));
82 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for scale-amplitude = %1\n", Properties::scale_amplitude.property_id));
86 AudioRegion::register_properties ()
88 /* no need to register parent class properties */
90 add_property (_envelope_active);
91 add_property (_default_fade_in);
92 add_property (_default_fade_out);
93 add_property (_fade_in_active);
94 add_property (_fade_out_active);
95 add_property (_scale_amplitude);
98 #define AUDIOREGION_STATE_DEFAULT \
99 _envelope_active (Properties::envelope_active, false) \
100 , _default_fade_in (Properties::default_fade_in, true) \
101 , _default_fade_out (Properties::default_fade_out, true) \
102 , _fade_in_active (Properties::fade_in_active, true) \
103 , _fade_out_active (Properties::fade_out_active, true) \
104 , _scale_amplitude (Properties::scale_amplitude, 1.0)
106 #define AUDIOREGION_COPY_STATE(other) \
107 _envelope_active (Properties::envelope_active, other->_envelope_active) \
108 , _default_fade_in (Properties::default_fade_in, other->_default_fade_in) \
109 , _default_fade_out (Properties::default_fade_out, other->_default_fade_out) \
110 , _fade_in_active (Properties::fade_in_active, other->_fade_in_active) \
111 , _fade_out_active (Properties::fade_out_active, other->_fade_out_active) \
112 , _scale_amplitude (Properties::scale_amplitude, other->_scale_amplitude)
113 /* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
118 register_properties ();
120 suspend_property_changes();
121 set_default_fades ();
122 set_default_envelope ();
123 resume_property_changes();
125 listen_to_my_curves ();
126 connect_to_analysis_changed ();
127 connect_to_header_position_offset_changed ();
130 /** Constructor for use by derived types only */
131 AudioRegion::AudioRegion (Session& s, framepos_t start, framecnt_t len, std::string name)
132 : Region (s, start, len, name, DataType::AUDIO)
133 , AUDIOREGION_STATE_DEFAULT
135 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
136 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
137 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
138 , _fade_in_suspended (0)
139 , _fade_out_suspended (0)
142 assert (_sources.size() == _master_sources.size());
145 /** Basic AudioRegion constructor */
146 AudioRegion::AudioRegion (const SourceList& srcs)
148 , AUDIOREGION_STATE_DEFAULT
149 , _automatable(srcs[0]->session())
150 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
151 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
152 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
153 , _fade_in_suspended (0)
154 , _fade_out_suspended (0)
157 assert (_sources.size() == _master_sources.size());
160 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
162 , AUDIOREGION_COPY_STATE (other)
163 , _automatable (other->session())
164 , _fade_in (new AutomationList (*other->_fade_in))
165 , _fade_out (new AutomationList (*other->_fade_out))
166 /* As far as I can see, the _envelope's times are relative to region position, and have nothing
167 to do with sources (and hence _start). So when we copy the envelope, we just use the supplied offset.
169 , _envelope (new AutomationList (*other->_envelope, 0, other->_length))
170 , _fade_in_suspended (0)
171 , _fade_out_suspended (0)
173 /* don't use init here, because we got fade in/out from the other region
175 register_properties ();
176 listen_to_my_curves ();
177 connect_to_analysis_changed ();
178 connect_to_header_position_offset_changed ();
180 assert(_type == DataType::AUDIO);
181 assert (_sources.size() == _master_sources.size());
184 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, framecnt_t offset)
185 : Region (other, offset)
186 , AUDIOREGION_COPY_STATE (other)
187 , _automatable (other->session())
188 , _fade_in (new AutomationList (*other->_fade_in))
189 , _fade_out (new AutomationList (*other->_fade_out))
190 /* As far as I can see, the _envelope's times are relative to region position, and have nothing
191 to do with sources (and hence _start). So when we copy the envelope, we just use the supplied offset.
193 , _envelope (new AutomationList (*other->_envelope, offset, other->_length))
194 , _fade_in_suspended (0)
195 , _fade_out_suspended (0)
197 /* don't use init here, because we got fade in/out from the other region
199 register_properties ();
200 listen_to_my_curves ();
201 connect_to_analysis_changed ();
202 connect_to_header_position_offset_changed ();
204 assert(_type == DataType::AUDIO);
205 assert (_sources.size() == _master_sources.size());
208 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& srcs)
209 : Region (boost::static_pointer_cast<const Region>(other), srcs)
210 , AUDIOREGION_COPY_STATE (other)
211 , _automatable (other->session())
212 , _fade_in (new AutomationList (*other->_fade_in))
213 , _fade_out (new AutomationList (*other->_fade_out))
214 , _envelope (new AutomationList (*other->_envelope))
215 , _fade_in_suspended (0)
216 , _fade_out_suspended (0)
218 /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
220 register_properties ();
222 listen_to_my_curves ();
223 connect_to_analysis_changed ();
224 connect_to_header_position_offset_changed ();
226 assert (_sources.size() == _master_sources.size());
229 AudioRegion::AudioRegion (SourceList& srcs)
231 , AUDIOREGION_STATE_DEFAULT
232 , _automatable(srcs[0]->session())
233 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
234 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
235 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
236 , _fade_in_suspended (0)
237 , _fade_out_suspended (0)
241 assert(_type == DataType::AUDIO);
242 assert (_sources.size() == _master_sources.size());
245 AudioRegion::~AudioRegion ()
250 AudioRegion::post_set (const PropertyChange& /*ignored*/)
253 _sync_position = _start;
256 /* return to default fades if the existing ones are too long */
258 if (_left_of_split) {
259 if (_fade_in->back()->when >= _length) {
260 set_default_fade_in ();
262 set_default_fade_out ();
263 _left_of_split = false;
266 if (_right_of_split) {
267 if (_fade_out->back()->when >= _length) {
268 set_default_fade_out ();
271 set_default_fade_in ();
272 _right_of_split = false;
275 /* If _length changed, adjust our gain envelope accordingly */
276 _envelope->truncate_end (_length);
280 AudioRegion::connect_to_analysis_changed ()
282 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
283 (*i)->AnalysisChanged.connect_same_thread (*this, boost::bind (&AudioRegion::invalidate_transients, this));
288 AudioRegion::connect_to_header_position_offset_changed ()
290 set<boost::shared_ptr<Source> > unique_srcs;
292 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
294 /* connect only once to HeaderPositionOffsetChanged, even if sources are replicated
297 if (unique_srcs.find (*i) == unique_srcs.end ()) {
298 unique_srcs.insert (*i);
299 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
301 afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
308 AudioRegion::listen_to_my_curves ()
310 _envelope->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::envelope_changed, this));
311 _fade_in->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_in_changed, this));
312 _fade_out->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_out_changed, this));
316 AudioRegion::set_envelope_active (bool yn)
318 if (envelope_active() != yn) {
319 _envelope_active = yn;
320 send_change (PropertyChange (Properties::envelope_active));
325 AudioRegion::read_peaks (PeakData *buf, framecnt_t npeaks, framecnt_t offset, framecnt_t cnt, uint32_t chan_n, double samples_per_unit) const
327 if (chan_n >= _sources.size()) {
331 if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
334 if (_scale_amplitude != 1.0f) {
335 for (framecnt_t n = 0; n < npeaks; ++n) {
336 buf[n].max *= _scale_amplitude;
337 buf[n].min *= _scale_amplitude;
345 AudioRegion::read (Sample* buf, framepos_t timeline_position, framecnt_t cnt, int channel) const
347 /* raw read, no fades, no gain, nada */
348 return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, ReadOps (0));
352 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
353 framepos_t file_position, framecnt_t cnt, uint32_t chan_n) 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, ReadOps (~0));
361 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
362 framepos_t position, framecnt_t cnt, uint32_t chan_n) const
364 /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
368 return _read_at (_master_sources, _master_sources.front()->length(_master_sources.front()->timeline_position()),
369 buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, ReadOps (0));
372 /** @param position Position within the session */
374 AudioRegion::_read_at (const SourceList& srcs, framecnt_t limit,
375 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
383 frameoffset_t internal_offset;
384 frameoffset_t buf_offset;
386 bool raw = (rops == ReadOpsNone);
388 if (n_channels() == 0) {
392 if (muted() && !raw) {
393 return 0; /* read nothing */
396 /* precondition: caller has verified that we cover the desired section */
398 if (position < _position) {
400 buf_offset = _position - position;
401 /* if this fails then the requested section is entirely
402 before the position of this region. An error in xfade
403 construction that was fixed in oct 2011 (rev 10259)
404 led to this being the case. We don't want to crash
405 when this error is encountered, so just settle
406 on displaying an error.
408 if (cnt < buf_offset) {
409 error << "trying to read region " << name() << " @ " << position << " which is outside region bounds "
410 << _position << " .. " << last_frame() << " (len = " << length() << ')'
412 return 0; // read nothing
416 internal_offset = position - _position;
420 if (internal_offset >= limit) {
421 return 0; /* read nothing */
424 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
425 return 0; /* read nothing */
428 if (opaque() || raw) {
429 /* overwrite whatever is there */
430 mixdown_buffer = buf + buf_offset;
432 mixdown_buffer += buf_offset;
435 if (chan_n < n_channels()) {
437 boost::shared_ptr<AudioSource> src = boost::dynamic_pointer_cast<AudioSource> (srcs[chan_n]);
438 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
439 return 0; /* "read nothing" */
444 /* track is N-channel, this region has less channels; silence the ones
448 if (Config->get_replicate_missing_region_channels()) {
449 /* track is N-channel, this region has less channels, so use a relevant channel
452 uint32_t channel = n_channels() % chan_n;
453 boost::shared_ptr<AudioSource> src = boost::dynamic_pointer_cast<AudioSource> (srcs[channel]);
455 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
456 return 0; /* "read nothing" */
460 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
464 if (rops & ReadOpsFades) {
468 if (_fade_in_active && _session.config.get_use_region_fades()) {
470 framecnt_t fade_in_length = (framecnt_t) _fade_in->back()->when;
472 /* see if this read is within the fade in */
474 if (internal_offset < fade_in_length) {
478 fi_limit = min (to_read, fade_in_length - internal_offset);
480 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
482 for (framecnt_t n = 0; n < fi_limit; ++n) {
483 mixdown_buffer[n] *= gain_buffer[n];
490 if (_fade_out_active && _session.config.get_use_region_fades()) {
492 /* see if some part of this read is within the fade out */
494 /* ................. >| REGION
500 limit - fade_out_length
503 ^internal_offset + to_read
505 we need the intersection of [internal_offset,internal_offset+to_read] with
506 [limit - fade_out_length, limit]
511 framecnt_t fade_out_length = (framecnt_t) _fade_out->back()->when;
512 framecnt_t fade_interval_start = max(internal_offset, limit-fade_out_length);
513 framecnt_t fade_interval_end = min(internal_offset + to_read, limit);
515 if (fade_interval_end > fade_interval_start) {
516 /* (part of the) the fade out is in this buffer */
518 framecnt_t fo_limit = fade_interval_end - fade_interval_start;
519 framecnt_t curve_offset = fade_interval_start - (limit-fade_out_length);
520 framecnt_t fade_offset = fade_interval_start - internal_offset;
522 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
524 for (framecnt_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
525 mixdown_buffer[m] *= gain_buffer[n];
532 /* Regular gain curves and scaling */
534 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
535 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
537 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
538 for (framecnt_t n = 0; n < to_read; ++n) {
539 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
542 for (framecnt_t n = 0; n < to_read; ++n) {
543 mixdown_buffer[n] *= gain_buffer[n];
546 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
548 // XXX this should be using what in 2.0 would have been:
549 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
551 for (framecnt_t n = 0; n < to_read; ++n) {
552 mixdown_buffer[n] *= _scale_amplitude;
556 if (!opaque() && (buf != mixdown_buffer)) {
558 /* gack. the things we do for users.
563 for (framecnt_t n = 0; n < to_read; ++n) {
564 buf[n] += mixdown_buffer[n];
572 AudioRegion::state ()
574 XMLNode& node (Region::state ());
577 LocaleGuard lg (X_("POSIX"));
579 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
580 node.add_property ("channels", buf);
582 Stateful::add_properties (node);
584 child = node.add_child ("Envelope");
586 bool default_env = false;
588 // If there are only two points, the points are in the start of the region and the end of the region
589 // so, if they are both at 1.0f, that means the default region.
591 if (_envelope->size() == 2 &&
592 _envelope->front()->value == 1.0f &&
593 _envelope->back()->value==1.0f) {
594 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
600 child->add_property ("default", "yes");
602 child->add_child_nocopy (_envelope->get_state ());
605 child = node.add_child (X_("FadeIn"));
607 if (_default_fade_in) {
608 child->add_property ("default", "yes");
610 child->add_child_nocopy (_fade_in->get_state ());
613 child = node.add_child (X_("FadeOut"));
615 if (_default_fade_out) {
616 child->add_property ("default", "yes");
618 child->add_child_nocopy (_fade_out->get_state ());
625 AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_changed, bool send)
627 const XMLNodeList& nlist = node.children();
628 const XMLProperty *prop;
629 LocaleGuard lg (X_("POSIX"));
630 boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
632 suspend_property_changes ();
635 the_playlist->freeze ();
639 /* this will set all our State members and stuff controlled by the Region.
640 It should NOT send any changed signals - that is our responsibility.
643 Region::_set_state (node, version, what_changed, false);
645 if ((prop = node.property ("scale-gain")) != 0) {
646 float a = atof (prop->value().c_str());
647 if (a != _scale_amplitude) {
648 _scale_amplitude = a;
649 what_changed.add (Properties::scale_amplitude);
653 /* Now find envelope description and other related child items */
655 _envelope->freeze ();
657 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
663 if (child->name() == "Envelope") {
667 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child, version)) {
668 set_default_envelope ();
671 _envelope->set_max_xval (_length);
672 _envelope->truncate_end (_length);
675 } else if (child->name() == "FadeIn") {
679 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
680 set_default_fade_in ();
682 XMLNode* grandchild = child->child ("AutomationList");
684 _fade_in->set_state (*grandchild, version);
688 if ((prop = child->property ("active")) != 0) {
689 if (string_is_affirmative (prop->value())) {
690 set_fade_in_active (true);
692 set_fade_in_active (false);
696 } else if (child->name() == "FadeOut") {
700 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
701 set_default_fade_out ();
703 XMLNode* grandchild = child->child ("AutomationList");
705 _fade_out->set_state (*grandchild, version);
709 if ((prop = child->property ("active")) != 0) {
710 if (string_is_affirmative (prop->value())) {
711 set_fade_out_active (true);
713 set_fade_out_active (false);
721 resume_property_changes ();
724 send_change (what_changed);
728 the_playlist->thaw ();
735 AudioRegion::set_state (const XMLNode& node, int version)
737 PropertyChange what_changed;
738 return _set_state (node, version, what_changed, true);
742 AudioRegion::set_fade_in_shape (FadeShape shape)
744 set_fade_in (shape, (framecnt_t) _fade_in->back()->when);
748 AudioRegion::set_fade_out_shape (FadeShape shape)
750 set_fade_out (shape, (framecnt_t) _fade_out->back()->when);
754 AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
760 send_change (PropertyChange (Properties::fade_in));
764 AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
771 _fade_in->fast_simple_add (0.0, 0.0);
772 _fade_in->fast_simple_add (len, 1.0);
776 _fade_in->fast_simple_add (0, 0);
777 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
778 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
779 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
780 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
781 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
782 _fade_in->fast_simple_add (len, 1);
786 _fade_in->fast_simple_add (0, 0);
787 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
788 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
789 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
790 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
791 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
792 _fade_in->fast_simple_add (len * 0.767281, 1);
793 _fade_in->fast_simple_add (len, 1);
797 _fade_in->fast_simple_add (0, 0);
798 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
799 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
800 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
801 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
802 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
803 _fade_in->fast_simple_add (len, 1);
807 _fade_in->fast_simple_add (0, 0);
808 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
809 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
810 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
811 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
812 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
813 _fade_in->fast_simple_add (len, 1);
818 send_change (PropertyChange (Properties::fade_in));
822 AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
824 _fade_out->freeze ();
828 send_change (PropertyChange (Properties::fade_in));
832 AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
834 _fade_out->freeze ();
839 _fade_out->fast_simple_add (len * 0, 1);
840 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
841 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
842 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
843 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
844 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
845 _fade_out->fast_simple_add (len * 1, 0);
849 _fade_out->fast_simple_add (len * 0, 1);
850 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
851 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
852 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
853 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
854 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
855 _fade_out->fast_simple_add (len * 1, 0);
859 _fade_out->fast_simple_add (len * 0, 1);
860 _fade_out->fast_simple_add (len * 0.305556, 1);
861 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
862 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
863 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
864 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
865 _fade_out->fast_simple_add (len * 1, 0);
869 _fade_out->fast_simple_add (len * 0, 1);
870 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
871 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
872 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
873 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
874 _fade_out->fast_simple_add (len * 1, 0);
878 _fade_out->fast_simple_add (len * 0, 1);
879 _fade_out->fast_simple_add (len * 1, 0);
884 send_change (PropertyChange (Properties::fade_in));
888 AudioRegion::set_fade_in_length (framecnt_t len)
894 bool changed = _fade_in->extend_to (len);
897 _default_fade_in = false;
898 send_change (PropertyChange (Properties::fade_in));
903 AudioRegion::set_fade_out_length (framecnt_t len)
909 bool changed = _fade_out->extend_to (len);
912 _default_fade_out = false;
913 send_change (PropertyChange (Properties::fade_out));
918 AudioRegion::set_fade_in_active (bool yn)
920 if (yn == _fade_in_active) {
924 _fade_in_active = yn;
925 send_change (PropertyChange (Properties::fade_in_active));
929 AudioRegion::set_fade_out_active (bool yn)
931 if (yn == _fade_out_active) {
934 _fade_out_active = yn;
935 send_change (PropertyChange (Properties::fade_out_active));
939 AudioRegion::fade_in_is_default () const
941 return _fade_in->size() == 2 && _fade_in->front()->when == 0 && _fade_in->back()->when == 64;
945 AudioRegion::fade_out_is_default () const
947 return _fade_out->size() == 2 && _fade_out->front()->when == 0 && _fade_out->back()->when == 64;
951 AudioRegion::set_default_fade_in ()
953 _fade_in_suspended = 0;
954 set_fade_in (FadeLinear, 64);
958 AudioRegion::set_default_fade_out ()
960 _fade_out_suspended = 0;
961 set_fade_out (FadeLinear, 64);
965 AudioRegion::set_default_fades ()
967 set_default_fade_in ();
968 set_default_fade_out ();
972 AudioRegion::set_default_envelope ()
974 _envelope->freeze ();
976 _envelope->fast_simple_add (0, 1.0f);
977 _envelope->fast_simple_add (_length, 1.0f);
982 AudioRegion::recompute_at_end ()
984 /* our length has changed. recompute a new final point by interpolating
985 based on the the existing curve.
988 _envelope->freeze ();
989 _envelope->truncate_end (_length);
990 _envelope->set_max_xval (_length);
993 suspend_property_changes();
995 if (_left_of_split) {
996 set_default_fade_out ();
997 _left_of_split = false;
998 } else if (_fade_out->back()->when > _length) {
999 _fade_out->extend_to (_length);
1000 send_change (PropertyChange (Properties::fade_out));
1003 if (_fade_in->back()->when > _length) {
1004 _fade_in->extend_to (_length);
1005 send_change (PropertyChange (Properties::fade_in));
1008 resume_property_changes();
1012 AudioRegion::recompute_at_start ()
1014 /* as above, but the shift was from the front */
1016 _envelope->truncate_start (_length);
1018 suspend_property_changes();
1020 if (_right_of_split) {
1021 set_default_fade_in ();
1022 _right_of_split = false;
1023 } else if (_fade_in->back()->when > _length) {
1024 _fade_in->extend_to (_length);
1025 send_change (PropertyChange (Properties::fade_in));
1028 if (_fade_out->back()->when > _length) {
1029 _fade_out->extend_to (_length);
1030 send_change (PropertyChange (Properties::fade_out));
1033 resume_property_changes();
1037 AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr<Region> >& v) const
1043 if (_sources.size() < 2) {
1047 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
1049 srcs.push_back (*i);
1053 if (_sources.size() == 2) {
1061 new_name += ('0' + n + 1);
1064 /* create a copy with just one source. prevent if from being thought of as
1065 "whole file" even if it covers the entire source file(s).
1070 plist.add (Properties::start, _start.val());
1071 plist.add (Properties::length, _length.val());
1072 plist.add (Properties::name, new_name);
1073 plist.add (Properties::layer, layer ());
1075 v.push_back(RegionFactory::create (srcs, plist));
1076 v.back()->set_whole_file (false);
1085 AudioRegion::read_raw_internal (Sample* buf, framepos_t pos, framecnt_t cnt, int channel) const
1087 return audio_source(channel)->read (buf, pos, cnt);
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 */
1100 pl->ContentsChanged();
1103 /* tell everybody else */
1105 send_change (PropertyChange (Properties::scale_amplitude));
1108 /** @return the maximum (linear) amplitude of the region, or a -ve
1109 * number if the Progress object reports that the process was cancelled.
1112 AudioRegion::maximum_amplitude (Progress* p) const
1114 framepos_t fpos = _start;
1115 framepos_t const fend = _start + _length;
1118 framecnt_t const blocksize = 64 * 1024;
1119 Sample buf[blocksize];
1121 while (fpos < fend) {
1125 framecnt_t const to_read = min (fend - fpos, blocksize);
1127 for (n = 0; n < n_channels(); ++n) {
1131 if (read_raw_internal (buf, fpos, to_read, n) != to_read) {
1135 maxamp = compute_peak (buf, to_read, maxamp);
1140 p->set_progress (float (fpos - _start) / _length);
1141 if (p->cancelled ()) {
1150 /** Normalize using a given maximum amplitude and target, so that region
1151 * _scale_amplitude becomes target / max_amplitude.
1154 AudioRegion::normalize (float max_amplitude, float target_dB)
1156 gain_t target = dB_to_coefficient (target_dB);
1158 if (target == 1.0f) {
1159 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1160 that we may have clipped.
1162 target -= FLT_EPSILON;
1165 if (max_amplitude == 0.0f) {
1166 /* don't even try */
1170 if (max_amplitude == target) {
1171 /* we can't do anything useful */
1175 set_scale_amplitude (target / max_amplitude);
1179 AudioRegion::fade_in_changed ()
1181 send_change (PropertyChange (Properties::fade_in));
1185 AudioRegion::fade_out_changed ()
1187 send_change (PropertyChange (Properties::fade_out));
1191 AudioRegion::envelope_changed ()
1193 send_change (PropertyChange (Properties::envelope));
1197 AudioRegion::suspend_fade_in ()
1199 if (++_fade_in_suspended == 1) {
1200 if (fade_in_is_default()) {
1201 set_fade_in_active (false);
1207 AudioRegion::resume_fade_in ()
1209 if (--_fade_in_suspended == 0 && _fade_in_suspended) {
1210 set_fade_in_active (true);
1215 AudioRegion::suspend_fade_out ()
1217 if (++_fade_out_suspended == 1) {
1218 if (fade_out_is_default()) {
1219 set_fade_out_active (false);
1225 AudioRegion::resume_fade_out ()
1227 if (--_fade_out_suspended == 0 &&_fade_out_suspended) {
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());
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::adjust_transients (frameoffset_t delta)
1275 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1276 (*x) = (*x) + delta;
1279 send_change (PropertyChange (Properties::valid_transients));
1285 AudioRegion::update_transient (framepos_t old_position, framepos_t new_position)
1287 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1288 if ((*x) == old_position) {
1289 (*x) = new_position;
1290 send_change (PropertyChange (Properties::valid_transients));
1300 AudioRegion::add_transient (framepos_t where)
1302 _transients.push_back(where);
1303 _valid_transients = true;
1305 send_change (PropertyChange (Properties::valid_transients));
1309 AudioRegion::remove_transient (framepos_t where)
1311 _transients.remove(where);
1312 _valid_transients = true;
1314 send_change (PropertyChange (Properties::valid_transients));
1318 AudioRegion::set_transients (AnalysisFeatureList& results)
1320 _transients.clear();
1321 _transients = results;
1322 _valid_transients = true;
1324 send_change (PropertyChange (Properties::valid_transients));
1330 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1332 boost::shared_ptr<Playlist> pl = playlist();
1338 if (_valid_transients && !force_new) {
1339 results = _transients;
1343 SourceList::iterator s;
1345 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1346 if (!(*s)->has_been_analysed()) {
1347 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1352 if (s == _sources.end()) {
1353 /* all sources are analyzed, merge data from each one */
1355 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1357 /* find the set of transients within the bounds of this region */
1359 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1360 (*s)->transients.end(),
1363 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1364 (*s)->transients.end(),
1369 results.insert (results.end(), low, high);
1372 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1374 /* translate all transients to current position */
1376 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1381 _transients = results;
1382 _valid_transients = true;
1387 /* no existing/complete transient info */
1389 static bool analyse_dialog_shown = false; /* global per instance of Ardour */
1391 if (!Config->get_auto_analyse_audio()) {
1392 if (!analyse_dialog_shown) {
1393 pl->session().Dialog (_("\
1394 You have requested an operation that requires audio analysis.\n\n\
1395 You currently have \"auto-analyse-audio\" disabled, which means \
1396 that transient data must be generated every time it is required.\n\n\
1397 If you are doing work that will require transient data on a \
1398 regular basis, you should probably enable \"auto-analyse-audio\" \
1399 then quit ardour and restart.\n\n\
1400 This dialog will not display again. But you may notice a slight delay \
1401 in this and future transient-detection operations.\n\
1403 analyse_dialog_shown = true;
1407 TransientDetector t (pl->session().frame_rate());
1408 bool existing_results = !results.empty();
1410 _transients.clear ();
1411 _valid_transients = false;
1413 for (uint32_t i = 0; i < n_channels(); ++i) {
1415 AnalysisFeatureList these_results;
1419 if (t.run ("", this, i, these_results)) {
1423 /* translate all transients to give absolute position */
1425 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1431 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1434 if (!results.empty()) {
1435 if (existing_results) {
1437 /* merge our transients into the existing ones, then clean up
1441 results.insert (results.end(), _transients.begin(), _transients.end());
1442 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1445 /* make sure ours are clean too */
1447 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1451 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1452 results = _transients;
1455 _valid_transients = true;
1460 /** Find areas of `silence' within a region.
1462 * @param threshold Threshold below which signal is considered silence (as a sample value)
1463 * @param min_length Minimum length of silent period to be reported.
1464 * @return Silent intervals, measured relative to the region start in the source
1468 AudioRegion::find_silence (Sample threshold, framecnt_t min_length, InterThreadInfo& itt) const
1470 framecnt_t const block_size = 64 * 1024;
1471 boost::scoped_array<Sample> loudest (new Sample[block_size]);
1472 boost::scoped_array<Sample> buf (new Sample[block_size]);
1474 framepos_t pos = _start;
1475 framepos_t const end = _start + _length - 1;
1477 AudioIntervalResult silent_periods;
1479 bool in_silence = false;
1480 frameoffset_t silence_start = 0;
1482 while (pos < end && !itt.cancel) {
1484 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1485 memset (loudest.get(), 0, sizeof (Sample) * block_size);
1486 for (uint32_t n = 0; n < n_channels(); ++n) {
1488 read_raw_internal (buf.get(), pos, block_size, n);
1489 for (framecnt_t i = 0; i < block_size; ++i) {
1490 loudest[i] = max (loudest[i], abs (buf[i]));
1494 /* now look for silence */
1495 for (framecnt_t i = 0; i < block_size; ++i) {
1496 bool const silence = abs (loudest[i]) < threshold;
1497 if (silence && !in_silence) {
1498 /* non-silence to silence */
1500 silence_start = pos + i;
1501 } else if (!silence && in_silence) {
1502 /* silence to non-silence */
1504 if (pos + i - 1 - silence_start >= min_length) {
1505 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1511 itt.progress = (end-pos)/(double)_length;
1514 if (in_silence && end - 1 - silence_start >= min_length) {
1515 /* last block was silent, so finish off the last period */
1516 silent_periods.push_back (std::make_pair (silence_start, end));
1521 return silent_periods;
1528 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)
1530 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (framecnt_t) npeaks, (framepos_t) start, (framecnt_t) cnt, n_chan,samples_per_unit);
1533 uint32_t region_length_from_c (void *arg)
1536 return ((AudioRegion *) arg)->length();
1539 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1541 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;