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 (rops & ReadOpsCount) {
437 _read_data_count = 0;
440 if (chan_n < n_channels()) {
442 boost::shared_ptr<AudioSource> src = boost::dynamic_pointer_cast<AudioSource> (srcs[chan_n]);
443 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
444 return 0; /* "read nothing" */
447 if (rops & ReadOpsCount) {
448 _read_data_count += src->read_data_count();
453 /* track is N-channel, this region has less channels; silence the ones
457 if (Config->get_replicate_missing_region_channels()) {
458 /* track is N-channel, this region has less channels, so use a relevant channel
461 uint32_t channel = n_channels() % chan_n;
462 boost::shared_ptr<AudioSource> src = boost::dynamic_pointer_cast<AudioSource> (srcs[channel]);
464 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
465 return 0; /* "read nothing" */
468 /* adjust read data count appropriately since this was a duplicate read */
469 src->dec_read_data_count (to_read);
471 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
475 if (rops & ReadOpsFades) {
479 if (_fade_in_active && _session.config.get_use_region_fades()) {
481 framecnt_t fade_in_length = (framecnt_t) _fade_in->back()->when;
483 /* see if this read is within the fade in */
485 if (internal_offset < fade_in_length) {
489 fi_limit = min (to_read, fade_in_length - internal_offset);
491 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
493 for (framecnt_t n = 0; n < fi_limit; ++n) {
494 mixdown_buffer[n] *= gain_buffer[n];
501 if (_fade_out_active && _session.config.get_use_region_fades()) {
503 /* see if some part of this read is within the fade out */
505 /* ................. >| REGION
511 limit - fade_out_length
514 ^internal_offset + to_read
516 we need the intersection of [internal_offset,internal_offset+to_read] with
517 [limit - fade_out_length, limit]
522 framecnt_t fade_out_length = (framecnt_t) _fade_out->back()->when;
523 framecnt_t fade_interval_start = max(internal_offset, limit-fade_out_length);
524 framecnt_t fade_interval_end = min(internal_offset + to_read, limit);
526 if (fade_interval_end > fade_interval_start) {
527 /* (part of the) the fade out is in this buffer */
529 framecnt_t fo_limit = fade_interval_end - fade_interval_start;
530 framecnt_t curve_offset = fade_interval_start - (limit-fade_out_length);
531 framecnt_t fade_offset = fade_interval_start - internal_offset;
533 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
535 for (framecnt_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
536 mixdown_buffer[m] *= gain_buffer[n];
543 /* Regular gain curves and scaling */
545 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
546 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
548 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
549 for (framecnt_t n = 0; n < to_read; ++n) {
550 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
553 for (framecnt_t n = 0; n < to_read; ++n) {
554 mixdown_buffer[n] *= gain_buffer[n];
557 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
559 // XXX this should be using what in 2.0 would have been:
560 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
562 for (framecnt_t n = 0; n < to_read; ++n) {
563 mixdown_buffer[n] *= _scale_amplitude;
567 if (!opaque() && (buf != mixdown_buffer)) {
569 /* gack. the things we do for users.
574 for (framecnt_t n = 0; n < to_read; ++n) {
575 buf[n] += mixdown_buffer[n];
583 AudioRegion::state ()
585 XMLNode& node (Region::state ());
588 LocaleGuard lg (X_("POSIX"));
590 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
591 node.add_property ("channels", buf);
593 Stateful::add_properties (node);
595 child = node.add_child ("Envelope");
597 bool default_env = false;
599 // If there are only two points, the points are in the start of the region and the end of the region
600 // so, if they are both at 1.0f, that means the default region.
602 if (_envelope->size() == 2 &&
603 _envelope->front()->value == 1.0f &&
604 _envelope->back()->value==1.0f) {
605 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
611 child->add_property ("default", "yes");
613 child->add_child_nocopy (_envelope->get_state ());
616 child = node.add_child (X_("FadeIn"));
618 if (_default_fade_in) {
619 child->add_property ("default", "yes");
621 child->add_child_nocopy (_fade_in->get_state ());
624 child = node.add_child (X_("FadeOut"));
626 if (_default_fade_out) {
627 child->add_property ("default", "yes");
629 child->add_child_nocopy (_fade_out->get_state ());
636 AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_changed, bool send)
638 const XMLNodeList& nlist = node.children();
639 const XMLProperty *prop;
640 LocaleGuard lg (X_("POSIX"));
641 boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
643 suspend_property_changes ();
646 the_playlist->freeze ();
650 /* this will set all our State members and stuff controlled by the Region.
651 It should NOT send any changed signals - that is our responsibility.
654 Region::_set_state (node, version, what_changed, false);
656 if ((prop = node.property ("scale-gain")) != 0) {
657 float a = atof (prop->value().c_str());
658 if (a != _scale_amplitude) {
659 _scale_amplitude = a;
660 what_changed.add (Properties::scale_amplitude);
664 /* Now find envelope description and other related child items */
666 _envelope->freeze ();
668 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
674 if (child->name() == "Envelope") {
678 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child, version)) {
679 set_default_envelope ();
682 _envelope->set_max_xval (_length);
683 _envelope->truncate_end (_length);
686 } else if (child->name() == "FadeIn") {
690 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
691 set_default_fade_in ();
693 XMLNode* grandchild = child->child ("AutomationList");
695 _fade_in->set_state (*grandchild, version);
699 if ((prop = child->property ("active")) != 0) {
700 if (string_is_affirmative (prop->value())) {
701 set_fade_in_active (true);
703 set_fade_in_active (false);
707 } else if (child->name() == "FadeOut") {
711 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
712 set_default_fade_out ();
714 XMLNode* grandchild = child->child ("AutomationList");
716 _fade_out->set_state (*grandchild, version);
720 if ((prop = child->property ("active")) != 0) {
721 if (string_is_affirmative (prop->value())) {
722 set_fade_out_active (true);
724 set_fade_out_active (false);
732 resume_property_changes ();
735 send_change (what_changed);
739 the_playlist->thaw ();
746 AudioRegion::set_state (const XMLNode& node, int version)
748 PropertyChange what_changed;
749 return _set_state (node, version, what_changed, true);
753 AudioRegion::set_fade_in_shape (FadeShape shape)
755 set_fade_in (shape, (framecnt_t) _fade_in->back()->when);
759 AudioRegion::set_fade_out_shape (FadeShape shape)
761 set_fade_out (shape, (framecnt_t) _fade_out->back()->when);
765 AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
771 send_change (PropertyChange (Properties::fade_in));
775 AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
782 _fade_in->fast_simple_add (0.0, 0.0);
783 _fade_in->fast_simple_add (len, 1.0);
787 _fade_in->fast_simple_add (0, 0);
788 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
789 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
790 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
791 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
792 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
793 _fade_in->fast_simple_add (len, 1);
797 _fade_in->fast_simple_add (0, 0);
798 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
799 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
800 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
801 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
802 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
803 _fade_in->fast_simple_add (len * 0.767281, 1);
804 _fade_in->fast_simple_add (len, 1);
808 _fade_in->fast_simple_add (0, 0);
809 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
810 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
811 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
812 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
813 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
814 _fade_in->fast_simple_add (len, 1);
818 _fade_in->fast_simple_add (0, 0);
819 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
820 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
821 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
822 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
823 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
824 _fade_in->fast_simple_add (len, 1);
829 send_change (PropertyChange (Properties::fade_in));
833 AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
835 _fade_out->freeze ();
839 send_change (PropertyChange (Properties::fade_in));
843 AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
845 _fade_out->freeze ();
850 _fade_out->fast_simple_add (len * 0, 1);
851 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
852 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
853 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
854 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
855 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
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.228111, 0.988889);
862 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
863 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
864 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
865 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
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.305556, 1);
872 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
873 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
874 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
875 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
876 _fade_out->fast_simple_add (len * 1, 0);
880 _fade_out->fast_simple_add (len * 0, 1);
881 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
882 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
883 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
884 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
885 _fade_out->fast_simple_add (len * 1, 0);
889 _fade_out->fast_simple_add (len * 0, 1);
890 _fade_out->fast_simple_add (len * 1, 0);
895 send_change (PropertyChange (Properties::fade_in));
899 AudioRegion::set_fade_in_length (framecnt_t len)
905 bool changed = _fade_in->extend_to (len);
908 _default_fade_in = false;
909 send_change (PropertyChange (Properties::fade_in));
914 AudioRegion::set_fade_out_length (framecnt_t len)
920 bool changed = _fade_out->extend_to (len);
923 _default_fade_out = false;
924 send_change (PropertyChange (Properties::fade_out));
929 AudioRegion::set_fade_in_active (bool yn)
931 if (yn == _fade_in_active) {
935 _fade_in_active = yn;
936 send_change (PropertyChange (Properties::fade_in_active));
940 AudioRegion::set_fade_out_active (bool yn)
942 if (yn == _fade_out_active) {
945 _fade_out_active = yn;
946 send_change (PropertyChange (Properties::fade_out_active));
950 AudioRegion::fade_in_is_default () const
952 return _fade_in->size() == 2 && _fade_in->front()->when == 0 && _fade_in->back()->when == 64;
956 AudioRegion::fade_out_is_default () const
958 return _fade_out->size() == 2 && _fade_out->front()->when == 0 && _fade_out->back()->when == 64;
962 AudioRegion::set_default_fade_in ()
964 _fade_in_suspended = 0;
965 set_fade_in (FadeLinear, 64);
969 AudioRegion::set_default_fade_out ()
971 _fade_out_suspended = 0;
972 set_fade_out (FadeLinear, 64);
976 AudioRegion::set_default_fades ()
978 set_default_fade_in ();
979 set_default_fade_out ();
983 AudioRegion::set_default_envelope ()
985 _envelope->freeze ();
987 _envelope->fast_simple_add (0, 1.0f);
988 _envelope->fast_simple_add (_length, 1.0f);
993 AudioRegion::recompute_at_end ()
995 /* our length has changed. recompute a new final point by interpolating
996 based on the the existing curve.
999 _envelope->freeze ();
1000 _envelope->truncate_end (_length);
1001 _envelope->set_max_xval (_length);
1004 suspend_property_changes();
1006 if (_left_of_split) {
1007 set_default_fade_out ();
1008 _left_of_split = false;
1009 } else if (_fade_out->back()->when > _length) {
1010 _fade_out->extend_to (_length);
1011 send_change (PropertyChange (Properties::fade_out));
1014 if (_fade_in->back()->when > _length) {
1015 _fade_in->extend_to (_length);
1016 send_change (PropertyChange (Properties::fade_in));
1019 resume_property_changes();
1023 AudioRegion::recompute_at_start ()
1025 /* as above, but the shift was from the front */
1027 _envelope->truncate_start (_length);
1029 suspend_property_changes();
1031 if (_right_of_split) {
1032 set_default_fade_in ();
1033 _right_of_split = false;
1034 } else if (_fade_in->back()->when > _length) {
1035 _fade_in->extend_to (_length);
1036 send_change (PropertyChange (Properties::fade_in));
1039 if (_fade_out->back()->when > _length) {
1040 _fade_out->extend_to (_length);
1041 send_change (PropertyChange (Properties::fade_out));
1044 resume_property_changes();
1048 AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr<Region> >& v) const
1054 if (_sources.size() < 2) {
1058 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
1060 srcs.push_back (*i);
1064 if (_sources.size() == 2) {
1072 new_name += ('0' + n + 1);
1075 /* create a copy with just one source. prevent if from being thought of as
1076 "whole file" even if it covers the entire source file(s).
1081 plist.add (Properties::start, _start.val());
1082 plist.add (Properties::length, _length.val());
1083 plist.add (Properties::name, new_name);
1084 plist.add (Properties::layer, _layer.val());
1086 v.push_back(RegionFactory::create (srcs, plist));
1087 v.back()->set_whole_file (false);
1096 AudioRegion::read_raw_internal (Sample* buf, framepos_t pos, framecnt_t cnt, int channel) const
1098 return audio_source(channel)->read (buf, pos, cnt);
1102 AudioRegion::exportme (Session& /*session*/, ARDOUR::ExportSpecification& /*spec*/)
1105 // const framecnt_t blocksize = 4096;
1106 // framecnt_t to_read;
1109 // spec.channels = _sources.size();
1111 // if (spec.prepare (blocksize, session.frame_rate())) {
1116 // spec.total_frames = _length;
1118 // while (spec.pos < _length && !spec.stop) {
1121 // /* step 1: interleave */
1123 // to_read = min (_length - spec.pos, blocksize);
1125 // if (spec.channels == 1) {
1127 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1133 // Sample buf[blocksize];
1135 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1137 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1141 // for (framecnt_t x = 0; x < to_read; ++x) {
1142 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1147 // if (spec.process (to_read)) {
1151 // spec.pos += to_read;
1152 // spec.progress = (double) spec.pos /_length;
1159 // spec.running = false;
1160 // spec.status = status;
1168 AudioRegion::set_scale_amplitude (gain_t g)
1170 boost::shared_ptr<Playlist> pl (playlist());
1172 _scale_amplitude = g;
1174 /* tell the diskstream we're in */
1177 pl->ContentsChanged();
1180 /* tell everybody else */
1182 send_change (PropertyChange (Properties::scale_amplitude));
1185 /** @return the maximum (linear) amplitude of the region, or a -ve
1186 * number if the Progress object reports that the process was cancelled.
1189 AudioRegion::maximum_amplitude (Progress* p) const
1191 framepos_t fpos = _start;
1192 framepos_t const fend = _start + _length;
1195 framecnt_t const blocksize = 64 * 1024;
1196 Sample buf[blocksize];
1198 while (fpos < fend) {
1202 framecnt_t const to_read = min (fend - fpos, blocksize);
1204 for (n = 0; n < n_channels(); ++n) {
1208 if (read_raw_internal (buf, fpos, to_read, n) != to_read) {
1212 maxamp = compute_peak (buf, to_read, maxamp);
1217 p->set_progress (float (fpos - _start) / _length);
1218 if (p->cancelled ()) {
1227 /** Normalize using a given maximum amplitude and target, so that region
1228 * _scale_amplitude becomes target / max_amplitude.
1231 AudioRegion::normalize (float max_amplitude, float target_dB)
1233 gain_t target = dB_to_coefficient (target_dB);
1235 if (target == 1.0f) {
1236 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1237 that we may have clipped.
1239 target -= FLT_EPSILON;
1242 if (max_amplitude == 0.0f) {
1243 /* don't even try */
1247 if (max_amplitude == target) {
1248 /* we can't do anything useful */
1252 set_scale_amplitude (target / max_amplitude);
1256 AudioRegion::fade_in_changed ()
1258 send_change (PropertyChange (Properties::fade_in));
1262 AudioRegion::fade_out_changed ()
1264 send_change (PropertyChange (Properties::fade_out));
1268 AudioRegion::envelope_changed ()
1270 send_change (PropertyChange (Properties::envelope));
1274 AudioRegion::suspend_fade_in ()
1276 if (++_fade_in_suspended == 1) {
1277 if (fade_in_is_default()) {
1278 set_fade_in_active (false);
1284 AudioRegion::resume_fade_in ()
1286 if (--_fade_in_suspended == 0 && _fade_in_suspended) {
1287 set_fade_in_active (true);
1292 AudioRegion::suspend_fade_out ()
1294 if (++_fade_out_suspended == 1) {
1295 if (fade_out_is_default()) {
1296 set_fade_out_active (false);
1302 AudioRegion::resume_fade_out ()
1304 if (--_fade_out_suspended == 0 &&_fade_out_suspended) {
1305 set_fade_out_active (true);
1310 AudioRegion::speed_mismatch (float sr) const
1312 if (_sources.empty()) {
1313 /* impossible, but ... */
1317 float fsr = audio_source()->sample_rate();
1323 AudioRegion::source_offset_changed ()
1325 /* XXX this fixes a crash that should not occur. It does occur
1326 becauses regions are not being deleted when a session
1327 is unloaded. That bug must be fixed.
1330 if (_sources.empty()) {
1334 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1336 if (afs && afs->destructive()) {
1337 // set_start (source()->natural_position(), this);
1338 set_position (source()->natural_position());
1342 boost::shared_ptr<AudioSource>
1343 AudioRegion::audio_source (uint32_t n) const
1345 // Guaranteed to succeed (use a static cast for speed?)
1346 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1350 AudioRegion::adjust_transients (frameoffset_t delta)
1352 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1353 (*x) = (*x) + delta;
1356 send_change (PropertyChange (Properties::valid_transients));
1362 AudioRegion::update_transient (framepos_t old_position, framepos_t new_position)
1364 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1365 if ((*x) == old_position) {
1366 (*x) = new_position;
1367 send_change (PropertyChange (Properties::valid_transients));
1377 AudioRegion::add_transient (framepos_t where)
1379 _transients.push_back(where);
1380 _valid_transients = true;
1382 send_change (PropertyChange (Properties::valid_transients));
1386 AudioRegion::remove_transient (framepos_t where)
1388 _transients.remove(where);
1389 _valid_transients = true;
1391 send_change (PropertyChange (Properties::valid_transients));
1395 AudioRegion::set_transients (AnalysisFeatureList& results)
1397 _transients.clear();
1398 _transients = results;
1399 _valid_transients = true;
1401 send_change (PropertyChange (Properties::valid_transients));
1407 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1409 boost::shared_ptr<Playlist> pl = playlist();
1415 if (_valid_transients && !force_new) {
1416 results = _transients;
1420 SourceList::iterator s;
1422 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1423 if (!(*s)->has_been_analysed()) {
1424 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1429 if (s == _sources.end()) {
1430 /* all sources are analyzed, merge data from each one */
1432 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1434 /* find the set of transients within the bounds of this region */
1436 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1437 (*s)->transients.end(),
1440 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1441 (*s)->transients.end(),
1446 results.insert (results.end(), low, high);
1449 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1451 /* translate all transients to current position */
1453 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1458 _transients = results;
1459 _valid_transients = true;
1464 /* no existing/complete transient info */
1466 static bool analyse_dialog_shown = false; /* global per instance of Ardour */
1468 if (!Config->get_auto_analyse_audio()) {
1469 if (!analyse_dialog_shown) {
1470 pl->session().Dialog (_("\
1471 You have requested an operation that requires audio analysis.\n\n\
1472 You currently have \"auto-analyse-audio\" disabled, which means \
1473 that transient data must be generated every time it is required.\n\n\
1474 If you are doing work that will require transient data on a \
1475 regular basis, you should probably enable \"auto-analyse-audio\" \
1476 then quit ardour and restart.\n\n\
1477 This dialog will not display again. But you may notice a slight delay \
1478 in this and future transient-detection operations.\n\
1480 analyse_dialog_shown = true;
1484 TransientDetector t (pl->session().frame_rate());
1485 bool existing_results = !results.empty();
1487 _transients.clear ();
1488 _valid_transients = false;
1490 for (uint32_t i = 0; i < n_channels(); ++i) {
1492 AnalysisFeatureList these_results;
1496 if (t.run ("", this, i, these_results)) {
1500 /* translate all transients to give absolute position */
1502 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1508 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1511 if (!results.empty()) {
1512 if (existing_results) {
1514 /* merge our transients into the existing ones, then clean up
1518 results.insert (results.end(), _transients.begin(), _transients.end());
1519 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1522 /* make sure ours are clean too */
1524 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1528 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1529 results = _transients;
1532 _valid_transients = true;
1537 /** Find areas of `silence' within a region.
1539 * @param threshold Threshold below which signal is considered silence (as a sample value)
1540 * @param min_length Minimum length of silent period to be reported.
1541 * @return Silent intervals, measured relative to the region start in the source
1545 AudioRegion::find_silence (Sample threshold, framecnt_t min_length, InterThreadInfo& itt) const
1547 framecnt_t const block_size = 64 * 1024;
1548 boost::scoped_array<Sample> loudest (new Sample[block_size]);
1549 boost::scoped_array<Sample> buf (new Sample[block_size]);
1551 framepos_t pos = _start;
1552 framepos_t const end = _start + _length - 1;
1554 AudioIntervalResult silent_periods;
1556 bool in_silence = false;
1557 frameoffset_t silence_start = 0;
1559 while (pos < end && !itt.cancel) {
1561 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1562 memset (loudest.get(), 0, sizeof (Sample) * block_size);
1563 for (uint32_t n = 0; n < n_channels(); ++n) {
1565 read_raw_internal (buf.get(), pos, block_size, n);
1566 for (framecnt_t i = 0; i < block_size; ++i) {
1567 loudest[i] = max (loudest[i], abs (buf[i]));
1571 /* now look for silence */
1572 for (framecnt_t i = 0; i < block_size; ++i) {
1573 bool const silence = abs (loudest[i]) < threshold;
1574 if (silence && !in_silence) {
1575 /* non-silence to silence */
1577 silence_start = pos + i;
1578 } else if (!silence && in_silence) {
1579 /* silence to non-silence */
1581 if (pos + i - 1 - silence_start >= min_length) {
1582 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1588 itt.progress = (end-pos)/(double)_length;
1591 if (in_silence && end - 1 - silence_start >= min_length) {
1592 /* last block was silent, so finish off the last period */
1593 silent_periods.push_back (std::make_pair (silence_start, end));
1598 return silent_periods;
1605 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)
1607 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (framecnt_t) npeaks, (framepos_t) start, (framecnt_t) cnt, n_chan,samples_per_unit);
1610 uint32_t region_length_from_c (void *arg)
1613 return ((AudioRegion *) arg)->length();
1616 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1618 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;