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)
113 /* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
118 register_properties ();
120 set_default_fades ();
121 set_default_envelope ();
123 listen_to_my_curves ();
124 connect_to_analysis_changed ();
125 connect_to_header_position_offset_changed ();
128 /** Constructor for use by derived types only */
129 AudioRegion::AudioRegion (Session& s, framepos_t start, framecnt_t len, std::string name)
130 : Region (s, start, len, name, DataType::AUDIO)
131 , AUDIOREGION_STATE_DEFAULT
133 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
134 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
135 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
136 , _fade_in_suspended (0)
137 , _fade_out_suspended (0)
140 assert (_sources.size() == _master_sources.size());
143 /** Basic AudioRegion constructor */
144 AudioRegion::AudioRegion (const SourceList& srcs)
146 , AUDIOREGION_STATE_DEFAULT
147 , _automatable(srcs[0]->session())
148 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
149 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
150 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
151 , _fade_in_suspended (0)
152 , _fade_out_suspended (0)
155 assert (_sources.size() == _master_sources.size());
158 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes64_t offset, bool offset_relative)
159 : Region (other, offset, offset_relative)
160 , AUDIOREGION_COPY_STATE (other)
161 , _automatable (other->session())
162 , _fade_in (new AutomationList (*other->_fade_in))
163 , _fade_out (new AutomationList (*other->_fade_out))
164 /* XXX is this guaranteed to work for all values of offset+offset_relative? */
165 , _envelope (new AutomationList (*other->_envelope, _start, _start + _length))
166 , _fade_in_suspended (0)
167 , _fade_out_suspended (0)
169 /* don't use init here, because we got fade in/out from the other region
171 register_properties ();
172 listen_to_my_curves ();
173 connect_to_analysis_changed ();
174 connect_to_header_position_offset_changed ();
176 assert(_type == DataType::AUDIO);
177 assert (_sources.size() == _master_sources.size());
180 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& srcs)
181 : Region (boost::static_pointer_cast<const Region>(other), srcs)
182 , AUDIOREGION_COPY_STATE (other)
183 , _automatable (other->session())
184 , _fade_in (new AutomationList (*other->_fade_in))
185 , _fade_out (new AutomationList (*other->_fade_out))
186 , _envelope (new AutomationList (*other->_envelope))
187 , _fade_in_suspended (0)
188 , _fade_out_suspended (0)
190 /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
192 register_properties ();
194 listen_to_my_curves ();
195 connect_to_analysis_changed ();
196 connect_to_header_position_offset_changed ();
198 assert (_sources.size() == _master_sources.size());
201 AudioRegion::AudioRegion (SourceList& srcs)
203 , AUDIOREGION_STATE_DEFAULT
204 , _automatable(srcs[0]->session())
205 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
206 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
207 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
208 , _fade_in_suspended (0)
209 , _fade_out_suspended (0)
213 assert(_type == DataType::AUDIO);
214 assert (_sources.size() == _master_sources.size());
217 AudioRegion::~AudioRegion ()
222 AudioRegion::post_set ()
225 _sync_position = _start;
228 /* return to default fades if the existing ones are too long */
230 if (_left_of_split) {
231 if (_fade_in->back()->when >= _length) {
232 set_default_fade_in ();
234 set_default_fade_out ();
235 _left_of_split = false;
238 if (_right_of_split) {
239 if (_fade_out->back()->when >= _length) {
240 set_default_fade_out ();
243 set_default_fade_in ();
244 _right_of_split = false;
247 /* If _length changed, adjust our gain envelope accordingly */
248 _envelope->truncate_end (_length);
252 AudioRegion::connect_to_analysis_changed ()
254 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
255 (*i)->AnalysisChanged.connect_same_thread (*this, boost::bind (&AudioRegion::invalidate_transients, this));
260 AudioRegion::connect_to_header_position_offset_changed ()
262 set<boost::shared_ptr<Source> > unique_srcs;
264 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
266 if (unique_srcs.find (*i) == unique_srcs.end ()) {
267 unique_srcs.insert (*i);
268 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
270 afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
277 AudioRegion::listen_to_my_curves ()
279 _envelope->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::envelope_changed, this));
280 _fade_in->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_in_changed, this));
281 _fade_out->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_out_changed, this));
285 AudioRegion::set_envelope_active (bool yn)
287 if (envelope_active() != yn) {
288 _envelope_active = yn;
289 send_change (PropertyChange (Properties::envelope_active));
294 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
296 if (chan_n >= _sources.size()) {
300 if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
303 if (_scale_amplitude != 1.0f) {
304 for (nframes_t n = 0; n < npeaks; ++n) {
305 buf[n].max *= _scale_amplitude;
306 buf[n].min *= _scale_amplitude;
314 AudioRegion::read (Sample* buf, framepos_t timeline_position, framecnt_t cnt, int channel) const
316 /* raw read, no fades, no gain, nada */
317 return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
321 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
322 framepos_t file_position, framecnt_t cnt, uint32_t chan_n,
323 framecnt_t read_frames, framecnt_t skip_frames) const
325 /* regular diskstream/butler read complete with fades etc */
326 return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer,
327 file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
331 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
332 framepos_t position, framecnt_t cnt, uint32_t chan_n) const
334 /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
336 return _read_at (_master_sources, _master_sources.front()->length(_master_sources.front()->timeline_position()),
337 buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0, ReadOps (0));
341 AudioRegion::_read_at (const SourceList& /*srcs*/, framecnt_t limit,
342 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
346 framecnt_t /*read_frames*/,
347 framecnt_t /*skip_frames*/,
350 frameoffset_t internal_offset;
351 frameoffset_t buf_offset;
353 bool raw = (rops == ReadOpsNone);
355 if (muted() && !raw) {
356 return 0; /* read nothing */
359 /* precondition: caller has verified that we cover the desired section */
361 if (position < _position) {
363 buf_offset = _position - position;
366 internal_offset = position - _position;
370 if (internal_offset >= limit) {
371 return 0; /* read nothing */
374 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
375 return 0; /* read nothing */
378 if (opaque() || raw) {
379 /* overwrite whatever is there */
380 mixdown_buffer = buf + buf_offset;
382 mixdown_buffer += buf_offset;
385 if (rops & ReadOpsCount) {
386 _read_data_count = 0;
389 if (chan_n < n_channels()) {
391 boost::shared_ptr<AudioSource> src = audio_source(chan_n);
392 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
393 return 0; /* "read nothing" */
396 if (rops & ReadOpsCount) {
397 _read_data_count += src->read_data_count();
402 /* track is N-channel, this region has less channels; silence the ones
406 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
409 if (rops & ReadOpsFades) {
413 if (_fade_in_active && _session.config.get_use_region_fades()) {
415 nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
417 /* see if this read is within the fade in */
419 if (internal_offset < fade_in_length) {
423 fi_limit = min (to_read, fade_in_length - internal_offset);
426 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
428 for (nframes_t n = 0; n < fi_limit; ++n) {
429 mixdown_buffer[n] *= gain_buffer[n];
436 if (_fade_out_active && _session.config.get_use_region_fades()) {
438 /* see if some part of this read is within the fade out */
440 /* ................. >| REGION
446 limit - fade_out_length
449 ^internal_offset + to_read
451 we need the intersection of [internal_offset,internal_offset+to_read] with
452 [limit - fade_out_length, limit]
457 nframes_t fade_out_length = (nframes_t) _fade_out->back()->when;
458 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
459 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
461 if (fade_interval_end > fade_interval_start) {
462 /* (part of the) the fade out is in this buffer */
464 nframes_t fo_limit = fade_interval_end - fade_interval_start;
465 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
466 nframes_t fade_offset = fade_interval_start - internal_offset;
468 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
470 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
471 mixdown_buffer[m] *= gain_buffer[n];
478 /* Regular gain curves and scaling */
480 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
481 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
483 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
484 for (nframes_t n = 0; n < to_read; ++n) {
485 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
488 for (nframes_t n = 0; n < to_read; ++n) {
489 mixdown_buffer[n] *= gain_buffer[n];
492 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
494 // XXX this should be using what in 2.0 would have been:
495 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
497 for (nframes_t n = 0; n < to_read; ++n) {
498 mixdown_buffer[n] *= _scale_amplitude;
504 /* gack. the things we do for users.
509 for (nframes_t n = 0; n < to_read; ++n) {
510 buf[n] += mixdown_buffer[n];
518 AudioRegion::state (bool full)
520 XMLNode& node (Region::state (full));
524 LocaleGuard lg (X_("POSIX"));
527 // XXX these should move into Region
529 for (uint32_t n=0; n < _sources.size(); ++n) {
530 snprintf (buf2, sizeof(buf2), "source-%d", n);
531 _sources[n]->id().print (buf, sizeof (buf));
532 node.add_property (buf2, buf);
535 for (uint32_t n=0; n < _master_sources.size(); ++n) {
536 snprintf (buf2, sizeof(buf2), "master-source-%d", n);
537 _master_sources[n]->id().print (buf, sizeof (buf));
538 node.add_property (buf2, buf);
541 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
542 node.add_property ("channels", buf);
545 Stateful::add_properties (node);
548 child = node.add_child ("Envelope");
551 bool default_env = false;
553 // If there are only two points, the points are in the start of the region and the end of the region
554 // so, if they are both at 1.0f, that means the default region.
556 if (_envelope->size() == 2 &&
557 _envelope->front()->value == 1.0f &&
558 _envelope->back()->value==1.0f) {
559 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
565 child->add_property ("default", "yes");
567 child->add_child_nocopy (_envelope->get_state ());
571 child->add_property ("default", "yes");
574 if (full && _extra_xml) {
575 node.add_child_copy (*_extra_xml);
582 AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_changed, bool send)
584 const XMLNodeList& nlist = node.children();
585 const XMLProperty *prop;
586 LocaleGuard lg (X_("POSIX"));
587 boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
589 suspend_property_changes ();
592 the_playlist->freeze ();
596 /* this will set all our State members and stuff controlled by the Region.
597 It should NOT send any changed signals - that is our responsibility.
600 Region::_set_state (node, version, what_changed, false);
602 if ((prop = node.property ("scale-gain")) != 0) {
603 float a = atof (prop->value().c_str());
604 if (a != _scale_amplitude) {
605 _scale_amplitude = a;
606 what_changed.add (Properties::scale_amplitude);
610 /* Now find envelope description and other related child items */
612 _envelope->freeze ();
614 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
620 if (child->name() == "Envelope") {
624 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child, version)) {
625 set_default_envelope ();
628 _envelope->set_max_xval (_length);
629 _envelope->truncate_end (_length);
632 } else if (child->name() == "FadeIn") {
636 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
637 set_default_fade_in ();
639 XMLNode* grandchild = child->child ("AutomationList");
641 _fade_in->set_state (*grandchild, version);
645 if ((prop = child->property ("active")) != 0) {
646 if (string_is_affirmative (prop->value())) {
647 set_fade_in_active (true);
649 set_fade_in_active (false);
653 } else if (child->name() == "FadeOut") {
657 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
658 set_default_fade_out ();
660 XMLNode* grandchild = child->child ("AutomationList");
662 _fade_out->set_state (*grandchild, version);
666 if ((prop = child->property ("active")) != 0) {
667 if (string_is_affirmative (prop->value())) {
668 set_fade_out_active (true);
670 set_fade_out_active (false);
678 resume_property_changes ();
681 send_change (what_changed);
685 the_playlist->thaw ();
692 AudioRegion::set_state (const XMLNode& node, int version)
694 PropertyChange what_changed;
695 return _set_state (node, version, what_changed, true);
699 AudioRegion::set_fade_in_shape (FadeShape shape)
701 set_fade_in (shape, (nframes_t) _fade_in->back()->when);
705 AudioRegion::set_fade_out_shape (FadeShape shape)
707 set_fade_out (shape, (nframes_t) _fade_out->back()->when);
711 AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
717 send_change (PropertyChange (Properties::fade_in));
721 AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
728 _fade_in->fast_simple_add (0.0, 0.0);
729 _fade_in->fast_simple_add (len, 1.0);
733 _fade_in->fast_simple_add (0, 0);
734 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
735 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
736 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
737 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
738 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
739 _fade_in->fast_simple_add (len, 1);
743 _fade_in->fast_simple_add (0, 0);
744 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
745 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
746 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
747 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
748 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
749 _fade_in->fast_simple_add (len * 0.767281, 1);
750 _fade_in->fast_simple_add (len, 1);
754 _fade_in->fast_simple_add (0, 0);
755 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
756 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
757 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
758 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
759 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
760 _fade_in->fast_simple_add (len, 1);
764 _fade_in->fast_simple_add (0, 0);
765 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
766 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
767 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
768 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
769 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
770 _fade_in->fast_simple_add (len, 1);
778 AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
780 _fade_out->freeze ();
784 send_change (PropertyChange (Properties::fade_in));
788 AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
790 _fade_out->freeze ();
795 _fade_out->fast_simple_add (len * 0, 1);
796 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
797 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
798 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
799 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
800 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
801 _fade_out->fast_simple_add (len * 1, 0);
805 _fade_out->fast_simple_add (len * 0, 1);
806 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
807 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
808 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
809 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
810 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
811 _fade_out->fast_simple_add (len * 1, 0);
815 _fade_out->fast_simple_add (len * 0, 1);
816 _fade_out->fast_simple_add (len * 0.305556, 1);
817 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
818 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
819 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
820 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
821 _fade_out->fast_simple_add (len * 1, 0);
825 _fade_out->fast_simple_add (len * 0, 1);
826 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
827 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
828 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
829 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
830 _fade_out->fast_simple_add (len * 1, 0);
834 _fade_out->fast_simple_add (len * 0, 1);
835 _fade_out->fast_simple_add (len * 1, 0);
843 AudioRegion::set_fade_in_length (framecnt_t len)
849 bool changed = _fade_in->extend_to (len);
852 _default_fade_in = false;
853 send_change (PropertyChange (Properties::fade_in));
858 AudioRegion::set_fade_out_length (framecnt_t len)
864 bool changed = _fade_out->extend_to (len);
867 _default_fade_out = false;
868 send_change (PropertyChange (Properties::fade_out));
873 AudioRegion::set_fade_in_active (bool yn)
875 if (yn == _fade_in_active) {
879 _fade_in_active = yn;
880 send_change (PropertyChange (Properties::fade_in_active));
884 AudioRegion::set_fade_out_active (bool yn)
886 if (yn == _fade_out_active) {
889 _fade_out_active = yn;
890 send_change (PropertyChange (Properties::fade_out_active));
894 AudioRegion::fade_in_is_default () const
896 return _fade_in->size() == 2 && _fade_in->front()->when == 0 && _fade_in->back()->when == 64;
900 AudioRegion::fade_out_is_default () const
902 return _fade_out->size() == 2 && _fade_out->front()->when == 0 && _fade_out->back()->when == 64;
906 AudioRegion::set_default_fade_in ()
908 _fade_in_suspended = 0;
909 set_fade_in (Linear, 64);
913 AudioRegion::set_default_fade_out ()
915 _fade_out_suspended = 0;
916 set_fade_out (Linear, 64);
920 AudioRegion::set_default_fades ()
922 set_default_fade_in ();
923 set_default_fade_out ();
927 AudioRegion::set_default_envelope ()
929 _envelope->freeze ();
931 _envelope->fast_simple_add (0, 1.0f);
932 _envelope->fast_simple_add (_length, 1.0f);
937 AudioRegion::recompute_at_end ()
939 /* our length has changed. recompute a new final point by interpolating
940 based on the the existing curve.
943 _envelope->freeze ();
944 _envelope->truncate_end (_length);
945 _envelope->set_max_xval (_length);
948 if (_left_of_split) {
949 set_default_fade_out ();
950 _left_of_split = false;
951 } else if (_fade_out->back()->when > _length) {
952 _fade_out->extend_to (_length);
953 send_change (PropertyChange (Properties::fade_out));
956 if (_fade_in->back()->when > _length) {
957 _fade_in->extend_to (_length);
958 send_change (PropertyChange (Properties::fade_in));
963 AudioRegion::recompute_at_start ()
965 /* as above, but the shift was from the front */
967 _envelope->truncate_start (_length);
969 if (_right_of_split) {
970 set_default_fade_in ();
971 _right_of_split = false;
972 } else if (_fade_in->back()->when > _length) {
973 _fade_in->extend_to (_length);
974 send_change (PropertyChange (Properties::fade_in));
977 if (_fade_out->back()->when > _length) {
978 _fade_out->extend_to (_length);
979 send_change (PropertyChange (Properties::fade_out));
984 AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr<Region> >& v) const
990 if (_sources.size() < 2) {
994 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
1000 if (_sources.size() == 2) {
1008 new_name += ('0' + n + 1);
1011 /* create a copy with just one source. prevent if from being thought of as
1012 "whole file" even if it covers the entire source file(s).
1017 plist.add (Properties::start, _start.val());
1018 plist.add (Properties::length, _length.val());
1019 plist.add (Properties::name, new_name);
1020 plist.add (Properties::layer, _layer.val());
1022 v.push_back(RegionFactory::create (srcs, plist));
1023 v.back()->set_whole_file (false);
1032 AudioRegion::read_raw_internal (Sample* buf, framepos_t pos, framecnt_t cnt, int channel) const
1034 return audio_source()->read (buf, pos, cnt, channel);
1038 AudioRegion::exportme (Session& /*session*/, ARDOUR::ExportSpecification& /*spec*/)
1041 // const nframes_t blocksize = 4096;
1042 // nframes_t to_read;
1045 // spec.channels = _sources.size();
1047 // if (spec.prepare (blocksize, session.frame_rate())) {
1052 // spec.total_frames = _length;
1054 // while (spec.pos < _length && !spec.stop) {
1057 // /* step 1: interleave */
1059 // to_read = min (_length - spec.pos, blocksize);
1061 // if (spec.channels == 1) {
1063 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1069 // Sample buf[blocksize];
1071 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1073 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1077 // for (nframes_t x = 0; x < to_read; ++x) {
1078 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1083 // if (spec.process (to_read)) {
1087 // spec.pos += to_read;
1088 // spec.progress = (double) spec.pos /_length;
1095 // spec.running = false;
1096 // spec.status = status;
1104 AudioRegion::set_scale_amplitude (gain_t g)
1106 boost::shared_ptr<Playlist> pl (playlist());
1108 _scale_amplitude = g;
1110 /* tell the diskstream we're in */
1113 pl->ContentsChanged();
1116 /* tell everybody else */
1118 send_change (PropertyChange (Properties::scale_amplitude));
1122 AudioRegion::normalize_to (float target_dB)
1124 const framecnt_t blocksize = 64 * 1024;
1125 Sample buf[blocksize];
1130 gain_t target = dB_to_coefficient (target_dB);
1132 if (target == 1.0f) {
1133 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1134 that we may have clipped.
1136 target -= FLT_EPSILON;
1140 fend = _start + _length;
1142 /* first pass: find max amplitude */
1144 while (fpos < fend) {
1148 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);
1164 if (maxamp == 0.0f) {
1165 /* don't even try */
1169 if (maxamp == target) {
1170 /* we can't do anything useful */
1174 /* compute scale factor */
1176 _scale_amplitude = target/maxamp;
1178 /* tell the diskstream we're in */
1180 boost::shared_ptr<Playlist> pl (playlist());
1183 pl->ContentsChanged();
1186 /* tell everybody else */
1188 send_change (PropertyChange (Properties::scale_amplitude));
1192 AudioRegion::fade_in_changed ()
1194 send_change (PropertyChange (Properties::fade_in));
1198 AudioRegion::fade_out_changed ()
1200 send_change (PropertyChange (Properties::fade_out));
1204 AudioRegion::envelope_changed ()
1206 send_change (PropertyChange (Properties::envelope));
1210 AudioRegion::suspend_fade_in ()
1212 if (++_fade_in_suspended == 1) {
1213 if (fade_in_is_default()) {
1214 set_fade_in_active (false);
1220 AudioRegion::resume_fade_in ()
1222 if (--_fade_in_suspended == 0 && _fade_in_suspended) {
1223 set_fade_in_active (true);
1228 AudioRegion::suspend_fade_out ()
1230 if (++_fade_out_suspended == 1) {
1231 if (fade_out_is_default()) {
1232 set_fade_out_active (false);
1238 AudioRegion::resume_fade_out ()
1240 if (--_fade_out_suspended == 0 &&_fade_out_suspended) {
1241 set_fade_out_active (true);
1246 AudioRegion::speed_mismatch (float sr) const
1248 if (_sources.empty()) {
1249 /* impossible, but ... */
1253 float fsr = audio_source()->sample_rate();
1259 AudioRegion::source_offset_changed ()
1261 /* XXX this fixes a crash that should not occur. It does occur
1262 becauses regions are not being deleted when a session
1263 is unloaded. That bug must be fixed.
1266 if (_sources.empty()) {
1270 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1272 if (afs && afs->destructive()) {
1273 // set_start (source()->natural_position(), this);
1274 set_position (source()->natural_position(), this);
1278 boost::shared_ptr<AudioSource>
1279 AudioRegion::audio_source (uint32_t n) const
1281 // Guaranteed to succeed (use a static cast for speed?)
1282 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1286 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1288 boost::shared_ptr<Playlist> pl = playlist();
1294 if (_valid_transients && !force_new) {
1295 results = _transients;
1299 SourceList::iterator s;
1301 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1302 if (!(*s)->has_been_analysed()) {
1303 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1308 if (s == _sources.end()) {
1309 /* all sources are analyzed, merge data from each one */
1311 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1313 /* find the set of transients within the bounds of this region */
1315 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1316 (*s)->transients.end(),
1319 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1320 (*s)->transients.end(),
1325 results.insert (results.end(), low, high);
1328 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1330 /* translate all transients to current position */
1332 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1337 _transients = results;
1338 _valid_transients = true;
1343 /* no existing/complete transient info */
1345 static bool analyse_dialog_shown = false; /* global per instance of Ardour */
1347 if (!Config->get_auto_analyse_audio()) {
1348 if (!analyse_dialog_shown) {
1349 pl->session().Dialog (_("\
1350 You have requested an operation that requires audio analysis.\n\n \
1351 You currently have \"auto-analyse-audio\" disabled, which means\n\
1352 that transient data must be generated every time it is required.\n\n\
1353 If you are doing work that will require transient data on a\n\
1354 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1355 +then quit ardour and restart.\n\n\
1356 +This dialog will not display again. But you may notice a slight delay\n\
1357 +in this and future transient-detection operations.\n\
1359 analyse_dialog_shown = true;
1363 TransientDetector t (pl->session().frame_rate());
1364 bool existing_results = !results.empty();
1366 _transients.clear ();
1367 _valid_transients = false;
1369 for (uint32_t i = 0; i < n_channels(); ++i) {
1371 AnalysisFeatureList these_results;
1375 if (t.run ("", this, i, these_results)) {
1379 /* translate all transients to give absolute position */
1381 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1387 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1390 if (!results.empty()) {
1391 if (existing_results) {
1393 /* merge our transients into the existing ones, then clean up
1397 results.insert (results.end(), _transients.begin(), _transients.end());
1398 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1401 /* make sure ours are clean too */
1403 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1407 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1408 results = _transients;
1411 _valid_transients = true;
1416 /** Find areas of `silence' within a region.
1418 * @param threshold Threshold below which signal is considered silence (as a sample value)
1419 * @param min_length Minimum length of silent period to be reported.
1420 * @return Silent periods; first of pair is the offset within the region, second is the length of the period
1423 std::list<std::pair<frameoffset_t, framecnt_t> >
1424 AudioRegion::find_silence (Sample threshold, framecnt_t min_length, InterThreadInfo& itt) const
1426 framecnt_t const block_size = 64 * 1024;
1427 Sample loudest[block_size];
1428 Sample buf[block_size];
1430 framepos_t pos = _start;
1431 framepos_t const end = _start + _length - 1;
1433 std::list<std::pair<frameoffset_t, framecnt_t> > silent_periods;
1435 bool in_silence = false;
1436 frameoffset_t silence_start = 0;
1439 while (pos < end && !itt.cancel) {
1441 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1442 memset (loudest, 0, sizeof (Sample) * block_size);
1443 for (uint32_t n = 0; n < n_channels(); ++n) {
1445 read_raw_internal (buf, pos, block_size, n);
1446 for (framecnt_t i = 0; i < block_size; ++i) {
1447 loudest[i] = max (loudest[i], abs (buf[i]));
1451 /* now look for silence */
1452 for (framecnt_t i = 0; i < block_size; ++i) {
1453 silence = abs (loudest[i]) < threshold;
1454 if (silence && !in_silence) {
1455 /* non-silence to silence */
1457 silence_start = pos + i;
1458 } else if (!silence && in_silence) {
1459 /* silence to non-silence */
1461 if (pos + i - 1 - silence_start >= min_length) {
1462 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1468 itt.progress = (end-pos)/(double)_length;
1471 if (in_silence && end - 1 - silence_start >= min_length) {
1472 /* last block was silent, so finish off the last period */
1473 silent_periods.push_back (std::make_pair (silence_start, end));
1478 return silent_periods;
1485 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)
1487 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (framecnt_t) npeaks, (framepos_t) start, (framecnt_t) cnt, n_chan,samples_per_unit);
1490 uint32_t region_length_from_c (void *arg)
1493 return ((AudioRegion *) arg)->length();
1496 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1498 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;