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.id = g_quark_from_static_string (X_("envelope-active"));
71 Properties::default_fade_in.id = g_quark_from_static_string (X_("default-fade-in"));
72 Properties::default_fade_out.id = g_quark_from_static_string (X_("default-fade-out"));
73 Properties::fade_in_active.id = g_quark_from_static_string (X_("fade-in-active"));
74 Properties::fade_out_active.id = g_quark_from_static_string (X_("fade-out-active"));
75 Properties::scale_amplitude.id = g_quark_from_static_string (X_("scale-amplitude"));
79 AudioRegion::register_properties ()
81 /* no need to register parent class properties */
83 add_property (_envelope_active);
84 add_property (_default_fade_in);
85 add_property (_default_fade_out);
86 add_property (_fade_in_active);
87 add_property (_fade_out_active);
88 add_property (_scale_amplitude);
91 #define AUDIOREGION_STATE_DEFAULT \
92 _envelope_active (Properties::envelope_active, false) \
93 , _default_fade_in (Properties::default_fade_in, true) \
94 , _default_fade_out (Properties::default_fade_out, true) \
95 , _fade_in_active (Properties::fade_in_active, true) \
96 , _fade_out_active (Properties::fade_out_active, true) \
97 , _scale_amplitude (Properties::scale_amplitude, 0.0)
99 #define AUDIOREGION_COPY_STATE(other) \
100 _envelope_active (other->_envelope_active) \
101 , _default_fade_in (other->_default_fade_in) \
102 , _default_fade_out (other->_default_fade_out) \
103 , _fade_in_active (other->_fade_in_active) \
104 , _fade_out_active (other->_fade_out_active) \
105 , _scale_amplitude (other->_scale_amplitude)
107 /* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
112 register_properties ();
114 set_default_fades ();
115 set_default_envelope ();
117 listen_to_my_curves ();
118 connect_to_analysis_changed ();
119 connect_to_header_position_offset_changed ();
122 /** Constructor for use by derived types only */
123 AudioRegion::AudioRegion (Session& s, framepos_t start, framecnt_t len, std::string name)
124 : Region (s, start, len, name, DataType::AUDIO)
125 , AUDIOREGION_STATE_DEFAULT
127 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
128 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
129 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
130 , _fade_in_suspended (0)
131 , _fade_out_suspended (0)
134 assert (_sources.size() == _master_sources.size());
137 /** Basic AudioRegion constructor */
138 AudioRegion::AudioRegion (const SourceList& srcs)
140 , AUDIOREGION_STATE_DEFAULT
141 , _automatable(srcs[0]->session())
142 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
143 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
144 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
145 , _fade_in_suspended (0)
146 , _fade_out_suspended (0)
149 assert (_sources.size() == _master_sources.size());
152 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes64_t offset, bool offset_relative)
153 : Region (other, offset, offset_relative)
154 , AUDIOREGION_COPY_STATE (other)
155 , _automatable (other->session())
156 , _fade_in (new AutomationList (*other->_fade_in))
157 , _fade_out (new AutomationList (*other->_fade_out))
158 /* XXX is this guaranteed to work for all values of offset+offset_relative? */
159 , _envelope (new AutomationList (*other->_envelope, _start, _start + _length))
160 , _fade_in_suspended (0)
161 , _fade_out_suspended (0)
163 /* don't use init here, because we got fade in/out from the other region
165 register_properties ();
166 listen_to_my_curves ();
167 connect_to_analysis_changed ();
168 connect_to_header_position_offset_changed ();
170 assert(_type == DataType::AUDIO);
171 assert (_sources.size() == _master_sources.size());
174 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& srcs)
175 : Region (boost::static_pointer_cast<const Region>(other), srcs)
176 , AUDIOREGION_COPY_STATE (other)
177 , _automatable (other->session())
178 , _fade_in (new AutomationList (*other->_fade_in))
179 , _fade_out (new AutomationList (*other->_fade_out))
180 , _envelope (new AutomationList (*other->_envelope))
181 , _fade_in_suspended (0)
182 , _fade_out_suspended (0)
184 /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
186 register_properties ();
188 listen_to_my_curves ();
189 connect_to_analysis_changed ();
190 connect_to_header_position_offset_changed ();
192 assert (_sources.size() == _master_sources.size());
195 AudioRegion::AudioRegion (SourceList& srcs)
197 , AUDIOREGION_STATE_DEFAULT
198 , _automatable(srcs[0]->session())
199 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
200 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
201 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
202 , _fade_in_suspended (0)
203 , _fade_out_suspended (0)
207 assert(_type == DataType::AUDIO);
208 assert (_sources.size() == _master_sources.size());
211 AudioRegion::~AudioRegion ()
216 AudioRegion::post_set ()
219 _sync_position = _start;
222 /* return to default fades if the existing ones are too long */
224 if (_left_of_split) {
225 if (_fade_in->back()->when >= _length) {
226 set_default_fade_in ();
228 set_default_fade_out ();
229 _left_of_split = false;
232 if (_right_of_split) {
233 if (_fade_out->back()->when >= _length) {
234 set_default_fade_out ();
237 set_default_fade_in ();
238 _right_of_split = false;
243 AudioRegion::connect_to_analysis_changed ()
245 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
246 (*i)->AnalysisChanged.connect_same_thread (*this, boost::bind (&AudioRegion::invalidate_transients, this));
251 AudioRegion::connect_to_header_position_offset_changed ()
253 set<boost::shared_ptr<Source> > unique_srcs;
255 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
257 if (unique_srcs.find (*i) == unique_srcs.end ()) {
258 unique_srcs.insert (*i);
259 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
261 afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
268 AudioRegion::listen_to_my_curves ()
270 _envelope->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::envelope_changed, this));
271 _fade_in->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_in_changed, this));
272 _fade_out->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_out_changed, this));
276 AudioRegion::set_envelope_active (bool yn)
278 if (envelope_active() != yn) {
279 _envelope_active = yn;
280 send_change (PropertyChange (Properties::envelope_active));
285 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
287 if (chan_n >= _sources.size()) {
291 if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
294 if (_scale_amplitude != 1.0f) {
295 for (nframes_t n = 0; n < npeaks; ++n) {
296 buf[n].max *= _scale_amplitude;
297 buf[n].min *= _scale_amplitude;
305 AudioRegion::read (Sample* buf, framepos_t timeline_position, framecnt_t cnt, int channel) const
307 /* raw read, no fades, no gain, nada */
308 return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
312 AudioRegion::read_with_ops (Sample* buf, framepos_t file_position, framecnt_t cnt, int channel, ReadOps rops) const
314 return _read_at (_sources, _length, buf, 0, 0, file_position, cnt, channel, 0, 0, rops);
318 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
319 framepos_t file_position, framecnt_t cnt, uint32_t chan_n,
320 framecnt_t read_frames, framecnt_t skip_frames) const
322 /* regular diskstream/butler read complete with fades etc */
323 return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer,
324 file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
328 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
329 framepos_t position, framecnt_t cnt, uint32_t chan_n) const
331 /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
333 return _read_at (_master_sources, _master_sources.front()->length(_master_sources.front()->timeline_position()),
334 buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0, ReadOps (0));
338 AudioRegion::_read_at (const SourceList& /*srcs*/, framecnt_t limit,
339 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
343 framecnt_t /*read_frames*/,
344 framecnt_t /*skip_frames*/,
347 frameoffset_t internal_offset;
348 frameoffset_t buf_offset;
350 bool raw = (rops == ReadOpsNone);
352 if (muted() && !raw) {
353 return 0; /* read nothing */
356 /* precondition: caller has verified that we cover the desired section */
358 if (position < _position) {
360 buf_offset = _position - position;
363 internal_offset = position - _position;
367 if (internal_offset >= limit) {
368 return 0; /* read nothing */
371 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
372 return 0; /* read nothing */
375 if (opaque() || raw) {
376 /* overwrite whatever is there */
377 mixdown_buffer = buf + buf_offset;
379 mixdown_buffer += buf_offset;
382 if (rops & ReadOpsCount) {
383 _read_data_count = 0;
386 if (chan_n < n_channels()) {
388 boost::shared_ptr<AudioSource> src = audio_source(chan_n);
389 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
390 return 0; /* "read nothing" */
393 if (rops & ReadOpsCount) {
394 _read_data_count += src->read_data_count();
399 /* track is N-channel, this region has less channels; silence the ones
403 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
406 if (rops & ReadOpsFades) {
410 if (_fade_in_active && _session.config.get_use_region_fades()) {
412 nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
414 /* see if this read is within the fade in */
416 if (internal_offset < fade_in_length) {
420 fi_limit = min (to_read, fade_in_length - internal_offset);
423 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
425 for (nframes_t n = 0; n < fi_limit; ++n) {
426 mixdown_buffer[n] *= gain_buffer[n];
433 if (_fade_out_active && _session.config.get_use_region_fades()) {
435 /* see if some part of this read is within the fade out */
437 /* ................. >| REGION
443 limit - fade_out_length
446 ^internal_offset + to_read
448 we need the intersection of [internal_offset,internal_offset+to_read] with
449 [limit - fade_out_length, limit]
454 nframes_t fade_out_length = (nframes_t) _fade_out->back()->when;
455 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
456 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
458 if (fade_interval_end > fade_interval_start) {
459 /* (part of the) the fade out is in this buffer */
461 nframes_t fo_limit = fade_interval_end - fade_interval_start;
462 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
463 nframes_t fade_offset = fade_interval_start - internal_offset;
465 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
467 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
468 mixdown_buffer[m] *= gain_buffer[n];
475 /* Regular gain curves and scaling */
477 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
478 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
480 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
481 for (nframes_t n = 0; n < to_read; ++n) {
482 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
485 for (nframes_t n = 0; n < to_read; ++n) {
486 mixdown_buffer[n] *= gain_buffer[n];
489 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
491 // XXX this should be using what in 2.0 would have been:
492 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
494 for (nframes_t n = 0; n < to_read; ++n) {
495 mixdown_buffer[n] *= _scale_amplitude;
501 /* gack. the things we do for users.
506 for (nframes_t n = 0; n < to_read; ++n) {
507 buf[n] += mixdown_buffer[n];
515 AudioRegion::state (bool full)
517 XMLNode& node (Region::state (full));
521 LocaleGuard lg (X_("POSIX"));
524 // XXX these should move into Region
526 for (uint32_t n=0; n < _sources.size(); ++n) {
527 snprintf (buf2, sizeof(buf2), "source-%d", n);
528 _sources[n]->id().print (buf, sizeof (buf));
529 node.add_property (buf2, buf);
532 for (uint32_t n=0; n < _master_sources.size(); ++n) {
533 snprintf (buf2, sizeof(buf2), "master-source-%d", n);
534 _master_sources[n]->id().print (buf, sizeof (buf));
535 node.add_property (buf2, buf);
538 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
539 node.add_property ("channels", buf);
542 Stateful::add_properties (node);
545 child = node.add_child ("Envelope");
548 bool default_env = false;
550 // If there are only two points, the points are in the start of the region and the end of the region
551 // so, if they are both at 1.0f, that means the default region.
553 if (_envelope->size() == 2 &&
554 _envelope->front()->value == 1.0f &&
555 _envelope->back()->value==1.0f) {
556 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
562 child->add_property ("default", "yes");
564 child->add_child_nocopy (_envelope->get_state ());
568 child->add_property ("default", "yes");
571 if (full && _extra_xml) {
572 node.add_child_copy (*_extra_xml);
579 AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_changed, bool send)
581 const XMLNodeList& nlist = node.children();
582 const XMLProperty *prop;
583 LocaleGuard lg (X_("POSIX"));
584 boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
589 the_playlist->freeze ();
593 /* this will set all our State members and stuff controlled by the Region.
594 It should NOT send any changed signals - that is our responsibility.
597 Region::_set_state (node, version, what_changed, false);
599 if ((prop = node.property ("scale-gain")) != 0) {
600 float a = atof (prop->value().c_str());
601 if (a != _scale_amplitude) {
602 _scale_amplitude = a;
603 what_changed.add (Properties::scale_amplitude);
607 /* Now find envelope description and other related child items */
609 _envelope->freeze ();
611 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
617 if (child->name() == "Envelope") {
621 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child, version)) {
622 set_default_envelope ();
625 _envelope->set_max_xval (_length);
626 _envelope->truncate_end (_length);
628 cerr << _name << " envelope changd\n";
631 } else if (child->name() == "FadeIn") {
635 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
636 set_default_fade_in ();
638 XMLNode* grandchild = child->child ("AutomationList");
640 _fade_in->set_state (*grandchild, version);
644 if ((prop = child->property ("active")) != 0) {
645 if (string_is_affirmative (prop->value())) {
646 set_fade_in_active (true);
648 set_fade_in_active (false);
651 cerr << _name << " fadein changd\n";
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);
673 cerr << _name << " fadeout changd\n";
682 send_change (what_changed);
686 the_playlist->thaw ();
693 AudioRegion::set_property (const PropertyBase& prop)
695 DEBUG_TRACE (DEBUG::Properties, string_compose ("audio region %1 set property %2\n", _name.val(), prop.property_name()));
697 if (prop == Properties::envelope_active.id) {
698 bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
699 if (val != _envelope_active) {
700 _envelope_active = val;
703 } else if (prop == Properties::default_fade_in.id) {
704 bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
705 if (val != _default_fade_in) {
706 _default_fade_in = val;
709 } else if (prop == Properties::default_fade_out.id) {
710 bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
711 if (val != _default_fade_out) {
712 _default_fade_out = val;
715 } else if (prop == Properties::fade_in_active.id) {
716 bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
717 if (val != _fade_in_active) {
718 _fade_in_active = val;
721 } else if (prop == Properties::fade_out_active.id) {
722 bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
723 if (val != _fade_out_active) {
724 _fade_out_active = val;
727 } else if (prop == Properties::scale_amplitude.id) {
728 gain_t val = dynamic_cast<const PropertyTemplate<gain_t>*>(&prop)->val();
729 if (val != _scale_amplitude) {
730 _scale_amplitude = val;
734 return Region::set_property (prop);
741 AudioRegion::set_state (const XMLNode& node, int version)
743 PropertyChange what_changed;
744 return _set_state (node, version, what_changed, true);
748 AudioRegion::set_fade_in_shape (FadeShape shape)
750 set_fade_in (shape, (nframes_t) _fade_in->back()->when);
754 AudioRegion::set_fade_out_shape (FadeShape shape)
756 set_fade_out (shape, (nframes_t) _fade_out->back()->when);
760 AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
766 send_change (PropertyChange (Properties::fade_in));
770 AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
777 _fade_in->fast_simple_add (0.0, 0.0);
778 _fade_in->fast_simple_add (len, 1.0);
782 _fade_in->fast_simple_add (0, 0);
783 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
784 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
785 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
786 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
787 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
788 _fade_in->fast_simple_add (len, 1);
792 _fade_in->fast_simple_add (0, 0);
793 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
794 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
795 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
796 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
797 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
798 _fade_in->fast_simple_add (len * 0.767281, 1);
799 _fade_in->fast_simple_add (len, 1);
803 _fade_in->fast_simple_add (0, 0);
804 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
805 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
806 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
807 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
808 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
809 _fade_in->fast_simple_add (len, 1);
813 _fade_in->fast_simple_add (0, 0);
814 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
815 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
816 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
817 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
818 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
819 _fade_in->fast_simple_add (len, 1);
827 AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
829 _fade_out->freeze ();
833 send_change (PropertyChange (Properties::fade_in));
837 AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
839 _fade_out->freeze ();
844 _fade_out->fast_simple_add (len * 0, 1);
845 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
846 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
847 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
848 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
849 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
850 _fade_out->fast_simple_add (len * 1, 0);
854 _fade_out->fast_simple_add (len * 0, 1);
855 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
856 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
857 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
858 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
859 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
860 _fade_out->fast_simple_add (len * 1, 0);
864 _fade_out->fast_simple_add (len * 0, 1);
865 _fade_out->fast_simple_add (len * 0.305556, 1);
866 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
867 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
868 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
869 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
870 _fade_out->fast_simple_add (len * 1, 0);
874 _fade_out->fast_simple_add (len * 0, 1);
875 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
876 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
877 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
878 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
879 _fade_out->fast_simple_add (len * 1, 0);
883 _fade_out->fast_simple_add (len * 0, 1);
884 _fade_out->fast_simple_add (len * 1, 0);
892 AudioRegion::set_fade_in_length (framecnt_t len)
898 bool changed = _fade_in->extend_to (len);
901 _default_fade_in = false;
902 send_change (PropertyChange (Properties::fade_in));
907 AudioRegion::set_fade_out_length (framecnt_t len)
913 bool changed = _fade_out->extend_to (len);
916 _default_fade_out = false;
917 send_change (PropertyChange (Properties::fade_out));
922 AudioRegion::set_fade_in_active (bool yn)
924 if (yn == _fade_in_active) {
928 _fade_in_active = yn;
929 send_change (PropertyChange (Properties::fade_in_active));
933 AudioRegion::set_fade_out_active (bool yn)
935 if (yn == _fade_out_active) {
938 _fade_out_active = yn;
939 send_change (PropertyChange (Properties::fade_out_active));
943 AudioRegion::fade_in_is_default () const
945 return _fade_in->size() == 2 && _fade_in->front()->when == 0 && _fade_in->back()->when == 64;
949 AudioRegion::fade_out_is_default () const
951 return _fade_out->size() == 2 && _fade_out->front()->when == 0 && _fade_out->back()->when == 64;
955 AudioRegion::set_default_fade_in ()
957 _fade_in_suspended = 0;
958 set_fade_in (Linear, 64);
962 AudioRegion::set_default_fade_out ()
964 _fade_out_suspended = 0;
965 set_fade_out (Linear, 64);
969 AudioRegion::set_default_fades ()
971 set_default_fade_in ();
972 set_default_fade_out ();
976 AudioRegion::set_default_envelope ()
978 _envelope->freeze ();
980 _envelope->fast_simple_add (0, 1.0f);
981 _envelope->fast_simple_add (_length, 1.0f);
986 AudioRegion::recompute_at_end ()
988 /* our length has changed. recompute a new final point by interpolating
989 based on the the existing curve.
992 _envelope->freeze ();
993 _envelope->truncate_end (_length);
994 _envelope->set_max_xval (_length);
997 if (_fade_in->back()->when > _length) {
998 _fade_in->extend_to (_length);
999 send_change (PropertyChange (Properties::fade_in));
1002 if (_fade_out->back()->when > _length) {
1003 _fade_out->extend_to (_length);
1004 send_change (PropertyChange (Properties::fade_out));
1009 AudioRegion::recompute_at_start ()
1011 /* as above, but the shift was from the front */
1013 _envelope->truncate_start (_length);
1015 if (_fade_in->back()->when > _length) {
1016 _fade_in->extend_to (_length);
1017 send_change (PropertyChange (Properties::fade_in));
1020 if (_fade_out->back()->when > _length) {
1021 _fade_out->extend_to (_length);
1022 send_change (PropertyChange (Properties::fade_out));
1027 AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr<Region> >& v) const
1033 if (_sources.size() < 2) {
1037 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
1039 srcs.push_back (*i);
1043 if (_sources.size() == 2) {
1051 new_name += ('0' + n + 1);
1054 /* create a copy with just one source. prevent if from being thought of as
1055 "whole file" even if it covers the entire source file(s).
1060 plist.add (Properties::start, _start.val());
1061 plist.add (Properties::length, _length.val());
1062 plist.add (Properties::name, new_name);
1063 plist.add (Properties::layer, _layer.val());
1065 v.push_back(RegionFactory::create (srcs, plist));
1066 v.back()->set_whole_file (false);
1075 AudioRegion::read_raw_internal (Sample* buf, framepos_t pos, framecnt_t cnt, int channel) const
1077 return audio_source()->read (buf, pos, cnt, channel);
1081 AudioRegion::exportme (Session& /*session*/, ARDOUR::ExportSpecification& /*spec*/)
1084 // const nframes_t blocksize = 4096;
1085 // nframes_t to_read;
1088 // spec.channels = _sources.size();
1090 // if (spec.prepare (blocksize, session.frame_rate())) {
1095 // spec.total_frames = _length;
1097 // while (spec.pos < _length && !spec.stop) {
1100 // /* step 1: interleave */
1102 // to_read = min (_length - spec.pos, blocksize);
1104 // if (spec.channels == 1) {
1106 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1112 // Sample buf[blocksize];
1114 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1116 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1120 // for (nframes_t x = 0; x < to_read; ++x) {
1121 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1126 // if (spec.process (to_read)) {
1130 // spec.pos += to_read;
1131 // spec.progress = (double) spec.pos /_length;
1138 // spec.running = false;
1139 // spec.status = status;
1147 AudioRegion::set_scale_amplitude (gain_t g)
1149 boost::shared_ptr<Playlist> pl (playlist());
1151 _scale_amplitude = g;
1153 /* tell the diskstream we're in */
1156 pl->ContentsChanged();
1159 /* tell everybody else */
1161 send_change (PropertyChange (Properties::scale_amplitude));
1165 AudioRegion::normalize_to (float target_dB)
1167 const framecnt_t blocksize = 64 * 1024;
1168 Sample buf[blocksize];
1173 gain_t target = dB_to_coefficient (target_dB);
1175 if (target == 1.0f) {
1176 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1177 that we may have clipped.
1179 target -= FLT_EPSILON;
1183 fend = _start + _length;
1185 /* first pass: find max amplitude */
1187 while (fpos < fend) {
1191 to_read = min (fend - fpos, blocksize);
1193 for (n = 0; n < n_channels(); ++n) {
1197 if (read_raw_internal (buf, fpos, to_read, 0) != to_read) {
1201 maxamp = compute_peak (buf, to_read, maxamp);
1207 if (maxamp == 0.0f) {
1208 /* don't even try */
1212 if (maxamp == target) {
1213 /* we can't do anything useful */
1217 /* compute scale factor */
1219 _scale_amplitude = target/maxamp;
1221 /* tell the diskstream we're in */
1223 boost::shared_ptr<Playlist> pl (playlist());
1226 pl->ContentsChanged();
1229 /* tell everybody else */
1231 send_change (PropertyChange (Properties::scale_amplitude));
1235 AudioRegion::fade_in_changed ()
1237 send_change (PropertyChange (Properties::fade_in));
1241 AudioRegion::fade_out_changed ()
1243 send_change (PropertyChange (Properties::fade_out));
1247 AudioRegion::envelope_changed ()
1249 send_change (PropertyChange (Properties::envelope));
1253 AudioRegion::suspend_fade_in ()
1255 if (++_fade_in_suspended == 1) {
1256 if (fade_in_is_default()) {
1257 set_fade_in_active (false);
1263 AudioRegion::resume_fade_in ()
1265 if (--_fade_in_suspended == 0 && _fade_in_suspended) {
1266 set_fade_in_active (true);
1271 AudioRegion::suspend_fade_out ()
1273 if (++_fade_out_suspended == 1) {
1274 if (fade_out_is_default()) {
1275 set_fade_out_active (false);
1281 AudioRegion::resume_fade_out ()
1283 if (--_fade_out_suspended == 0 &&_fade_out_suspended) {
1284 set_fade_out_active (true);
1289 AudioRegion::speed_mismatch (float sr) const
1291 if (_sources.empty()) {
1292 /* impossible, but ... */
1296 float fsr = audio_source()->sample_rate();
1302 AudioRegion::source_offset_changed ()
1304 /* XXX this fixes a crash that should not occur. It does occur
1305 becauses regions are not being deleted when a session
1306 is unloaded. That bug must be fixed.
1309 if (_sources.empty()) {
1313 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1315 if (afs && afs->destructive()) {
1316 // set_start (source()->natural_position(), this);
1317 set_position (source()->natural_position(), this);
1321 boost::shared_ptr<AudioSource>
1322 AudioRegion::audio_source (uint32_t n) const
1324 // Guaranteed to succeed (use a static cast for speed?)
1325 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1329 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1331 boost::shared_ptr<Playlist> pl = playlist();
1337 if (_valid_transients && !force_new) {
1338 results = _transients;
1342 SourceList::iterator s;
1344 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1345 if (!(*s)->has_been_analysed()) {
1346 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1351 if (s == _sources.end()) {
1352 /* all sources are analyzed, merge data from each one */
1354 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1356 /* find the set of transients within the bounds of this region */
1358 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1359 (*s)->transients.end(),
1362 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1363 (*s)->transients.end(),
1368 results.insert (results.end(), low, high);
1371 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1373 /* translate all transients to current position */
1375 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1380 _transients = results;
1381 _valid_transients = true;
1386 /* no existing/complete transient info */
1388 if (!Config->get_auto_analyse_audio()) {
1389 pl->session().Dialog (_("\
1390 You have requested an operation that requires audio analysis.\n\n\
1391 You currently have \"auto-analyse-audio\" disabled, which means\n\
1392 that transient data must be generated every time it is required.\n\n\
1393 If you are doing work that will require transient data on a\n\
1394 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1395 then quit ardour and restart."));
1398 TransientDetector t (pl->session().frame_rate());
1399 bool existing_results = !results.empty();
1401 _transients.clear ();
1402 _valid_transients = false;
1404 for (uint32_t i = 0; i < n_channels(); ++i) {
1406 AnalysisFeatureList these_results;
1410 if (t.run ("", this, i, these_results)) {
1414 /* translate all transients to give absolute position */
1416 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1422 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1425 if (!results.empty()) {
1426 if (existing_results) {
1428 /* merge our transients into the existing ones, then clean up
1432 results.insert (results.end(), _transients.begin(), _transients.end());
1433 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1436 /* make sure ours are clean too */
1438 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1442 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1443 results = _transients;
1446 _valid_transients = true;
1451 /** Find areas of `silence' within a region.
1453 * @param threshold Threshold below which signal is considered silence (as a sample value)
1454 * @param min_length Minimum length of silent period to be reported.
1455 * @return Silent periods; first of pair is the offset within the region, second is the length of the period
1458 std::list<std::pair<frameoffset_t, framecnt_t> >
1459 AudioRegion::find_silence (Sample threshold, framecnt_t min_length) const
1461 framecnt_t const block_size = 64 * 1024;
1462 Sample loudest[block_size];
1463 Sample buf[block_size];
1465 framepos_t pos = _start;
1466 framepos_t const end = _start + _length - 1;
1468 std::list<std::pair<frameoffset_t, framecnt_t> > silent_periods;
1470 bool in_silence = false;
1471 frameoffset_t silence_start = 0;
1476 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1477 memset (loudest, 0, sizeof (Sample) * block_size);
1478 for (uint32_t n = 0; n < n_channels(); ++n) {
1480 read_raw_internal (buf, pos, block_size, n);
1481 for (framecnt_t i = 0; i < block_size; ++i) {
1482 loudest[i] = max (loudest[i], abs (buf[i]));
1486 /* now look for silence */
1487 for (framecnt_t i = 0; i < block_size; ++i) {
1488 silence = abs (loudest[i]) < threshold;
1489 if (silence && !in_silence) {
1490 /* non-silence to silence */
1492 silence_start = pos + i;
1493 } else if (!silence && in_silence) {
1494 /* silence to non-silence */
1496 if (pos + i - 1 - silence_start >= min_length) {
1497 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1505 if (in_silence && end - 1 - silence_start >= min_length) {
1506 /* last block was silent, so finish off the last period */
1507 silent_periods.push_back (std::make_pair (silence_start, end));
1510 return silent_periods;
1517 int region_read_peaks_from_c (void *arg, uint32_t npeaks, uint32_t start, uint32_t cnt, intptr_t data, uint32_t n_chan, double samples_per_unit)
1519 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (framecnt_t) npeaks, (framepos_t) start, (framecnt_t) cnt, n_chan,samples_per_unit);
1522 uint32_t region_length_from_c (void *arg)
1525 return ((AudioRegion *) arg)->length();
1528 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1530 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;