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 (other->_envelope_active) \
107 , _default_fade_in (other->_default_fade_in) \
108 , _default_fade_out (other->_default_fade_out) \
109 , _fade_in_active (other->_fade_in_active) \
110 , _fade_out_active (other->_fade_out_active) \
111 , _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 /* XXX is this guaranteed to work for all values of offset+offset_relative? */
164 , _envelope (new AutomationList (*other->_envelope, _start, _start + _length))
165 , _fade_in_suspended (0)
166 , _fade_out_suspended (0)
168 /* don't use init here, because we got fade in/out from the other region
170 register_properties ();
171 listen_to_my_curves ();
172 connect_to_analysis_changed ();
173 connect_to_header_position_offset_changed ();
175 assert(_type == DataType::AUDIO);
176 assert (_sources.size() == _master_sources.size());
179 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& srcs)
180 : Region (boost::static_pointer_cast<const Region>(other), srcs)
181 , AUDIOREGION_COPY_STATE (other)
182 , _automatable (other->session())
183 , _fade_in (new AutomationList (*other->_fade_in))
184 , _fade_out (new AutomationList (*other->_fade_out))
185 , _envelope (new AutomationList (*other->_envelope))
186 , _fade_in_suspended (0)
187 , _fade_out_suspended (0)
189 /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
191 register_properties ();
193 listen_to_my_curves ();
194 connect_to_analysis_changed ();
195 connect_to_header_position_offset_changed ();
197 assert (_sources.size() == _master_sources.size());
200 AudioRegion::AudioRegion (SourceList& srcs)
202 , AUDIOREGION_STATE_DEFAULT
203 , _automatable(srcs[0]->session())
204 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
205 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
206 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
207 , _fade_in_suspended (0)
208 , _fade_out_suspended (0)
212 assert(_type == DataType::AUDIO);
213 assert (_sources.size() == _master_sources.size());
216 AudioRegion::~AudioRegion ()
221 AudioRegion::post_set ()
224 _sync_position = _start;
227 /* return to default fades if the existing ones are too long */
229 if (_left_of_split) {
230 if (_fade_in->back()->when >= _length) {
231 set_default_fade_in ();
233 set_default_fade_out ();
234 _left_of_split = false;
237 if (_right_of_split) {
238 if (_fade_out->back()->when >= _length) {
239 set_default_fade_out ();
242 set_default_fade_in ();
243 _right_of_split = false;
246 /* If _length changed, adjust our gain envelope accordingly */
247 _envelope->truncate_end (_length);
251 AudioRegion::connect_to_analysis_changed ()
253 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
254 (*i)->AnalysisChanged.connect_same_thread (*this, boost::bind (&AudioRegion::invalidate_transients, this));
259 AudioRegion::connect_to_header_position_offset_changed ()
261 set<boost::shared_ptr<Source> > unique_srcs;
263 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
265 /* connect only once to HeaderPositionOffsetChanged, even if sources are replicated
268 if (unique_srcs.find (*i) == unique_srcs.end ()) {
269 unique_srcs.insert (*i);
270 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
272 afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
279 AudioRegion::listen_to_my_curves ()
281 _envelope->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::envelope_changed, this));
282 _fade_in->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_in_changed, this));
283 _fade_out->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_out_changed, this));
287 AudioRegion::set_envelope_active (bool yn)
289 if (envelope_active() != yn) {
290 _envelope_active = yn;
291 send_change (PropertyChange (Properties::envelope_active));
296 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
298 if (chan_n >= _sources.size()) {
302 if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
305 if (_scale_amplitude != 1.0f) {
306 for (nframes_t n = 0; n < npeaks; ++n) {
307 buf[n].max *= _scale_amplitude;
308 buf[n].min *= _scale_amplitude;
316 AudioRegion::read (Sample* buf, framepos_t timeline_position, framecnt_t cnt, int channel) const
318 /* raw read, no fades, no gain, nada */
319 return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
323 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
324 framepos_t file_position, framecnt_t cnt, uint32_t chan_n,
325 framecnt_t read_frames, framecnt_t skip_frames) const
327 /* regular diskstream/butler read complete with fades etc */
328 return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer,
329 file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
333 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
334 framepos_t position, framecnt_t cnt, uint32_t chan_n) const
336 /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
338 return _read_at (_master_sources, _master_sources.front()->length(_master_sources.front()->timeline_position()),
339 buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0, ReadOps (0));
343 AudioRegion::_read_at (const SourceList& /*srcs*/, framecnt_t limit,
344 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
348 framecnt_t /*read_frames*/,
349 framecnt_t /*skip_frames*/,
352 frameoffset_t internal_offset;
353 frameoffset_t buf_offset;
355 bool raw = (rops == ReadOpsNone);
357 if (muted() && !raw) {
358 return 0; /* read nothing */
361 /* precondition: caller has verified that we cover the desired section */
363 if (position < _position) {
365 buf_offset = _position - position;
368 internal_offset = position - _position;
372 if (internal_offset >= limit) {
373 return 0; /* read nothing */
376 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
377 return 0; /* read nothing */
380 if (opaque() || raw) {
381 /* overwrite whatever is there */
382 mixdown_buffer = buf + buf_offset;
384 mixdown_buffer += buf_offset;
387 if (rops & ReadOpsCount) {
388 _read_data_count = 0;
391 if (chan_n < n_channels()) {
393 boost::shared_ptr<AudioSource> src = audio_source(chan_n);
394 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
395 return 0; /* "read nothing" */
398 if (rops & ReadOpsCount) {
399 _read_data_count += src->read_data_count();
404 /* track is N-channel, this region has less channels; silence the ones
408 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
411 if (rops & ReadOpsFades) {
415 if (_fade_in_active && _session.config.get_use_region_fades()) {
417 nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
419 /* see if this read is within the fade in */
421 if (internal_offset < fade_in_length) {
425 fi_limit = min (to_read, fade_in_length - internal_offset);
428 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
430 for (nframes_t n = 0; n < fi_limit; ++n) {
431 mixdown_buffer[n] *= gain_buffer[n];
438 if (_fade_out_active && _session.config.get_use_region_fades()) {
440 /* see if some part of this read is within the fade out */
442 /* ................. >| REGION
448 limit - fade_out_length
451 ^internal_offset + to_read
453 we need the intersection of [internal_offset,internal_offset+to_read] with
454 [limit - fade_out_length, limit]
459 nframes_t fade_out_length = (nframes_t) _fade_out->back()->when;
460 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
461 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
463 if (fade_interval_end > fade_interval_start) {
464 /* (part of the) the fade out is in this buffer */
466 nframes_t fo_limit = fade_interval_end - fade_interval_start;
467 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
468 nframes_t fade_offset = fade_interval_start - internal_offset;
470 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
472 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
473 mixdown_buffer[m] *= gain_buffer[n];
480 /* Regular gain curves and scaling */
482 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
483 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
485 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
486 for (nframes_t n = 0; n < to_read; ++n) {
487 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
490 for (nframes_t n = 0; n < to_read; ++n) {
491 mixdown_buffer[n] *= gain_buffer[n];
494 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
496 // XXX this should be using what in 2.0 would have been:
497 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
499 for (nframes_t n = 0; n < to_read; ++n) {
500 mixdown_buffer[n] *= _scale_amplitude;
506 /* gack. the things we do for users.
511 for (nframes_t n = 0; n < to_read; ++n) {
512 buf[n] += mixdown_buffer[n];
520 AudioRegion::state ()
522 XMLNode& node (Region::state ());
525 LocaleGuard lg (X_("POSIX"));
527 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
528 node.add_property ("channels", buf);
530 Stateful::add_properties (node);
532 child = node.add_child ("Envelope");
534 bool default_env = false;
536 // If there are only two points, the points are in the start of the region and the end of the region
537 // so, if they are both at 1.0f, that means the default region.
539 if (_envelope->size() == 2 &&
540 _envelope->front()->value == 1.0f &&
541 _envelope->back()->value==1.0f) {
542 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
548 child->add_property ("default", "yes");
550 child->add_child_nocopy (_envelope->get_state ());
557 AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_changed, bool send)
559 const XMLNodeList& nlist = node.children();
560 const XMLProperty *prop;
561 LocaleGuard lg (X_("POSIX"));
562 boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
564 suspend_property_changes ();
567 the_playlist->freeze ();
571 /* this will set all our State members and stuff controlled by the Region.
572 It should NOT send any changed signals - that is our responsibility.
575 Region::_set_state (node, version, what_changed, false);
577 if ((prop = node.property ("scale-gain")) != 0) {
578 float a = atof (prop->value().c_str());
579 if (a != _scale_amplitude) {
580 _scale_amplitude = a;
581 what_changed.add (Properties::scale_amplitude);
585 /* Now find envelope description and other related child items */
587 _envelope->freeze ();
589 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
595 if (child->name() == "Envelope") {
599 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child, version)) {
600 set_default_envelope ();
603 _envelope->set_max_xval (_length);
604 _envelope->truncate_end (_length);
607 } else if (child->name() == "FadeIn") {
611 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
612 set_default_fade_in ();
614 XMLNode* grandchild = child->child ("AutomationList");
616 _fade_in->set_state (*grandchild, version);
620 if ((prop = child->property ("active")) != 0) {
621 if (string_is_affirmative (prop->value())) {
622 set_fade_in_active (true);
624 set_fade_in_active (false);
628 } else if (child->name() == "FadeOut") {
632 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
633 set_default_fade_out ();
635 XMLNode* grandchild = child->child ("AutomationList");
637 _fade_out->set_state (*grandchild, version);
641 if ((prop = child->property ("active")) != 0) {
642 if (string_is_affirmative (prop->value())) {
643 set_fade_out_active (true);
645 set_fade_out_active (false);
653 resume_property_changes ();
656 send_change (what_changed);
660 the_playlist->thaw ();
667 AudioRegion::set_state (const XMLNode& node, int version)
669 PropertyChange what_changed;
670 return _set_state (node, version, what_changed, true);
674 AudioRegion::set_fade_in_shape (FadeShape shape)
676 set_fade_in (shape, (nframes_t) _fade_in->back()->when);
680 AudioRegion::set_fade_out_shape (FadeShape shape)
682 set_fade_out (shape, (nframes_t) _fade_out->back()->when);
686 AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
692 send_change (PropertyChange (Properties::fade_in));
696 AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
703 _fade_in->fast_simple_add (0.0, 0.0);
704 _fade_in->fast_simple_add (len, 1.0);
708 _fade_in->fast_simple_add (0, 0);
709 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
710 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
711 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
712 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
713 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
714 _fade_in->fast_simple_add (len, 1);
718 _fade_in->fast_simple_add (0, 0);
719 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
720 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
721 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
722 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
723 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
724 _fade_in->fast_simple_add (len * 0.767281, 1);
725 _fade_in->fast_simple_add (len, 1);
729 _fade_in->fast_simple_add (0, 0);
730 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
731 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
732 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
733 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
734 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
735 _fade_in->fast_simple_add (len, 1);
739 _fade_in->fast_simple_add (0, 0);
740 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
741 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
742 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
743 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
744 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
745 _fade_in->fast_simple_add (len, 1);
753 AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
755 _fade_out->freeze ();
759 send_change (PropertyChange (Properties::fade_in));
763 AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
765 _fade_out->freeze ();
770 _fade_out->fast_simple_add (len * 0, 1);
771 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
772 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
773 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
774 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
775 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
776 _fade_out->fast_simple_add (len * 1, 0);
780 _fade_out->fast_simple_add (len * 0, 1);
781 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
782 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
783 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
784 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
785 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
786 _fade_out->fast_simple_add (len * 1, 0);
790 _fade_out->fast_simple_add (len * 0, 1);
791 _fade_out->fast_simple_add (len * 0.305556, 1);
792 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
793 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
794 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
795 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
796 _fade_out->fast_simple_add (len * 1, 0);
800 _fade_out->fast_simple_add (len * 0, 1);
801 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
802 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
803 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
804 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
805 _fade_out->fast_simple_add (len * 1, 0);
809 _fade_out->fast_simple_add (len * 0, 1);
810 _fade_out->fast_simple_add (len * 1, 0);
818 AudioRegion::set_fade_in_length (framecnt_t len)
824 bool changed = _fade_in->extend_to (len);
827 _default_fade_in = false;
828 send_change (PropertyChange (Properties::fade_in));
833 AudioRegion::set_fade_out_length (framecnt_t len)
839 bool changed = _fade_out->extend_to (len);
842 _default_fade_out = false;
843 send_change (PropertyChange (Properties::fade_out));
848 AudioRegion::set_fade_in_active (bool yn)
850 if (yn == _fade_in_active) {
854 _fade_in_active = yn;
855 send_change (PropertyChange (Properties::fade_in_active));
859 AudioRegion::set_fade_out_active (bool yn)
861 if (yn == _fade_out_active) {
864 _fade_out_active = yn;
865 send_change (PropertyChange (Properties::fade_out_active));
869 AudioRegion::fade_in_is_default () const
871 return _fade_in->size() == 2 && _fade_in->front()->when == 0 && _fade_in->back()->when == 64;
875 AudioRegion::fade_out_is_default () const
877 return _fade_out->size() == 2 && _fade_out->front()->when == 0 && _fade_out->back()->when == 64;
881 AudioRegion::set_default_fade_in ()
883 _fade_in_suspended = 0;
884 set_fade_in (Linear, 64);
888 AudioRegion::set_default_fade_out ()
890 _fade_out_suspended = 0;
891 set_fade_out (Linear, 64);
895 AudioRegion::set_default_fades ()
897 set_default_fade_in ();
898 set_default_fade_out ();
902 AudioRegion::set_default_envelope ()
904 _envelope->freeze ();
906 _envelope->fast_simple_add (0, 1.0f);
907 _envelope->fast_simple_add (_length, 1.0f);
912 AudioRegion::recompute_at_end ()
914 /* our length has changed. recompute a new final point by interpolating
915 based on the the existing curve.
918 _envelope->freeze ();
919 _envelope->truncate_end (_length);
920 _envelope->set_max_xval (_length);
923 if (_left_of_split) {
924 set_default_fade_out ();
925 _left_of_split = false;
926 } else if (_fade_out->back()->when > _length) {
927 _fade_out->extend_to (_length);
928 send_change (PropertyChange (Properties::fade_out));
931 if (_fade_in->back()->when > _length) {
932 _fade_in->extend_to (_length);
933 send_change (PropertyChange (Properties::fade_in));
938 AudioRegion::recompute_at_start ()
940 /* as above, but the shift was from the front */
942 _envelope->truncate_start (_length);
944 if (_right_of_split) {
945 set_default_fade_in ();
946 _right_of_split = false;
947 } else if (_fade_in->back()->when > _length) {
948 _fade_in->extend_to (_length);
949 send_change (PropertyChange (Properties::fade_in));
952 if (_fade_out->back()->when > _length) {
953 _fade_out->extend_to (_length);
954 send_change (PropertyChange (Properties::fade_out));
959 AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr<Region> >& v) const
965 if (_sources.size() < 2) {
969 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
975 if (_sources.size() == 2) {
983 new_name += ('0' + n + 1);
986 /* create a copy with just one source. prevent if from being thought of as
987 "whole file" even if it covers the entire source file(s).
992 plist.add (Properties::start, _start.val());
993 plist.add (Properties::length, _length.val());
994 plist.add (Properties::name, new_name);
995 plist.add (Properties::layer, _layer.val());
997 v.push_back(RegionFactory::create (srcs, plist));
998 v.back()->set_whole_file (false);
1007 AudioRegion::read_raw_internal (Sample* buf, framepos_t pos, framecnt_t cnt, int channel) const
1009 return audio_source()->read (buf, pos, cnt, channel);
1013 AudioRegion::exportme (Session& /*session*/, ARDOUR::ExportSpecification& /*spec*/)
1016 // const nframes_t blocksize = 4096;
1017 // nframes_t to_read;
1020 // spec.channels = _sources.size();
1022 // if (spec.prepare (blocksize, session.frame_rate())) {
1027 // spec.total_frames = _length;
1029 // while (spec.pos < _length && !spec.stop) {
1032 // /* step 1: interleave */
1034 // to_read = min (_length - spec.pos, blocksize);
1036 // if (spec.channels == 1) {
1038 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1044 // Sample buf[blocksize];
1046 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1048 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1052 // for (nframes_t x = 0; x < to_read; ++x) {
1053 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1058 // if (spec.process (to_read)) {
1062 // spec.pos += to_read;
1063 // spec.progress = (double) spec.pos /_length;
1070 // spec.running = false;
1071 // spec.status = status;
1079 AudioRegion::set_scale_amplitude (gain_t g)
1081 boost::shared_ptr<Playlist> pl (playlist());
1083 _scale_amplitude = g;
1085 /* tell the diskstream we're in */
1088 pl->ContentsChanged();
1091 /* tell everybody else */
1093 send_change (PropertyChange (Properties::scale_amplitude));
1097 AudioRegion::normalize_to (float target_dB)
1099 const framecnt_t blocksize = 64 * 1024;
1100 Sample buf[blocksize];
1105 gain_t target = dB_to_coefficient (target_dB);
1107 if (target == 1.0f) {
1108 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1109 that we may have clipped.
1111 target -= FLT_EPSILON;
1115 fend = _start + _length;
1117 /* first pass: find max amplitude */
1119 while (fpos < fend) {
1123 to_read = min (fend - fpos, blocksize);
1125 for (n = 0; n < n_channels(); ++n) {
1129 if (read_raw_internal (buf, fpos, to_read, 0) != to_read) {
1133 maxamp = compute_peak (buf, to_read, maxamp);
1139 if (maxamp == 0.0f) {
1140 /* don't even try */
1144 if (maxamp == target) {
1145 /* we can't do anything useful */
1149 /* compute scale factor */
1151 _scale_amplitude = target/maxamp;
1153 /* tell the diskstream we're in */
1155 boost::shared_ptr<Playlist> pl (playlist());
1158 pl->ContentsChanged();
1161 /* tell everybody else */
1163 send_change (PropertyChange (Properties::scale_amplitude));
1167 AudioRegion::fade_in_changed ()
1169 send_change (PropertyChange (Properties::fade_in));
1173 AudioRegion::fade_out_changed ()
1175 send_change (PropertyChange (Properties::fade_out));
1179 AudioRegion::envelope_changed ()
1181 send_change (PropertyChange (Properties::envelope));
1185 AudioRegion::suspend_fade_in ()
1187 if (++_fade_in_suspended == 1) {
1188 if (fade_in_is_default()) {
1189 set_fade_in_active (false);
1195 AudioRegion::resume_fade_in ()
1197 if (--_fade_in_suspended == 0 && _fade_in_suspended) {
1198 set_fade_in_active (true);
1203 AudioRegion::suspend_fade_out ()
1205 if (++_fade_out_suspended == 1) {
1206 if (fade_out_is_default()) {
1207 set_fade_out_active (false);
1213 AudioRegion::resume_fade_out ()
1215 if (--_fade_out_suspended == 0 &&_fade_out_suspended) {
1216 set_fade_out_active (true);
1221 AudioRegion::speed_mismatch (float sr) const
1223 if (_sources.empty()) {
1224 /* impossible, but ... */
1228 float fsr = audio_source()->sample_rate();
1234 AudioRegion::source_offset_changed ()
1236 /* XXX this fixes a crash that should not occur. It does occur
1237 becauses regions are not being deleted when a session
1238 is unloaded. That bug must be fixed.
1241 if (_sources.empty()) {
1245 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1247 if (afs && afs->destructive()) {
1248 // set_start (source()->natural_position(), this);
1249 set_position (source()->natural_position(), this);
1253 boost::shared_ptr<AudioSource>
1254 AudioRegion::audio_source (uint32_t n) const
1256 // Guaranteed to succeed (use a static cast for speed?)
1257 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1261 AudioRegion::adjust_transients (nframes64_t delta)
1263 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1264 (*x) = (*x) + delta;
1267 send_change (PropertyChange (Properties::valid_transients));
1273 AudioRegion::update_transient (nframes64_t old_position, nframes64_t new_position)
1275 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1276 if ((*x) == old_position) {
1277 (*x) = new_position;
1278 send_change (PropertyChange (Properties::valid_transients));
1288 AudioRegion::add_transient (nframes64_t where)
1290 _transients.push_back(where);
1291 _valid_transients = true;
1293 send_change (PropertyChange (Properties::valid_transients));
1297 AudioRegion::remove_transient (nframes64_t where)
1299 _transients.remove(where);
1300 _valid_transients = true;
1302 send_change (PropertyChange (Properties::valid_transients));
1306 AudioRegion::set_transients (AnalysisFeatureList& results)
1308 _transients.clear();
1309 _transients = results;
1310 _valid_transients = true;
1312 send_change (PropertyChange (Properties::valid_transients));
1318 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1320 boost::shared_ptr<Playlist> pl = playlist();
1326 if (_valid_transients && !force_new) {
1327 results = _transients;
1331 SourceList::iterator s;
1333 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1334 if (!(*s)->has_been_analysed()) {
1335 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1340 if (s == _sources.end()) {
1341 /* all sources are analyzed, merge data from each one */
1343 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1345 /* find the set of transients within the bounds of this region */
1347 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1348 (*s)->transients.end(),
1351 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1352 (*s)->transients.end(),
1357 results.insert (results.end(), low, high);
1360 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1362 /* translate all transients to current position */
1364 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1369 _transients = results;
1370 _valid_transients = true;
1375 /* no existing/complete transient info */
1377 static bool analyse_dialog_shown = false; /* global per instance of Ardour */
1379 if (!Config->get_auto_analyse_audio()) {
1380 if (!analyse_dialog_shown) {
1381 pl->session().Dialog (_("\
1382 You have requested an operation that requires audio analysis.\n\n \
1383 You currently have \"auto-analyse-audio\" disabled, which means\n\
1384 that transient data must be generated every time it is required.\n\n\
1385 If you are doing work that will require transient data on a\n\
1386 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1387 +then quit ardour and restart.\n\n\
1388 +This dialog will not display again. But you may notice a slight delay\n\
1389 +in this and future transient-detection operations.\n\
1391 analyse_dialog_shown = true;
1395 TransientDetector t (pl->session().frame_rate());
1396 bool existing_results = !results.empty();
1398 _transients.clear ();
1399 _valid_transients = false;
1401 for (uint32_t i = 0; i < n_channels(); ++i) {
1403 AnalysisFeatureList these_results;
1407 if (t.run ("", this, i, these_results)) {
1411 /* translate all transients to give absolute position */
1413 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1419 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1422 if (!results.empty()) {
1423 if (existing_results) {
1425 /* merge our transients into the existing ones, then clean up
1429 results.insert (results.end(), _transients.begin(), _transients.end());
1430 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1433 /* make sure ours are clean too */
1435 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1439 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1440 results = _transients;
1443 _valid_transients = true;
1448 /** Find areas of `silence' within a region.
1450 * @param threshold Threshold below which signal is considered silence (as a sample value)
1451 * @param min_length Minimum length of silent period to be reported.
1452 * @return Silent periods; first of pair is the offset within the region, second is the length of the period
1455 std::list<std::pair<frameoffset_t, framecnt_t> >
1456 AudioRegion::find_silence (Sample threshold, framecnt_t min_length, InterThreadInfo& itt) const
1458 framecnt_t const block_size = 64 * 1024;
1459 Sample loudest[block_size];
1460 Sample buf[block_size];
1462 framepos_t pos = _start;
1463 framepos_t const end = _start + _length - 1;
1465 std::list<std::pair<frameoffset_t, framecnt_t> > silent_periods;
1467 bool in_silence = false;
1468 frameoffset_t silence_start = 0;
1471 while (pos < end && !itt.cancel) {
1473 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1474 memset (loudest, 0, sizeof (Sample) * block_size);
1475 for (uint32_t n = 0; n < n_channels(); ++n) {
1477 read_raw_internal (buf, pos, block_size, n);
1478 for (framecnt_t i = 0; i < block_size; ++i) {
1479 loudest[i] = max (loudest[i], abs (buf[i]));
1483 /* now look for silence */
1484 for (framecnt_t i = 0; i < block_size; ++i) {
1485 silence = abs (loudest[i]) < threshold;
1486 if (silence && !in_silence) {
1487 /* non-silence to silence */
1489 silence_start = pos + i;
1490 } else if (!silence && in_silence) {
1491 /* silence to non-silence */
1493 if (pos + i - 1 - silence_start >= min_length) {
1494 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1500 itt.progress = (end-pos)/(double)_length;
1503 if (in_silence && end - 1 - silence_start >= min_length) {
1504 /* last block was silent, so finish off the last period */
1505 silent_periods.push_back (std::make_pair (silence_start, end));
1510 return silent_periods;
1517 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)
1519 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (framecnt_t) npeaks, (framepos_t) start, (framecnt_t) cnt, n_chan,samples_per_unit);
1522 uint32_t region_length_from_c (void *arg)
1525 return ((AudioRegion *) arg)->length();
1528 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1530 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;