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, EnvelopeActiveChanged, false) \
93 , _default_fade_in (Properties::default_fade_in, FadeInChanged, true) \
94 , _default_fade_out (Properties::default_fade_out, FadeOutChanged, true) \
95 , _fade_in_active (Properties::fade_in_active, FadeInActiveChanged, true) \
96 , _fade_out_active (Properties::fade_out_active, FadeOutActiveChanged, true) \
97 , _scale_amplitude (Properties::scale_amplitude, ScaleAmplitudeChanged, 1.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 PropertyChange AudioRegion::FadeInChanged = PBD::new_change();
108 PropertyChange AudioRegion::FadeOutChanged = PBD::new_change();
109 PropertyChange AudioRegion::FadeInActiveChanged = PBD::new_change();
110 PropertyChange AudioRegion::FadeOutActiveChanged = PBD::new_change();
111 PropertyChange AudioRegion::EnvelopeActiveChanged = PBD::new_change();
112 PropertyChange AudioRegion::ScaleAmplitudeChanged = PBD::new_change();
113 PropertyChange AudioRegion::EnvelopeChanged = PBD::new_change();
115 /* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
120 register_properties ();
122 set_default_fades ();
123 set_default_envelope ();
125 listen_to_my_curves ();
126 connect_to_analysis_changed ();
127 connect_to_header_position_offset_changed ();
130 /** Constructor for use by derived types only */
131 AudioRegion::AudioRegion (Session& s, framepos_t start, framecnt_t len, std::string name)
132 : Region (s, start, len, name, DataType::AUDIO)
133 , AUDIOREGION_STATE_DEFAULT
135 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
136 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
137 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
138 , _fade_in_suspended (0)
139 , _fade_out_suspended (0)
142 assert (_sources.size() == _master_sources.size());
145 /** Basic AudioRegion constructor (one channel) */
146 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src)
147 : Region (boost::static_pointer_cast<Source>(src))
148 , AUDIOREGION_STATE_DEFAULT
149 , _automatable(src->session())
150 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
151 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
152 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
153 , _fade_in_suspended (0)
154 , _fade_out_suspended (0)
158 /* XXX why is this set here ? - set in a property list given to RegionFactory */
161 assert (_sources.size() == _master_sources.size());
164 /** Basic AudioRegion constructor (many channels) */
165 AudioRegion::AudioRegion (const SourceList& srcs)
167 , AUDIOREGION_STATE_DEFAULT
168 , _automatable(srcs[0]->session())
169 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
170 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
171 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
172 , _fade_in_suspended (0)
173 , _fade_out_suspended (0)
176 assert (_sources.size() == _master_sources.size());
179 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes64_t offset, bool offset_relative)
180 : Region (other, offset, offset_relative)
181 , AUDIOREGION_COPY_STATE (other)
182 , _automatable (other->session())
183 , _fade_in (new AutomationList (*other->_fade_in))
184 , _fade_out (new AutomationList (*other->_fade_out))
185 /* XXX is this guaranteed to work for all values of offset+offset_relative? */
186 , _envelope (new AutomationList (*other->_envelope, _start, _start + _length))
187 , _fade_in_suspended (0)
188 , _fade_out_suspended (0)
190 /* don't use init here, because we got fade in/out from the other region
192 register_properties ();
193 listen_to_my_curves ();
194 connect_to_analysis_changed ();
195 connect_to_header_position_offset_changed ();
197 assert(_type == DataType::AUDIO);
198 assert (_sources.size() == _master_sources.size());
201 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& srcs)
202 : Region (boost::static_pointer_cast<const Region>(other), srcs)
203 , AUDIOREGION_COPY_STATE (other)
204 , _automatable (other->session())
205 , _fade_in (new AutomationList (*other->_fade_in))
206 , _fade_out (new AutomationList (*other->_fade_out))
207 , _envelope (new AutomationList (*other->_envelope))
208 , _fade_in_suspended (0)
209 , _fade_out_suspended (0)
211 /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
213 register_properties ();
215 listen_to_my_curves ();
216 connect_to_analysis_changed ();
217 connect_to_header_position_offset_changed ();
219 assert (_sources.size() == _master_sources.size());
222 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node)
224 , AUDIOREGION_STATE_DEFAULT
225 , _automatable(src->session())
226 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
227 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
228 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
232 if (set_state (node, Stateful::loading_state_version)) {
233 throw failed_constructor();
236 assert(_type == DataType::AUDIO);
237 assert (_sources.size() == _master_sources.size());
240 AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
241 : Region (srcs, node)
242 , AUDIOREGION_STATE_DEFAULT
243 , _automatable(srcs[0]->session())
244 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
245 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
246 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
247 , _fade_in_suspended (0)
248 , _fade_out_suspended (0)
252 if (set_state (node, Stateful::loading_state_version)) {
253 throw failed_constructor();
256 assert(_type == DataType::AUDIO);
257 connect_to_analysis_changed ();
258 assert (_sources.size() == _master_sources.size());
261 AudioRegion::~AudioRegion ()
266 AudioRegion::post_set ()
269 _sync_position = _start;
272 /* return to default fades if the existing ones are too long */
274 if (_left_of_split) {
275 if (_fade_in->back()->when >= _length) {
276 set_default_fade_in ();
278 set_default_fade_out ();
279 _left_of_split = false;
282 if (_right_of_split) {
283 if (_fade_out->back()->when >= _length) {
284 set_default_fade_out ();
287 set_default_fade_in ();
288 _right_of_split = false;
293 AudioRegion::connect_to_analysis_changed ()
295 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
296 (*i)->AnalysisChanged.connect_same_thread (*this, boost::bind (&AudioRegion::invalidate_transients, this));
301 AudioRegion::connect_to_header_position_offset_changed ()
303 set<boost::shared_ptr<Source> > unique_srcs;
305 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
307 if (unique_srcs.find (*i) == unique_srcs.end ()) {
308 unique_srcs.insert (*i);
309 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
311 afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
318 AudioRegion::listen_to_my_curves ()
320 _envelope->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::envelope_changed, this));
321 _fade_in->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_in_changed, this));
322 _fade_out->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_out_changed, this));
326 AudioRegion::set_envelope_active (bool yn)
328 if (envelope_active() != yn) {
329 _envelope_active = yn;
330 send_change (EnvelopeActiveChanged);
335 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
337 if (chan_n >= _sources.size()) {
341 if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
344 if (_scale_amplitude != 1.0f) {
345 for (nframes_t n = 0; n < npeaks; ++n) {
346 buf[n].max *= _scale_amplitude;
347 buf[n].min *= _scale_amplitude;
355 AudioRegion::read (Sample* buf, framepos_t timeline_position, framecnt_t cnt, int channel) const
357 /* raw read, no fades, no gain, nada */
358 return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
362 AudioRegion::read_with_ops (Sample* buf, framepos_t file_position, framecnt_t cnt, int channel, ReadOps rops) const
364 return _read_at (_sources, _length, buf, 0, 0, file_position, cnt, channel, 0, 0, rops);
368 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
369 framepos_t file_position, framecnt_t cnt, uint32_t chan_n,
370 framecnt_t read_frames, framecnt_t skip_frames) const
372 /* regular diskstream/butler read complete with fades etc */
373 return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer,
374 file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
378 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
379 framepos_t position, framecnt_t cnt, uint32_t chan_n) const
381 /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
383 return _read_at (_master_sources, _master_sources.front()->length(_master_sources.front()->timeline_position()),
384 buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0, ReadOps (0));
388 AudioRegion::_read_at (const SourceList& /*srcs*/, framecnt_t limit,
389 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
393 framecnt_t /*read_frames*/,
394 framecnt_t /*skip_frames*/,
397 frameoffset_t internal_offset;
398 frameoffset_t buf_offset;
400 bool raw = (rops == ReadOpsNone);
402 if (muted() && !raw) {
403 return 0; /* read nothing */
406 /* precondition: caller has verified that we cover the desired section */
408 if (position < _position) {
410 buf_offset = _position - position;
413 internal_offset = position - _position;
417 if (internal_offset >= limit) {
418 return 0; /* read nothing */
421 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
422 return 0; /* read nothing */
425 if (opaque() || raw) {
426 /* overwrite whatever is there */
427 mixdown_buffer = buf + buf_offset;
429 mixdown_buffer += buf_offset;
432 if (rops & ReadOpsCount) {
433 _read_data_count = 0;
436 if (chan_n < n_channels()) {
438 boost::shared_ptr<AudioSource> src = audio_source(chan_n);
439 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
440 return 0; /* "read nothing" */
443 if (rops & ReadOpsCount) {
444 _read_data_count += src->read_data_count();
449 /* track is N-channel, this region has less channels; silence the ones
453 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
456 if (rops & ReadOpsFades) {
460 if (_fade_in_active && _session.config.get_use_region_fades()) {
462 nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
464 /* see if this read is within the fade in */
466 if (internal_offset < fade_in_length) {
470 fi_limit = min (to_read, fade_in_length - internal_offset);
473 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
475 for (nframes_t n = 0; n < fi_limit; ++n) {
476 mixdown_buffer[n] *= gain_buffer[n];
483 if (_fade_out_active && _session.config.get_use_region_fades()) {
485 /* see if some part of this read is within the fade out */
487 /* ................. >| REGION
493 limit - fade_out_length
496 ^internal_offset + to_read
498 we need the intersection of [internal_offset,internal_offset+to_read] with
499 [limit - fade_out_length, limit]
504 nframes_t fade_out_length = (nframes_t) _fade_out->back()->when;
505 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
506 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
508 if (fade_interval_end > fade_interval_start) {
509 /* (part of the) the fade out is in this buffer */
511 nframes_t fo_limit = fade_interval_end - fade_interval_start;
512 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
513 nframes_t fade_offset = fade_interval_start - internal_offset;
515 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
517 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
518 mixdown_buffer[m] *= gain_buffer[n];
525 /* Regular gain curves and scaling */
527 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
528 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
530 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
531 for (nframes_t n = 0; n < to_read; ++n) {
532 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
535 for (nframes_t n = 0; n < to_read; ++n) {
536 mixdown_buffer[n] *= gain_buffer[n];
539 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
541 // XXX this should be using what in 2.0 would have been:
542 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
544 for (nframes_t n = 0; n < to_read; ++n) {
545 mixdown_buffer[n] *= _scale_amplitude;
551 /* gack. the things we do for users.
556 for (nframes_t n = 0; n < to_read; ++n) {
557 buf[n] += mixdown_buffer[n];
565 AudioRegion::state (bool full)
567 XMLNode& node (Region::state (full));
571 LocaleGuard lg (X_("POSIX"));
574 // XXX these should move into Region
576 for (uint32_t n=0; n < _sources.size(); ++n) {
577 snprintf (buf2, sizeof(buf2), "source-%d", n);
578 _sources[n]->id().print (buf, sizeof (buf));
579 node.add_property (buf2, buf);
582 for (uint32_t n=0; n < _master_sources.size(); ++n) {
583 snprintf (buf2, sizeof(buf2), "master-source-%d", n);
584 _master_sources[n]->id().print (buf, sizeof (buf));
585 node.add_property (buf2, buf);
588 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
589 node.add_property ("channels", buf);
592 Stateful::add_properties (node);
595 child = node.add_child ("Envelope");
598 bool default_env = false;
600 // If there are only two points, the points are in the start of the region and the end of the region
601 // so, if they are both at 1.0f, that means the default region.
603 if (_envelope->size() == 2 &&
604 _envelope->front()->value == 1.0f &&
605 _envelope->back()->value==1.0f) {
606 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
612 child->add_property ("default", "yes");
614 child->add_child_nocopy (_envelope->get_state ());
618 child->add_property ("default", "yes");
621 if (full && _extra_xml) {
622 node.add_child_copy (*_extra_xml);
629 AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_changed, bool send)
631 const XMLNodeList& nlist = node.children();
632 const XMLProperty *prop;
633 LocaleGuard lg (X_("POSIX"));
634 boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
639 the_playlist->freeze ();
643 /* this will set all our State members and stuff controlled by the Region.
644 It should NOT send any changed signals - that is our responsibility.
647 Region::_set_state (node, version, what_changed, false);
649 if ((prop = node.property ("scale-gain")) != 0) {
650 float a = atof (prop->value().c_str());
651 if (a != _scale_amplitude) {
652 _scale_amplitude = a;
653 what_changed = PropertyChange (what_changed|ScaleAmplitudeChanged);
654 cerr << _name << " amp changed\n";
658 /* Now find envelope description and other related child items */
660 _envelope->freeze ();
662 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
668 if (child->name() == "Envelope") {
672 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child, version)) {
673 set_default_envelope ();
676 _envelope->set_max_xval (_length);
677 _envelope->truncate_end (_length);
679 cerr << _name << " envelope changd\n";
682 } else if (child->name() == "FadeIn") {
686 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
687 set_default_fade_in ();
689 XMLNode* grandchild = child->child ("AutomationList");
691 _fade_in->set_state (*grandchild, version);
695 if ((prop = child->property ("active")) != 0) {
696 if (string_is_affirmative (prop->value())) {
697 set_fade_in_active (true);
699 set_fade_in_active (false);
702 cerr << _name << " fadein changd\n";
704 } else if (child->name() == "FadeOut") {
708 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
709 set_default_fade_out ();
711 XMLNode* grandchild = child->child ("AutomationList");
713 _fade_out->set_state (*grandchild, version);
717 if ((prop = child->property ("active")) != 0) {
718 if (string_is_affirmative (prop->value())) {
719 set_fade_out_active (true);
721 set_fade_out_active (false);
724 cerr << _name << " fadeout changd\n";
733 cerr << _name << ": audio final change: " << hex << what_changed << dec << endl;
734 send_change (what_changed);
738 the_playlist->thaw ();
745 AudioRegion::set_property (const PropertyBase& prop)
747 PropertyChange c = PropertyChange (0);
749 DEBUG_TRACE (DEBUG::Properties, string_compose ("audio region %1 set property %2\n", _name.val(), prop.property_name()));
751 if (prop == Properties::envelope_active.id) {
752 bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
753 if (val != _envelope_active) {
754 _envelope_active = val;
755 c = EnvelopeActiveChanged;
757 } else if (prop == Properties::default_fade_in.id) {
758 bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
759 if (val != _default_fade_in) {
760 _default_fade_in = val;
763 } else if (prop == Properties::default_fade_out.id) {
764 bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
765 if (val != _default_fade_out) {
766 _default_fade_out = val;
769 } else if (prop == Properties::fade_in_active.id) {
770 bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
771 if (val != _fade_in_active) {
772 _fade_in_active = val;
773 c = FadeInActiveChanged;
775 } else if (prop == Properties::fade_out_active.id) {
776 bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
777 if (val != _fade_out_active) {
778 _fade_out_active = val;
781 } else if (prop == Properties::scale_amplitude.id) {
782 gain_t val = dynamic_cast<const PropertyTemplate<gain_t>*>(&prop)->val();
783 if (val != _scale_amplitude) {
784 _scale_amplitude = val;
785 c = ScaleAmplitudeChanged;
788 return Region::set_property (prop);
795 AudioRegion::set_state (const XMLNode& node, int version)
797 PropertyChange what_changed;
798 return _set_state (node, version, what_changed, true);
802 AudioRegion::set_fade_in_shape (FadeShape shape)
804 set_fade_in (shape, (nframes_t) _fade_in->back()->when);
808 AudioRegion::set_fade_out_shape (FadeShape shape)
810 set_fade_out (shape, (nframes_t) _fade_out->back()->when);
814 AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
820 send_change (FadeInChanged);
824 AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
831 _fade_in->fast_simple_add (0.0, 0.0);
832 _fade_in->fast_simple_add (len, 1.0);
836 _fade_in->fast_simple_add (0, 0);
837 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
838 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
839 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
840 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
841 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
842 _fade_in->fast_simple_add (len, 1);
846 _fade_in->fast_simple_add (0, 0);
847 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
848 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
849 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
850 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
851 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
852 _fade_in->fast_simple_add (len * 0.767281, 1);
853 _fade_in->fast_simple_add (len, 1);
857 _fade_in->fast_simple_add (0, 0);
858 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
859 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
860 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
861 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
862 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
863 _fade_in->fast_simple_add (len, 1);
867 _fade_in->fast_simple_add (0, 0);
868 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
869 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
870 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
871 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
872 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
873 _fade_in->fast_simple_add (len, 1);
881 AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
883 _fade_out->freeze ();
887 send_change (FadeInChanged);
891 AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
893 _fade_out->freeze ();
898 _fade_out->fast_simple_add (len * 0, 1);
899 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
900 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
901 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
902 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
903 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
904 _fade_out->fast_simple_add (len * 1, 0);
908 _fade_out->fast_simple_add (len * 0, 1);
909 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
910 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
911 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
912 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
913 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
914 _fade_out->fast_simple_add (len * 1, 0);
918 _fade_out->fast_simple_add (len * 0, 1);
919 _fade_out->fast_simple_add (len * 0.305556, 1);
920 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
921 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
922 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
923 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
924 _fade_out->fast_simple_add (len * 1, 0);
928 _fade_out->fast_simple_add (len * 0, 1);
929 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
930 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
931 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
932 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
933 _fade_out->fast_simple_add (len * 1, 0);
937 _fade_out->fast_simple_add (len * 0, 1);
938 _fade_out->fast_simple_add (len * 1, 0);
946 AudioRegion::set_fade_in_length (framecnt_t len)
952 bool changed = _fade_in->extend_to (len);
955 _default_fade_in = false;
956 send_change (FadeInChanged);
961 AudioRegion::set_fade_out_length (framecnt_t len)
967 bool changed = _fade_out->extend_to (len);
970 _default_fade_out = false;
971 send_change (FadeOutChanged);
976 AudioRegion::set_fade_in_active (bool yn)
978 if (yn == _fade_in_active) {
982 _fade_in_active = yn;
983 send_change (FadeInActiveChanged);
987 AudioRegion::set_fade_out_active (bool yn)
989 if (yn == _fade_out_active) {
992 _fade_out_active = yn;
993 send_change (FadeOutActiveChanged);
997 AudioRegion::fade_in_is_default () const
999 return _fade_in->size() == 2 && _fade_in->front()->when == 0 && _fade_in->back()->when == 64;
1003 AudioRegion::fade_out_is_default () const
1005 return _fade_out->size() == 2 && _fade_out->front()->when == 0 && _fade_out->back()->when == 64;
1009 AudioRegion::set_default_fade_in ()
1011 _fade_in_suspended = 0;
1012 set_fade_in (Linear, 64);
1016 AudioRegion::set_default_fade_out ()
1018 _fade_out_suspended = 0;
1019 set_fade_out (Linear, 64);
1023 AudioRegion::set_default_fades ()
1025 set_default_fade_in ();
1026 set_default_fade_out ();
1030 AudioRegion::set_default_envelope ()
1032 _envelope->freeze ();
1033 _envelope->clear ();
1034 _envelope->fast_simple_add (0, 1.0f);
1035 _envelope->fast_simple_add (_length, 1.0f);
1040 AudioRegion::recompute_at_end ()
1042 /* our length has changed. recompute a new final point by interpolating
1043 based on the the existing curve.
1046 _envelope->freeze ();
1047 _envelope->truncate_end (_length);
1048 _envelope->set_max_xval (_length);
1051 if (_fade_in->back()->when > _length) {
1052 _fade_in->extend_to (_length);
1053 send_change (FadeInChanged);
1056 if (_fade_out->back()->when > _length) {
1057 _fade_out->extend_to (_length);
1058 send_change (FadeOutChanged);
1063 AudioRegion::recompute_at_start ()
1065 /* as above, but the shift was from the front */
1067 _envelope->truncate_start (_length);
1069 if (_fade_in->back()->when > _length) {
1070 _fade_in->extend_to (_length);
1071 send_change (FadeInChanged);
1074 if (_fade_out->back()->when > _length) {
1075 _fade_out->extend_to (_length);
1076 send_change (FadeOutChanged);
1081 AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr<Region> >& v) const
1087 if (_sources.size() < 2) {
1091 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
1093 srcs.push_back (*i);
1097 if (_sources.size() == 2) {
1105 new_name += ('0' + n + 1);
1108 /* create a copy with just one source. prevent if from being thought of as
1109 "whole file" even if it covers the entire source file(s).
1114 plist.add (Properties::start, _start.val());
1115 plist.add (Properties::length, _length.val());
1116 plist.add (Properties::name, new_name);
1117 plist.add (Properties::layer, _layer.val());
1119 v.push_back(RegionFactory::create (srcs, plist));
1120 v.back()->set_whole_file (false);
1129 AudioRegion::read_raw_internal (Sample* buf, framepos_t pos, framecnt_t cnt, int channel) const
1131 return audio_source()->read (buf, pos, cnt, channel);
1135 AudioRegion::exportme (Session& /*session*/, ARDOUR::ExportSpecification& /*spec*/)
1138 // const nframes_t blocksize = 4096;
1139 // nframes_t to_read;
1142 // spec.channels = _sources.size();
1144 // if (spec.prepare (blocksize, session.frame_rate())) {
1149 // spec.total_frames = _length;
1151 // while (spec.pos < _length && !spec.stop) {
1154 // /* step 1: interleave */
1156 // to_read = min (_length - spec.pos, blocksize);
1158 // if (spec.channels == 1) {
1160 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1166 // Sample buf[blocksize];
1168 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1170 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1174 // for (nframes_t x = 0; x < to_read; ++x) {
1175 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1180 // if (spec.process (to_read)) {
1184 // spec.pos += to_read;
1185 // spec.progress = (double) spec.pos /_length;
1192 // spec.running = false;
1193 // spec.status = status;
1201 AudioRegion::set_scale_amplitude (gain_t g)
1203 boost::shared_ptr<Playlist> pl (playlist());
1205 _scale_amplitude = g;
1207 /* tell the diskstream we're in */
1210 pl->ContentsChanged();
1213 /* tell everybody else */
1215 send_change (ScaleAmplitudeChanged);
1219 AudioRegion::normalize_to (float target_dB)
1221 const framecnt_t blocksize = 64 * 1024;
1222 Sample buf[blocksize];
1227 gain_t target = dB_to_coefficient (target_dB);
1229 if (target == 1.0f) {
1230 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1231 that we may have clipped.
1233 target -= FLT_EPSILON;
1237 fend = _start + _length;
1239 /* first pass: find max amplitude */
1241 while (fpos < fend) {
1245 to_read = min (fend - fpos, blocksize);
1247 for (n = 0; n < n_channels(); ++n) {
1251 if (read_raw_internal (buf, fpos, to_read, 0) != to_read) {
1255 maxamp = compute_peak (buf, to_read, maxamp);
1261 if (maxamp == 0.0f) {
1262 /* don't even try */
1266 if (maxamp == target) {
1267 /* we can't do anything useful */
1271 /* compute scale factor */
1273 _scale_amplitude = target/maxamp;
1275 /* tell the diskstream we're in */
1277 boost::shared_ptr<Playlist> pl (playlist());
1280 pl->ContentsChanged();
1283 /* tell everybody else */
1285 send_change (ScaleAmplitudeChanged);
1289 AudioRegion::fade_in_changed ()
1291 send_change (FadeInChanged);
1295 AudioRegion::fade_out_changed ()
1297 send_change (FadeOutChanged);
1301 AudioRegion::envelope_changed ()
1303 send_change (EnvelopeChanged);
1307 AudioRegion::suspend_fade_in ()
1309 if (++_fade_in_suspended == 1) {
1310 if (fade_in_is_default()) {
1311 set_fade_in_active (false);
1317 AudioRegion::resume_fade_in ()
1319 if (--_fade_in_suspended == 0 && _fade_in_suspended) {
1320 set_fade_in_active (true);
1325 AudioRegion::suspend_fade_out ()
1327 if (++_fade_out_suspended == 1) {
1328 if (fade_out_is_default()) {
1329 set_fade_out_active (false);
1335 AudioRegion::resume_fade_out ()
1337 if (--_fade_out_suspended == 0 &&_fade_out_suspended) {
1338 set_fade_out_active (true);
1343 AudioRegion::speed_mismatch (float sr) const
1345 if (_sources.empty()) {
1346 /* impossible, but ... */
1350 float fsr = audio_source()->sample_rate();
1356 AudioRegion::source_offset_changed ()
1358 /* XXX this fixes a crash that should not occur. It does occur
1359 becauses regions are not being deleted when a session
1360 is unloaded. That bug must be fixed.
1363 if (_sources.empty()) {
1367 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1369 if (afs && afs->destructive()) {
1370 // set_start (source()->natural_position(), this);
1371 set_position (source()->natural_position(), this);
1375 boost::shared_ptr<AudioSource>
1376 AudioRegion::audio_source (uint32_t n) const
1378 // Guaranteed to succeed (use a static cast for speed?)
1379 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1383 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1385 boost::shared_ptr<Playlist> pl = playlist();
1391 if (_valid_transients && !force_new) {
1392 results = _transients;
1396 SourceList::iterator s;
1398 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1399 if (!(*s)->has_been_analysed()) {
1400 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1405 if (s == _sources.end()) {
1406 /* all sources are analyzed, merge data from each one */
1408 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1410 /* find the set of transients within the bounds of this region */
1412 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1413 (*s)->transients.end(),
1416 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1417 (*s)->transients.end(),
1422 results.insert (results.end(), low, high);
1425 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1427 /* translate all transients to current position */
1429 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1434 _transients = results;
1435 _valid_transients = true;
1440 /* no existing/complete transient info */
1442 if (!Config->get_auto_analyse_audio()) {
1443 pl->session().Dialog (_("\
1444 You have requested an operation that requires audio analysis.\n\n\
1445 You currently have \"auto-analyse-audio\" disabled, which means\n\
1446 that transient data must be generated every time it is required.\n\n\
1447 If you are doing work that will require transient data on a\n\
1448 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1449 then quit ardour and restart."));
1452 TransientDetector t (pl->session().frame_rate());
1453 bool existing_results = !results.empty();
1455 _transients.clear ();
1456 _valid_transients = false;
1458 for (uint32_t i = 0; i < n_channels(); ++i) {
1460 AnalysisFeatureList these_results;
1464 if (t.run ("", this, i, these_results)) {
1468 /* translate all transients to give absolute position */
1470 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1476 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1479 if (!results.empty()) {
1480 if (existing_results) {
1482 /* merge our transients into the existing ones, then clean up
1486 results.insert (results.end(), _transients.begin(), _transients.end());
1487 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1490 /* make sure ours are clean too */
1492 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1496 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1497 results = _transients;
1500 _valid_transients = true;
1505 /** Find areas of `silence' within a region.
1507 * @param threshold Threshold below which signal is considered silence (as a sample value)
1508 * @param min_length Minimum length of silent period to be reported.
1509 * @return Silent periods; first of pair is the offset within the region, second is the length of the period
1512 std::list<std::pair<frameoffset_t, framecnt_t> >
1513 AudioRegion::find_silence (Sample threshold, framecnt_t min_length) const
1515 framecnt_t const block_size = 64 * 1024;
1516 Sample loudest[block_size];
1517 Sample buf[block_size];
1519 framepos_t pos = _start;
1520 framepos_t const end = _start + _length - 1;
1522 std::list<std::pair<frameoffset_t, framecnt_t> > silent_periods;
1524 bool in_silence = false;
1525 frameoffset_t silence_start = 0;
1530 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1531 memset (loudest, 0, sizeof (Sample) * block_size);
1532 for (uint32_t n = 0; n < n_channels(); ++n) {
1534 read_raw_internal (buf, pos, block_size, n);
1535 for (framecnt_t i = 0; i < block_size; ++i) {
1536 loudest[i] = max (loudest[i], abs (buf[i]));
1540 /* now look for silence */
1541 for (framecnt_t i = 0; i < block_size; ++i) {
1542 silence = abs (loudest[i]) < threshold;
1543 if (silence && !in_silence) {
1544 /* non-silence to silence */
1546 silence_start = pos + i;
1547 } else if (!silence && in_silence) {
1548 /* silence to non-silence */
1550 if (pos + i - 1 - silence_start >= min_length) {
1551 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1559 if (in_silence && end - 1 - silence_start >= min_length) {
1560 /* last block was silent, so finish off the last period */
1561 silent_periods.push_back (std::make_pair (silence_start, end));
1564 return silent_periods;
1571 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)
1573 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (framecnt_t) npeaks, (framepos_t) start, (framecnt_t) cnt, n_chan,samples_per_unit);
1576 uint32_t region_length_from_c (void *arg)
1579 return ((AudioRegion *) arg)->length();
1582 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1584 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;