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;
249 AudioRegion::connect_to_analysis_changed ()
251 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
252 (*i)->AnalysisChanged.connect_same_thread (*this, boost::bind (&AudioRegion::invalidate_transients, this));
257 AudioRegion::connect_to_header_position_offset_changed ()
259 set<boost::shared_ptr<Source> > unique_srcs;
261 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
263 if (unique_srcs.find (*i) == unique_srcs.end ()) {
264 unique_srcs.insert (*i);
265 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
267 afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
274 AudioRegion::listen_to_my_curves ()
276 _envelope->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::envelope_changed, this));
277 _fade_in->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_in_changed, this));
278 _fade_out->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_out_changed, this));
282 AudioRegion::set_envelope_active (bool yn)
284 if (envelope_active() != yn) {
285 _envelope_active = yn;
286 send_change (PropertyChange (Properties::envelope_active));
291 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
293 if (chan_n >= _sources.size()) {
297 if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
300 if (_scale_amplitude != 1.0f) {
301 for (nframes_t n = 0; n < npeaks; ++n) {
302 buf[n].max *= _scale_amplitude;
303 buf[n].min *= _scale_amplitude;
311 AudioRegion::read (Sample* buf, framepos_t timeline_position, framecnt_t cnt, int channel) const
313 /* raw read, no fades, no gain, nada */
314 return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
318 AudioRegion::read_with_ops (Sample* buf, framepos_t file_position, framecnt_t cnt, int channel, ReadOps rops) const
320 return _read_at (_sources, _length, buf, 0, 0, file_position, cnt, channel, 0, 0, rops);
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));
527 LocaleGuard lg (X_("POSIX"));
530 // XXX these should move into Region
532 for (uint32_t n=0; n < _sources.size(); ++n) {
533 snprintf (buf2, sizeof(buf2), "source-%d", n);
534 _sources[n]->id().print (buf, sizeof (buf));
535 node.add_property (buf2, buf);
538 for (uint32_t n=0; n < _master_sources.size(); ++n) {
539 snprintf (buf2, sizeof(buf2), "master-source-%d", n);
540 _master_sources[n]->id().print (buf, sizeof (buf));
541 node.add_property (buf2, buf);
544 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
545 node.add_property ("channels", buf);
548 Stateful::add_properties (node);
551 child = node.add_child ("Envelope");
554 bool default_env = false;
556 // If there are only two points, the points are in the start of the region and the end of the region
557 // so, if they are both at 1.0f, that means the default region.
559 if (_envelope->size() == 2 &&
560 _envelope->front()->value == 1.0f &&
561 _envelope->back()->value==1.0f) {
562 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
568 child->add_property ("default", "yes");
570 child->add_child_nocopy (_envelope->get_state ());
574 child->add_property ("default", "yes");
577 if (full && _extra_xml) {
578 node.add_child_copy (*_extra_xml);
585 AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_changed, bool send)
587 const XMLNodeList& nlist = node.children();
588 const XMLProperty *prop;
589 LocaleGuard lg (X_("POSIX"));
590 boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
595 the_playlist->freeze ();
599 /* this will set all our State members and stuff controlled by the Region.
600 It should NOT send any changed signals - that is our responsibility.
603 Region::_set_state (node, version, what_changed, false);
605 if ((prop = node.property ("scale-gain")) != 0) {
606 float a = atof (prop->value().c_str());
607 if (a != _scale_amplitude) {
608 _scale_amplitude = a;
609 what_changed.add (Properties::scale_amplitude);
613 /* Now find envelope description and other related child items */
615 _envelope->freeze ();
617 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
623 if (child->name() == "Envelope") {
627 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child, version)) {
628 set_default_envelope ();
631 _envelope->set_max_xval (_length);
632 _envelope->truncate_end (_length);
635 } else if (child->name() == "FadeIn") {
639 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
640 set_default_fade_in ();
642 XMLNode* grandchild = child->child ("AutomationList");
644 _fade_in->set_state (*grandchild, version);
648 if ((prop = child->property ("active")) != 0) {
649 if (string_is_affirmative (prop->value())) {
650 set_fade_in_active (true);
652 set_fade_in_active (false);
656 } else if (child->name() == "FadeOut") {
660 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
661 set_default_fade_out ();
663 XMLNode* grandchild = child->child ("AutomationList");
665 _fade_out->set_state (*grandchild, version);
669 if ((prop = child->property ("active")) != 0) {
670 if (string_is_affirmative (prop->value())) {
671 set_fade_out_active (true);
673 set_fade_out_active (false);
684 send_change (what_changed);
688 the_playlist->thaw ();
695 AudioRegion::set_property (const PropertyBase& prop)
697 DEBUG_TRACE (DEBUG::Properties, string_compose ("audio region %1 set property %2\n", _name.val(), prop.property_name()));
699 if (prop == Properties::envelope_active.property_id) {
700 bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
701 if (val != _envelope_active) {
702 _envelope_active = val;
705 } else if (prop == Properties::default_fade_in.property_id) {
706 bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
707 if (val != _default_fade_in) {
708 _default_fade_in = val;
711 } else if (prop == Properties::default_fade_out.property_id) {
712 bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
713 if (val != _default_fade_out) {
714 _default_fade_out = val;
717 } else if (prop == Properties::fade_in_active.property_id) {
718 bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
719 if (val != _fade_in_active) {
720 _fade_in_active = val;
723 } else if (prop == Properties::fade_out_active.property_id) {
724 bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
725 if (val != _fade_out_active) {
726 _fade_out_active = val;
729 } else if (prop == Properties::scale_amplitude.property_id) {
730 gain_t val = dynamic_cast<const PropertyTemplate<gain_t>*>(&prop)->val();
731 if (val != _scale_amplitude) {
732 _scale_amplitude = val;
736 return Region::set_property (prop);
743 AudioRegion::set_state (const XMLNode& node, int version)
745 PropertyChange what_changed;
746 return _set_state (node, version, what_changed, true);
750 AudioRegion::set_fade_in_shape (FadeShape shape)
752 set_fade_in (shape, (nframes_t) _fade_in->back()->when);
756 AudioRegion::set_fade_out_shape (FadeShape shape)
758 set_fade_out (shape, (nframes_t) _fade_out->back()->when);
762 AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
768 send_change (PropertyChange (Properties::fade_in));
772 AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
779 _fade_in->fast_simple_add (0.0, 0.0);
780 _fade_in->fast_simple_add (len, 1.0);
784 _fade_in->fast_simple_add (0, 0);
785 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
786 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
787 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
788 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
789 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
790 _fade_in->fast_simple_add (len, 1);
794 _fade_in->fast_simple_add (0, 0);
795 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
796 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
797 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
798 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
799 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
800 _fade_in->fast_simple_add (len * 0.767281, 1);
801 _fade_in->fast_simple_add (len, 1);
805 _fade_in->fast_simple_add (0, 0);
806 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
807 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
808 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
809 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
810 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
811 _fade_in->fast_simple_add (len, 1);
815 _fade_in->fast_simple_add (0, 0);
816 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
817 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
818 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
819 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
820 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
821 _fade_in->fast_simple_add (len, 1);
829 AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
831 _fade_out->freeze ();
835 send_change (PropertyChange (Properties::fade_in));
839 AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
841 _fade_out->freeze ();
846 _fade_out->fast_simple_add (len * 0, 1);
847 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
848 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
849 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
850 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
851 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
852 _fade_out->fast_simple_add (len * 1, 0);
856 _fade_out->fast_simple_add (len * 0, 1);
857 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
858 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
859 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
860 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
861 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
862 _fade_out->fast_simple_add (len * 1, 0);
866 _fade_out->fast_simple_add (len * 0, 1);
867 _fade_out->fast_simple_add (len * 0.305556, 1);
868 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
869 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
870 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
871 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
872 _fade_out->fast_simple_add (len * 1, 0);
876 _fade_out->fast_simple_add (len * 0, 1);
877 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
878 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
879 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
880 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
881 _fade_out->fast_simple_add (len * 1, 0);
885 _fade_out->fast_simple_add (len * 0, 1);
886 _fade_out->fast_simple_add (len * 1, 0);
894 AudioRegion::set_fade_in_length (framecnt_t len)
900 bool changed = _fade_in->extend_to (len);
903 _default_fade_in = false;
904 send_change (PropertyChange (Properties::fade_in));
909 AudioRegion::set_fade_out_length (framecnt_t len)
915 bool changed = _fade_out->extend_to (len);
918 _default_fade_out = false;
919 send_change (PropertyChange (Properties::fade_out));
924 AudioRegion::set_fade_in_active (bool yn)
926 if (yn == _fade_in_active) {
930 _fade_in_active = yn;
931 send_change (PropertyChange (Properties::fade_in_active));
935 AudioRegion::set_fade_out_active (bool yn)
937 if (yn == _fade_out_active) {
940 _fade_out_active = yn;
941 send_change (PropertyChange (Properties::fade_out_active));
945 AudioRegion::fade_in_is_default () const
947 return _fade_in->size() == 2 && _fade_in->front()->when == 0 && _fade_in->back()->when == 64;
951 AudioRegion::fade_out_is_default () const
953 return _fade_out->size() == 2 && _fade_out->front()->when == 0 && _fade_out->back()->when == 64;
957 AudioRegion::set_default_fade_in ()
959 _fade_in_suspended = 0;
960 set_fade_in (Linear, 64);
964 AudioRegion::set_default_fade_out ()
966 _fade_out_suspended = 0;
967 set_fade_out (Linear, 64);
971 AudioRegion::set_default_fades ()
973 set_default_fade_in ();
974 set_default_fade_out ();
978 AudioRegion::set_default_envelope ()
980 _envelope->freeze ();
982 _envelope->fast_simple_add (0, 1.0f);
983 _envelope->fast_simple_add (_length, 1.0f);
988 AudioRegion::recompute_at_end ()
990 /* our length has changed. recompute a new final point by interpolating
991 based on the the existing curve.
994 _envelope->freeze ();
995 _envelope->truncate_end (_length);
996 _envelope->set_max_xval (_length);
999 if (_fade_in->back()->when > _length) {
1000 _fade_in->extend_to (_length);
1001 send_change (PropertyChange (Properties::fade_in));
1004 if (_fade_out->back()->when > _length) {
1005 _fade_out->extend_to (_length);
1006 send_change (PropertyChange (Properties::fade_out));
1011 AudioRegion::recompute_at_start ()
1013 /* as above, but the shift was from the front */
1015 _envelope->truncate_start (_length);
1017 if (_fade_in->back()->when > _length) {
1018 _fade_in->extend_to (_length);
1019 send_change (PropertyChange (Properties::fade_in));
1022 if (_fade_out->back()->when > _length) {
1023 _fade_out->extend_to (_length);
1024 send_change (PropertyChange (Properties::fade_out));
1029 AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr<Region> >& v) const
1035 if (_sources.size() < 2) {
1039 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
1041 srcs.push_back (*i);
1045 if (_sources.size() == 2) {
1053 new_name += ('0' + n + 1);
1056 /* create a copy with just one source. prevent if from being thought of as
1057 "whole file" even if it covers the entire source file(s).
1062 plist.add (Properties::start, _start.val());
1063 plist.add (Properties::length, _length.val());
1064 plist.add (Properties::name, new_name);
1065 plist.add (Properties::layer, _layer.val());
1067 v.push_back(RegionFactory::create (srcs, plist));
1068 v.back()->set_whole_file (false);
1077 AudioRegion::read_raw_internal (Sample* buf, framepos_t pos, framecnt_t cnt, int channel) const
1079 return audio_source()->read (buf, pos, cnt, channel);
1083 AudioRegion::exportme (Session& /*session*/, ARDOUR::ExportSpecification& /*spec*/)
1086 // const nframes_t blocksize = 4096;
1087 // nframes_t to_read;
1090 // spec.channels = _sources.size();
1092 // if (spec.prepare (blocksize, session.frame_rate())) {
1097 // spec.total_frames = _length;
1099 // while (spec.pos < _length && !spec.stop) {
1102 // /* step 1: interleave */
1104 // to_read = min (_length - spec.pos, blocksize);
1106 // if (spec.channels == 1) {
1108 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1114 // Sample buf[blocksize];
1116 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1118 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1122 // for (nframes_t x = 0; x < to_read; ++x) {
1123 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1128 // if (spec.process (to_read)) {
1132 // spec.pos += to_read;
1133 // spec.progress = (double) spec.pos /_length;
1140 // spec.running = false;
1141 // spec.status = status;
1149 AudioRegion::set_scale_amplitude (gain_t g)
1151 boost::shared_ptr<Playlist> pl (playlist());
1153 _scale_amplitude = g;
1155 /* tell the diskstream we're in */
1158 pl->ContentsChanged();
1161 /* tell everybody else */
1163 send_change (PropertyChange (Properties::scale_amplitude));
1167 AudioRegion::normalize_to (float target_dB)
1169 const framecnt_t blocksize = 64 * 1024;
1170 Sample buf[blocksize];
1175 gain_t target = dB_to_coefficient (target_dB);
1177 if (target == 1.0f) {
1178 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1179 that we may have clipped.
1181 target -= FLT_EPSILON;
1185 fend = _start + _length;
1187 /* first pass: find max amplitude */
1189 while (fpos < fend) {
1193 to_read = min (fend - fpos, blocksize);
1195 for (n = 0; n < n_channels(); ++n) {
1199 if (read_raw_internal (buf, fpos, to_read, 0) != to_read) {
1203 maxamp = compute_peak (buf, to_read, maxamp);
1209 if (maxamp == 0.0f) {
1210 /* don't even try */
1214 if (maxamp == target) {
1215 /* we can't do anything useful */
1219 /* compute scale factor */
1221 _scale_amplitude = target/maxamp;
1223 /* tell the diskstream we're in */
1225 boost::shared_ptr<Playlist> pl (playlist());
1228 pl->ContentsChanged();
1231 /* tell everybody else */
1233 send_change (PropertyChange (Properties::scale_amplitude));
1237 AudioRegion::fade_in_changed ()
1239 send_change (PropertyChange (Properties::fade_in));
1243 AudioRegion::fade_out_changed ()
1245 send_change (PropertyChange (Properties::fade_out));
1249 AudioRegion::envelope_changed ()
1251 send_change (PropertyChange (Properties::envelope));
1255 AudioRegion::suspend_fade_in ()
1257 if (++_fade_in_suspended == 1) {
1258 if (fade_in_is_default()) {
1259 set_fade_in_active (false);
1265 AudioRegion::resume_fade_in ()
1267 if (--_fade_in_suspended == 0 && _fade_in_suspended) {
1268 set_fade_in_active (true);
1273 AudioRegion::suspend_fade_out ()
1275 if (++_fade_out_suspended == 1) {
1276 if (fade_out_is_default()) {
1277 set_fade_out_active (false);
1283 AudioRegion::resume_fade_out ()
1285 if (--_fade_out_suspended == 0 &&_fade_out_suspended) {
1286 set_fade_out_active (true);
1291 AudioRegion::speed_mismatch (float sr) const
1293 if (_sources.empty()) {
1294 /* impossible, but ... */
1298 float fsr = audio_source()->sample_rate();
1304 AudioRegion::source_offset_changed ()
1306 /* XXX this fixes a crash that should not occur. It does occur
1307 becauses regions are not being deleted when a session
1308 is unloaded. That bug must be fixed.
1311 if (_sources.empty()) {
1315 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1317 if (afs && afs->destructive()) {
1318 // set_start (source()->natural_position(), this);
1319 set_position (source()->natural_position(), this);
1323 boost::shared_ptr<AudioSource>
1324 AudioRegion::audio_source (uint32_t n) const
1326 // Guaranteed to succeed (use a static cast for speed?)
1327 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1331 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1333 boost::shared_ptr<Playlist> pl = playlist();
1339 if (_valid_transients && !force_new) {
1340 results = _transients;
1344 SourceList::iterator s;
1346 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1347 if (!(*s)->has_been_analysed()) {
1348 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1353 if (s == _sources.end()) {
1354 /* all sources are analyzed, merge data from each one */
1356 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1358 /* find the set of transients within the bounds of this region */
1360 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1361 (*s)->transients.end(),
1364 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1365 (*s)->transients.end(),
1370 results.insert (results.end(), low, high);
1373 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1375 /* translate all transients to current position */
1377 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1382 _transients = results;
1383 _valid_transients = true;
1388 /* no existing/complete transient info */
1390 if (!Config->get_auto_analyse_audio()) {
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."));
1400 TransientDetector t (pl->session().frame_rate());
1401 bool existing_results = !results.empty();
1403 _transients.clear ();
1404 _valid_transients = false;
1406 for (uint32_t i = 0; i < n_channels(); ++i) {
1408 AnalysisFeatureList these_results;
1412 if (t.run ("", this, i, these_results)) {
1416 /* translate all transients to give absolute position */
1418 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1424 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1427 if (!results.empty()) {
1428 if (existing_results) {
1430 /* merge our transients into the existing ones, then clean up
1434 results.insert (results.end(), _transients.begin(), _transients.end());
1435 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1438 /* make sure ours are clean too */
1440 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1444 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1445 results = _transients;
1448 _valid_transients = true;
1453 /** Find areas of `silence' within a region.
1455 * @param threshold Threshold below which signal is considered silence (as a sample value)
1456 * @param min_length Minimum length of silent period to be reported.
1457 * @return Silent periods; first of pair is the offset within the region, second is the length of the period
1460 std::list<std::pair<frameoffset_t, framecnt_t> >
1461 AudioRegion::find_silence (Sample threshold, framecnt_t min_length) const
1463 framecnt_t const block_size = 64 * 1024;
1464 Sample loudest[block_size];
1465 Sample buf[block_size];
1467 framepos_t pos = _start;
1468 framepos_t const end = _start + _length - 1;
1470 std::list<std::pair<frameoffset_t, framecnt_t> > silent_periods;
1472 bool in_silence = false;
1473 frameoffset_t silence_start = 0;
1478 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1479 memset (loudest, 0, sizeof (Sample) * block_size);
1480 for (uint32_t n = 0; n < n_channels(); ++n) {
1482 read_raw_internal (buf, pos, block_size, n);
1483 for (framecnt_t i = 0; i < block_size; ++i) {
1484 loudest[i] = max (loudest[i], abs (buf[i]));
1488 /* now look for silence */
1489 for (framecnt_t i = 0; i < block_size; ++i) {
1490 silence = abs (loudest[i]) < threshold;
1491 if (silence && !in_silence) {
1492 /* non-silence to silence */
1494 silence_start = pos + i;
1495 } else if (!silence && in_silence) {
1496 /* silence to non-silence */
1498 if (pos + i - 1 - silence_start >= min_length) {
1499 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1507 if (in_silence && end - 1 - silence_start >= min_length) {
1508 /* last block was silent, so finish off the last period */
1509 silent_periods.push_back (std::make_pair (silence_start, end));
1512 return silent_periods;
1519 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)
1521 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (framecnt_t) npeaks, (framepos_t) start, (framecnt_t) cnt, n_chan,samples_per_unit);
1524 uint32_t region_length_from_c (void *arg)
1527 return ((AudioRegion *) arg)->length();
1530 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1532 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;