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.val());
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::exportme (Session& /*session*/, ARDOUR::ExportSpecification& /*spec*/)
1095 // const framecnt_t blocksize = 4096;
1096 // framecnt_t to_read;
1099 // spec.channels = _sources.size();
1101 // if (spec.prepare (blocksize, session.frame_rate())) {
1106 // spec.total_frames = _length;
1108 // while (spec.pos < _length && !spec.stop) {
1111 // /* step 1: interleave */
1113 // to_read = min (_length - spec.pos, blocksize);
1115 // if (spec.channels == 1) {
1117 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1123 // Sample buf[blocksize];
1125 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1127 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1131 // for (framecnt_t x = 0; x < to_read; ++x) {
1132 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1137 // if (spec.process (to_read)) {
1141 // spec.pos += to_read;
1142 // spec.progress = (double) spec.pos /_length;
1149 // spec.running = false;
1150 // spec.status = status;
1158 AudioRegion::set_scale_amplitude (gain_t g)
1160 boost::shared_ptr<Playlist> pl (playlist());
1162 _scale_amplitude = g;
1164 /* tell the diskstream we're in */
1167 pl->ContentsChanged();
1170 /* tell everybody else */
1172 send_change (PropertyChange (Properties::scale_amplitude));
1175 /** @return the maximum (linear) amplitude of the region, or a -ve
1176 * number if the Progress object reports that the process was cancelled.
1179 AudioRegion::maximum_amplitude (Progress* p) const
1181 framepos_t fpos = _start;
1182 framepos_t const fend = _start + _length;
1185 framecnt_t const blocksize = 64 * 1024;
1186 Sample buf[blocksize];
1188 while (fpos < fend) {
1192 framecnt_t const to_read = min (fend - fpos, blocksize);
1194 for (n = 0; n < n_channels(); ++n) {
1198 if (read_raw_internal (buf, fpos, to_read, n) != to_read) {
1202 maxamp = compute_peak (buf, to_read, maxamp);
1207 p->set_progress (float (fpos - _start) / _length);
1208 if (p->cancelled ()) {
1217 /** Normalize using a given maximum amplitude and target, so that region
1218 * _scale_amplitude becomes target / max_amplitude.
1221 AudioRegion::normalize (float max_amplitude, float target_dB)
1223 gain_t target = dB_to_coefficient (target_dB);
1225 if (target == 1.0f) {
1226 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1227 that we may have clipped.
1229 target -= FLT_EPSILON;
1232 if (max_amplitude == 0.0f) {
1233 /* don't even try */
1237 if (max_amplitude == target) {
1238 /* we can't do anything useful */
1242 set_scale_amplitude (target / max_amplitude);
1246 AudioRegion::fade_in_changed ()
1248 send_change (PropertyChange (Properties::fade_in));
1252 AudioRegion::fade_out_changed ()
1254 send_change (PropertyChange (Properties::fade_out));
1258 AudioRegion::envelope_changed ()
1260 send_change (PropertyChange (Properties::envelope));
1264 AudioRegion::suspend_fade_in ()
1266 if (++_fade_in_suspended == 1) {
1267 if (fade_in_is_default()) {
1268 set_fade_in_active (false);
1274 AudioRegion::resume_fade_in ()
1276 if (--_fade_in_suspended == 0 && _fade_in_suspended) {
1277 set_fade_in_active (true);
1282 AudioRegion::suspend_fade_out ()
1284 if (++_fade_out_suspended == 1) {
1285 if (fade_out_is_default()) {
1286 set_fade_out_active (false);
1292 AudioRegion::resume_fade_out ()
1294 if (--_fade_out_suspended == 0 &&_fade_out_suspended) {
1295 set_fade_out_active (true);
1300 AudioRegion::speed_mismatch (float sr) const
1302 if (_sources.empty()) {
1303 /* impossible, but ... */
1307 float fsr = audio_source()->sample_rate();
1313 AudioRegion::source_offset_changed ()
1315 /* XXX this fixes a crash that should not occur. It does occur
1316 becauses regions are not being deleted when a session
1317 is unloaded. That bug must be fixed.
1320 if (_sources.empty()) {
1324 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1326 if (afs && afs->destructive()) {
1327 // set_start (source()->natural_position(), this);
1328 set_position (source()->natural_position());
1332 boost::shared_ptr<AudioSource>
1333 AudioRegion::audio_source (uint32_t n) const
1335 // Guaranteed to succeed (use a static cast for speed?)
1336 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1340 AudioRegion::adjust_transients (frameoffset_t delta)
1342 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1343 (*x) = (*x) + delta;
1346 send_change (PropertyChange (Properties::valid_transients));
1352 AudioRegion::update_transient (framepos_t old_position, framepos_t new_position)
1354 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1355 if ((*x) == old_position) {
1356 (*x) = new_position;
1357 send_change (PropertyChange (Properties::valid_transients));
1367 AudioRegion::add_transient (framepos_t where)
1369 _transients.push_back(where);
1370 _valid_transients = true;
1372 send_change (PropertyChange (Properties::valid_transients));
1376 AudioRegion::remove_transient (framepos_t where)
1378 _transients.remove(where);
1379 _valid_transients = true;
1381 send_change (PropertyChange (Properties::valid_transients));
1385 AudioRegion::set_transients (AnalysisFeatureList& results)
1387 _transients.clear();
1388 _transients = results;
1389 _valid_transients = true;
1391 send_change (PropertyChange (Properties::valid_transients));
1397 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1399 boost::shared_ptr<Playlist> pl = playlist();
1405 if (_valid_transients && !force_new) {
1406 results = _transients;
1410 SourceList::iterator s;
1412 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1413 if (!(*s)->has_been_analysed()) {
1414 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1419 if (s == _sources.end()) {
1420 /* all sources are analyzed, merge data from each one */
1422 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1424 /* find the set of transients within the bounds of this region */
1426 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1427 (*s)->transients.end(),
1430 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1431 (*s)->transients.end(),
1436 results.insert (results.end(), low, high);
1439 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1441 /* translate all transients to current position */
1443 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1448 _transients = results;
1449 _valid_transients = true;
1454 /* no existing/complete transient info */
1456 static bool analyse_dialog_shown = false; /* global per instance of Ardour */
1458 if (!Config->get_auto_analyse_audio()) {
1459 if (!analyse_dialog_shown) {
1460 pl->session().Dialog (_("\
1461 You have requested an operation that requires audio analysis.\n\n\
1462 You currently have \"auto-analyse-audio\" disabled, which means \
1463 that transient data must be generated every time it is required.\n\n\
1464 If you are doing work that will require transient data on a \
1465 regular basis, you should probably enable \"auto-analyse-audio\" \
1466 then quit ardour and restart.\n\n\
1467 This dialog will not display again. But you may notice a slight delay \
1468 in this and future transient-detection operations.\n\
1470 analyse_dialog_shown = true;
1474 TransientDetector t (pl->session().frame_rate());
1475 bool existing_results = !results.empty();
1477 _transients.clear ();
1478 _valid_transients = false;
1480 for (uint32_t i = 0; i < n_channels(); ++i) {
1482 AnalysisFeatureList these_results;
1486 if (t.run ("", this, i, these_results)) {
1490 /* translate all transients to give absolute position */
1492 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1498 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1501 if (!results.empty()) {
1502 if (existing_results) {
1504 /* merge our transients into the existing ones, then clean up
1508 results.insert (results.end(), _transients.begin(), _transients.end());
1509 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1512 /* make sure ours are clean too */
1514 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1518 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1519 results = _transients;
1522 _valid_transients = true;
1527 /** Find areas of `silence' within a region.
1529 * @param threshold Threshold below which signal is considered silence (as a sample value)
1530 * @param min_length Minimum length of silent period to be reported.
1531 * @return Silent intervals, measured relative to the region start in the source
1535 AudioRegion::find_silence (Sample threshold, framecnt_t min_length, InterThreadInfo& itt) const
1537 framecnt_t const block_size = 64 * 1024;
1538 boost::scoped_array<Sample> loudest (new Sample[block_size]);
1539 boost::scoped_array<Sample> buf (new Sample[block_size]);
1541 framepos_t pos = _start;
1542 framepos_t const end = _start + _length - 1;
1544 AudioIntervalResult silent_periods;
1546 bool in_silence = false;
1547 frameoffset_t silence_start = 0;
1549 while (pos < end && !itt.cancel) {
1551 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1552 memset (loudest.get(), 0, sizeof (Sample) * block_size);
1553 for (uint32_t n = 0; n < n_channels(); ++n) {
1555 read_raw_internal (buf.get(), pos, block_size, n);
1556 for (framecnt_t i = 0; i < block_size; ++i) {
1557 loudest[i] = max (loudest[i], abs (buf[i]));
1561 /* now look for silence */
1562 for (framecnt_t i = 0; i < block_size; ++i) {
1563 bool const silence = abs (loudest[i]) < threshold;
1564 if (silence && !in_silence) {
1565 /* non-silence to silence */
1567 silence_start = pos + i;
1568 } else if (!silence && in_silence) {
1569 /* silence to non-silence */
1571 if (pos + i - 1 - silence_start >= min_length) {
1572 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1578 itt.progress = (end-pos)/(double)_length;
1581 if (in_silence && end - 1 - silence_start >= min_length) {
1582 /* last block was silent, so finish off the last period */
1583 silent_periods.push_back (std::make_pair (silence_start, end));
1588 return silent_periods;
1595 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)
1597 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (framecnt_t) npeaks, (framepos_t) start, (framecnt_t) cnt, n_chan,samples_per_unit);
1600 uint32_t region_length_from_c (void *arg)
1603 return ((AudioRegion *) arg)->length();
1606 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1608 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;