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 /* 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 (muted() && !raw) {
360 return 0; /* read nothing */
363 /* precondition: caller has verified that we cover the desired section */
365 if (position < _position) {
367 buf_offset = _position - position;
370 internal_offset = position - _position;
374 if (internal_offset >= limit) {
375 return 0; /* read nothing */
378 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
379 return 0; /* read nothing */
382 if (opaque() || raw) {
383 /* overwrite whatever is there */
384 mixdown_buffer = buf + buf_offset;
386 mixdown_buffer += buf_offset;
389 if (rops & ReadOpsCount) {
390 _read_data_count = 0;
393 if (chan_n < n_channels()) {
395 boost::shared_ptr<AudioSource> src = audio_source(chan_n);
396 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
397 return 0; /* "read nothing" */
400 if (rops & ReadOpsCount) {
401 _read_data_count += src->read_data_count();
406 /* track is N-channel, this region has less channels; silence the ones
410 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
413 if (rops & ReadOpsFades) {
417 if (_fade_in_active && _session.config.get_use_region_fades()) {
419 nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
421 /* see if this read is within the fade in */
423 if (internal_offset < fade_in_length) {
427 fi_limit = min (to_read, fade_in_length - internal_offset);
430 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
432 for (nframes_t n = 0; n < fi_limit; ++n) {
433 mixdown_buffer[n] *= gain_buffer[n];
440 if (_fade_out_active && _session.config.get_use_region_fades()) {
442 /* see if some part of this read is within the fade out */
444 /* ................. >| REGION
450 limit - fade_out_length
453 ^internal_offset + to_read
455 we need the intersection of [internal_offset,internal_offset+to_read] with
456 [limit - fade_out_length, limit]
461 nframes_t fade_out_length = (nframes_t) _fade_out->back()->when;
462 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
463 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
465 if (fade_interval_end > fade_interval_start) {
466 /* (part of the) the fade out is in this buffer */
468 nframes_t fo_limit = fade_interval_end - fade_interval_start;
469 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
470 nframes_t fade_offset = fade_interval_start - internal_offset;
472 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
474 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
475 mixdown_buffer[m] *= gain_buffer[n];
482 /* Regular gain curves and scaling */
484 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
485 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
487 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
488 for (nframes_t n = 0; n < to_read; ++n) {
489 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
492 for (nframes_t n = 0; n < to_read; ++n) {
493 mixdown_buffer[n] *= gain_buffer[n];
496 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
498 // XXX this should be using what in 2.0 would have been:
499 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
501 for (nframes_t n = 0; n < to_read; ++n) {
502 mixdown_buffer[n] *= _scale_amplitude;
508 /* gack. the things we do for users.
513 for (nframes_t n = 0; n < to_read; ++n) {
514 buf[n] += mixdown_buffer[n];
522 AudioRegion::state ()
524 XMLNode& node (Region::state ());
527 LocaleGuard lg (X_("POSIX"));
529 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
530 node.add_property ("channels", buf);
532 Stateful::add_properties (node);
534 child = node.add_child ("Envelope");
536 bool default_env = false;
538 // If there are only two points, the points are in the start of the region and the end of the region
539 // so, if they are both at 1.0f, that means the default region.
541 if (_envelope->size() == 2 &&
542 _envelope->front()->value == 1.0f &&
543 _envelope->back()->value==1.0f) {
544 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
550 child->add_property ("default", "yes");
552 child->add_child_nocopy (_envelope->get_state ());
555 child = node.add_child (X_("FadeIn"));
557 if (_default_fade_in) {
558 child->add_property ("default", "yes");
560 child->add_child_nocopy (_fade_in->get_state ());
563 child = node.add_child (X_("FadeOut"));
565 if (_default_fade_out) {
566 child->add_property ("default", "yes");
568 child->add_child_nocopy (_fade_out->get_state ());
575 AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_changed, bool send)
577 const XMLNodeList& nlist = node.children();
578 const XMLProperty *prop;
579 LocaleGuard lg (X_("POSIX"));
580 boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
582 suspend_property_changes ();
585 the_playlist->freeze ();
589 /* this will set all our State members and stuff controlled by the Region.
590 It should NOT send any changed signals - that is our responsibility.
593 Region::_set_state (node, version, what_changed, false);
595 if ((prop = node.property ("scale-gain")) != 0) {
596 float a = atof (prop->value().c_str());
597 if (a != _scale_amplitude) {
598 _scale_amplitude = a;
599 what_changed.add (Properties::scale_amplitude);
603 /* Now find envelope description and other related child items */
605 _envelope->freeze ();
607 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
613 if (child->name() == "Envelope") {
617 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child, version)) {
618 set_default_envelope ();
621 _envelope->set_max_xval (_length);
622 _envelope->truncate_end (_length);
625 } else if (child->name() == "FadeIn") {
629 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
630 set_default_fade_in ();
632 XMLNode* grandchild = child->child ("AutomationList");
634 _fade_in->set_state (*grandchild, version);
638 if ((prop = child->property ("active")) != 0) {
639 if (string_is_affirmative (prop->value())) {
640 set_fade_in_active (true);
642 set_fade_in_active (false);
646 } else if (child->name() == "FadeOut") {
650 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
651 set_default_fade_out ();
653 XMLNode* grandchild = child->child ("AutomationList");
655 _fade_out->set_state (*grandchild, version);
659 if ((prop = child->property ("active")) != 0) {
660 if (string_is_affirmative (prop->value())) {
661 set_fade_out_active (true);
663 set_fade_out_active (false);
671 resume_property_changes ();
674 send_change (what_changed);
678 the_playlist->thaw ();
685 AudioRegion::set_state (const XMLNode& node, int version)
687 PropertyChange what_changed;
688 return _set_state (node, version, what_changed, true);
692 AudioRegion::set_fade_in_shape (FadeShape shape)
694 set_fade_in (shape, (nframes_t) _fade_in->back()->when);
698 AudioRegion::set_fade_out_shape (FadeShape shape)
700 set_fade_out (shape, (nframes_t) _fade_out->back()->when);
704 AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
710 send_change (PropertyChange (Properties::fade_in));
714 AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
721 _fade_in->fast_simple_add (0.0, 0.0);
722 _fade_in->fast_simple_add (len, 1.0);
726 _fade_in->fast_simple_add (0, 0);
727 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
728 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
729 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
730 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
731 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
732 _fade_in->fast_simple_add (len, 1);
736 _fade_in->fast_simple_add (0, 0);
737 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
738 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
739 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
740 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
741 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
742 _fade_in->fast_simple_add (len * 0.767281, 1);
743 _fade_in->fast_simple_add (len, 1);
747 _fade_in->fast_simple_add (0, 0);
748 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
749 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
750 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
751 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
752 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
753 _fade_in->fast_simple_add (len, 1);
757 _fade_in->fast_simple_add (0, 0);
758 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
759 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
760 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
761 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
762 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
763 _fade_in->fast_simple_add (len, 1);
771 AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
773 _fade_out->freeze ();
777 send_change (PropertyChange (Properties::fade_in));
781 AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
783 _fade_out->freeze ();
788 _fade_out->fast_simple_add (len * 0, 1);
789 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
790 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
791 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
792 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
793 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
794 _fade_out->fast_simple_add (len * 1, 0);
798 _fade_out->fast_simple_add (len * 0, 1);
799 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
800 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
801 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
802 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
803 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
804 _fade_out->fast_simple_add (len * 1, 0);
808 _fade_out->fast_simple_add (len * 0, 1);
809 _fade_out->fast_simple_add (len * 0.305556, 1);
810 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
811 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
812 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
813 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
814 _fade_out->fast_simple_add (len * 1, 0);
818 _fade_out->fast_simple_add (len * 0, 1);
819 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
820 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
821 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
822 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
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 * 1, 0);
836 AudioRegion::set_fade_in_length (framecnt_t len)
842 bool changed = _fade_in->extend_to (len);
845 _default_fade_in = false;
846 send_change (PropertyChange (Properties::fade_in));
851 AudioRegion::set_fade_out_length (framecnt_t len)
857 bool changed = _fade_out->extend_to (len);
860 _default_fade_out = false;
861 send_change (PropertyChange (Properties::fade_out));
866 AudioRegion::set_fade_in_active (bool yn)
868 if (yn == _fade_in_active) {
872 _fade_in_active = yn;
873 send_change (PropertyChange (Properties::fade_in_active));
877 AudioRegion::set_fade_out_active (bool yn)
879 if (yn == _fade_out_active) {
882 _fade_out_active = yn;
883 send_change (PropertyChange (Properties::fade_out_active));
887 AudioRegion::fade_in_is_default () const
889 return _fade_in->size() == 2 && _fade_in->front()->when == 0 && _fade_in->back()->when == 64;
893 AudioRegion::fade_out_is_default () const
895 return _fade_out->size() == 2 && _fade_out->front()->when == 0 && _fade_out->back()->when == 64;
899 AudioRegion::set_default_fade_in ()
901 _fade_in_suspended = 0;
902 set_fade_in (Linear, 64);
906 AudioRegion::set_default_fade_out ()
908 _fade_out_suspended = 0;
909 set_fade_out (Linear, 64);
913 AudioRegion::set_default_fades ()
915 set_default_fade_in ();
916 set_default_fade_out ();
920 AudioRegion::set_default_envelope ()
922 _envelope->freeze ();
924 _envelope->fast_simple_add (0, 1.0f);
925 _envelope->fast_simple_add (_length, 1.0f);
930 AudioRegion::recompute_at_end ()
932 /* our length has changed. recompute a new final point by interpolating
933 based on the the existing curve.
936 _envelope->freeze ();
937 _envelope->truncate_end (_length);
938 _envelope->set_max_xval (_length);
941 if (_left_of_split) {
942 set_default_fade_out ();
943 _left_of_split = false;
944 } else if (_fade_out->back()->when > _length) {
945 _fade_out->extend_to (_length);
946 send_change (PropertyChange (Properties::fade_out));
949 if (_fade_in->back()->when > _length) {
950 _fade_in->extend_to (_length);
951 send_change (PropertyChange (Properties::fade_in));
956 AudioRegion::recompute_at_start ()
958 /* as above, but the shift was from the front */
960 _envelope->truncate_start (_length);
962 if (_right_of_split) {
963 set_default_fade_in ();
964 _right_of_split = false;
965 } else if (_fade_in->back()->when > _length) {
966 _fade_in->extend_to (_length);
967 send_change (PropertyChange (Properties::fade_in));
970 if (_fade_out->back()->when > _length) {
971 _fade_out->extend_to (_length);
972 send_change (PropertyChange (Properties::fade_out));
977 AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr<Region> >& v) const
983 if (_sources.size() < 2) {
987 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
993 if (_sources.size() == 2) {
1001 new_name += ('0' + n + 1);
1004 /* create a copy with just one source. prevent if from being thought of as
1005 "whole file" even if it covers the entire source file(s).
1010 plist.add (Properties::start, _start.val());
1011 plist.add (Properties::length, _length.val());
1012 plist.add (Properties::name, new_name);
1013 plist.add (Properties::layer, _layer.val());
1015 v.push_back(RegionFactory::create (srcs, plist));
1016 v.back()->set_whole_file (false);
1025 AudioRegion::read_raw_internal (Sample* buf, framepos_t pos, framecnt_t cnt, int channel) const
1027 return audio_source()->read (buf, pos, cnt, channel);
1031 AudioRegion::exportme (Session& /*session*/, ARDOUR::ExportSpecification& /*spec*/)
1034 // const nframes_t blocksize = 4096;
1035 // nframes_t to_read;
1038 // spec.channels = _sources.size();
1040 // if (spec.prepare (blocksize, session.frame_rate())) {
1045 // spec.total_frames = _length;
1047 // while (spec.pos < _length && !spec.stop) {
1050 // /* step 1: interleave */
1052 // to_read = min (_length - spec.pos, blocksize);
1054 // if (spec.channels == 1) {
1056 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1062 // Sample buf[blocksize];
1064 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1066 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1070 // for (nframes_t x = 0; x < to_read; ++x) {
1071 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1076 // if (spec.process (to_read)) {
1080 // spec.pos += to_read;
1081 // spec.progress = (double) spec.pos /_length;
1088 // spec.running = false;
1089 // spec.status = status;
1097 AudioRegion::set_scale_amplitude (gain_t g)
1099 boost::shared_ptr<Playlist> pl (playlist());
1101 _scale_amplitude = g;
1103 /* tell the diskstream we're in */
1106 pl->ContentsChanged();
1109 /* tell everybody else */
1111 send_change (PropertyChange (Properties::scale_amplitude));
1114 /** @return the maximum (linear) amplitude of the region */
1116 AudioRegion::maximum_amplitude () const
1118 framepos_t fpos = _start;
1119 framepos_t const fend = _start + _length;
1122 framecnt_t const blocksize = 64 * 1024;
1123 Sample buf[blocksize];
1125 while (fpos < fend) {
1129 framecnt_t const to_read = min (fend - fpos, blocksize);
1131 for (n = 0; n < n_channels(); ++n) {
1135 if (read_raw_internal (buf, fpos, to_read, 0) != to_read) {
1139 maxamp = compute_peak (buf, to_read, maxamp);
1148 /** Normalize using a given maximum amplitude and target, so that region
1149 * _scale_amplitude becomes target / max_amplitude.
1152 AudioRegion::normalize (float max_amplitude, float target_dB)
1154 gain_t target = dB_to_coefficient (target_dB);
1156 if (target == 1.0f) {
1157 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1158 that we may have clipped.
1160 target -= FLT_EPSILON;
1163 if (max_amplitude == 0.0f) {
1164 /* don't even try */
1168 if (max_amplitude == target) {
1169 /* we can't do anything useful */
1173 set_scale_amplitude (target / max_amplitude);
1177 AudioRegion::fade_in_changed ()
1179 send_change (PropertyChange (Properties::fade_in));
1183 AudioRegion::fade_out_changed ()
1185 send_change (PropertyChange (Properties::fade_out));
1189 AudioRegion::envelope_changed ()
1191 send_change (PropertyChange (Properties::envelope));
1195 AudioRegion::suspend_fade_in ()
1197 if (++_fade_in_suspended == 1) {
1198 if (fade_in_is_default()) {
1199 set_fade_in_active (false);
1205 AudioRegion::resume_fade_in ()
1207 if (--_fade_in_suspended == 0 && _fade_in_suspended) {
1208 set_fade_in_active (true);
1213 AudioRegion::suspend_fade_out ()
1215 if (++_fade_out_suspended == 1) {
1216 if (fade_out_is_default()) {
1217 set_fade_out_active (false);
1223 AudioRegion::resume_fade_out ()
1225 if (--_fade_out_suspended == 0 &&_fade_out_suspended) {
1226 set_fade_out_active (true);
1231 AudioRegion::speed_mismatch (float sr) const
1233 if (_sources.empty()) {
1234 /* impossible, but ... */
1238 float fsr = audio_source()->sample_rate();
1244 AudioRegion::source_offset_changed ()
1246 /* XXX this fixes a crash that should not occur. It does occur
1247 becauses regions are not being deleted when a session
1248 is unloaded. That bug must be fixed.
1251 if (_sources.empty()) {
1255 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1257 if (afs && afs->destructive()) {
1258 // set_start (source()->natural_position(), this);
1259 set_position (source()->natural_position(), this);
1263 boost::shared_ptr<AudioSource>
1264 AudioRegion::audio_source (uint32_t n) const
1266 // Guaranteed to succeed (use a static cast for speed?)
1267 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1271 AudioRegion::adjust_transients (nframes64_t delta)
1273 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1274 (*x) = (*x) + delta;
1277 send_change (PropertyChange (Properties::valid_transients));
1283 AudioRegion::update_transient (nframes64_t old_position, nframes64_t new_position)
1285 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1286 if ((*x) == old_position) {
1287 (*x) = new_position;
1288 send_change (PropertyChange (Properties::valid_transients));
1298 AudioRegion::add_transient (nframes64_t where)
1300 _transients.push_back(where);
1301 _valid_transients = true;
1303 send_change (PropertyChange (Properties::valid_transients));
1307 AudioRegion::remove_transient (nframes64_t where)
1309 _transients.remove(where);
1310 _valid_transients = true;
1312 send_change (PropertyChange (Properties::valid_transients));
1316 AudioRegion::set_transients (AnalysisFeatureList& results)
1318 _transients.clear();
1319 _transients = results;
1320 _valid_transients = true;
1322 send_change (PropertyChange (Properties::valid_transients));
1328 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1330 boost::shared_ptr<Playlist> pl = playlist();
1336 if (_valid_transients && !force_new) {
1337 results = _transients;
1341 SourceList::iterator s;
1343 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1344 if (!(*s)->has_been_analysed()) {
1345 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1350 if (s == _sources.end()) {
1351 /* all sources are analyzed, merge data from each one */
1353 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1355 /* find the set of transients within the bounds of this region */
1357 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1358 (*s)->transients.end(),
1361 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1362 (*s)->transients.end(),
1367 results.insert (results.end(), low, high);
1370 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1372 /* translate all transients to current position */
1374 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1379 _transients = results;
1380 _valid_transients = true;
1385 /* no existing/complete transient info */
1387 static bool analyse_dialog_shown = false; /* global per instance of Ardour */
1389 if (!Config->get_auto_analyse_audio()) {
1390 if (!analyse_dialog_shown) {
1391 pl->session().Dialog (_("\
1392 You have requested an operation that requires audio analysis.\n\n \
1393 You currently have \"auto-analyse-audio\" disabled, which means\n\
1394 that transient data must be generated every time it is required.\n\n\
1395 If you are doing work that will require transient data on a\n\
1396 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1397 +then quit ardour and restart.\n\n\
1398 +This dialog will not display again. But you may notice a slight delay\n\
1399 +in this and future transient-detection operations.\n\
1401 analyse_dialog_shown = true;
1405 TransientDetector t (pl->session().frame_rate());
1406 bool existing_results = !results.empty();
1408 _transients.clear ();
1409 _valid_transients = false;
1411 for (uint32_t i = 0; i < n_channels(); ++i) {
1413 AnalysisFeatureList these_results;
1417 if (t.run ("", this, i, these_results)) {
1421 /* translate all transients to give absolute position */
1423 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1429 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1432 if (!results.empty()) {
1433 if (existing_results) {
1435 /* merge our transients into the existing ones, then clean up
1439 results.insert (results.end(), _transients.begin(), _transients.end());
1440 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1443 /* make sure ours are clean too */
1445 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1449 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1450 results = _transients;
1453 _valid_transients = true;
1458 /** Find areas of `silence' within a region.
1460 * @param threshold Threshold below which signal is considered silence (as a sample value)
1461 * @param min_length Minimum length of silent period to be reported.
1462 * @return Silent periods; first of pair is the offset within the region, second is the length of the period
1465 std::list<std::pair<frameoffset_t, framecnt_t> >
1466 AudioRegion::find_silence (Sample threshold, framecnt_t min_length, InterThreadInfo& itt) const
1468 framecnt_t const block_size = 64 * 1024;
1469 Sample loudest[block_size];
1470 Sample buf[block_size];
1472 framepos_t pos = _start;
1473 framepos_t const end = _start + _length - 1;
1475 std::list<std::pair<frameoffset_t, framecnt_t> > silent_periods;
1477 bool in_silence = false;
1478 frameoffset_t silence_start = 0;
1481 while (pos < end && !itt.cancel) {
1483 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1484 memset (loudest, 0, sizeof (Sample) * block_size);
1485 for (uint32_t n = 0; n < n_channels(); ++n) {
1487 read_raw_internal (buf, pos, block_size, n);
1488 for (framecnt_t i = 0; i < block_size; ++i) {
1489 loudest[i] = max (loudest[i], abs (buf[i]));
1493 /* now look for silence */
1494 for (framecnt_t i = 0; i < block_size; ++i) {
1495 silence = abs (loudest[i]) < threshold;
1496 if (silence && !in_silence) {
1497 /* non-silence to silence */
1499 silence_start = pos + i;
1500 } else if (!silence && in_silence) {
1501 /* silence to non-silence */
1503 if (pos + i - 1 - silence_start >= min_length) {
1504 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1510 itt.progress = (end-pos)/(double)_length;
1513 if (in_silence && end - 1 - silence_start >= min_length) {
1514 /* last block was silent, so finish off the last period */
1515 silent_periods.push_back (std::make_pair (silence_start, end));
1520 return silent_periods;
1527 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)
1529 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (framecnt_t) npeaks, (framepos_t) start, (framecnt_t) cnt, n_chan,samples_per_unit);
1532 uint32_t region_length_from_c (void *arg)
1535 return ((AudioRegion *) arg)->length();
1538 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1540 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;