beat slicing patch #1 from lincoln spiteri
[ardour2.git] / libs / ardour / audioregion.cc
blob5f8b35256b7593c423d11e3ac3efcc3dd5d9591b
1 /*
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.
20 #include <cmath>
21 #include <climits>
22 #include <cfloat>
23 #include <algorithm>
25 #include <set>
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"
49 #include "i18n.h"
50 #include <locale.h>
52 using namespace std;
53 using namespace ARDOUR;
54 using namespace PBD;
56 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;
67 void
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));
84 void
85 AudioRegion::register_properties ()
87 /* no need to register parent class properties */
89 add_property (_envelope_active);
90 add_property (_default_fade_in);
91 add_property (_default_fade_out);
92 add_property (_fade_in_active);
93 add_property (_fade_out_active);
94 add_property (_scale_amplitude);
97 #define AUDIOREGION_STATE_DEFAULT \
98 _envelope_active (Properties::envelope_active, false) \
99 , _default_fade_in (Properties::default_fade_in, true) \
100 , _default_fade_out (Properties::default_fade_out, true) \
101 , _fade_in_active (Properties::fade_in_active, true) \
102 , _fade_out_active (Properties::fade_out_active, true) \
103 , _scale_amplitude (Properties::scale_amplitude, 1.0)
105 #define AUDIOREGION_COPY_STATE(other) \
106 _envelope_active (other->_envelope_active) \
107 , _default_fade_in (other->_default_fade_in) \
108 , _default_fade_out (other->_default_fade_out) \
109 , _fade_in_active (other->_fade_in_active) \
110 , _fade_out_active (other->_fade_out_active) \
111 , _scale_amplitude (other->_scale_amplitude)
112 /* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
114 void
115 AudioRegion::init ()
117 register_properties ();
119 set_default_fades ();
120 set_default_envelope ();
122 listen_to_my_curves ();
123 connect_to_analysis_changed ();
124 connect_to_header_position_offset_changed ();
127 /** Constructor for use by derived types only */
128 AudioRegion::AudioRegion (Session& s, framepos_t start, framecnt_t len, std::string name)
129 : Region (s, start, len, name, DataType::AUDIO)
130 , AUDIOREGION_STATE_DEFAULT
131 , _automatable (s)
132 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
133 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
134 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
135 , _fade_in_suspended (0)
136 , _fade_out_suspended (0)
138 init ();
139 assert (_sources.size() == _master_sources.size());
142 /** Basic AudioRegion constructor */
143 AudioRegion::AudioRegion (const SourceList& srcs)
144 : Region (srcs)
145 , AUDIOREGION_STATE_DEFAULT
146 , _automatable(srcs[0]->session())
147 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
148 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
149 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
150 , _fade_in_suspended (0)
151 , _fade_out_suspended (0)
153 init ();
154 assert (_sources.size() == _master_sources.size());
157 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes64_t offset, bool offset_relative)
158 : Region (other, offset, offset_relative)
159 , AUDIOREGION_COPY_STATE (other)
160 , _automatable (other->session())
161 , _fade_in (new AutomationList (*other->_fade_in))
162 , _fade_out (new AutomationList (*other->_fade_out))
163 /* XXX is this guaranteed to work for all values of offset+offset_relative? */
164 , _envelope (new AutomationList (*other->_envelope, _start, _start + _length))
165 , _fade_in_suspended (0)
166 , _fade_out_suspended (0)
168 /* don't use init here, because we got fade in/out from the other region
170 register_properties ();
171 listen_to_my_curves ();
172 connect_to_analysis_changed ();
173 connect_to_header_position_offset_changed ();
175 assert(_type == DataType::AUDIO);
176 assert (_sources.size() == _master_sources.size());
179 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& srcs)
180 : Region (boost::static_pointer_cast<const Region>(other), srcs)
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 , _envelope (new AutomationList (*other->_envelope))
186 , _fade_in_suspended (0)
187 , _fade_out_suspended (0)
189 /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
191 register_properties ();
193 listen_to_my_curves ();
194 connect_to_analysis_changed ();
195 connect_to_header_position_offset_changed ();
197 assert (_sources.size() == _master_sources.size());
200 AudioRegion::AudioRegion (SourceList& srcs)
201 : Region (srcs)
202 , AUDIOREGION_STATE_DEFAULT
203 , _automatable(srcs[0]->session())
204 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
205 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
206 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
207 , _fade_in_suspended (0)
208 , _fade_out_suspended (0)
210 init ();
212 assert(_type == DataType::AUDIO);
213 assert (_sources.size() == _master_sources.size());
216 AudioRegion::~AudioRegion ()
220 void
221 AudioRegion::post_set ()
223 if (!_sync_marked) {
224 _sync_position = _start;
227 /* return to default fades if the existing ones are too long */
229 if (_left_of_split) {
230 if (_fade_in->back()->when >= _length) {
231 set_default_fade_in ();
233 set_default_fade_out ();
234 _left_of_split = false;
237 if (_right_of_split) {
238 if (_fade_out->back()->when >= _length) {
239 set_default_fade_out ();
242 set_default_fade_in ();
243 _right_of_split = false;
246 /* If _length changed, adjust our gain envelope accordingly */
247 _envelope->truncate_end (_length);
250 void
251 AudioRegion::connect_to_analysis_changed ()
253 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
254 (*i)->AnalysisChanged.connect_same_thread (*this, boost::bind (&AudioRegion::invalidate_transients, this));
258 void
259 AudioRegion::connect_to_header_position_offset_changed ()
261 set<boost::shared_ptr<Source> > unique_srcs;
263 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
265 /* connect only once to HeaderPositionOffsetChanged, even if sources are replicated
268 if (unique_srcs.find (*i) == unique_srcs.end ()) {
269 unique_srcs.insert (*i);
270 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
271 if (afs) {
272 afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
278 void
279 AudioRegion::listen_to_my_curves ()
281 _envelope->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::envelope_changed, this));
282 _fade_in->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_in_changed, this));
283 _fade_out->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_out_changed, this));
286 void
287 AudioRegion::set_envelope_active (bool yn)
289 if (envelope_active() != yn) {
290 _envelope_active = yn;
291 send_change (PropertyChange (Properties::envelope_active));
295 ARDOUR::nframes_t
296 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
298 if (chan_n >= _sources.size()) {
299 return 0;
302 if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
303 return 0;
304 } else {
305 if (_scale_amplitude != 1.0f) {
306 for (nframes_t n = 0; n < npeaks; ++n) {
307 buf[n].max *= _scale_amplitude;
308 buf[n].min *= _scale_amplitude;
311 return cnt;
315 framecnt_t
316 AudioRegion::read (Sample* buf, framepos_t timeline_position, framecnt_t cnt, int channel) const
318 /* raw read, no fades, no gain, nada */
319 return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
322 framecnt_t
323 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
324 framepos_t file_position, framecnt_t cnt, uint32_t chan_n,
325 framecnt_t read_frames, framecnt_t skip_frames) const
327 /* regular diskstream/butler read complete with fades etc */
328 return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer,
329 file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
332 framecnt_t
333 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
334 framepos_t position, framecnt_t cnt, uint32_t chan_n) const
336 /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
338 return _read_at (_master_sources, _master_sources.front()->length(_master_sources.front()->timeline_position()),
339 buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0, ReadOps (0));
342 framecnt_t
343 AudioRegion::_read_at (const SourceList& /*srcs*/, framecnt_t limit,
344 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
345 framepos_t position,
346 framecnt_t cnt,
347 uint32_t chan_n,
348 framecnt_t /*read_frames*/,
349 framecnt_t /*skip_frames*/,
350 ReadOps rops) const
352 frameoffset_t internal_offset;
353 frameoffset_t buf_offset;
354 framecnt_t to_read;
355 bool raw = (rops == ReadOpsNone);
357 if (muted() && !raw) {
358 return 0; /* read nothing */
361 /* precondition: caller has verified that we cover the desired section */
363 if (position < _position) {
364 internal_offset = 0;
365 buf_offset = _position - position;
366 cnt -= buf_offset;
367 } else {
368 internal_offset = position - _position;
369 buf_offset = 0;
372 if (internal_offset >= limit) {
373 return 0; /* read nothing */
376 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
377 return 0; /* read nothing */
380 if (opaque() || raw) {
381 /* overwrite whatever is there */
382 mixdown_buffer = buf + buf_offset;
383 } else {
384 mixdown_buffer += buf_offset;
387 if (rops & ReadOpsCount) {
388 _read_data_count = 0;
391 if (chan_n < n_channels()) {
393 boost::shared_ptr<AudioSource> src = audio_source(chan_n);
394 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
395 return 0; /* "read nothing" */
398 if (rops & ReadOpsCount) {
399 _read_data_count += src->read_data_count();
402 } else {
404 /* track is N-channel, this region has less channels; silence the ones
405 we don't have.
408 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
411 if (rops & ReadOpsFades) {
413 /* fade in */
415 if (_fade_in_active && _session.config.get_use_region_fades()) {
417 nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
419 /* see if this read is within the fade in */
421 if (internal_offset < fade_in_length) {
423 nframes_t fi_limit;
425 fi_limit = min (to_read, fade_in_length - internal_offset);
428 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
430 for (nframes_t n = 0; n < fi_limit; ++n) {
431 mixdown_buffer[n] *= gain_buffer[n];
436 /* fade out */
438 if (_fade_out_active && _session.config.get_use_region_fades()) {
440 /* see if some part of this read is within the fade out */
442 /* ................. >| REGION
443 limit
445 { } FADE
446 fade_out_length
448 limit - fade_out_length
449 |--------------|
450 ^internal_offset
451 ^internal_offset + to_read
453 we need the intersection of [internal_offset,internal_offset+to_read] with
454 [limit - fade_out_length, limit]
459 nframes_t fade_out_length = (nframes_t) _fade_out->back()->when;
460 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
461 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
463 if (fade_interval_end > fade_interval_start) {
464 /* (part of the) the fade out is in this buffer */
466 nframes_t fo_limit = fade_interval_end - fade_interval_start;
467 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
468 nframes_t fade_offset = fade_interval_start - internal_offset;
470 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
472 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
473 mixdown_buffer[m] *= gain_buffer[n];
480 /* Regular gain curves and scaling */
482 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
483 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
485 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
486 for (nframes_t n = 0; n < to_read; ++n) {
487 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
489 } else {
490 for (nframes_t n = 0; n < to_read; ++n) {
491 mixdown_buffer[n] *= gain_buffer[n];
494 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
496 // XXX this should be using what in 2.0 would have been:
497 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
499 for (nframes_t n = 0; n < to_read; ++n) {
500 mixdown_buffer[n] *= _scale_amplitude;
504 if (!opaque()) {
506 /* gack. the things we do for users.
509 buf += buf_offset;
511 for (nframes_t n = 0; n < to_read; ++n) {
512 buf[n] += mixdown_buffer[n];
516 return to_read;
519 XMLNode&
520 AudioRegion::state (bool full)
522 XMLNode& node (Region::state (full));
523 XMLNode *child;
524 char buf[64];
525 LocaleGuard lg (X_("POSIX"));
527 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
528 node.add_property ("channels", buf);
530 if (full) {
531 Stateful::add_properties (node);
534 child = node.add_child ("Envelope");
536 if (full) {
537 bool default_env = false;
539 // If there are only two points, the points are in the start of the region and the end of the region
540 // so, if they are both at 1.0f, that means the default region.
542 if (_envelope->size() == 2 &&
543 _envelope->front()->value == 1.0f &&
544 _envelope->back()->value==1.0f) {
545 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
546 default_env = true;
550 if (default_env) {
551 child->add_property ("default", "yes");
552 } else {
553 child->add_child_nocopy (_envelope->get_state ());
556 } else {
557 child->add_property ("default", "yes");
560 return node;
564 AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_changed, bool send)
566 const XMLNodeList& nlist = node.children();
567 const XMLProperty *prop;
568 LocaleGuard lg (X_("POSIX"));
569 boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
571 suspend_property_changes ();
573 if (the_playlist) {
574 the_playlist->freeze ();
578 /* this will set all our State members and stuff controlled by the Region.
579 It should NOT send any changed signals - that is our responsibility.
582 Region::_set_state (node, version, what_changed, false);
584 if ((prop = node.property ("scale-gain")) != 0) {
585 float a = atof (prop->value().c_str());
586 if (a != _scale_amplitude) {
587 _scale_amplitude = a;
588 what_changed.add (Properties::scale_amplitude);
592 /* Now find envelope description and other related child items */
594 _envelope->freeze ();
596 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
597 XMLNode *child;
598 XMLProperty *prop;
600 child = (*niter);
602 if (child->name() == "Envelope") {
604 _envelope->clear ();
606 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child, version)) {
607 set_default_envelope ();
610 _envelope->set_max_xval (_length);
611 _envelope->truncate_end (_length);
614 } else if (child->name() == "FadeIn") {
616 _fade_in->clear ();
618 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
619 set_default_fade_in ();
620 } else {
621 XMLNode* grandchild = child->child ("AutomationList");
622 if (grandchild) {
623 _fade_in->set_state (*grandchild, version);
627 if ((prop = child->property ("active")) != 0) {
628 if (string_is_affirmative (prop->value())) {
629 set_fade_in_active (true);
630 } else {
631 set_fade_in_active (false);
635 } else if (child->name() == "FadeOut") {
637 _fade_out->clear ();
639 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
640 set_default_fade_out ();
641 } else {
642 XMLNode* grandchild = child->child ("AutomationList");
643 if (grandchild) {
644 _fade_out->set_state (*grandchild, version);
648 if ((prop = child->property ("active")) != 0) {
649 if (string_is_affirmative (prop->value())) {
650 set_fade_out_active (true);
651 } else {
652 set_fade_out_active (false);
659 _envelope->thaw ();
660 resume_property_changes ();
662 if (send) {
663 send_change (what_changed);
666 if (the_playlist) {
667 the_playlist->thaw ();
670 return 0;
674 AudioRegion::set_state (const XMLNode& node, int version)
676 PropertyChange what_changed;
677 return _set_state (node, version, what_changed, true);
680 void
681 AudioRegion::set_fade_in_shape (FadeShape shape)
683 set_fade_in (shape, (nframes_t) _fade_in->back()->when);
686 void
687 AudioRegion::set_fade_out_shape (FadeShape shape)
689 set_fade_out (shape, (nframes_t) _fade_out->back()->when);
692 void
693 AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
695 _fade_in->freeze ();
696 *_fade_in = *f;
697 _fade_in->thaw ();
699 send_change (PropertyChange (Properties::fade_in));
702 void
703 AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
705 _fade_in->freeze ();
706 _fade_in->clear ();
708 switch (shape) {
709 case Linear:
710 _fade_in->fast_simple_add (0.0, 0.0);
711 _fade_in->fast_simple_add (len, 1.0);
712 break;
714 case Fast:
715 _fade_in->fast_simple_add (0, 0);
716 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
717 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
718 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
719 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
720 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
721 _fade_in->fast_simple_add (len, 1);
722 break;
724 case Slow:
725 _fade_in->fast_simple_add (0, 0);
726 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
727 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
728 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
729 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
730 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
731 _fade_in->fast_simple_add (len * 0.767281, 1);
732 _fade_in->fast_simple_add (len, 1);
733 break;
735 case LogA:
736 _fade_in->fast_simple_add (0, 0);
737 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
738 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
739 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
740 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
741 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
742 _fade_in->fast_simple_add (len, 1);
743 break;
745 case LogB:
746 _fade_in->fast_simple_add (0, 0);
747 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
748 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
749 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
750 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
751 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
752 _fade_in->fast_simple_add (len, 1);
753 break;
756 _fade_in->thaw ();
759 void
760 AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
762 _fade_out->freeze ();
763 *_fade_out = *f;
764 _fade_out->thaw ();
766 send_change (PropertyChange (Properties::fade_in));
769 void
770 AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
772 _fade_out->freeze ();
773 _fade_out->clear ();
775 switch (shape) {
776 case Fast:
777 _fade_out->fast_simple_add (len * 0, 1);
778 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
779 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
780 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
781 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
782 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
783 _fade_out->fast_simple_add (len * 1, 0);
784 break;
786 case LogA:
787 _fade_out->fast_simple_add (len * 0, 1);
788 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
789 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
790 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
791 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
792 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
793 _fade_out->fast_simple_add (len * 1, 0);
794 break;
796 case Slow:
797 _fade_out->fast_simple_add (len * 0, 1);
798 _fade_out->fast_simple_add (len * 0.305556, 1);
799 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
800 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
801 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
802 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
803 _fade_out->fast_simple_add (len * 1, 0);
804 break;
806 case LogB:
807 _fade_out->fast_simple_add (len * 0, 1);
808 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
809 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
810 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
811 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
812 _fade_out->fast_simple_add (len * 1, 0);
813 break;
815 case Linear:
816 _fade_out->fast_simple_add (len * 0, 1);
817 _fade_out->fast_simple_add (len * 1, 0);
818 break;
821 _fade_out->thaw ();
824 void
825 AudioRegion::set_fade_in_length (framecnt_t len)
827 if (len > _length) {
828 len = _length - 1;
831 bool changed = _fade_in->extend_to (len);
833 if (changed) {
834 _default_fade_in = false;
835 send_change (PropertyChange (Properties::fade_in));
839 void
840 AudioRegion::set_fade_out_length (framecnt_t len)
842 if (len > _length) {
843 len = _length - 1;
846 bool changed = _fade_out->extend_to (len);
848 if (changed) {
849 _default_fade_out = false;
850 send_change (PropertyChange (Properties::fade_out));
854 void
855 AudioRegion::set_fade_in_active (bool yn)
857 if (yn == _fade_in_active) {
858 return;
861 _fade_in_active = yn;
862 send_change (PropertyChange (Properties::fade_in_active));
865 void
866 AudioRegion::set_fade_out_active (bool yn)
868 if (yn == _fade_out_active) {
869 return;
871 _fade_out_active = yn;
872 send_change (PropertyChange (Properties::fade_out_active));
875 bool
876 AudioRegion::fade_in_is_default () const
878 return _fade_in->size() == 2 && _fade_in->front()->when == 0 && _fade_in->back()->when == 64;
881 bool
882 AudioRegion::fade_out_is_default () const
884 return _fade_out->size() == 2 && _fade_out->front()->when == 0 && _fade_out->back()->when == 64;
887 void
888 AudioRegion::set_default_fade_in ()
890 _fade_in_suspended = 0;
891 set_fade_in (Linear, 64);
894 void
895 AudioRegion::set_default_fade_out ()
897 _fade_out_suspended = 0;
898 set_fade_out (Linear, 64);
901 void
902 AudioRegion::set_default_fades ()
904 set_default_fade_in ();
905 set_default_fade_out ();
908 void
909 AudioRegion::set_default_envelope ()
911 _envelope->freeze ();
912 _envelope->clear ();
913 _envelope->fast_simple_add (0, 1.0f);
914 _envelope->fast_simple_add (_length, 1.0f);
915 _envelope->thaw ();
918 void
919 AudioRegion::recompute_at_end ()
921 /* our length has changed. recompute a new final point by interpolating
922 based on the the existing curve.
925 _envelope->freeze ();
926 _envelope->truncate_end (_length);
927 _envelope->set_max_xval (_length);
928 _envelope->thaw ();
930 if (_left_of_split) {
931 set_default_fade_out ();
932 _left_of_split = false;
933 } else if (_fade_out->back()->when > _length) {
934 _fade_out->extend_to (_length);
935 send_change (PropertyChange (Properties::fade_out));
938 if (_fade_in->back()->when > _length) {
939 _fade_in->extend_to (_length);
940 send_change (PropertyChange (Properties::fade_in));
944 void
945 AudioRegion::recompute_at_start ()
947 /* as above, but the shift was from the front */
949 _envelope->truncate_start (_length);
951 if (_right_of_split) {
952 set_default_fade_in ();
953 _right_of_split = false;
954 } else if (_fade_in->back()->when > _length) {
955 _fade_in->extend_to (_length);
956 send_change (PropertyChange (Properties::fade_in));
959 if (_fade_out->back()->when > _length) {
960 _fade_out->extend_to (_length);
961 send_change (PropertyChange (Properties::fade_out));
966 AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr<Region> >& v) const
968 SourceList srcs;
969 string new_name;
970 int n = 0;
972 if (_sources.size() < 2) {
973 return 0;
976 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
977 srcs.clear ();
978 srcs.push_back (*i);
980 new_name = _name;
982 if (_sources.size() == 2) {
983 if (n == 0) {
984 new_name += "-L";
985 } else {
986 new_name += "-R";
988 } else {
989 new_name += '-';
990 new_name += ('0' + n + 1);
993 /* create a copy with just one source. prevent if from being thought of as
994 "whole file" even if it covers the entire source file(s).
997 PropertyList plist;
999 plist.add (Properties::start, _start.val());
1000 plist.add (Properties::length, _length.val());
1001 plist.add (Properties::name, new_name);
1002 plist.add (Properties::layer, _layer.val());
1004 v.push_back(RegionFactory::create (srcs, plist));
1005 v.back()->set_whole_file (false);
1007 ++n;
1010 return 0;
1013 framecnt_t
1014 AudioRegion::read_raw_internal (Sample* buf, framepos_t pos, framecnt_t cnt, int channel) const
1016 return audio_source()->read (buf, pos, cnt, channel);
1020 AudioRegion::exportme (Session& /*session*/, ARDOUR::ExportSpecification& /*spec*/)
1022 // TODO EXPORT
1023 // const nframes_t blocksize = 4096;
1024 // nframes_t to_read;
1025 // int status = -1;
1027 // spec.channels = _sources.size();
1029 // if (spec.prepare (blocksize, session.frame_rate())) {
1030 // goto out;
1031 // }
1033 // spec.pos = 0;
1034 // spec.total_frames = _length;
1036 // while (spec.pos < _length && !spec.stop) {
1039 // /* step 1: interleave */
1041 // to_read = min (_length - spec.pos, blocksize);
1043 // if (spec.channels == 1) {
1045 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1046 // goto out;
1047 // }
1049 // } else {
1051 // Sample buf[blocksize];
1053 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1055 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1056 // goto out;
1057 // }
1059 // for (nframes_t x = 0; x < to_read; ++x) {
1060 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1061 // }
1062 // }
1063 // }
1065 // if (spec.process (to_read)) {
1066 // goto out;
1067 // }
1069 // spec.pos += to_read;
1070 // spec.progress = (double) spec.pos /_length;
1072 // }
1074 // status = 0;
1076 // out:
1077 // spec.running = false;
1078 // spec.status = status;
1079 // spec.clear();
1081 // return status;
1082 return 0;
1085 void
1086 AudioRegion::set_scale_amplitude (gain_t g)
1088 boost::shared_ptr<Playlist> pl (playlist());
1090 _scale_amplitude = g;
1092 /* tell the diskstream we're in */
1094 if (pl) {
1095 pl->ContentsChanged();
1098 /* tell everybody else */
1100 send_change (PropertyChange (Properties::scale_amplitude));
1103 void
1104 AudioRegion::normalize_to (float target_dB)
1106 const framecnt_t blocksize = 64 * 1024;
1107 Sample buf[blocksize];
1108 framepos_t fpos;
1109 framepos_t fend;
1110 framecnt_t to_read;
1111 double maxamp = 0;
1112 gain_t target = dB_to_coefficient (target_dB);
1114 if (target == 1.0f) {
1115 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1116 that we may have clipped.
1118 target -= FLT_EPSILON;
1121 fpos = _start;
1122 fend = _start + _length;
1124 /* first pass: find max amplitude */
1126 while (fpos < fend) {
1128 uint32_t n;
1130 to_read = min (fend - fpos, blocksize);
1132 for (n = 0; n < n_channels(); ++n) {
1134 /* read it in */
1136 if (read_raw_internal (buf, fpos, to_read, 0) != to_read) {
1137 return;
1140 maxamp = compute_peak (buf, to_read, maxamp);
1143 fpos += to_read;
1146 if (maxamp == 0.0f) {
1147 /* don't even try */
1148 return;
1151 if (maxamp == target) {
1152 /* we can't do anything useful */
1153 return;
1156 /* compute scale factor */
1158 _scale_amplitude = target/maxamp;
1160 /* tell the diskstream we're in */
1162 boost::shared_ptr<Playlist> pl (playlist());
1164 if (pl) {
1165 pl->ContentsChanged();
1168 /* tell everybody else */
1170 send_change (PropertyChange (Properties::scale_amplitude));
1173 void
1174 AudioRegion::fade_in_changed ()
1176 send_change (PropertyChange (Properties::fade_in));
1179 void
1180 AudioRegion::fade_out_changed ()
1182 send_change (PropertyChange (Properties::fade_out));
1185 void
1186 AudioRegion::envelope_changed ()
1188 send_change (PropertyChange (Properties::envelope));
1191 void
1192 AudioRegion::suspend_fade_in ()
1194 if (++_fade_in_suspended == 1) {
1195 if (fade_in_is_default()) {
1196 set_fade_in_active (false);
1201 void
1202 AudioRegion::resume_fade_in ()
1204 if (--_fade_in_suspended == 0 && _fade_in_suspended) {
1205 set_fade_in_active (true);
1209 void
1210 AudioRegion::suspend_fade_out ()
1212 if (++_fade_out_suspended == 1) {
1213 if (fade_out_is_default()) {
1214 set_fade_out_active (false);
1219 void
1220 AudioRegion::resume_fade_out ()
1222 if (--_fade_out_suspended == 0 &&_fade_out_suspended) {
1223 set_fade_out_active (true);
1227 bool
1228 AudioRegion::speed_mismatch (float sr) const
1230 if (_sources.empty()) {
1231 /* impossible, but ... */
1232 return false;
1235 float fsr = audio_source()->sample_rate();
1237 return fsr != sr;
1240 void
1241 AudioRegion::source_offset_changed ()
1243 /* XXX this fixes a crash that should not occur. It does occur
1244 becauses regions are not being deleted when a session
1245 is unloaded. That bug must be fixed.
1248 if (_sources.empty()) {
1249 return;
1252 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1254 if (afs && afs->destructive()) {
1255 // set_start (source()->natural_position(), this);
1256 set_position (source()->natural_position(), this);
1260 boost::shared_ptr<AudioSource>
1261 AudioRegion::audio_source (uint32_t n) const
1263 // Guaranteed to succeed (use a static cast for speed?)
1264 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1267 int
1268 AudioRegion::adjust_transients (nframes64_t delta)
1270 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1271 (*x) = (*x) + delta;
1274 send_change (PropertyChange (Properties::valid_transients));
1276 return 0;
1280 AudioRegion::update_transient (nframes64_t old_position, nframes64_t new_position)
1282 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1283 if ((*x) == old_position) {
1284 (*x) = new_position;
1285 send_change (PropertyChange (Properties::valid_transients));
1287 break;
1291 return 0;
1294 void
1295 AudioRegion::add_transient (nframes64_t where)
1297 _transients.push_back(where);
1298 _valid_transients = true;
1300 send_change (PropertyChange (Properties::valid_transients));
1303 void
1304 AudioRegion::remove_transient (nframes64_t where)
1306 _transients.remove(where);
1307 _valid_transients = true;
1309 send_change (PropertyChange (Properties::valid_transients));
1313 AudioRegion::set_transients (AnalysisFeatureList& results)
1315 _transients.clear();
1316 _transients = results;
1317 _valid_transients = true;
1319 send_change (PropertyChange (Properties::valid_transients));
1321 return 0;
1325 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1327 boost::shared_ptr<Playlist> pl = playlist();
1329 if (!pl) {
1330 return -1;
1333 if (_valid_transients && !force_new) {
1334 results = _transients;
1335 return 0;
1338 SourceList::iterator s;
1340 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1341 if (!(*s)->has_been_analysed()) {
1342 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1343 break;
1347 if (s == _sources.end()) {
1348 /* all sources are analyzed, merge data from each one */
1350 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1352 /* find the set of transients within the bounds of this region */
1354 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1355 (*s)->transients.end(),
1356 _start);
1358 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1359 (*s)->transients.end(),
1360 _start + _length);
1362 /* and add them */
1364 results.insert (results.end(), low, high);
1367 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1369 /* translate all transients to current position */
1371 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1372 (*x) -= _start;
1373 (*x) += _position;
1376 _transients = results;
1377 _valid_transients = true;
1379 return 0;
1382 /* no existing/complete transient info */
1384 static bool analyse_dialog_shown = false; /* global per instance of Ardour */
1386 if (!Config->get_auto_analyse_audio()) {
1387 if (!analyse_dialog_shown) {
1388 pl->session().Dialog (_("\
1389 You have requested an operation that requires audio analysis.\n\n \
1390 You currently have \"auto-analyse-audio\" disabled, which means\n\
1391 that transient data must be generated every time it is required.\n\n\
1392 If you are doing work that will require transient data on a\n\
1393 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1394 +then quit ardour and restart.\n\n\
1395 +This dialog will not display again. But you may notice a slight delay\n\
1396 +in this and future transient-detection operations.\n\
1397 +"));
1398 analyse_dialog_shown = true;
1402 TransientDetector t (pl->session().frame_rate());
1403 bool existing_results = !results.empty();
1405 _transients.clear ();
1406 _valid_transients = false;
1408 for (uint32_t i = 0; i < n_channels(); ++i) {
1410 AnalysisFeatureList these_results;
1412 t.reset ();
1414 if (t.run ("", this, i, these_results)) {
1415 return -1;
1418 /* translate all transients to give absolute position */
1420 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1421 (*i) += _position;
1424 /* merge */
1426 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1429 if (!results.empty()) {
1430 if (existing_results) {
1432 /* merge our transients into the existing ones, then clean up
1433 those.
1436 results.insert (results.end(), _transients.begin(), _transients.end());
1437 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1440 /* make sure ours are clean too */
1442 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1444 } else {
1446 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1447 results = _transients;
1450 _valid_transients = true;
1452 return 0;
1455 /** Find areas of `silence' within a region.
1457 * @param threshold Threshold below which signal is considered silence (as a sample value)
1458 * @param min_length Minimum length of silent period to be reported.
1459 * @return Silent periods; first of pair is the offset within the region, second is the length of the period
1462 std::list<std::pair<frameoffset_t, framecnt_t> >
1463 AudioRegion::find_silence (Sample threshold, framecnt_t min_length, InterThreadInfo& itt) const
1465 framecnt_t const block_size = 64 * 1024;
1466 Sample loudest[block_size];
1467 Sample buf[block_size];
1469 framepos_t pos = _start;
1470 framepos_t const end = _start + _length - 1;
1472 std::list<std::pair<frameoffset_t, framecnt_t> > silent_periods;
1474 bool in_silence = false;
1475 frameoffset_t silence_start = 0;
1476 bool silence;
1478 while (pos < end && !itt.cancel) {
1480 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1481 memset (loudest, 0, sizeof (Sample) * block_size);
1482 for (uint32_t n = 0; n < n_channels(); ++n) {
1484 read_raw_internal (buf, pos, block_size, n);
1485 for (framecnt_t i = 0; i < block_size; ++i) {
1486 loudest[i] = max (loudest[i], abs (buf[i]));
1490 /* now look for silence */
1491 for (framecnt_t i = 0; i < block_size; ++i) {
1492 silence = abs (loudest[i]) < threshold;
1493 if (silence && !in_silence) {
1494 /* non-silence to silence */
1495 in_silence = true;
1496 silence_start = pos + i;
1497 } else if (!silence && in_silence) {
1498 /* silence to non-silence */
1499 in_silence = false;
1500 if (pos + i - 1 - silence_start >= min_length) {
1501 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1506 pos += block_size;
1507 itt.progress = (end-pos)/(double)_length;
1510 if (in_silence && end - 1 - silence_start >= min_length) {
1511 /* last block was silent, so finish off the last period */
1512 silent_periods.push_back (std::make_pair (silence_start, end));
1515 itt.done = true;
1517 return silent_periods;
1522 extern "C" {
1524 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)
1526 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (framecnt_t) npeaks, (framepos_t) start, (framecnt_t) cnt, n_chan,samples_per_unit);
1529 uint32_t region_length_from_c (void *arg)
1532 return ((AudioRegion *) arg)->length();
1535 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1537 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;
1540 } /* extern "C" */