2 Copyright (C) 2000-2006 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include <glibmm/thread.h>
30 #include "pbd/basename.h"
31 #include "pbd/xml++.h"
32 #include "pbd/stacktrace.h"
33 #include "pbd/enumwriter.h"
34 #include "pbd/convert.h"
36 #include "evoral/Curve.hpp"
38 #include "ardour/audioregion.h"
39 #include "ardour/debug.h"
40 #include "ardour/session.h"
41 #include "ardour/gain.h"
42 #include "ardour/dB.h"
43 #include "ardour/playlist.h"
44 #include "ardour/audiofilesource.h"
45 #include "ardour/region_factory.h"
46 #include "ardour/runtime_functions.h"
47 #include "ardour/transient_detector.h"
53 using namespace ARDOUR;
57 namespace Properties {
58 PBD::PropertyDescriptor<bool> envelope_active;
59 PBD::PropertyDescriptor<bool> default_fade_in;
60 PBD::PropertyDescriptor<bool> default_fade_out;
61 PBD::PropertyDescriptor<bool> fade_in_active;
62 PBD::PropertyDescriptor<bool> fade_out_active;
63 PBD::PropertyDescriptor<float> scale_amplitude;
68 AudioRegion::make_property_quarks ()
70 Properties::envelope_active.property_id = g_quark_from_static_string (X_("envelope-active"));
71 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for envelope-active = %1\n", Properties::envelope_active.property_id));
72 Properties::default_fade_in.property_id = g_quark_from_static_string (X_("default-fade-in"));
73 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for default-fade-in = %1\n", Properties::default_fade_in.property_id));
74 Properties::default_fade_out.property_id = g_quark_from_static_string (X_("default-fade-out"));
75 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for default-fade-out = %1\n", Properties::default_fade_out.property_id));
76 Properties::fade_in_active.property_id = g_quark_from_static_string (X_("fade-in-active"));
77 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for fade-in-active = %1\n", Properties::fade_in_active.property_id));
78 Properties::fade_out_active.property_id = g_quark_from_static_string (X_("fade-out-active"));
79 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for fade-out-active = %1\n", Properties::fade_out_active.property_id));
80 Properties::scale_amplitude.property_id = g_quark_from_static_string (X_("scale-amplitude"));
81 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for scale-amplitude = %1\n", Properties::scale_amplitude.property_id));
85 AudioRegion::register_properties ()
87 /* no need to register parent class properties */
89 add_property (_envelope_active);
90 add_property (_default_fade_in);
91 add_property (_default_fade_out);
92 add_property (_fade_in_active);
93 add_property (_fade_out_active);
94 add_property (_scale_amplitude);
97 #define AUDIOREGION_STATE_DEFAULT \
98 _envelope_active (Properties::envelope_active, false) \
99 , _default_fade_in (Properties::default_fade_in, true) \
100 , _default_fade_out (Properties::default_fade_out, true) \
101 , _fade_in_active (Properties::fade_in_active, true) \
102 , _fade_out_active (Properties::fade_out_active, true) \
103 , _scale_amplitude (Properties::scale_amplitude, 1.0)
105 #define AUDIOREGION_COPY_STATE(other) \
106 _envelope_active (Properties::envelope_active, other->_envelope_active) \
107 , _default_fade_in (Properties::default_fade_in, other->_default_fade_in) \
108 , _default_fade_out (Properties::default_fade_out, other->_default_fade_out) \
109 , _fade_in_active (Properties::fade_in_active, other->_fade_in_active) \
110 , _fade_out_active (Properties::fade_out_active, other->_fade_out_active) \
111 , _scale_amplitude (Properties::scale_amplitude, other->_scale_amplitude)
112 /* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
117 register_properties ();
119 set_default_fades ();
120 set_default_envelope ();
122 listen_to_my_curves ();
123 connect_to_analysis_changed ();
124 connect_to_header_position_offset_changed ();
127 /** Constructor for use by derived types only */
128 AudioRegion::AudioRegion (Session& s, framepos_t start, framecnt_t len, std::string name)
129 : Region (s, start, len, name, DataType::AUDIO)
130 , AUDIOREGION_STATE_DEFAULT
132 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
133 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
134 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
135 , _fade_in_suspended (0)
136 , _fade_out_suspended (0)
139 assert (_sources.size() == _master_sources.size());
142 /** Basic AudioRegion constructor */
143 AudioRegion::AudioRegion (const SourceList& srcs)
145 , AUDIOREGION_STATE_DEFAULT
146 , _automatable(srcs[0]->session())
147 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
148 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
149 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
150 , _fade_in_suspended (0)
151 , _fade_out_suspended (0)
154 assert (_sources.size() == _master_sources.size());
157 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes64_t offset, bool offset_relative)
158 : Region (other, offset, offset_relative)
159 , AUDIOREGION_COPY_STATE (other)
160 , _automatable (other->session())
161 , _fade_in (new AutomationList (*other->_fade_in))
162 , _fade_out (new AutomationList (*other->_fade_out))
163 /* As far as I can see, the _envelope's times are relative to region position, and have nothing
164 to do with sources (and hence _start). So when we copy the envelope, we just use the supplied offset.
166 , _envelope (new AutomationList (*other->_envelope, offset, other->_length))
167 , _fade_in_suspended (0)
168 , _fade_out_suspended (0)
170 /* don't use init here, because we got fade in/out from the other region
172 register_properties ();
173 listen_to_my_curves ();
174 connect_to_analysis_changed ();
175 connect_to_header_position_offset_changed ();
177 assert(_type == DataType::AUDIO);
178 assert (_sources.size() == _master_sources.size());
181 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& srcs)
182 : Region (boost::static_pointer_cast<const Region>(other), srcs)
183 , AUDIOREGION_COPY_STATE (other)
184 , _automatable (other->session())
185 , _fade_in (new AutomationList (*other->_fade_in))
186 , _fade_out (new AutomationList (*other->_fade_out))
187 , _envelope (new AutomationList (*other->_envelope))
188 , _fade_in_suspended (0)
189 , _fade_out_suspended (0)
191 /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
193 register_properties ();
195 listen_to_my_curves ();
196 connect_to_analysis_changed ();
197 connect_to_header_position_offset_changed ();
199 assert (_sources.size() == _master_sources.size());
202 AudioRegion::AudioRegion (SourceList& srcs)
204 , AUDIOREGION_STATE_DEFAULT
205 , _automatable(srcs[0]->session())
206 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
207 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
208 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
209 , _fade_in_suspended (0)
210 , _fade_out_suspended (0)
214 assert(_type == DataType::AUDIO);
215 assert (_sources.size() == _master_sources.size());
218 AudioRegion::~AudioRegion ()
223 AudioRegion::post_set ()
226 _sync_position = _start;
229 /* return to default fades if the existing ones are too long */
231 if (_left_of_split) {
232 if (_fade_in->back()->when >= _length) {
233 set_default_fade_in ();
235 set_default_fade_out ();
236 _left_of_split = false;
239 if (_right_of_split) {
240 if (_fade_out->back()->when >= _length) {
241 set_default_fade_out ();
244 set_default_fade_in ();
245 _right_of_split = false;
248 /* If _length changed, adjust our gain envelope accordingly */
249 _envelope->truncate_end (_length);
253 AudioRegion::connect_to_analysis_changed ()
255 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
256 (*i)->AnalysisChanged.connect_same_thread (*this, boost::bind (&AudioRegion::invalidate_transients, this));
261 AudioRegion::connect_to_header_position_offset_changed ()
263 set<boost::shared_ptr<Source> > unique_srcs;
265 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
267 /* connect only once to HeaderPositionOffsetChanged, even if sources are replicated
270 if (unique_srcs.find (*i) == unique_srcs.end ()) {
271 unique_srcs.insert (*i);
272 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
274 afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
281 AudioRegion::listen_to_my_curves ()
283 _envelope->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::envelope_changed, this));
284 _fade_in->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_in_changed, this));
285 _fade_out->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_out_changed, this));
289 AudioRegion::set_envelope_active (bool yn)
291 if (envelope_active() != yn) {
292 _envelope_active = yn;
293 send_change (PropertyChange (Properties::envelope_active));
298 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
300 if (chan_n >= _sources.size()) {
304 if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
307 if (_scale_amplitude != 1.0f) {
308 for (nframes_t n = 0; n < npeaks; ++n) {
309 buf[n].max *= _scale_amplitude;
310 buf[n].min *= _scale_amplitude;
318 AudioRegion::read (Sample* buf, framepos_t timeline_position, framecnt_t cnt, int channel) const
320 /* raw read, no fades, no gain, nada */
321 return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
325 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
326 framepos_t file_position, framecnt_t cnt, uint32_t chan_n,
327 framecnt_t read_frames, framecnt_t skip_frames) const
329 /* regular diskstream/butler read complete with fades etc */
330 return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer,
331 file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
335 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
336 framepos_t position, framecnt_t cnt, uint32_t chan_n) const
338 /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
340 return _read_at (_master_sources, _master_sources.front()->length(_master_sources.front()->timeline_position()),
341 buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0, ReadOps (0));
345 AudioRegion::_read_at (const SourceList& /*srcs*/, framecnt_t limit,
346 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
350 framecnt_t /*read_frames*/,
351 framecnt_t /*skip_frames*/,
354 frameoffset_t internal_offset;
355 frameoffset_t buf_offset;
357 bool raw = (rops == ReadOpsNone);
359 if (n_channels() == 0) {
363 if (muted() && !raw) {
364 return 0; /* read nothing */
367 /* precondition: caller has verified that we cover the desired section */
369 if (position < _position) {
371 buf_offset = _position - position;
374 internal_offset = position - _position;
378 if (internal_offset >= limit) {
379 return 0; /* read nothing */
382 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
383 return 0; /* read nothing */
386 if (opaque() || raw) {
387 /* overwrite whatever is there */
388 mixdown_buffer = buf + buf_offset;
390 mixdown_buffer += buf_offset;
393 if (rops & ReadOpsCount) {
394 _read_data_count = 0;
397 if (chan_n < n_channels()) {
399 boost::shared_ptr<AudioSource> src = audio_source(chan_n);
400 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
401 return 0; /* "read nothing" */
404 if (rops & ReadOpsCount) {
405 _read_data_count += src->read_data_count();
410 /* track is N-channel, this region has less channels; silence the ones
414 if (Config->get_replicate_missing_region_channels()) {
415 /* track is N-channel, this region has less channels, so use a relevant channel
418 uint32_t channel = n_channels() % chan_n;
419 boost::shared_ptr<AudioSource> src = audio_source (channel);
421 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
422 return 0; /* "read nothing" */
425 /* adjust read data count appropriately since this was a duplicate read */
426 src->dec_read_data_count (to_read);
428 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
432 if (rops & ReadOpsFades) {
436 if (_fade_in_active && _session.config.get_use_region_fades()) {
438 nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
440 /* see if this read is within the fade in */
442 if (internal_offset < fade_in_length) {
446 fi_limit = min (to_read, fade_in_length - internal_offset);
449 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
451 for (nframes_t n = 0; n < fi_limit; ++n) {
452 mixdown_buffer[n] *= gain_buffer[n];
459 if (_fade_out_active && _session.config.get_use_region_fades()) {
461 /* see if some part of this read is within the fade out */
463 /* ................. >| REGION
469 limit - fade_out_length
472 ^internal_offset + to_read
474 we need the intersection of [internal_offset,internal_offset+to_read] with
475 [limit - fade_out_length, limit]
480 nframes_t fade_out_length = (nframes_t) _fade_out->back()->when;
481 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
482 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
484 if (fade_interval_end > fade_interval_start) {
485 /* (part of the) the fade out is in this buffer */
487 nframes_t fo_limit = fade_interval_end - fade_interval_start;
488 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
489 nframes_t fade_offset = fade_interval_start - internal_offset;
491 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
493 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
494 mixdown_buffer[m] *= gain_buffer[n];
501 /* Regular gain curves and scaling */
503 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
504 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
506 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
507 for (nframes_t n = 0; n < to_read; ++n) {
508 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
511 for (nframes_t n = 0; n < to_read; ++n) {
512 mixdown_buffer[n] *= gain_buffer[n];
515 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
517 // XXX this should be using what in 2.0 would have been:
518 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
520 for (nframes_t n = 0; n < to_read; ++n) {
521 mixdown_buffer[n] *= _scale_amplitude;
525 if (!opaque() && (buf != mixdown_buffer)) {
527 /* gack. the things we do for users.
532 for (nframes_t n = 0; n < to_read; ++n) {
533 buf[n] += mixdown_buffer[n];
541 AudioRegion::state ()
543 XMLNode& node (Region::state ());
546 LocaleGuard lg (X_("POSIX"));
548 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
549 node.add_property ("channels", buf);
551 Stateful::add_properties (node);
553 child = node.add_child ("Envelope");
555 bool default_env = false;
557 // If there are only two points, the points are in the start of the region and the end of the region
558 // so, if they are both at 1.0f, that means the default region.
560 if (_envelope->size() == 2 &&
561 _envelope->front()->value == 1.0f &&
562 _envelope->back()->value==1.0f) {
563 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
569 child->add_property ("default", "yes");
571 child->add_child_nocopy (_envelope->get_state ());
574 child = node.add_child (X_("FadeIn"));
576 if (_default_fade_in) {
577 child->add_property ("default", "yes");
579 child->add_child_nocopy (_fade_in->get_state ());
582 child = node.add_child (X_("FadeOut"));
584 if (_default_fade_out) {
585 child->add_property ("default", "yes");
587 child->add_child_nocopy (_fade_out->get_state ());
594 AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_changed, bool send)
596 const XMLNodeList& nlist = node.children();
597 const XMLProperty *prop;
598 LocaleGuard lg (X_("POSIX"));
599 boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
601 suspend_property_changes ();
604 the_playlist->freeze ();
608 /* this will set all our State members and stuff controlled by the Region.
609 It should NOT send any changed signals - that is our responsibility.
612 Region::_set_state (node, version, what_changed, false);
614 if ((prop = node.property ("scale-gain")) != 0) {
615 float a = atof (prop->value().c_str());
616 if (a != _scale_amplitude) {
617 _scale_amplitude = a;
618 what_changed.add (Properties::scale_amplitude);
622 /* Now find envelope description and other related child items */
624 _envelope->freeze ();
626 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
632 if (child->name() == "Envelope") {
636 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child, version)) {
637 set_default_envelope ();
640 _envelope->set_max_xval (_length);
641 _envelope->truncate_end (_length);
644 } else if (child->name() == "FadeIn") {
648 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
649 set_default_fade_in ();
651 XMLNode* grandchild = child->child ("AutomationList");
653 _fade_in->set_state (*grandchild, version);
657 if ((prop = child->property ("active")) != 0) {
658 if (string_is_affirmative (prop->value())) {
659 set_fade_in_active (true);
661 set_fade_in_active (false);
665 } else if (child->name() == "FadeOut") {
669 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
670 set_default_fade_out ();
672 XMLNode* grandchild = child->child ("AutomationList");
674 _fade_out->set_state (*grandchild, version);
678 if ((prop = child->property ("active")) != 0) {
679 if (string_is_affirmative (prop->value())) {
680 set_fade_out_active (true);
682 set_fade_out_active (false);
690 resume_property_changes ();
693 send_change (what_changed);
697 the_playlist->thaw ();
704 AudioRegion::set_state (const XMLNode& node, int version)
706 PropertyChange what_changed;
707 return _set_state (node, version, what_changed, true);
711 AudioRegion::set_fade_in_shape (FadeShape shape)
713 set_fade_in (shape, (nframes_t) _fade_in->back()->when);
717 AudioRegion::set_fade_out_shape (FadeShape shape)
719 set_fade_out (shape, (nframes_t) _fade_out->back()->when);
723 AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
729 send_change (PropertyChange (Properties::fade_in));
733 AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
740 _fade_in->fast_simple_add (0.0, 0.0);
741 _fade_in->fast_simple_add (len, 1.0);
745 _fade_in->fast_simple_add (0, 0);
746 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
747 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
748 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
749 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
750 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
751 _fade_in->fast_simple_add (len, 1);
755 _fade_in->fast_simple_add (0, 0);
756 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
757 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
758 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
759 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
760 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
761 _fade_in->fast_simple_add (len * 0.767281, 1);
762 _fade_in->fast_simple_add (len, 1);
766 _fade_in->fast_simple_add (0, 0);
767 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
768 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
769 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
770 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
771 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
772 _fade_in->fast_simple_add (len, 1);
776 _fade_in->fast_simple_add (0, 0);
777 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
778 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
779 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
780 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
781 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
782 _fade_in->fast_simple_add (len, 1);
790 AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
792 _fade_out->freeze ();
796 send_change (PropertyChange (Properties::fade_in));
800 AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
802 _fade_out->freeze ();
807 _fade_out->fast_simple_add (len * 0, 1);
808 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
809 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
810 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
811 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
812 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
813 _fade_out->fast_simple_add (len * 1, 0);
817 _fade_out->fast_simple_add (len * 0, 1);
818 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
819 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
820 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
821 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
822 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
823 _fade_out->fast_simple_add (len * 1, 0);
827 _fade_out->fast_simple_add (len * 0, 1);
828 _fade_out->fast_simple_add (len * 0.305556, 1);
829 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
830 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
831 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
832 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
833 _fade_out->fast_simple_add (len * 1, 0);
837 _fade_out->fast_simple_add (len * 0, 1);
838 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
839 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
840 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
841 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
842 _fade_out->fast_simple_add (len * 1, 0);
846 _fade_out->fast_simple_add (len * 0, 1);
847 _fade_out->fast_simple_add (len * 1, 0);
855 AudioRegion::set_fade_in_length (framecnt_t len)
861 bool changed = _fade_in->extend_to (len);
864 _default_fade_in = false;
865 send_change (PropertyChange (Properties::fade_in));
870 AudioRegion::set_fade_out_length (framecnt_t len)
876 bool changed = _fade_out->extend_to (len);
879 _default_fade_out = false;
880 send_change (PropertyChange (Properties::fade_out));
885 AudioRegion::set_fade_in_active (bool yn)
887 if (yn == _fade_in_active) {
891 _fade_in_active = yn;
892 send_change (PropertyChange (Properties::fade_in_active));
896 AudioRegion::set_fade_out_active (bool yn)
898 if (yn == _fade_out_active) {
901 _fade_out_active = yn;
902 send_change (PropertyChange (Properties::fade_out_active));
906 AudioRegion::fade_in_is_default () const
908 return _fade_in->size() == 2 && _fade_in->front()->when == 0 && _fade_in->back()->when == 64;
912 AudioRegion::fade_out_is_default () const
914 return _fade_out->size() == 2 && _fade_out->front()->when == 0 && _fade_out->back()->when == 64;
918 AudioRegion::set_default_fade_in ()
920 _fade_in_suspended = 0;
921 set_fade_in (Linear, 64);
925 AudioRegion::set_default_fade_out ()
927 _fade_out_suspended = 0;
928 set_fade_out (Linear, 64);
932 AudioRegion::set_default_fades ()
934 set_default_fade_in ();
935 set_default_fade_out ();
939 AudioRegion::set_default_envelope ()
941 _envelope->freeze ();
943 _envelope->fast_simple_add (0, 1.0f);
944 _envelope->fast_simple_add (_length, 1.0f);
949 AudioRegion::recompute_at_end ()
951 /* our length has changed. recompute a new final point by interpolating
952 based on the the existing curve.
955 _envelope->freeze ();
956 _envelope->truncate_end (_length);
957 _envelope->set_max_xval (_length);
960 if (_left_of_split) {
961 set_default_fade_out ();
962 _left_of_split = false;
963 } else if (_fade_out->back()->when > _length) {
964 _fade_out->extend_to (_length);
965 send_change (PropertyChange (Properties::fade_out));
968 if (_fade_in->back()->when > _length) {
969 _fade_in->extend_to (_length);
970 send_change (PropertyChange (Properties::fade_in));
975 AudioRegion::recompute_at_start ()
977 /* as above, but the shift was from the front */
979 _envelope->truncate_start (_length);
981 if (_right_of_split) {
982 set_default_fade_in ();
983 _right_of_split = false;
984 } else if (_fade_in->back()->when > _length) {
985 _fade_in->extend_to (_length);
986 send_change (PropertyChange (Properties::fade_in));
989 if (_fade_out->back()->when > _length) {
990 _fade_out->extend_to (_length);
991 send_change (PropertyChange (Properties::fade_out));
996 AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr<Region> >& v) const
1002 if (_sources.size() < 2) {
1006 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
1008 srcs.push_back (*i);
1012 if (_sources.size() == 2) {
1020 new_name += ('0' + n + 1);
1023 /* create a copy with just one source. prevent if from being thought of as
1024 "whole file" even if it covers the entire source file(s).
1029 plist.add (Properties::start, _start.val());
1030 plist.add (Properties::length, _length.val());
1031 plist.add (Properties::name, new_name);
1032 plist.add (Properties::layer, _layer.val());
1034 v.push_back(RegionFactory::create (srcs, plist));
1035 v.back()->set_whole_file (false);
1044 AudioRegion::read_raw_internal (Sample* buf, framepos_t pos, framecnt_t cnt, int channel) const
1046 return audio_source()->read (buf, pos, cnt, channel);
1050 AudioRegion::exportme (Session& /*session*/, ARDOUR::ExportSpecification& /*spec*/)
1053 // const nframes_t blocksize = 4096;
1054 // nframes_t to_read;
1057 // spec.channels = _sources.size();
1059 // if (spec.prepare (blocksize, session.frame_rate())) {
1064 // spec.total_frames = _length;
1066 // while (spec.pos < _length && !spec.stop) {
1069 // /* step 1: interleave */
1071 // to_read = min (_length - spec.pos, blocksize);
1073 // if (spec.channels == 1) {
1075 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1081 // Sample buf[blocksize];
1083 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1085 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1089 // for (nframes_t x = 0; x < to_read; ++x) {
1090 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1095 // if (spec.process (to_read)) {
1099 // spec.pos += to_read;
1100 // spec.progress = (double) spec.pos /_length;
1107 // spec.running = false;
1108 // spec.status = status;
1116 AudioRegion::set_scale_amplitude (gain_t g)
1118 boost::shared_ptr<Playlist> pl (playlist());
1120 _scale_amplitude = g;
1122 /* tell the diskstream we're in */
1125 pl->ContentsChanged();
1128 /* tell everybody else */
1130 send_change (PropertyChange (Properties::scale_amplitude));
1133 /** @return the maximum (linear) amplitude of the region */
1135 AudioRegion::maximum_amplitude () const
1137 framepos_t fpos = _start;
1138 framepos_t const fend = _start + _length;
1141 framecnt_t const blocksize = 64 * 1024;
1142 Sample buf[blocksize];
1144 while (fpos < fend) {
1148 framecnt_t const to_read = min (fend - fpos, blocksize);
1150 for (n = 0; n < n_channels(); ++n) {
1154 if (read_raw_internal (buf, fpos, to_read, 0) != to_read) {
1158 maxamp = compute_peak (buf, to_read, maxamp);
1167 /** Normalize using a given maximum amplitude and target, so that region
1168 * _scale_amplitude becomes target / max_amplitude.
1171 AudioRegion::normalize (float max_amplitude, float target_dB)
1173 gain_t target = dB_to_coefficient (target_dB);
1175 if (target == 1.0f) {
1176 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1177 that we may have clipped.
1179 target -= FLT_EPSILON;
1182 if (max_amplitude == 0.0f) {
1183 /* don't even try */
1187 if (max_amplitude == target) {
1188 /* we can't do anything useful */
1192 set_scale_amplitude (target / max_amplitude);
1196 AudioRegion::fade_in_changed ()
1198 send_change (PropertyChange (Properties::fade_in));
1202 AudioRegion::fade_out_changed ()
1204 send_change (PropertyChange (Properties::fade_out));
1208 AudioRegion::envelope_changed ()
1210 send_change (PropertyChange (Properties::envelope));
1214 AudioRegion::suspend_fade_in ()
1216 if (++_fade_in_suspended == 1) {
1217 if (fade_in_is_default()) {
1218 set_fade_in_active (false);
1224 AudioRegion::resume_fade_in ()
1226 if (--_fade_in_suspended == 0 && _fade_in_suspended) {
1227 set_fade_in_active (true);
1232 AudioRegion::suspend_fade_out ()
1234 if (++_fade_out_suspended == 1) {
1235 if (fade_out_is_default()) {
1236 set_fade_out_active (false);
1242 AudioRegion::resume_fade_out ()
1244 if (--_fade_out_suspended == 0 &&_fade_out_suspended) {
1245 set_fade_out_active (true);
1250 AudioRegion::speed_mismatch (float sr) const
1252 if (_sources.empty()) {
1253 /* impossible, but ... */
1257 float fsr = audio_source()->sample_rate();
1263 AudioRegion::source_offset_changed ()
1265 /* XXX this fixes a crash that should not occur. It does occur
1266 becauses regions are not being deleted when a session
1267 is unloaded. That bug must be fixed.
1270 if (_sources.empty()) {
1274 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1276 if (afs && afs->destructive()) {
1277 // set_start (source()->natural_position(), this);
1278 set_position (source()->natural_position(), this);
1282 boost::shared_ptr<AudioSource>
1283 AudioRegion::audio_source (uint32_t n) const
1285 // Guaranteed to succeed (use a static cast for speed?)
1286 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1290 AudioRegion::adjust_transients (nframes64_t delta)
1292 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1293 (*x) = (*x) + delta;
1296 send_change (PropertyChange (Properties::valid_transients));
1302 AudioRegion::update_transient (nframes64_t old_position, nframes64_t new_position)
1304 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1305 if ((*x) == old_position) {
1306 (*x) = new_position;
1307 send_change (PropertyChange (Properties::valid_transients));
1317 AudioRegion::add_transient (nframes64_t where)
1319 _transients.push_back(where);
1320 _valid_transients = true;
1322 send_change (PropertyChange (Properties::valid_transients));
1326 AudioRegion::remove_transient (nframes64_t where)
1328 _transients.remove(where);
1329 _valid_transients = true;
1331 send_change (PropertyChange (Properties::valid_transients));
1335 AudioRegion::set_transients (AnalysisFeatureList& results)
1337 _transients.clear();
1338 _transients = results;
1339 _valid_transients = true;
1341 send_change (PropertyChange (Properties::valid_transients));
1347 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1349 boost::shared_ptr<Playlist> pl = playlist();
1355 if (_valid_transients && !force_new) {
1356 results = _transients;
1360 SourceList::iterator s;
1362 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1363 if (!(*s)->has_been_analysed()) {
1364 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1369 if (s == _sources.end()) {
1370 /* all sources are analyzed, merge data from each one */
1372 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1374 /* find the set of transients within the bounds of this region */
1376 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1377 (*s)->transients.end(),
1380 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1381 (*s)->transients.end(),
1386 results.insert (results.end(), low, high);
1389 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1391 /* translate all transients to current position */
1393 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1398 _transients = results;
1399 _valid_transients = true;
1404 /* no existing/complete transient info */
1406 static bool analyse_dialog_shown = false; /* global per instance of Ardour */
1408 if (!Config->get_auto_analyse_audio()) {
1409 if (!analyse_dialog_shown) {
1410 pl->session().Dialog (_("\
1411 You have requested an operation that requires audio analysis.\n\n \
1412 You currently have \"auto-analyse-audio\" disabled, which means\n\
1413 that transient data must be generated every time it is required.\n\n\
1414 If you are doing work that will require transient data on a\n\
1415 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1416 +then quit ardour and restart.\n\n\
1417 +This dialog will not display again. But you may notice a slight delay\n\
1418 +in this and future transient-detection operations.\n\
1420 analyse_dialog_shown = true;
1424 TransientDetector t (pl->session().frame_rate());
1425 bool existing_results = !results.empty();
1427 _transients.clear ();
1428 _valid_transients = false;
1430 for (uint32_t i = 0; i < n_channels(); ++i) {
1432 AnalysisFeatureList these_results;
1436 if (t.run ("", this, i, these_results)) {
1440 /* translate all transients to give absolute position */
1442 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1448 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1451 if (!results.empty()) {
1452 if (existing_results) {
1454 /* merge our transients into the existing ones, then clean up
1458 results.insert (results.end(), _transients.begin(), _transients.end());
1459 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1462 /* make sure ours are clean too */
1464 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1468 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1469 results = _transients;
1472 _valid_transients = true;
1477 /** Find areas of `silence' within a region.
1479 * @param threshold Threshold below which signal is considered silence (as a sample value)
1480 * @param min_length Minimum length of silent period to be reported.
1481 * @return Silent periods; first of pair is the offset within the region, second is the length of the period
1484 std::list<std::pair<frameoffset_t, framecnt_t> >
1485 AudioRegion::find_silence (Sample threshold, framecnt_t min_length, InterThreadInfo& itt) const
1487 framecnt_t const block_size = 64 * 1024;
1488 Sample loudest[block_size];
1489 Sample buf[block_size];
1491 framepos_t pos = _start;
1492 framepos_t const end = _start + _length - 1;
1494 std::list<std::pair<frameoffset_t, framecnt_t> > silent_periods;
1496 bool in_silence = false;
1497 frameoffset_t silence_start = 0;
1500 while (pos < end && !itt.cancel) {
1502 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1503 memset (loudest, 0, sizeof (Sample) * block_size);
1504 for (uint32_t n = 0; n < n_channels(); ++n) {
1506 read_raw_internal (buf, pos, block_size, n);
1507 for (framecnt_t i = 0; i < block_size; ++i) {
1508 loudest[i] = max (loudest[i], abs (buf[i]));
1512 /* now look for silence */
1513 for (framecnt_t i = 0; i < block_size; ++i) {
1514 silence = abs (loudest[i]) < threshold;
1515 if (silence && !in_silence) {
1516 /* non-silence to silence */
1518 silence_start = pos + i;
1519 } else if (!silence && in_silence) {
1520 /* silence to non-silence */
1522 if (pos + i - 1 - silence_start >= min_length) {
1523 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1529 itt.progress = (end-pos)/(double)_length;
1532 if (in_silence && end - 1 - silence_start >= min_length) {
1533 /* last block was silent, so finish off the last period */
1534 silent_periods.push_back (std::make_pair (silence_start, end));
1539 return silent_periods;
1546 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)
1548 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (framecnt_t) npeaks, (framepos_t) start, (framecnt_t) cnt, n_chan,samples_per_unit);
1551 uint32_t region_length_from_c (void *arg)
1554 return ((AudioRegion *) arg)->length();
1557 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1559 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;