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 /* connect only once to HeaderPositionOffsetChanged, even if sources are replicated
269 if (unique_srcs.find (*i) == unique_srcs.end ()) {
270 unique_srcs.insert (*i);
271 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
273 afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
280 AudioRegion::listen_to_my_curves ()
282 _envelope->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::envelope_changed, this));
283 _fade_in->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_in_changed, this));
284 _fade_out->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_out_changed, this));
288 AudioRegion::set_envelope_active (bool yn)
290 if (envelope_active() != yn) {
291 _envelope_active = yn;
292 send_change (PropertyChange (Properties::envelope_active));
297 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
299 if (chan_n >= _sources.size()) {
303 if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
306 if (_scale_amplitude != 1.0f) {
307 for (nframes_t n = 0; n < npeaks; ++n) {
308 buf[n].max *= _scale_amplitude;
309 buf[n].min *= _scale_amplitude;
317 AudioRegion::read (Sample* buf, framepos_t timeline_position, framecnt_t cnt, int channel) const
319 /* raw read, no fades, no gain, nada */
320 return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
324 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
325 framepos_t file_position, framecnt_t cnt, uint32_t chan_n,
326 framecnt_t read_frames, framecnt_t skip_frames) const
328 /* regular diskstream/butler read complete with fades etc */
329 return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer,
330 file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
334 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
335 framepos_t position, framecnt_t cnt, uint32_t chan_n) const
337 /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
339 return _read_at (_master_sources, _master_sources.front()->length(_master_sources.front()->timeline_position()),
340 buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0, ReadOps (0));
344 AudioRegion::_read_at (const SourceList& /*srcs*/, framecnt_t limit,
345 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
349 framecnt_t /*read_frames*/,
350 framecnt_t /*skip_frames*/,
353 frameoffset_t internal_offset;
354 frameoffset_t buf_offset;
356 bool raw = (rops == ReadOpsNone);
358 if (muted() && !raw) {
359 return 0; /* read nothing */
362 /* precondition: caller has verified that we cover the desired section */
364 if (position < _position) {
366 buf_offset = _position - position;
369 internal_offset = position - _position;
373 if (internal_offset >= limit) {
374 return 0; /* read nothing */
377 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
378 return 0; /* read nothing */
381 if (opaque() || raw) {
382 /* overwrite whatever is there */
383 mixdown_buffer = buf + buf_offset;
385 mixdown_buffer += buf_offset;
388 if (rops & ReadOpsCount) {
389 _read_data_count = 0;
392 if (chan_n < n_channels()) {
394 boost::shared_ptr<AudioSource> src = audio_source(chan_n);
395 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
396 return 0; /* "read nothing" */
399 if (rops & ReadOpsCount) {
400 _read_data_count += src->read_data_count();
405 /* track is N-channel, this region has less channels; silence the ones
409 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
412 if (rops & ReadOpsFades) {
416 if (_fade_in_active && _session.config.get_use_region_fades()) {
418 nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
420 /* see if this read is within the fade in */
422 if (internal_offset < fade_in_length) {
426 fi_limit = min (to_read, fade_in_length - internal_offset);
429 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
431 for (nframes_t n = 0; n < fi_limit; ++n) {
432 mixdown_buffer[n] *= gain_buffer[n];
439 if (_fade_out_active && _session.config.get_use_region_fades()) {
441 /* see if some part of this read is within the fade out */
443 /* ................. >| REGION
449 limit - fade_out_length
452 ^internal_offset + to_read
454 we need the intersection of [internal_offset,internal_offset+to_read] with
455 [limit - fade_out_length, limit]
460 nframes_t fade_out_length = (nframes_t) _fade_out->back()->when;
461 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
462 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
464 if (fade_interval_end > fade_interval_start) {
465 /* (part of the) the fade out is in this buffer */
467 nframes_t fo_limit = fade_interval_end - fade_interval_start;
468 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
469 nframes_t fade_offset = fade_interval_start - internal_offset;
471 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
473 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
474 mixdown_buffer[m] *= gain_buffer[n];
481 /* Regular gain curves and scaling */
483 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
484 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
486 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
487 for (nframes_t n = 0; n < to_read; ++n) {
488 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
491 for (nframes_t n = 0; n < to_read; ++n) {
492 mixdown_buffer[n] *= gain_buffer[n];
495 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
497 // XXX this should be using what in 2.0 would have been:
498 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
500 for (nframes_t n = 0; n < to_read; ++n) {
501 mixdown_buffer[n] *= _scale_amplitude;
507 /* gack. the things we do for users.
512 for (nframes_t n = 0; n < to_read; ++n) {
513 buf[n] += mixdown_buffer[n];
521 AudioRegion::state (bool full)
523 XMLNode& node (Region::state (full));
526 LocaleGuard lg (X_("POSIX"));
528 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
529 node.add_property ("channels", buf);
532 Stateful::add_properties (node);
535 child = node.add_child ("Envelope");
538 bool default_env = false;
540 // If there are only two points, the points are in the start of the region and the end of the region
541 // so, if they are both at 1.0f, that means the default region.
543 if (_envelope->size() == 2 &&
544 _envelope->front()->value == 1.0f &&
545 _envelope->back()->value==1.0f) {
546 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
552 child->add_property ("default", "yes");
554 child->add_child_nocopy (_envelope->get_state ());
558 child->add_property ("default", "yes");
565 AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_changed, bool send)
567 const XMLNodeList& nlist = node.children();
568 const XMLProperty *prop;
569 LocaleGuard lg (X_("POSIX"));
570 boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
572 suspend_property_changes ();
575 the_playlist->freeze ();
579 /* this will set all our State members and stuff controlled by the Region.
580 It should NOT send any changed signals - that is our responsibility.
583 Region::_set_state (node, version, what_changed, false);
585 if ((prop = node.property ("scale-gain")) != 0) {
586 float a = atof (prop->value().c_str());
587 if (a != _scale_amplitude) {
588 _scale_amplitude = a;
589 what_changed.add (Properties::scale_amplitude);
593 /* Now find envelope description and other related child items */
595 _envelope->freeze ();
597 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
603 if (child->name() == "Envelope") {
607 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child, version)) {
608 set_default_envelope ();
611 _envelope->set_max_xval (_length);
612 _envelope->truncate_end (_length);
615 } else if (child->name() == "FadeIn") {
619 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
620 set_default_fade_in ();
622 XMLNode* grandchild = child->child ("AutomationList");
624 _fade_in->set_state (*grandchild, version);
628 if ((prop = child->property ("active")) != 0) {
629 if (string_is_affirmative (prop->value())) {
630 set_fade_in_active (true);
632 set_fade_in_active (false);
636 } else if (child->name() == "FadeOut") {
640 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
641 set_default_fade_out ();
643 XMLNode* grandchild = child->child ("AutomationList");
645 _fade_out->set_state (*grandchild, version);
649 if ((prop = child->property ("active")) != 0) {
650 if (string_is_affirmative (prop->value())) {
651 set_fade_out_active (true);
653 set_fade_out_active (false);
661 resume_property_changes ();
664 send_change (what_changed);
668 the_playlist->thaw ();
675 AudioRegion::set_state (const XMLNode& node, int version)
677 PropertyChange what_changed;
678 return _set_state (node, version, what_changed, true);
682 AudioRegion::set_fade_in_shape (FadeShape shape)
684 set_fade_in (shape, (nframes_t) _fade_in->back()->when);
688 AudioRegion::set_fade_out_shape (FadeShape shape)
690 set_fade_out (shape, (nframes_t) _fade_out->back()->when);
694 AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
700 send_change (PropertyChange (Properties::fade_in));
704 AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
711 _fade_in->fast_simple_add (0.0, 0.0);
712 _fade_in->fast_simple_add (len, 1.0);
716 _fade_in->fast_simple_add (0, 0);
717 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
718 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
719 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
720 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
721 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
722 _fade_in->fast_simple_add (len, 1);
726 _fade_in->fast_simple_add (0, 0);
727 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
728 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
729 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
730 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
731 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
732 _fade_in->fast_simple_add (len * 0.767281, 1);
733 _fade_in->fast_simple_add (len, 1);
737 _fade_in->fast_simple_add (0, 0);
738 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
739 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
740 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
741 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
742 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
743 _fade_in->fast_simple_add (len, 1);
747 _fade_in->fast_simple_add (0, 0);
748 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
749 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
750 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
751 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
752 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
753 _fade_in->fast_simple_add (len, 1);
761 AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
763 _fade_out->freeze ();
767 send_change (PropertyChange (Properties::fade_in));
771 AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
773 _fade_out->freeze ();
778 _fade_out->fast_simple_add (len * 0, 1);
779 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
780 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
781 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
782 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
783 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
784 _fade_out->fast_simple_add (len * 1, 0);
788 _fade_out->fast_simple_add (len * 0, 1);
789 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
790 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
791 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
792 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
793 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
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.305556, 1);
800 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
801 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
802 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
803 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
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.080645, 0.730556);
810 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
811 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
812 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
813 _fade_out->fast_simple_add (len * 1, 0);
817 _fade_out->fast_simple_add (len * 0, 1);
818 _fade_out->fast_simple_add (len * 1, 0);
826 AudioRegion::set_fade_in_length (framecnt_t len)
832 bool changed = _fade_in->extend_to (len);
835 _default_fade_in = false;
836 send_change (PropertyChange (Properties::fade_in));
841 AudioRegion::set_fade_out_length (framecnt_t len)
847 bool changed = _fade_out->extend_to (len);
850 _default_fade_out = false;
851 send_change (PropertyChange (Properties::fade_out));
856 AudioRegion::set_fade_in_active (bool yn)
858 if (yn == _fade_in_active) {
862 _fade_in_active = yn;
863 send_change (PropertyChange (Properties::fade_in_active));
867 AudioRegion::set_fade_out_active (bool yn)
869 if (yn == _fade_out_active) {
872 _fade_out_active = yn;
873 send_change (PropertyChange (Properties::fade_out_active));
877 AudioRegion::fade_in_is_default () const
879 return _fade_in->size() == 2 && _fade_in->front()->when == 0 && _fade_in->back()->when == 64;
883 AudioRegion::fade_out_is_default () const
885 return _fade_out->size() == 2 && _fade_out->front()->when == 0 && _fade_out->back()->when == 64;
889 AudioRegion::set_default_fade_in ()
891 _fade_in_suspended = 0;
892 set_fade_in (Linear, 64);
896 AudioRegion::set_default_fade_out ()
898 _fade_out_suspended = 0;
899 set_fade_out (Linear, 64);
903 AudioRegion::set_default_fades ()
905 set_default_fade_in ();
906 set_default_fade_out ();
910 AudioRegion::set_default_envelope ()
912 _envelope->freeze ();
914 _envelope->fast_simple_add (0, 1.0f);
915 _envelope->fast_simple_add (_length, 1.0f);
920 AudioRegion::recompute_at_end ()
922 /* our length has changed. recompute a new final point by interpolating
923 based on the the existing curve.
926 _envelope->freeze ();
927 _envelope->truncate_end (_length);
928 _envelope->set_max_xval (_length);
931 if (_left_of_split) {
932 set_default_fade_out ();
933 _left_of_split = false;
934 } else if (_fade_out->back()->when > _length) {
935 _fade_out->extend_to (_length);
936 send_change (PropertyChange (Properties::fade_out));
939 if (_fade_in->back()->when > _length) {
940 _fade_in->extend_to (_length);
941 send_change (PropertyChange (Properties::fade_in));
946 AudioRegion::recompute_at_start ()
948 /* as above, but the shift was from the front */
950 _envelope->truncate_start (_length);
952 if (_right_of_split) {
953 set_default_fade_in ();
954 _right_of_split = false;
955 } else if (_fade_in->back()->when > _length) {
956 _fade_in->extend_to (_length);
957 send_change (PropertyChange (Properties::fade_in));
960 if (_fade_out->back()->when > _length) {
961 _fade_out->extend_to (_length);
962 send_change (PropertyChange (Properties::fade_out));
967 AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr<Region> >& v) const
973 if (_sources.size() < 2) {
977 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
983 if (_sources.size() == 2) {
991 new_name += ('0' + n + 1);
994 /* create a copy with just one source. prevent if from being thought of as
995 "whole file" even if it covers the entire source file(s).
1000 plist.add (Properties::start, _start.val());
1001 plist.add (Properties::length, _length.val());
1002 plist.add (Properties::name, new_name);
1003 plist.add (Properties::layer, _layer.val());
1005 v.push_back(RegionFactory::create (srcs, plist));
1006 v.back()->set_whole_file (false);
1015 AudioRegion::read_raw_internal (Sample* buf, framepos_t pos, framecnt_t cnt, int channel) const
1017 return audio_source()->read (buf, pos, cnt, channel);
1021 AudioRegion::exportme (Session& /*session*/, ARDOUR::ExportSpecification& /*spec*/)
1024 // const nframes_t blocksize = 4096;
1025 // nframes_t to_read;
1028 // spec.channels = _sources.size();
1030 // if (spec.prepare (blocksize, session.frame_rate())) {
1035 // spec.total_frames = _length;
1037 // while (spec.pos < _length && !spec.stop) {
1040 // /* step 1: interleave */
1042 // to_read = min (_length - spec.pos, blocksize);
1044 // if (spec.channels == 1) {
1046 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1052 // Sample buf[blocksize];
1054 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1056 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1060 // for (nframes_t x = 0; x < to_read; ++x) {
1061 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1066 // if (spec.process (to_read)) {
1070 // spec.pos += to_read;
1071 // spec.progress = (double) spec.pos /_length;
1078 // spec.running = false;
1079 // spec.status = status;
1087 AudioRegion::set_scale_amplitude (gain_t g)
1089 boost::shared_ptr<Playlist> pl (playlist());
1091 _scale_amplitude = g;
1093 /* tell the diskstream we're in */
1096 pl->ContentsChanged();
1099 /* tell everybody else */
1101 send_change (PropertyChange (Properties::scale_amplitude));
1105 AudioRegion::normalize_to (float target_dB)
1107 const framecnt_t blocksize = 64 * 1024;
1108 Sample buf[blocksize];
1113 gain_t target = dB_to_coefficient (target_dB);
1115 if (target == 1.0f) {
1116 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1117 that we may have clipped.
1119 target -= FLT_EPSILON;
1123 fend = _start + _length;
1125 /* first pass: find max amplitude */
1127 while (fpos < fend) {
1131 to_read = min (fend - fpos, blocksize);
1133 for (n = 0; n < n_channels(); ++n) {
1137 if (read_raw_internal (buf, fpos, to_read, 0) != to_read) {
1141 maxamp = compute_peak (buf, to_read, maxamp);
1147 if (maxamp == 0.0f) {
1148 /* don't even try */
1152 if (maxamp == target) {
1153 /* we can't do anything useful */
1157 /* compute scale factor */
1159 _scale_amplitude = target/maxamp;
1161 /* tell the diskstream we're in */
1163 boost::shared_ptr<Playlist> pl (playlist());
1166 pl->ContentsChanged();
1169 /* tell everybody else */
1171 send_change (PropertyChange (Properties::scale_amplitude));
1175 AudioRegion::fade_in_changed ()
1177 send_change (PropertyChange (Properties::fade_in));
1181 AudioRegion::fade_out_changed ()
1183 send_change (PropertyChange (Properties::fade_out));
1187 AudioRegion::envelope_changed ()
1189 send_change (PropertyChange (Properties::envelope));
1193 AudioRegion::suspend_fade_in ()
1195 if (++_fade_in_suspended == 1) {
1196 if (fade_in_is_default()) {
1197 set_fade_in_active (false);
1203 AudioRegion::resume_fade_in ()
1205 if (--_fade_in_suspended == 0 && _fade_in_suspended) {
1206 set_fade_in_active (true);
1211 AudioRegion::suspend_fade_out ()
1213 if (++_fade_out_suspended == 1) {
1214 if (fade_out_is_default()) {
1215 set_fade_out_active (false);
1221 AudioRegion::resume_fade_out ()
1223 if (--_fade_out_suspended == 0 &&_fade_out_suspended) {
1224 set_fade_out_active (true);
1229 AudioRegion::speed_mismatch (float sr) const
1231 if (_sources.empty()) {
1232 /* impossible, but ... */
1236 float fsr = audio_source()->sample_rate();
1242 AudioRegion::source_offset_changed ()
1244 /* XXX this fixes a crash that should not occur. It does occur
1245 becauses regions are not being deleted when a session
1246 is unloaded. That bug must be fixed.
1249 if (_sources.empty()) {
1253 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1255 if (afs && afs->destructive()) {
1256 // set_start (source()->natural_position(), this);
1257 set_position (source()->natural_position(), this);
1261 boost::shared_ptr<AudioSource>
1262 AudioRegion::audio_source (uint32_t n) const
1264 // Guaranteed to succeed (use a static cast for speed?)
1265 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1269 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1271 boost::shared_ptr<Playlist> pl = playlist();
1277 if (_valid_transients && !force_new) {
1278 results = _transients;
1282 SourceList::iterator s;
1284 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1285 if (!(*s)->has_been_analysed()) {
1286 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1291 if (s == _sources.end()) {
1292 /* all sources are analyzed, merge data from each one */
1294 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1296 /* find the set of transients within the bounds of this region */
1298 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1299 (*s)->transients.end(),
1302 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1303 (*s)->transients.end(),
1308 results.insert (results.end(), low, high);
1311 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1313 /* translate all transients to current position */
1315 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1320 _transients = results;
1321 _valid_transients = true;
1326 /* no existing/complete transient info */
1328 static bool analyse_dialog_shown = false; /* global per instance of Ardour */
1330 if (!Config->get_auto_analyse_audio()) {
1331 if (!analyse_dialog_shown) {
1332 pl->session().Dialog (_("\
1333 You have requested an operation that requires audio analysis.\n\n \
1334 You currently have \"auto-analyse-audio\" disabled, which means\n\
1335 that transient data must be generated every time it is required.\n\n\
1336 If you are doing work that will require transient data on a\n\
1337 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1338 +then quit ardour and restart.\n\n\
1339 +This dialog will not display again. But you may notice a slight delay\n\
1340 +in this and future transient-detection operations.\n\
1342 analyse_dialog_shown = true;
1346 TransientDetector t (pl->session().frame_rate());
1347 bool existing_results = !results.empty();
1349 _transients.clear ();
1350 _valid_transients = false;
1352 for (uint32_t i = 0; i < n_channels(); ++i) {
1354 AnalysisFeatureList these_results;
1358 if (t.run ("", this, i, these_results)) {
1362 /* translate all transients to give absolute position */
1364 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1370 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1373 if (!results.empty()) {
1374 if (existing_results) {
1376 /* merge our transients into the existing ones, then clean up
1380 results.insert (results.end(), _transients.begin(), _transients.end());
1381 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1384 /* make sure ours are clean too */
1386 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1390 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1391 results = _transients;
1394 _valid_transients = true;
1399 /** Find areas of `silence' within a region.
1401 * @param threshold Threshold below which signal is considered silence (as a sample value)
1402 * @param min_length Minimum length of silent period to be reported.
1403 * @return Silent periods; first of pair is the offset within the region, second is the length of the period
1406 std::list<std::pair<frameoffset_t, framecnt_t> >
1407 AudioRegion::find_silence (Sample threshold, framecnt_t min_length, InterThreadInfo& itt) const
1409 framecnt_t const block_size = 64 * 1024;
1410 Sample loudest[block_size];
1411 Sample buf[block_size];
1413 framepos_t pos = _start;
1414 framepos_t const end = _start + _length - 1;
1416 std::list<std::pair<frameoffset_t, framecnt_t> > silent_periods;
1418 bool in_silence = false;
1419 frameoffset_t silence_start = 0;
1422 while (pos < end && !itt.cancel) {
1424 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1425 memset (loudest, 0, sizeof (Sample) * block_size);
1426 for (uint32_t n = 0; n < n_channels(); ++n) {
1428 read_raw_internal (buf, pos, block_size, n);
1429 for (framecnt_t i = 0; i < block_size; ++i) {
1430 loudest[i] = max (loudest[i], abs (buf[i]));
1434 /* now look for silence */
1435 for (framecnt_t i = 0; i < block_size; ++i) {
1436 silence = abs (loudest[i]) < threshold;
1437 if (silence && !in_silence) {
1438 /* non-silence to silence */
1440 silence_start = pos + i;
1441 } else if (!silence && in_silence) {
1442 /* silence to non-silence */
1444 if (pos + i - 1 - silence_start >= min_length) {
1445 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1451 itt.progress = (end-pos)/(double)_length;
1454 if (in_silence && end - 1 - silence_start >= min_length) {
1455 /* last block was silent, so finish off the last period */
1456 silent_periods.push_back (std::make_pair (silence_start, end));
1461 return silent_periods;
1468 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)
1470 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (framecnt_t) npeaks, (framepos_t) start, (framecnt_t) cnt, n_chan,samples_per_unit);
1473 uint32_t region_length_from_c (void *arg)
1476 return ((AudioRegion *) arg)->length();
1479 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1481 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;