fix up file renaming code a little bit
[ArdourMidi.git] / libs / ardour / audioregion.cc
blob8c66591fa771a0730b0e812854ab4351ce3b491a
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 ()
522 XMLNode& node (Region::state ());
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 Stateful::add_properties (node);
532 child = node.add_child ("Envelope");
534 bool default_env = false;
536 // If there are only two points, the points are in the start of the region and the end of the region
537 // so, if they are both at 1.0f, that means the default region.
539 if (_envelope->size() == 2 &&
540 _envelope->front()->value == 1.0f &&
541 _envelope->back()->value==1.0f) {
542 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
543 default_env = true;
547 if (default_env) {
548 child->add_property ("default", "yes");
549 } else {
550 child->add_child_nocopy (_envelope->get_state ());
553 child = node.add_child (X_("FadeIn"));
555 if (_default_fade_in) {
556 child->add_property ("default", "yes");
557 } else {
558 child->add_child_nocopy (_fade_in->get_state ());
561 child = node.add_child (X_("FadeOut"));
563 if (_default_fade_out) {
564 child->add_property ("default", "yes");
565 } else {
566 child->add_child_nocopy (_fade_out->get_state ());
569 return node;
573 AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_changed, bool send)
575 const XMLNodeList& nlist = node.children();
576 const XMLProperty *prop;
577 LocaleGuard lg (X_("POSIX"));
578 boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
580 suspend_property_changes ();
582 if (the_playlist) {
583 the_playlist->freeze ();
587 /* this will set all our State members and stuff controlled by the Region.
588 It should NOT send any changed signals - that is our responsibility.
591 Region::_set_state (node, version, what_changed, false);
593 if ((prop = node.property ("scale-gain")) != 0) {
594 float a = atof (prop->value().c_str());
595 if (a != _scale_amplitude) {
596 _scale_amplitude = a;
597 what_changed.add (Properties::scale_amplitude);
601 /* Now find envelope description and other related child items */
603 _envelope->freeze ();
605 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
606 XMLNode *child;
607 XMLProperty *prop;
609 child = (*niter);
611 if (child->name() == "Envelope") {
613 _envelope->clear ();
615 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child, version)) {
616 set_default_envelope ();
619 _envelope->set_max_xval (_length);
620 _envelope->truncate_end (_length);
623 } else if (child->name() == "FadeIn") {
625 _fade_in->clear ();
627 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
628 set_default_fade_in ();
629 } else {
630 XMLNode* grandchild = child->child ("AutomationList");
631 if (grandchild) {
632 _fade_in->set_state (*grandchild, version);
636 if ((prop = child->property ("active")) != 0) {
637 if (string_is_affirmative (prop->value())) {
638 set_fade_in_active (true);
639 } else {
640 set_fade_in_active (false);
644 } else if (child->name() == "FadeOut") {
646 _fade_out->clear ();
648 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
649 set_default_fade_out ();
650 } else {
651 XMLNode* grandchild = child->child ("AutomationList");
652 if (grandchild) {
653 _fade_out->set_state (*grandchild, version);
657 if ((prop = child->property ("active")) != 0) {
658 if (string_is_affirmative (prop->value())) {
659 set_fade_out_active (true);
660 } else {
661 set_fade_out_active (false);
668 _envelope->thaw ();
669 resume_property_changes ();
671 if (send) {
672 send_change (what_changed);
675 if (the_playlist) {
676 the_playlist->thaw ();
679 return 0;
683 AudioRegion::set_state (const XMLNode& node, int version)
685 PropertyChange what_changed;
686 return _set_state (node, version, what_changed, true);
689 void
690 AudioRegion::set_fade_in_shape (FadeShape shape)
692 set_fade_in (shape, (nframes_t) _fade_in->back()->when);
695 void
696 AudioRegion::set_fade_out_shape (FadeShape shape)
698 set_fade_out (shape, (nframes_t) _fade_out->back()->when);
701 void
702 AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
704 _fade_in->freeze ();
705 *_fade_in = *f;
706 _fade_in->thaw ();
708 send_change (PropertyChange (Properties::fade_in));
711 void
712 AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
714 _fade_in->freeze ();
715 _fade_in->clear ();
717 switch (shape) {
718 case Linear:
719 _fade_in->fast_simple_add (0.0, 0.0);
720 _fade_in->fast_simple_add (len, 1.0);
721 break;
723 case Fast:
724 _fade_in->fast_simple_add (0, 0);
725 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
726 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
727 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
728 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
729 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
730 _fade_in->fast_simple_add (len, 1);
731 break;
733 case Slow:
734 _fade_in->fast_simple_add (0, 0);
735 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
736 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
737 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
738 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
739 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
740 _fade_in->fast_simple_add (len * 0.767281, 1);
741 _fade_in->fast_simple_add (len, 1);
742 break;
744 case LogA:
745 _fade_in->fast_simple_add (0, 0);
746 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
747 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
748 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
749 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
750 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
751 _fade_in->fast_simple_add (len, 1);
752 break;
754 case LogB:
755 _fade_in->fast_simple_add (0, 0);
756 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
757 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
758 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
759 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
760 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
761 _fade_in->fast_simple_add (len, 1);
762 break;
765 _fade_in->thaw ();
768 void
769 AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
771 _fade_out->freeze ();
772 *_fade_out = *f;
773 _fade_out->thaw ();
775 send_change (PropertyChange (Properties::fade_in));
778 void
779 AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
781 _fade_out->freeze ();
782 _fade_out->clear ();
784 switch (shape) {
785 case Fast:
786 _fade_out->fast_simple_add (len * 0, 1);
787 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
788 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
789 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
790 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
791 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
792 _fade_out->fast_simple_add (len * 1, 0);
793 break;
795 case LogA:
796 _fade_out->fast_simple_add (len * 0, 1);
797 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
798 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
799 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
800 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
801 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
802 _fade_out->fast_simple_add (len * 1, 0);
803 break;
805 case Slow:
806 _fade_out->fast_simple_add (len * 0, 1);
807 _fade_out->fast_simple_add (len * 0.305556, 1);
808 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
809 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
810 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
811 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
812 _fade_out->fast_simple_add (len * 1, 0);
813 break;
815 case LogB:
816 _fade_out->fast_simple_add (len * 0, 1);
817 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
818 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
819 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
820 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
821 _fade_out->fast_simple_add (len * 1, 0);
822 break;
824 case Linear:
825 _fade_out->fast_simple_add (len * 0, 1);
826 _fade_out->fast_simple_add (len * 1, 0);
827 break;
830 _fade_out->thaw ();
833 void
834 AudioRegion::set_fade_in_length (framecnt_t len)
836 if (len > _length) {
837 len = _length - 1;
840 bool changed = _fade_in->extend_to (len);
842 if (changed) {
843 _default_fade_in = false;
844 send_change (PropertyChange (Properties::fade_in));
848 void
849 AudioRegion::set_fade_out_length (framecnt_t len)
851 if (len > _length) {
852 len = _length - 1;
855 bool changed = _fade_out->extend_to (len);
857 if (changed) {
858 _default_fade_out = false;
859 send_change (PropertyChange (Properties::fade_out));
863 void
864 AudioRegion::set_fade_in_active (bool yn)
866 if (yn == _fade_in_active) {
867 return;
870 _fade_in_active = yn;
871 send_change (PropertyChange (Properties::fade_in_active));
874 void
875 AudioRegion::set_fade_out_active (bool yn)
877 if (yn == _fade_out_active) {
878 return;
880 _fade_out_active = yn;
881 send_change (PropertyChange (Properties::fade_out_active));
884 bool
885 AudioRegion::fade_in_is_default () const
887 return _fade_in->size() == 2 && _fade_in->front()->when == 0 && _fade_in->back()->when == 64;
890 bool
891 AudioRegion::fade_out_is_default () const
893 return _fade_out->size() == 2 && _fade_out->front()->when == 0 && _fade_out->back()->when == 64;
896 void
897 AudioRegion::set_default_fade_in ()
899 _fade_in_suspended = 0;
900 set_fade_in (Linear, 64);
903 void
904 AudioRegion::set_default_fade_out ()
906 _fade_out_suspended = 0;
907 set_fade_out (Linear, 64);
910 void
911 AudioRegion::set_default_fades ()
913 set_default_fade_in ();
914 set_default_fade_out ();
917 void
918 AudioRegion::set_default_envelope ()
920 _envelope->freeze ();
921 _envelope->clear ();
922 _envelope->fast_simple_add (0, 1.0f);
923 _envelope->fast_simple_add (_length, 1.0f);
924 _envelope->thaw ();
927 void
928 AudioRegion::recompute_at_end ()
930 /* our length has changed. recompute a new final point by interpolating
931 based on the the existing curve.
934 _envelope->freeze ();
935 _envelope->truncate_end (_length);
936 _envelope->set_max_xval (_length);
937 _envelope->thaw ();
939 if (_left_of_split) {
940 set_default_fade_out ();
941 _left_of_split = false;
942 } else if (_fade_out->back()->when > _length) {
943 _fade_out->extend_to (_length);
944 send_change (PropertyChange (Properties::fade_out));
947 if (_fade_in->back()->when > _length) {
948 _fade_in->extend_to (_length);
949 send_change (PropertyChange (Properties::fade_in));
953 void
954 AudioRegion::recompute_at_start ()
956 /* as above, but the shift was from the front */
958 _envelope->truncate_start (_length);
960 if (_right_of_split) {
961 set_default_fade_in ();
962 _right_of_split = false;
963 } else if (_fade_in->back()->when > _length) {
964 _fade_in->extend_to (_length);
965 send_change (PropertyChange (Properties::fade_in));
968 if (_fade_out->back()->when > _length) {
969 _fade_out->extend_to (_length);
970 send_change (PropertyChange (Properties::fade_out));
975 AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr<Region> >& v) const
977 SourceList srcs;
978 string new_name;
979 int n = 0;
981 if (_sources.size() < 2) {
982 return 0;
985 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
986 srcs.clear ();
987 srcs.push_back (*i);
989 new_name = _name;
991 if (_sources.size() == 2) {
992 if (n == 0) {
993 new_name += "-L";
994 } else {
995 new_name += "-R";
997 } else {
998 new_name += '-';
999 new_name += ('0' + n + 1);
1002 /* create a copy with just one source. prevent if from being thought of as
1003 "whole file" even if it covers the entire source file(s).
1006 PropertyList plist;
1008 plist.add (Properties::start, _start.val());
1009 plist.add (Properties::length, _length.val());
1010 plist.add (Properties::name, new_name);
1011 plist.add (Properties::layer, _layer.val());
1013 v.push_back(RegionFactory::create (srcs, plist));
1014 v.back()->set_whole_file (false);
1016 ++n;
1019 return 0;
1022 framecnt_t
1023 AudioRegion::read_raw_internal (Sample* buf, framepos_t pos, framecnt_t cnt, int channel) const
1025 return audio_source()->read (buf, pos, cnt, channel);
1029 AudioRegion::exportme (Session& /*session*/, ARDOUR::ExportSpecification& /*spec*/)
1031 // TODO EXPORT
1032 // const nframes_t blocksize = 4096;
1033 // nframes_t to_read;
1034 // int status = -1;
1036 // spec.channels = _sources.size();
1038 // if (spec.prepare (blocksize, session.frame_rate())) {
1039 // goto out;
1040 // }
1042 // spec.pos = 0;
1043 // spec.total_frames = _length;
1045 // while (spec.pos < _length && !spec.stop) {
1048 // /* step 1: interleave */
1050 // to_read = min (_length - spec.pos, blocksize);
1052 // if (spec.channels == 1) {
1054 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1055 // goto out;
1056 // }
1058 // } else {
1060 // Sample buf[blocksize];
1062 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1064 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1065 // goto out;
1066 // }
1068 // for (nframes_t x = 0; x < to_read; ++x) {
1069 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1070 // }
1071 // }
1072 // }
1074 // if (spec.process (to_read)) {
1075 // goto out;
1076 // }
1078 // spec.pos += to_read;
1079 // spec.progress = (double) spec.pos /_length;
1081 // }
1083 // status = 0;
1085 // out:
1086 // spec.running = false;
1087 // spec.status = status;
1088 // spec.clear();
1090 // return status;
1091 return 0;
1094 void
1095 AudioRegion::set_scale_amplitude (gain_t g)
1097 boost::shared_ptr<Playlist> pl (playlist());
1099 _scale_amplitude = g;
1101 /* tell the diskstream we're in */
1103 if (pl) {
1104 pl->ContentsChanged();
1107 /* tell everybody else */
1109 send_change (PropertyChange (Properties::scale_amplitude));
1112 void
1113 AudioRegion::normalize_to (float target_dB)
1115 const framecnt_t blocksize = 64 * 1024;
1116 Sample buf[blocksize];
1117 framepos_t fpos;
1118 framepos_t fend;
1119 framecnt_t to_read;
1120 double maxamp = 0;
1121 gain_t target = dB_to_coefficient (target_dB);
1123 if (target == 1.0f) {
1124 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1125 that we may have clipped.
1127 target -= FLT_EPSILON;
1130 fpos = _start;
1131 fend = _start + _length;
1133 /* first pass: find max amplitude */
1135 while (fpos < fend) {
1137 uint32_t n;
1139 to_read = min (fend - fpos, blocksize);
1141 for (n = 0; n < n_channels(); ++n) {
1143 /* read it in */
1145 if (read_raw_internal (buf, fpos, to_read, 0) != to_read) {
1146 return;
1149 maxamp = compute_peak (buf, to_read, maxamp);
1152 fpos += to_read;
1155 if (maxamp == 0.0f) {
1156 /* don't even try */
1157 return;
1160 if (maxamp == target) {
1161 /* we can't do anything useful */
1162 return;
1165 /* compute scale factor */
1167 _scale_amplitude = target/maxamp;
1169 /* tell the diskstream we're in */
1171 boost::shared_ptr<Playlist> pl (playlist());
1173 if (pl) {
1174 pl->ContentsChanged();
1177 /* tell everybody else */
1179 send_change (PropertyChange (Properties::scale_amplitude));
1182 void
1183 AudioRegion::fade_in_changed ()
1185 send_change (PropertyChange (Properties::fade_in));
1188 void
1189 AudioRegion::fade_out_changed ()
1191 send_change (PropertyChange (Properties::fade_out));
1194 void
1195 AudioRegion::envelope_changed ()
1197 send_change (PropertyChange (Properties::envelope));
1200 void
1201 AudioRegion::suspend_fade_in ()
1203 if (++_fade_in_suspended == 1) {
1204 if (fade_in_is_default()) {
1205 set_fade_in_active (false);
1210 void
1211 AudioRegion::resume_fade_in ()
1213 if (--_fade_in_suspended == 0 && _fade_in_suspended) {
1214 set_fade_in_active (true);
1218 void
1219 AudioRegion::suspend_fade_out ()
1221 if (++_fade_out_suspended == 1) {
1222 if (fade_out_is_default()) {
1223 set_fade_out_active (false);
1228 void
1229 AudioRegion::resume_fade_out ()
1231 if (--_fade_out_suspended == 0 &&_fade_out_suspended) {
1232 set_fade_out_active (true);
1236 bool
1237 AudioRegion::speed_mismatch (float sr) const
1239 if (_sources.empty()) {
1240 /* impossible, but ... */
1241 return false;
1244 float fsr = audio_source()->sample_rate();
1246 return fsr != sr;
1249 void
1250 AudioRegion::source_offset_changed ()
1252 /* XXX this fixes a crash that should not occur. It does occur
1253 becauses regions are not being deleted when a session
1254 is unloaded. That bug must be fixed.
1257 if (_sources.empty()) {
1258 return;
1261 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1263 if (afs && afs->destructive()) {
1264 // set_start (source()->natural_position(), this);
1265 set_position (source()->natural_position(), this);
1269 boost::shared_ptr<AudioSource>
1270 AudioRegion::audio_source (uint32_t n) const
1272 // Guaranteed to succeed (use a static cast for speed?)
1273 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1276 int
1277 AudioRegion::adjust_transients (nframes64_t delta)
1279 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1280 (*x) = (*x) + delta;
1283 send_change (PropertyChange (Properties::valid_transients));
1285 return 0;
1289 AudioRegion::update_transient (nframes64_t old_position, nframes64_t new_position)
1291 for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
1292 if ((*x) == old_position) {
1293 (*x) = new_position;
1294 send_change (PropertyChange (Properties::valid_transients));
1296 break;
1300 return 0;
1303 void
1304 AudioRegion::add_transient (nframes64_t where)
1306 _transients.push_back(where);
1307 _valid_transients = true;
1309 send_change (PropertyChange (Properties::valid_transients));
1312 void
1313 AudioRegion::remove_transient (nframes64_t where)
1315 _transients.remove(where);
1316 _valid_transients = true;
1318 send_change (PropertyChange (Properties::valid_transients));
1322 AudioRegion::set_transients (AnalysisFeatureList& results)
1324 _transients.clear();
1325 _transients = results;
1326 _valid_transients = true;
1328 send_change (PropertyChange (Properties::valid_transients));
1330 return 0;
1334 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1336 boost::shared_ptr<Playlist> pl = playlist();
1338 if (!pl) {
1339 return -1;
1342 if (_valid_transients && !force_new) {
1343 results = _transients;
1344 return 0;
1347 SourceList::iterator s;
1349 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1350 if (!(*s)->has_been_analysed()) {
1351 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1352 break;
1356 if (s == _sources.end()) {
1357 /* all sources are analyzed, merge data from each one */
1359 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1361 /* find the set of transients within the bounds of this region */
1363 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1364 (*s)->transients.end(),
1365 _start);
1367 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1368 (*s)->transients.end(),
1369 _start + _length);
1371 /* and add them */
1373 results.insert (results.end(), low, high);
1376 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1378 /* translate all transients to current position */
1380 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1381 (*x) -= _start;
1382 (*x) += _position;
1385 _transients = results;
1386 _valid_transients = true;
1388 return 0;
1391 /* no existing/complete transient info */
1393 static bool analyse_dialog_shown = false; /* global per instance of Ardour */
1395 if (!Config->get_auto_analyse_audio()) {
1396 if (!analyse_dialog_shown) {
1397 pl->session().Dialog (_("\
1398 You have requested an operation that requires audio analysis.\n\n \
1399 You currently have \"auto-analyse-audio\" disabled, which means\n\
1400 that transient data must be generated every time it is required.\n\n\
1401 If you are doing work that will require transient data on a\n\
1402 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1403 +then quit ardour and restart.\n\n\
1404 +This dialog will not display again. But you may notice a slight delay\n\
1405 +in this and future transient-detection operations.\n\
1406 +"));
1407 analyse_dialog_shown = true;
1411 TransientDetector t (pl->session().frame_rate());
1412 bool existing_results = !results.empty();
1414 _transients.clear ();
1415 _valid_transients = false;
1417 for (uint32_t i = 0; i < n_channels(); ++i) {
1419 AnalysisFeatureList these_results;
1421 t.reset ();
1423 if (t.run ("", this, i, these_results)) {
1424 return -1;
1427 /* translate all transients to give absolute position */
1429 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1430 (*i) += _position;
1433 /* merge */
1435 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1438 if (!results.empty()) {
1439 if (existing_results) {
1441 /* merge our transients into the existing ones, then clean up
1442 those.
1445 results.insert (results.end(), _transients.begin(), _transients.end());
1446 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1449 /* make sure ours are clean too */
1451 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1453 } else {
1455 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1456 results = _transients;
1459 _valid_transients = true;
1461 return 0;
1464 /** Find areas of `silence' within a region.
1466 * @param threshold Threshold below which signal is considered silence (as a sample value)
1467 * @param min_length Minimum length of silent period to be reported.
1468 * @return Silent periods; first of pair is the offset within the region, second is the length of the period
1471 std::list<std::pair<frameoffset_t, framecnt_t> >
1472 AudioRegion::find_silence (Sample threshold, framecnt_t min_length, InterThreadInfo& itt) const
1474 framecnt_t const block_size = 64 * 1024;
1475 Sample loudest[block_size];
1476 Sample buf[block_size];
1478 framepos_t pos = _start;
1479 framepos_t const end = _start + _length - 1;
1481 std::list<std::pair<frameoffset_t, framecnt_t> > silent_periods;
1483 bool in_silence = false;
1484 frameoffset_t silence_start = 0;
1485 bool silence;
1487 while (pos < end && !itt.cancel) {
1489 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1490 memset (loudest, 0, sizeof (Sample) * block_size);
1491 for (uint32_t n = 0; n < n_channels(); ++n) {
1493 read_raw_internal (buf, pos, block_size, n);
1494 for (framecnt_t i = 0; i < block_size; ++i) {
1495 loudest[i] = max (loudest[i], abs (buf[i]));
1499 /* now look for silence */
1500 for (framecnt_t i = 0; i < block_size; ++i) {
1501 silence = abs (loudest[i]) < threshold;
1502 if (silence && !in_silence) {
1503 /* non-silence to silence */
1504 in_silence = true;
1505 silence_start = pos + i;
1506 } else if (!silence && in_silence) {
1507 /* silence to non-silence */
1508 in_silence = false;
1509 if (pos + i - 1 - silence_start >= min_length) {
1510 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1515 pos += block_size;
1516 itt.progress = (end-pos)/(double)_length;
1519 if (in_silence && end - 1 - silence_start >= min_length) {
1520 /* last block was silent, so finish off the last period */
1521 silent_periods.push_back (std::make_pair (silence_start, end));
1524 itt.done = true;
1526 return silent_periods;
1531 extern "C" {
1533 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)
1535 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (framecnt_t) npeaks, (framepos_t) start, (framecnt_t) cnt, n_chan,samples_per_unit);
1538 uint32_t region_length_from_c (void *arg)
1541 return ((AudioRegion *) arg)->length();
1544 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1546 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;
1549 } /* extern "C" */