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/gain.h"
43 #include "ardour/dB.h"
44 #include "ardour/playlist.h"
45 #include "ardour/audiofilesource.h"
46 #include "ardour/region_factory.h"
47 #include "ardour/runtime_functions.h"
48 #include "ardour/transient_detector.h"
49 #include "ardour/progress.h"
55 using namespace ARDOUR;
59 namespace Properties {
60 PBD::PropertyDescriptor<bool> envelope_active;
61 PBD::PropertyDescriptor<bool> default_fade_in;
62 PBD::PropertyDescriptor<bool> default_fade_out;
63 PBD::PropertyDescriptor<bool> fade_in_active;
64 PBD::PropertyDescriptor<bool> fade_out_active;
65 PBD::PropertyDescriptor<float> scale_amplitude;
70 AudioRegion::make_property_quarks ()
72 Properties::envelope_active.property_id = g_quark_from_static_string (X_("envelope-active"));
73 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for envelope-active = %1\n", Properties::envelope_active.property_id));
74 Properties::default_fade_in.property_id = g_quark_from_static_string (X_("default-fade-in"));
75 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for default-fade-in = %1\n", Properties::default_fade_in.property_id));
76 Properties::default_fade_out.property_id = g_quark_from_static_string (X_("default-fade-out"));
77 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for default-fade-out = %1\n", Properties::default_fade_out.property_id));
78 Properties::fade_in_active.property_id = g_quark_from_static_string (X_("fade-in-active"));
79 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for fade-in-active = %1\n", Properties::fade_in_active.property_id));
80 Properties::fade_out_active.property_id = g_quark_from_static_string (X_("fade-out-active"));
81 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for fade-out-active = %1\n", Properties::fade_out_active.property_id));
82 Properties::scale_amplitude.property_id = g_quark_from_static_string (X_("scale-amplitude"));
83 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for scale-amplitude = %1\n", Properties::scale_amplitude.property_id));
87 AudioRegion::register_properties ()
89 /* no need to register parent class properties */
91 add_property (_envelope_active);
92 add_property (_default_fade_in);
93 add_property (_default_fade_out);
94 add_property (_fade_in_active);
95 add_property (_fade_out_active);
96 add_property (_scale_amplitude);
99 #define AUDIOREGION_STATE_DEFAULT \
100 _envelope_active (Properties::envelope_active, false) \
101 , _default_fade_in (Properties::default_fade_in, true) \
102 , _default_fade_out (Properties::default_fade_out, true) \
103 , _fade_in_active (Properties::fade_in_active, true) \
104 , _fade_out_active (Properties::fade_out_active, true) \
105 , _scale_amplitude (Properties::scale_amplitude, 1.0)
107 #define AUDIOREGION_COPY_STATE(other) \
108 _envelope_active (Properties::envelope_active, other->_envelope_active) \
109 , _default_fade_in (Properties::default_fade_in, other->_default_fade_in) \
110 , _default_fade_out (Properties::default_fade_out, other->_default_fade_out) \
111 , _fade_in_active (Properties::fade_in_active, other->_fade_in_active) \
112 , _fade_out_active (Properties::fade_out_active, other->_fade_out_active) \
113 , _scale_amplitude (Properties::scale_amplitude, other->_scale_amplitude)
114 /* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
119 register_properties ();
121 suspend_property_changes();
122 set_default_fades ();
123 set_default_envelope ();
124 resume_property_changes();
126 listen_to_my_curves ();
127 connect_to_analysis_changed ();
128 connect_to_header_position_offset_changed ();
131 /** Constructor for use by derived types only */
132 AudioRegion::AudioRegion (Session& s, framepos_t start, framecnt_t len, std::string name)
133 : Region (s, start, len, name, DataType::AUDIO)
134 , AUDIOREGION_STATE_DEFAULT
136 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
137 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
138 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
139 , _fade_in_suspended (0)
140 , _fade_out_suspended (0)
143 assert (_sources.size() == _master_sources.size());
146 /** Basic AudioRegion constructor */
147 AudioRegion::AudioRegion (const SourceList& srcs)
149 , AUDIOREGION_STATE_DEFAULT
150 , _automatable(srcs[0]->session())
151 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
152 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
153 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
154 , _fade_in_suspended (0)
155 , _fade_out_suspended (0)
158 assert (_sources.size() == _master_sources.size());
161 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
163 , AUDIOREGION_COPY_STATE (other)
164 , _automatable (other->session())
165 , _fade_in (new AutomationList (*other->_fade_in))
166 , _fade_out (new AutomationList (*other->_fade_out))
167 /* As far as I can see, the _envelope's times are relative to region position, and have nothing
168 to do with sources (and hence _start). So when we copy the envelope, we just use the supplied offset.
170 , _envelope (new AutomationList (*other->_envelope, 0, other->_length))
171 , _fade_in_suspended (0)
172 , _fade_out_suspended (0)
174 /* don't use init here, because we got fade in/out from the other region
176 register_properties ();
177 listen_to_my_curves ();
178 connect_to_analysis_changed ();
179 connect_to_header_position_offset_changed ();
181 assert(_type == DataType::AUDIO);
182 assert (_sources.size() == _master_sources.size());
185 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, framecnt_t offset)
186 : Region (other, offset)
187 , AUDIOREGION_COPY_STATE (other)
188 , _automatable (other->session())
189 , _fade_in (new AutomationList (*other->_fade_in))
190 , _fade_out (new AutomationList (*other->_fade_out))
191 /* As far as I can see, the _envelope's times are relative to region position, and have nothing
192 to do with sources (and hence _start). So when we copy the envelope, we just use the supplied offset.
194 , _envelope (new AutomationList (*other->_envelope, offset, other->_length))
195 , _fade_in_suspended (0)
196 , _fade_out_suspended (0)
198 /* don't use init here, because we got fade in/out from the other region
200 register_properties ();
201 listen_to_my_curves ();
202 connect_to_analysis_changed ();
203 connect_to_header_position_offset_changed ();
205 assert(_type == DataType::AUDIO);
206 assert (_sources.size() == _master_sources.size());
209 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& srcs)
210 : Region (boost::static_pointer_cast<const Region>(other), srcs)
211 , AUDIOREGION_COPY_STATE (other)
212 , _automatable (other->session())
213 , _fade_in (new AutomationList (*other->_fade_in))
214 , _fade_out (new AutomationList (*other->_fade_out))
215 , _envelope (new AutomationList (*other->_envelope))
216 , _fade_in_suspended (0)
217 , _fade_out_suspended (0)
219 /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
221 register_properties ();
223 listen_to_my_curves ();
224 connect_to_analysis_changed ();
225 connect_to_header_position_offset_changed ();
227 assert (_sources.size() == _master_sources.size());
230 AudioRegion::AudioRegion (SourceList& srcs)
232 , AUDIOREGION_STATE_DEFAULT
233 , _automatable(srcs[0]->session())
234 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
235 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
236 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
237 , _fade_in_suspended (0)
238 , _fade_out_suspended (0)
242 assert(_type == DataType::AUDIO);
243 assert (_sources.size() == _master_sources.size());
246 AudioRegion::~AudioRegion ()
251 AudioRegion::post_set (const PropertyChange& /*ignored*/)
254 _sync_position = _start;
257 /* return to default fades if the existing ones are too long */
259 if (_left_of_split) {
260 if (_fade_in->back()->when >= _length) {
261 set_default_fade_in ();
263 set_default_fade_out ();
264 _left_of_split = false;
267 if (_right_of_split) {
268 if (_fade_out->back()->when >= _length) {
269 set_default_fade_out ();
272 set_default_fade_in ();
273 _right_of_split = false;
276 /* If _length changed, adjust our gain envelope accordingly */
277 _envelope->truncate_end (_length);
281 AudioRegion::connect_to_analysis_changed ()
283 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
284 (*i)->AnalysisChanged.connect_same_thread (*this, boost::bind (&AudioRegion::invalidate_transients, this));
289 AudioRegion::connect_to_header_position_offset_changed ()
291 set<boost::shared_ptr<Source> > unique_srcs;
293 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
295 /* connect only once to HeaderPositionOffsetChanged, even if sources are replicated
298 if (unique_srcs.find (*i) == unique_srcs.end ()) {
299 unique_srcs.insert (*i);
300 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
302 afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
309 AudioRegion::listen_to_my_curves ()
311 _envelope->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::envelope_changed, this));
312 _fade_in->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_in_changed, this));
313 _fade_out->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_out_changed, this));
317 AudioRegion::set_envelope_active (bool yn)
319 if (envelope_active() != yn) {
320 _envelope_active = yn;
321 send_change (PropertyChange (Properties::envelope_active));
326 AudioRegion::read_peaks (PeakData *buf, framecnt_t npeaks, framecnt_t offset, framecnt_t cnt, uint32_t chan_n, double samples_per_unit) const
328 if (chan_n >= _sources.size()) {
332 if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
335 if (_scale_amplitude != 1.0f) {
336 for (framecnt_t n = 0; n < npeaks; ++n) {
337 buf[n].max *= _scale_amplitude;
338 buf[n].min *= _scale_amplitude;
346 AudioRegion::read (Sample* buf, framepos_t timeline_position, framecnt_t cnt, int channel) const
348 /* raw read, no fades, no gain, nada */
349 return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, ReadOps (0));
353 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
354 framepos_t file_position, framecnt_t cnt, uint32_t chan_n) const
356 /* regular diskstream/butler read complete with fades etc */
357 return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer,
358 file_position, cnt, chan_n, ReadOps (~0));
362 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
363 framepos_t position, framecnt_t cnt, uint32_t chan_n) const
365 /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
369 return _read_at (_master_sources, _master_sources.front()->length(_master_sources.front()->timeline_position()),
370 buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, ReadOps (0));
373 /** @param position Position within the session */
375 AudioRegion::_read_at (const SourceList& srcs, framecnt_t limit,
376 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
384 frameoffset_t internal_offset;
385 frameoffset_t buf_offset;
387 bool raw = (rops == ReadOpsNone);
389 if (n_channels() == 0) {
393 if (muted() && !raw) {
394 return 0; /* read nothing */
397 /* precondition: caller has verified that we cover the desired section */
399 if (position < _position) {
401 buf_offset = _position - position;
402 /* if this fails then the requested section is entirely
403 before the position of this region. An error in xfade
404 construction that was fixed in oct 2011 (rev 10259)
405 led to this being the case. We don't want to crash
406 when this error is encountered, so just settle
407 on displaying an error.
409 if (cnt < buf_offset) {
410 error << "trying to read region " << name() << " @ " << position << " which is outside region bounds "
411 << _position << " .. " << last_frame() << " (len = " << length() << ')'
413 return 0; // read nothing
417 internal_offset = position - _position;
421 if (internal_offset >= limit) {
422 return 0; /* read nothing */
425 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
426 return 0; /* read nothing */
429 if (opaque() || raw) {
430 /* overwrite whatever is there */
431 mixdown_buffer = buf + buf_offset;
433 mixdown_buffer += buf_offset;
436 if (chan_n < n_channels()) {
438 boost::shared_ptr<AudioSource> src = boost::dynamic_pointer_cast<AudioSource> (srcs[chan_n]);
439 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
440 return 0; /* "read nothing" */
445 /* track is N-channel, this region has less channels; silence the ones
449 if (Config->get_replicate_missing_region_channels()) {
450 /* track is N-channel, this region has less channels, so use a relevant channel
453 uint32_t channel = n_channels() % chan_n;
454 boost::shared_ptr<AudioSource> src = boost::dynamic_pointer_cast<AudioSource> (srcs[channel]);
456 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
457 return 0; /* "read nothing" */
461 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
465 if (rops & ReadOpsFades) {
469 if (_fade_in_active && _session.config.get_use_region_fades()) {
471 framecnt_t fade_in_length = (framecnt_t) _fade_in->back()->when;
473 /* see if this read is within the fade in */
475 if (internal_offset < fade_in_length) {
479 fi_limit = min (to_read, fade_in_length - internal_offset);
481 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
483 for (framecnt_t n = 0; n < fi_limit; ++n) {
484 mixdown_buffer[n] *= gain_buffer[n];
491 if (_fade_out_active && _session.config.get_use_region_fades()) {
493 /* see if some part of this read is within the fade out */
495 /* ................. >| REGION
501 limit - fade_out_length
504 ^internal_offset + to_read
506 we need the intersection of [internal_offset,internal_offset+to_read] with
507 [limit - fade_out_length, limit]
512 framecnt_t fade_out_length = (framecnt_t) _fade_out->back()->when;
513 framecnt_t fade_interval_start = max(internal_offset, limit-fade_out_length);
514 framecnt_t fade_interval_end = min(internal_offset + to_read, limit);
516 if (fade_interval_end > fade_interval_start) {
517 /* (part of the) the fade out is in this buffer */
519 framecnt_t fo_limit = fade_interval_end - fade_interval_start;
520 framecnt_t curve_offset = fade_interval_start - (limit-fade_out_length);
521 framecnt_t fade_offset = fade_interval_start - internal_offset;
523 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
525 for (framecnt_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
526 mixdown_buffer[m] *= gain_buffer[n];
533 /* Regular gain curves and scaling */
535 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
536 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
538 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
539 for (framecnt_t n = 0; n < to_read; ++n) {
540 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
543 for (framecnt_t n = 0; n < to_read; ++n) {
544 mixdown_buffer[n] *= gain_buffer[n];
547 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
549 // XXX this should be using what in 2.0 would have been:
550 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
552 for (framecnt_t n = 0; n < to_read; ++n) {
553 mixdown_buffer[n] *= _scale_amplitude;
557 if (!opaque() && (buf != mixdown_buffer)) {
559 /* gack. the things we do for users.
564 for (framecnt_t n = 0; n < to_read; ++n) {
565 buf[n] += mixdown_buffer[n];
573 AudioRegion::state ()
575 XMLNode& node (Region::state ());
578 LocaleGuard lg (X_("POSIX"));
580 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
581 node.add_property ("channels", buf);
583 Stateful::add_properties (node);
585 child = node.add_child ("Envelope");
587 bool default_env = false;
589 // If there are only two points, the points are in the start of the region and the end of the region
590 // so, if they are both at 1.0f, that means the default region.
592 if (_envelope->size() == 2 &&
593 _envelope->front()->value == 1.0f &&
594 _envelope->back()->value==1.0f) {
595 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
601 child->add_property ("default", "yes");
603 child->add_child_nocopy (_envelope->get_state ());
606 child = node.add_child (X_("FadeIn"));
608 if (_default_fade_in) {
609 child->add_property ("default", "yes");
611 child->add_child_nocopy (_fade_in->get_state ());
614 child = node.add_child (X_("FadeOut"));
616 if (_default_fade_out) {
617 child->add_property ("default", "yes");
619 child->add_child_nocopy (_fade_out->get_state ());
626 AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_changed, bool send)
628 const XMLNodeList& nlist = node.children();
629 const XMLProperty *prop;
630 LocaleGuard lg (X_("POSIX"));
631 boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
633 suspend_property_changes ();
636 the_playlist->freeze ();
640 /* this will set all our State members and stuff controlled by the Region.
641 It should NOT send any changed signals - that is our responsibility.
644 Region::_set_state (node, version, what_changed, false);
646 if ((prop = node.property ("scale-gain")) != 0) {
647 float a = atof (prop->value().c_str());
648 if (a != _scale_amplitude) {
649 _scale_amplitude = a;
650 what_changed.add (Properties::scale_amplitude);
654 /* Now find envelope description and other related child items */
656 _envelope->freeze ();
658 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
664 if (child->name() == "Envelope") {
668 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child, version)) {
669 set_default_envelope ();
672 _envelope->set_max_xval (_length);
673 _envelope->truncate_end (_length);
676 } else if (child->name() == "FadeIn") {
680 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
681 set_default_fade_in ();
683 XMLNode* grandchild = child->child ("AutomationList");
685 _fade_in->set_state (*grandchild, version);
689 if ((prop = child->property ("active")) != 0) {
690 if (string_is_affirmative (prop->value())) {
691 set_fade_in_active (true);
693 set_fade_in_active (false);
697 } else if (child->name() == "FadeOut") {
701 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
702 set_default_fade_out ();
704 XMLNode* grandchild = child->child ("AutomationList");
706 _fade_out->set_state (*grandchild, version);
710 if ((prop = child->property ("active")) != 0) {
711 if (string_is_affirmative (prop->value())) {
712 set_fade_out_active (true);
714 set_fade_out_active (false);
722 resume_property_changes ();
725 send_change (what_changed);
729 the_playlist->thaw ();
736 AudioRegion::set_state (const XMLNode& node, int version)
738 PropertyChange what_changed;
739 return _set_state (node, version, what_changed, true);
743 AudioRegion::set_fade_in_shape (FadeShape shape)
745 set_fade_in (shape, (framecnt_t) _fade_in->back()->when);
749 AudioRegion::set_fade_out_shape (FadeShape shape)
751 set_fade_out (shape, (framecnt_t) _fade_out->back()->when);
755 AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
761 send_change (PropertyChange (Properties::fade_in));
765 AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
772 _fade_in->fast_simple_add (0.0, 0.0);
773 _fade_in->fast_simple_add (len, 1.0);
777 _fade_in->fast_simple_add (0, 0);
778 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
779 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
780 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
781 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
782 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
783 _fade_in->fast_simple_add (len, 1);
787 _fade_in->fast_simple_add (0, 0);
788 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
789 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
790 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
791 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
792 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
793 _fade_in->fast_simple_add (len * 0.767281, 1);
794 _fade_in->fast_simple_add (len, 1);
798 _fade_in->fast_simple_add (0, 0);
799 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
800 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
801 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
802 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
803 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
804 _fade_in->fast_simple_add (len, 1);
808 _fade_in->fast_simple_add (0, 0);
809 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
810 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
811 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
812 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
813 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
814 _fade_in->fast_simple_add (len, 1);
819 send_change (PropertyChange (Properties::fade_in));
823 AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
825 _fade_out->freeze ();
829 send_change (PropertyChange (Properties::fade_in));
833 AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
835 _fade_out->freeze ();
840 _fade_out->fast_simple_add (len * 0, 1);
841 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
842 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
843 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
844 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
845 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
846 _fade_out->fast_simple_add (len * 1, 0);
850 _fade_out->fast_simple_add (len * 0, 1);
851 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
852 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
853 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
854 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
855 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
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 * 0.305556, 1);
862 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
863 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
864 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
865 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
866 _fade_out->fast_simple_add (len * 1, 0);
870 _fade_out->fast_simple_add (len * 0, 1);
871 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
872 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
873 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
874 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
875 _fade_out->fast_simple_add (len * 1, 0);
879 _fade_out->fast_simple_add (len * 0, 1);
880 _fade_out->fast_simple_add (len * 1, 0);
885 send_change (PropertyChange (Properties::fade_in));
889 AudioRegion::set_fade_in_length (framecnt_t len)
895 bool changed = _fade_in->extend_to (len);
898 _default_fade_in = false;
899 send_change (PropertyChange (Properties::fade_in));
904 AudioRegion::set_fade_out_length (framecnt_t len)
910 bool changed = _fade_out->extend_to (len);
913 _default_fade_out = false;
914 send_change (PropertyChange (Properties::fade_out));
919 AudioRegion::set_fade_in_active (bool yn)
921 if (yn == _fade_in_active) {
925 _fade_in_active = yn;
926 send_change (PropertyChange (Properties::fade_in_active));
930 AudioRegion::set_fade_out_active (bool yn)
932 if (yn == _fade_out_active) {
935 _fade_out_active = yn;
936 send_change (PropertyChange (Properties::fade_out_active));
940 AudioRegion::fade_in_is_default () const
942 return _fade_in->size() == 2 && _fade_in->front()->when == 0 && _fade_in->back()->when == 64;
946 AudioRegion::fade_out_is_default () const
948 return _fade_out->size() == 2 && _fade_out->front()->when == 0 && _fade_out->back()->when == 64;
952 AudioRegion::set_default_fade_in ()
954 _fade_in_suspended = 0;
955 set_fade_in (FadeLinear, 64);
959 AudioRegion::set_default_fade_out ()
961 _fade_out_suspended = 0;
962 set_fade_out (FadeLinear, 64);
966 AudioRegion::set_default_fades ()
968 set_default_fade_in ();
969 set_default_fade_out ();
973 AudioRegion::set_default_envelope ()
975 _envelope->freeze ();
977 _envelope->fast_simple_add (0, 1.0f);
978 _envelope->fast_simple_add (_length, 1.0f);
983 AudioRegion::recompute_at_end ()
985 /* our length has changed. recompute a new final point by interpolating
986 based on the the existing curve.
989 _envelope->freeze ();
990 _envelope->truncate_end (_length);
991 _envelope->set_max_xval (_length);
994 suspend_property_changes();
996 if (_left_of_split) {
997 set_default_fade_out ();
998 _left_of_split = false;
999 } else if (_fade_out->back()->when > _length) {
1000 _fade_out->extend_to (_length);
1001 send_change (PropertyChange (Properties::fade_out));
1004 if (_fade_in->back()->when > _length) {
1005 _fade_in->extend_to (_length);
1006 send_change (PropertyChange (Properties::fade_in));
1009 resume_property_changes();
1013 AudioRegion::recompute_at_start ()
1015 /* as above, but the shift was from the front */
1017 _envelope->truncate_start (_length);
1019 suspend_property_changes();
1021 if (_right_of_split) {
1022 set_default_fade_in ();
1023 _right_of_split = false;
1024 } else if (_fade_in->back()->when > _length) {
1025 _fade_in->extend_to (_length);
1026 send_change (PropertyChange (Properties::fade_in));
1029 if (_fade_out->back()->when > _length) {
1030 _fade_out->extend_to (_length);
1031 send_change (PropertyChange (Properties::fade_out));
1034 resume_property_changes();
1038 AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr<Region> >& v) const
1044 if (_sources.size() < 2) {
1048 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
1050 srcs.push_back (*i);
1054 if (_sources.size() == 2) {
1062 new_name += ('0' + n + 1);
1065 /* create a copy with just one source. prevent if from being thought of as
1066 "whole file" even if it covers the entire source file(s).
1071 plist.add (Properties::start, _start.val());
1072 plist.add (Properties::length, _length.val());
1073 plist.add (Properties::name, new_name);
1074 plist.add (Properties::layer, layer ());
1076 v.push_back(RegionFactory::create (srcs, plist));
1077 v.back()->set_whole_file (false);
1086 AudioRegion::read_raw_internal (Sample* buf, framepos_t pos, framecnt_t cnt, int channel) const
1088 return audio_source(channel)->read (buf, pos, cnt);
1092 AudioRegion::set_scale_amplitude (gain_t g)
1094 boost::shared_ptr<Playlist> pl (playlist());
1096 _scale_amplitude = g;
1098 /* tell the diskstream we're in */
1101 pl->ContentsChanged();
1104 /* tell everybody else */
1106 send_change (PropertyChange (Properties::scale_amplitude));
1109 /** @return the maximum (linear) amplitude of the region, or a -ve
1110 * number if the Progress object reports that the process was cancelled.
1113 AudioRegion::maximum_amplitude (Progress* p) const
1115 framepos_t fpos = _start;
1116 framepos_t const fend = _start + _length;
1119 framecnt_t const blocksize = 64 * 1024;
1120 Sample buf[blocksize];
1122 while (fpos < fend) {
1126 framecnt_t const to_read = min (fend - fpos, blocksize);
1128 for (n = 0; n < n_channels(); ++n) {
1132 if (read_raw_internal (buf, fpos, to_read, n) != to_read) {
1136 maxamp = compute_peak (buf, to_read, maxamp);
1141 p->set_progress (float (fpos - _start) / _length);
1142 if (p->cancelled ()) {
1151 /** Normalize using a given maximum amplitude and target, so that region
1152 * _scale_amplitude becomes target / max_amplitude.
1155 AudioRegion::normalize (float max_amplitude, float target_dB)
1157 gain_t target = dB_to_coefficient (target_dB);
1159 if (target == 1.0f) {
1160 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1161 that we may have clipped.
1163 target -= FLT_EPSILON;
1166 if (max_amplitude == 0.0f) {
1167 /* don't even try */
1171 if (max_amplitude == target) {
1172 /* we can't do anything useful */
1176 set_scale_amplitude (target / max_amplitude);
1180 AudioRegion::fade_in_changed ()
1182 send_change (PropertyChange (Properties::fade_in));
1186 AudioRegion::fade_out_changed ()
1188 send_change (PropertyChange (Properties::fade_out));
1192 AudioRegion::envelope_changed ()
1194 send_change (PropertyChange (Properties::envelope));
1198 AudioRegion::suspend_fade_in ()
1200 if (++_fade_in_suspended == 1) {
1201 if (fade_in_is_default()) {
1202 set_fade_in_active (false);
1208 AudioRegion::resume_fade_in ()
1210 if (--_fade_in_suspended == 0 && _fade_in_suspended) {
1211 set_fade_in_active (true);
1216 AudioRegion::suspend_fade_out ()
1218 if (++_fade_out_suspended == 1) {
1219 if (fade_out_is_default()) {
1220 set_fade_out_active (false);
1226 AudioRegion::resume_fade_out ()
1228 if (--_fade_out_suspended == 0 &&_fade_out_suspended) {
1229 set_fade_out_active (true);
1234 AudioRegion::speed_mismatch (float sr) const
1236 if (_sources.empty()) {
1237 /* impossible, but ... */
1241 float fsr = audio_source()->sample_rate();
1247 AudioRegion::source_offset_changed ()
1249 /* XXX this fixes a crash that should not occur. It does occur
1250 becauses regions are not being deleted when a session
1251 is unloaded. That bug must be fixed.
1254 if (_sources.empty()) {
1258 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1260 if (afs && afs->destructive()) {
1261 // set_start (source()->natural_position(), this);
1262 set_position (source()->natural_position());
1266 boost::shared_ptr<AudioSource>
1267 AudioRegion::audio_source (uint32_t n) const
1269 // Guaranteed to succeed (use a static cast for speed?)
1270 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1274 AudioRegion::adjust_transients (frameoffset_t delta)
1276 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1277 (*x) = (*x) + delta;
1280 send_change (PropertyChange (Properties::valid_transients));
1286 AudioRegion::update_transient (framepos_t old_position, framepos_t new_position)
1288 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1289 if ((*x) == old_position) {
1290 (*x) = new_position;
1291 send_change (PropertyChange (Properties::valid_transients));
1301 AudioRegion::add_transient (framepos_t where)
1303 _transients.push_back(where);
1304 _valid_transients = true;
1306 send_change (PropertyChange (Properties::valid_transients));
1310 AudioRegion::remove_transient (framepos_t where)
1312 _transients.remove(where);
1313 _valid_transients = true;
1315 send_change (PropertyChange (Properties::valid_transients));
1319 AudioRegion::set_transients (AnalysisFeatureList& results)
1321 _transients.clear();
1322 _transients = results;
1323 _valid_transients = true;
1325 send_change (PropertyChange (Properties::valid_transients));
1331 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1333 boost::shared_ptr<Playlist> pl = playlist();
1339 if (_valid_transients && !force_new) {
1340 results = _transients;
1344 SourceList::iterator s;
1346 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1347 if (!(*s)->has_been_analysed()) {
1348 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1353 if (s == _sources.end()) {
1354 /* all sources are analyzed, merge data from each one */
1356 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1358 /* find the set of transients within the bounds of this region */
1360 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1361 (*s)->transients.end(),
1364 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1365 (*s)->transients.end(),
1370 results.insert (results.end(), low, high);
1373 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1375 /* translate all transients to current position */
1377 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1382 _transients = results;
1383 _valid_transients = true;
1388 /* no existing/complete transient info */
1390 static bool analyse_dialog_shown = false; /* global per instance of Ardour */
1392 if (!Config->get_auto_analyse_audio()) {
1393 if (!analyse_dialog_shown) {
1394 pl->session().Dialog (_("\
1395 You have requested an operation that requires audio analysis.\n\n\
1396 You currently have \"auto-analyse-audio\" disabled, which means \
1397 that transient data must be generated every time it is required.\n\n\
1398 If you are doing work that will require transient data on a \
1399 regular basis, you should probably enable \"auto-analyse-audio\" \
1400 then quit ardour and restart.\n\n\
1401 This dialog will not display again. But you may notice a slight delay \
1402 in this and future transient-detection operations.\n\
1404 analyse_dialog_shown = true;
1408 TransientDetector t (pl->session().frame_rate());
1409 bool existing_results = !results.empty();
1411 _transients.clear ();
1412 _valid_transients = false;
1414 for (uint32_t i = 0; i < n_channels(); ++i) {
1416 AnalysisFeatureList these_results;
1420 if (t.run ("", this, i, these_results)) {
1424 /* translate all transients to give absolute position */
1426 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1432 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1435 if (!results.empty()) {
1436 if (existing_results) {
1438 /* merge our transients into the existing ones, then clean up
1442 results.insert (results.end(), _transients.begin(), _transients.end());
1443 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1446 /* make sure ours are clean too */
1448 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1452 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1453 results = _transients;
1456 _valid_transients = true;
1461 /** Find areas of `silence' within a region.
1463 * @param threshold Threshold below which signal is considered silence (as a sample value)
1464 * @param min_length Minimum length of silent period to be reported.
1465 * @return Silent intervals, measured relative to the region start in the source
1469 AudioRegion::find_silence (Sample threshold, framecnt_t min_length, InterThreadInfo& itt) const
1471 framecnt_t const block_size = 64 * 1024;
1472 boost::scoped_array<Sample> loudest (new Sample[block_size]);
1473 boost::scoped_array<Sample> buf (new Sample[block_size]);
1475 framepos_t pos = _start;
1476 framepos_t const end = _start + _length - 1;
1478 AudioIntervalResult silent_periods;
1480 bool in_silence = false;
1481 frameoffset_t silence_start = 0;
1483 while (pos < end && !itt.cancel) {
1485 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1486 memset (loudest.get(), 0, sizeof (Sample) * block_size);
1487 for (uint32_t n = 0; n < n_channels(); ++n) {
1489 read_raw_internal (buf.get(), pos, block_size, n);
1490 for (framecnt_t i = 0; i < block_size; ++i) {
1491 loudest[i] = max (loudest[i], abs (buf[i]));
1495 /* now look for silence */
1496 for (framecnt_t i = 0; i < block_size; ++i) {
1497 bool const silence = abs (loudest[i]) < threshold;
1498 if (silence && !in_silence) {
1499 /* non-silence to silence */
1501 silence_start = pos + i;
1502 } else if (!silence && in_silence) {
1503 /* silence to non-silence */
1505 if (pos + i - 1 - silence_start >= min_length) {
1506 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1512 itt.progress = (end-pos)/(double)_length;
1515 if (in_silence && end - 1 - silence_start >= min_length) {
1516 /* last block was silent, so finish off the last period */
1517 silent_periods.push_back (std::make_pair (silence_start, end));
1522 return silent_periods;
1529 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)
1531 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (framecnt_t) npeaks, (framepos_t) start, (framecnt_t) cnt, n_chan,samples_per_unit);
1534 uint32_t region_length_from_c (void *arg)
1537 return ((AudioRegion *) arg)->length();
1540 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1542 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;