possible fix for race between diskstream buffer overwrite and channel setup
[ardour2.git] / libs / ardour / audioregion.cc
blobbe6cce251aad7977917154da1024b789b956585e
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)
113 /* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
115 void
116 AudioRegion::init ()
118 register_properties ();
120 set_default_fades ();
121 set_default_envelope ();
123 listen_to_my_curves ();
124 connect_to_analysis_changed ();
125 connect_to_header_position_offset_changed ();
128 /** Constructor for use by derived types only */
129 AudioRegion::AudioRegion (Session& s, framepos_t start, framecnt_t len, std::string name)
130 : Region (s, start, len, name, DataType::AUDIO)
131 , AUDIOREGION_STATE_DEFAULT
132 , _automatable (s)
133 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
134 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
135 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
136 , _fade_in_suspended (0)
137 , _fade_out_suspended (0)
139 init ();
140 assert (_sources.size() == _master_sources.size());
143 /** Basic AudioRegion constructor */
144 AudioRegion::AudioRegion (const SourceList& srcs)
145 : Region (srcs)
146 , AUDIOREGION_STATE_DEFAULT
147 , _automatable(srcs[0]->session())
148 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
149 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
150 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
151 , _fade_in_suspended (0)
152 , _fade_out_suspended (0)
154 init ();
155 assert (_sources.size() == _master_sources.size());
158 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes64_t offset, bool offset_relative)
159 : Region (other, offset, offset_relative)
160 , AUDIOREGION_COPY_STATE (other)
161 , _automatable (other->session())
162 , _fade_in (new AutomationList (*other->_fade_in))
163 , _fade_out (new AutomationList (*other->_fade_out))
164 /* XXX is this guaranteed to work for all values of offset+offset_relative? */
165 , _envelope (new AutomationList (*other->_envelope, _start, _start + _length))
166 , _fade_in_suspended (0)
167 , _fade_out_suspended (0)
169 /* don't use init here, because we got fade in/out from the other region
171 register_properties ();
172 listen_to_my_curves ();
173 connect_to_analysis_changed ();
174 connect_to_header_position_offset_changed ();
176 assert(_type == DataType::AUDIO);
177 assert (_sources.size() == _master_sources.size());
180 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& srcs)
181 : Region (boost::static_pointer_cast<const Region>(other), srcs)
182 , AUDIOREGION_COPY_STATE (other)
183 , _automatable (other->session())
184 , _fade_in (new AutomationList (*other->_fade_in))
185 , _fade_out (new AutomationList (*other->_fade_out))
186 , _envelope (new AutomationList (*other->_envelope))
187 , _fade_in_suspended (0)
188 , _fade_out_suspended (0)
190 /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
192 register_properties ();
194 listen_to_my_curves ();
195 connect_to_analysis_changed ();
196 connect_to_header_position_offset_changed ();
198 assert (_sources.size() == _master_sources.size());
201 AudioRegion::AudioRegion (SourceList& srcs)
202 : Region (srcs)
203 , AUDIOREGION_STATE_DEFAULT
204 , _automatable(srcs[0]->session())
205 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
206 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
207 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
208 , _fade_in_suspended (0)
209 , _fade_out_suspended (0)
211 init ();
213 assert(_type == DataType::AUDIO);
214 assert (_sources.size() == _master_sources.size());
217 AudioRegion::~AudioRegion ()
221 void
222 AudioRegion::post_set ()
224 if (!_sync_marked) {
225 _sync_position = _start;
228 /* return to default fades if the existing ones are too long */
230 if (_left_of_split) {
231 if (_fade_in->back()->when >= _length) {
232 set_default_fade_in ();
234 set_default_fade_out ();
235 _left_of_split = false;
238 if (_right_of_split) {
239 if (_fade_out->back()->when >= _length) {
240 set_default_fade_out ();
243 set_default_fade_in ();
244 _right_of_split = false;
248 void
249 AudioRegion::connect_to_analysis_changed ()
251 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
252 (*i)->AnalysisChanged.connect_same_thread (*this, boost::bind (&AudioRegion::invalidate_transients, this));
256 void
257 AudioRegion::connect_to_header_position_offset_changed ()
259 set<boost::shared_ptr<Source> > unique_srcs;
261 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
263 if (unique_srcs.find (*i) == unique_srcs.end ()) {
264 unique_srcs.insert (*i);
265 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
266 if (afs) {
267 afs->HeaderPositionOffsetChanged.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed, this));
273 void
274 AudioRegion::listen_to_my_curves ()
276 _envelope->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::envelope_changed, this));
277 _fade_in->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_in_changed, this));
278 _fade_out->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_out_changed, this));
281 void
282 AudioRegion::set_envelope_active (bool yn)
284 if (envelope_active() != yn) {
285 _envelope_active = yn;
286 send_change (PropertyChange (Properties::envelope_active));
290 ARDOUR::nframes_t
291 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
293 if (chan_n >= _sources.size()) {
294 return 0;
297 if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
298 return 0;
299 } else {
300 if (_scale_amplitude != 1.0f) {
301 for (nframes_t n = 0; n < npeaks; ++n) {
302 buf[n].max *= _scale_amplitude;
303 buf[n].min *= _scale_amplitude;
306 return cnt;
310 framecnt_t
311 AudioRegion::read (Sample* buf, framepos_t timeline_position, framecnt_t cnt, int channel) const
313 /* raw read, no fades, no gain, nada */
314 return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
317 framecnt_t
318 AudioRegion::read_with_ops (Sample* buf, framepos_t file_position, framecnt_t cnt, int channel, ReadOps rops) const
320 return _read_at (_sources, _length, buf, 0, 0, file_position, cnt, channel, 0, 0, rops);
323 framecnt_t
324 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
325 framepos_t file_position, framecnt_t cnt, uint32_t chan_n,
326 framecnt_t read_frames, framecnt_t skip_frames) const
328 /* regular diskstream/butler read complete with fades etc */
329 return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer,
330 file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
333 framecnt_t
334 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
335 framepos_t position, framecnt_t cnt, uint32_t chan_n) const
337 /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
339 return _read_at (_master_sources, _master_sources.front()->length(_master_sources.front()->timeline_position()),
340 buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0, ReadOps (0));
343 framecnt_t
344 AudioRegion::_read_at (const SourceList& /*srcs*/, framecnt_t limit,
345 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
346 framepos_t position,
347 framecnt_t cnt,
348 uint32_t chan_n,
349 framecnt_t /*read_frames*/,
350 framecnt_t /*skip_frames*/,
351 ReadOps rops) const
353 frameoffset_t internal_offset;
354 frameoffset_t buf_offset;
355 framecnt_t to_read;
356 bool raw = (rops == ReadOpsNone);
358 if (muted() && !raw) {
359 return 0; /* read nothing */
362 /* precondition: caller has verified that we cover the desired section */
364 if (position < _position) {
365 internal_offset = 0;
366 buf_offset = _position - position;
367 cnt -= buf_offset;
368 } else {
369 internal_offset = position - _position;
370 buf_offset = 0;
373 if (internal_offset >= limit) {
374 return 0; /* read nothing */
377 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
378 return 0; /* read nothing */
381 if (opaque() || raw) {
382 /* overwrite whatever is there */
383 mixdown_buffer = buf + buf_offset;
384 } else {
385 mixdown_buffer += buf_offset;
388 if (rops & ReadOpsCount) {
389 _read_data_count = 0;
392 if (chan_n < n_channels()) {
394 boost::shared_ptr<AudioSource> src = audio_source(chan_n);
395 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
396 return 0; /* "read nothing" */
399 if (rops & ReadOpsCount) {
400 _read_data_count += src->read_data_count();
403 } else {
405 /* track is N-channel, this region has less channels; silence the ones
406 we don't have.
409 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
412 if (rops & ReadOpsFades) {
414 /* fade in */
416 if (_fade_in_active && _session.config.get_use_region_fades()) {
418 nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
420 /* see if this read is within the fade in */
422 if (internal_offset < fade_in_length) {
424 nframes_t fi_limit;
426 fi_limit = min (to_read, fade_in_length - internal_offset);
429 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
431 for (nframes_t n = 0; n < fi_limit; ++n) {
432 mixdown_buffer[n] *= gain_buffer[n];
437 /* fade out */
439 if (_fade_out_active && _session.config.get_use_region_fades()) {
441 /* see if some part of this read is within the fade out */
443 /* ................. >| REGION
444 limit
446 { } FADE
447 fade_out_length
449 limit - fade_out_length
450 |--------------|
451 ^internal_offset
452 ^internal_offset + to_read
454 we need the intersection of [internal_offset,internal_offset+to_read] with
455 [limit - fade_out_length, limit]
460 nframes_t fade_out_length = (nframes_t) _fade_out->back()->when;
461 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
462 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
464 if (fade_interval_end > fade_interval_start) {
465 /* (part of the) the fade out is in this buffer */
467 nframes_t fo_limit = fade_interval_end - fade_interval_start;
468 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
469 nframes_t fade_offset = fade_interval_start - internal_offset;
471 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
473 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
474 mixdown_buffer[m] *= gain_buffer[n];
481 /* Regular gain curves and scaling */
483 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
484 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
486 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
487 for (nframes_t n = 0; n < to_read; ++n) {
488 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
490 } else {
491 for (nframes_t n = 0; n < to_read; ++n) {
492 mixdown_buffer[n] *= gain_buffer[n];
495 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
497 // XXX this should be using what in 2.0 would have been:
498 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
500 for (nframes_t n = 0; n < to_read; ++n) {
501 mixdown_buffer[n] *= _scale_amplitude;
505 if (!opaque()) {
507 /* gack. the things we do for users.
510 buf += buf_offset;
512 for (nframes_t n = 0; n < to_read; ++n) {
513 buf[n] += mixdown_buffer[n];
517 return to_read;
520 XMLNode&
521 AudioRegion::state (bool full)
523 XMLNode& node (Region::state (full));
524 XMLNode *child;
525 char buf[64];
526 char buf2[64];
527 LocaleGuard lg (X_("POSIX"));
530 // XXX these should move into Region
532 for (uint32_t n=0; n < _sources.size(); ++n) {
533 snprintf (buf2, sizeof(buf2), "source-%d", n);
534 _sources[n]->id().print (buf, sizeof (buf));
535 node.add_property (buf2, buf);
538 for (uint32_t n=0; n < _master_sources.size(); ++n) {
539 snprintf (buf2, sizeof(buf2), "master-source-%d", n);
540 _master_sources[n]->id().print (buf, sizeof (buf));
541 node.add_property (buf2, buf);
544 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
545 node.add_property ("channels", buf);
547 if (full) {
548 Stateful::add_properties (node);
551 child = node.add_child ("Envelope");
553 if (full) {
554 bool default_env = false;
556 // If there are only two points, the points are in the start of the region and the end of the region
557 // so, if they are both at 1.0f, that means the default region.
559 if (_envelope->size() == 2 &&
560 _envelope->front()->value == 1.0f &&
561 _envelope->back()->value==1.0f) {
562 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
563 default_env = true;
567 if (default_env) {
568 child->add_property ("default", "yes");
569 } else {
570 child->add_child_nocopy (_envelope->get_state ());
573 } else {
574 child->add_property ("default", "yes");
577 if (full && _extra_xml) {
578 node.add_child_copy (*_extra_xml);
581 return node;
585 AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_changed, bool send)
587 const XMLNodeList& nlist = node.children();
588 const XMLProperty *prop;
589 LocaleGuard lg (X_("POSIX"));
590 boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
592 suspend_property_changes ();
594 if (the_playlist) {
595 the_playlist->freeze ();
599 /* this will set all our State members and stuff controlled by the Region.
600 It should NOT send any changed signals - that is our responsibility.
603 Region::_set_state (node, version, what_changed, false);
605 if ((prop = node.property ("scale-gain")) != 0) {
606 float a = atof (prop->value().c_str());
607 if (a != _scale_amplitude) {
608 _scale_amplitude = a;
609 what_changed.add (Properties::scale_amplitude);
613 /* Now find envelope description and other related child items */
615 _envelope->freeze ();
617 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
618 XMLNode *child;
619 XMLProperty *prop;
621 child = (*niter);
623 if (child->name() == "Envelope") {
625 _envelope->clear ();
627 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child, version)) {
628 set_default_envelope ();
631 _envelope->set_max_xval (_length);
632 _envelope->truncate_end (_length);
635 } else if (child->name() == "FadeIn") {
637 _fade_in->clear ();
639 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
640 set_default_fade_in ();
641 } else {
642 XMLNode* grandchild = child->child ("AutomationList");
643 if (grandchild) {
644 _fade_in->set_state (*grandchild, version);
648 if ((prop = child->property ("active")) != 0) {
649 if (string_is_affirmative (prop->value())) {
650 set_fade_in_active (true);
651 } else {
652 set_fade_in_active (false);
656 } else if (child->name() == "FadeOut") {
658 _fade_out->clear ();
660 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
661 set_default_fade_out ();
662 } else {
663 XMLNode* grandchild = child->child ("AutomationList");
664 if (grandchild) {
665 _fade_out->set_state (*grandchild, version);
669 if ((prop = child->property ("active")) != 0) {
670 if (string_is_affirmative (prop->value())) {
671 set_fade_out_active (true);
672 } else {
673 set_fade_out_active (false);
680 _envelope->thaw ();
681 resume_property_changes ();
683 if (send) {
684 send_change (what_changed);
687 if (the_playlist) {
688 the_playlist->thaw ();
691 return 0;
695 AudioRegion::set_state (const XMLNode& node, int version)
697 PropertyChange what_changed;
698 return _set_state (node, version, what_changed, true);
701 void
702 AudioRegion::set_fade_in_shape (FadeShape shape)
704 set_fade_in (shape, (nframes_t) _fade_in->back()->when);
707 void
708 AudioRegion::set_fade_out_shape (FadeShape shape)
710 set_fade_out (shape, (nframes_t) _fade_out->back()->when);
713 void
714 AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
716 _fade_in->freeze ();
717 *_fade_in = *f;
718 _fade_in->thaw ();
720 send_change (PropertyChange (Properties::fade_in));
723 void
724 AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
726 _fade_in->freeze ();
727 _fade_in->clear ();
729 switch (shape) {
730 case Linear:
731 _fade_in->fast_simple_add (0.0, 0.0);
732 _fade_in->fast_simple_add (len, 1.0);
733 break;
735 case Fast:
736 _fade_in->fast_simple_add (0, 0);
737 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
738 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
739 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
740 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
741 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
742 _fade_in->fast_simple_add (len, 1);
743 break;
745 case Slow:
746 _fade_in->fast_simple_add (0, 0);
747 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
748 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
749 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
750 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
751 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
752 _fade_in->fast_simple_add (len * 0.767281, 1);
753 _fade_in->fast_simple_add (len, 1);
754 break;
756 case LogA:
757 _fade_in->fast_simple_add (0, 0);
758 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
759 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
760 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
761 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
762 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
763 _fade_in->fast_simple_add (len, 1);
764 break;
766 case LogB:
767 _fade_in->fast_simple_add (0, 0);
768 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
769 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
770 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
771 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
772 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
773 _fade_in->fast_simple_add (len, 1);
774 break;
777 _fade_in->thaw ();
780 void
781 AudioRegion::set_fade_out (boost::shared_ptr<AutomationList> f)
783 _fade_out->freeze ();
784 *_fade_out = *f;
785 _fade_out->thaw ();
787 send_change (PropertyChange (Properties::fade_in));
790 void
791 AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
793 _fade_out->freeze ();
794 _fade_out->clear ();
796 switch (shape) {
797 case Fast:
798 _fade_out->fast_simple_add (len * 0, 1);
799 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
800 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
801 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
802 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
803 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
804 _fade_out->fast_simple_add (len * 1, 0);
805 break;
807 case LogA:
808 _fade_out->fast_simple_add (len * 0, 1);
809 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
810 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
811 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
812 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
813 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
814 _fade_out->fast_simple_add (len * 1, 0);
815 break;
817 case Slow:
818 _fade_out->fast_simple_add (len * 0, 1);
819 _fade_out->fast_simple_add (len * 0.305556, 1);
820 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
821 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
822 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
823 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
824 _fade_out->fast_simple_add (len * 1, 0);
825 break;
827 case LogB:
828 _fade_out->fast_simple_add (len * 0, 1);
829 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
830 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
831 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
832 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
833 _fade_out->fast_simple_add (len * 1, 0);
834 break;
836 case Linear:
837 _fade_out->fast_simple_add (len * 0, 1);
838 _fade_out->fast_simple_add (len * 1, 0);
839 break;
842 _fade_out->thaw ();
845 void
846 AudioRegion::set_fade_in_length (framecnt_t len)
848 if (len > _length) {
849 len = _length - 1;
852 bool changed = _fade_in->extend_to (len);
854 if (changed) {
855 _default_fade_in = false;
856 send_change (PropertyChange (Properties::fade_in));
860 void
861 AudioRegion::set_fade_out_length (framecnt_t len)
863 if (len > _length) {
864 len = _length - 1;
867 bool changed = _fade_out->extend_to (len);
869 if (changed) {
870 _default_fade_out = false;
871 send_change (PropertyChange (Properties::fade_out));
875 void
876 AudioRegion::set_fade_in_active (bool yn)
878 if (yn == _fade_in_active) {
879 return;
882 _fade_in_active = yn;
883 send_change (PropertyChange (Properties::fade_in_active));
886 void
887 AudioRegion::set_fade_out_active (bool yn)
889 if (yn == _fade_out_active) {
890 return;
892 _fade_out_active = yn;
893 send_change (PropertyChange (Properties::fade_out_active));
896 bool
897 AudioRegion::fade_in_is_default () const
899 return _fade_in->size() == 2 && _fade_in->front()->when == 0 && _fade_in->back()->when == 64;
902 bool
903 AudioRegion::fade_out_is_default () const
905 return _fade_out->size() == 2 && _fade_out->front()->when == 0 && _fade_out->back()->when == 64;
908 void
909 AudioRegion::set_default_fade_in ()
911 _fade_in_suspended = 0;
912 set_fade_in (Linear, 64);
915 void
916 AudioRegion::set_default_fade_out ()
918 _fade_out_suspended = 0;
919 set_fade_out (Linear, 64);
922 void
923 AudioRegion::set_default_fades ()
925 set_default_fade_in ();
926 set_default_fade_out ();
929 void
930 AudioRegion::set_default_envelope ()
932 _envelope->freeze ();
933 _envelope->clear ();
934 _envelope->fast_simple_add (0, 1.0f);
935 _envelope->fast_simple_add (_length, 1.0f);
936 _envelope->thaw ();
939 void
940 AudioRegion::recompute_at_end ()
942 /* our length has changed. recompute a new final point by interpolating
943 based on the the existing curve.
946 _envelope->freeze ();
947 _envelope->truncate_end (_length);
948 _envelope->set_max_xval (_length);
949 _envelope->thaw ();
951 if (_fade_in->back()->when > _length) {
952 _fade_in->extend_to (_length);
953 send_change (PropertyChange (Properties::fade_in));
956 if (_fade_out->back()->when > _length) {
957 _fade_out->extend_to (_length);
958 send_change (PropertyChange (Properties::fade_out));
962 void
963 AudioRegion::recompute_at_start ()
965 /* as above, but the shift was from the front */
967 _envelope->truncate_start (_length);
969 if (_fade_in->back()->when > _length) {
970 _fade_in->extend_to (_length);
971 send_change (PropertyChange (Properties::fade_in));
974 if (_fade_out->back()->when > _length) {
975 _fade_out->extend_to (_length);
976 send_change (PropertyChange (Properties::fade_out));
981 AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr<Region> >& v) const
983 SourceList srcs;
984 string new_name;
985 int n = 0;
987 if (_sources.size() < 2) {
988 return 0;
991 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
992 srcs.clear ();
993 srcs.push_back (*i);
995 new_name = _name;
997 if (_sources.size() == 2) {
998 if (n == 0) {
999 new_name += "-L";
1000 } else {
1001 new_name += "-R";
1003 } else {
1004 new_name += '-';
1005 new_name += ('0' + n + 1);
1008 /* create a copy with just one source. prevent if from being thought of as
1009 "whole file" even if it covers the entire source file(s).
1012 PropertyList plist;
1014 plist.add (Properties::start, _start.val());
1015 plist.add (Properties::length, _length.val());
1016 plist.add (Properties::name, new_name);
1017 plist.add (Properties::layer, _layer.val());
1019 v.push_back(RegionFactory::create (srcs, plist));
1020 v.back()->set_whole_file (false);
1022 ++n;
1025 return 0;
1028 framecnt_t
1029 AudioRegion::read_raw_internal (Sample* buf, framepos_t pos, framecnt_t cnt, int channel) const
1031 return audio_source()->read (buf, pos, cnt, channel);
1035 AudioRegion::exportme (Session& /*session*/, ARDOUR::ExportSpecification& /*spec*/)
1037 // TODO EXPORT
1038 // const nframes_t blocksize = 4096;
1039 // nframes_t to_read;
1040 // int status = -1;
1042 // spec.channels = _sources.size();
1044 // if (spec.prepare (blocksize, session.frame_rate())) {
1045 // goto out;
1046 // }
1048 // spec.pos = 0;
1049 // spec.total_frames = _length;
1051 // while (spec.pos < _length && !spec.stop) {
1054 // /* step 1: interleave */
1056 // to_read = min (_length - spec.pos, blocksize);
1058 // if (spec.channels == 1) {
1060 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1061 // goto out;
1062 // }
1064 // } else {
1066 // Sample buf[blocksize];
1068 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1070 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1071 // goto out;
1072 // }
1074 // for (nframes_t x = 0; x < to_read; ++x) {
1075 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1076 // }
1077 // }
1078 // }
1080 // if (spec.process (to_read)) {
1081 // goto out;
1082 // }
1084 // spec.pos += to_read;
1085 // spec.progress = (double) spec.pos /_length;
1087 // }
1089 // status = 0;
1091 // out:
1092 // spec.running = false;
1093 // spec.status = status;
1094 // spec.clear();
1096 // return status;
1097 return 0;
1100 void
1101 AudioRegion::set_scale_amplitude (gain_t g)
1103 boost::shared_ptr<Playlist> pl (playlist());
1105 _scale_amplitude = g;
1107 /* tell the diskstream we're in */
1109 if (pl) {
1110 pl->ContentsChanged();
1113 /* tell everybody else */
1115 send_change (PropertyChange (Properties::scale_amplitude));
1118 void
1119 AudioRegion::normalize_to (float target_dB)
1121 const framecnt_t blocksize = 64 * 1024;
1122 Sample buf[blocksize];
1123 framepos_t fpos;
1124 framepos_t fend;
1125 framecnt_t to_read;
1126 double maxamp = 0;
1127 gain_t target = dB_to_coefficient (target_dB);
1129 if (target == 1.0f) {
1130 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1131 that we may have clipped.
1133 target -= FLT_EPSILON;
1136 fpos = _start;
1137 fend = _start + _length;
1139 /* first pass: find max amplitude */
1141 while (fpos < fend) {
1143 uint32_t n;
1145 to_read = min (fend - fpos, blocksize);
1147 for (n = 0; n < n_channels(); ++n) {
1149 /* read it in */
1151 if (read_raw_internal (buf, fpos, to_read, 0) != to_read) {
1152 return;
1155 maxamp = compute_peak (buf, to_read, maxamp);
1158 fpos += to_read;
1161 if (maxamp == 0.0f) {
1162 /* don't even try */
1163 return;
1166 if (maxamp == target) {
1167 /* we can't do anything useful */
1168 return;
1171 /* compute scale factor */
1173 _scale_amplitude = target/maxamp;
1175 /* tell the diskstream we're in */
1177 boost::shared_ptr<Playlist> pl (playlist());
1179 if (pl) {
1180 pl->ContentsChanged();
1183 /* tell everybody else */
1185 send_change (PropertyChange (Properties::scale_amplitude));
1188 void
1189 AudioRegion::fade_in_changed ()
1191 send_change (PropertyChange (Properties::fade_in));
1194 void
1195 AudioRegion::fade_out_changed ()
1197 send_change (PropertyChange (Properties::fade_out));
1200 void
1201 AudioRegion::envelope_changed ()
1203 send_change (PropertyChange (Properties::envelope));
1206 void
1207 AudioRegion::suspend_fade_in ()
1209 if (++_fade_in_suspended == 1) {
1210 if (fade_in_is_default()) {
1211 set_fade_in_active (false);
1216 void
1217 AudioRegion::resume_fade_in ()
1219 if (--_fade_in_suspended == 0 && _fade_in_suspended) {
1220 set_fade_in_active (true);
1224 void
1225 AudioRegion::suspend_fade_out ()
1227 if (++_fade_out_suspended == 1) {
1228 if (fade_out_is_default()) {
1229 set_fade_out_active (false);
1234 void
1235 AudioRegion::resume_fade_out ()
1237 if (--_fade_out_suspended == 0 &&_fade_out_suspended) {
1238 set_fade_out_active (true);
1242 bool
1243 AudioRegion::speed_mismatch (float sr) const
1245 if (_sources.empty()) {
1246 /* impossible, but ... */
1247 return false;
1250 float fsr = audio_source()->sample_rate();
1252 return fsr != sr;
1255 void
1256 AudioRegion::source_offset_changed ()
1258 /* XXX this fixes a crash that should not occur. It does occur
1259 becauses regions are not being deleted when a session
1260 is unloaded. That bug must be fixed.
1263 if (_sources.empty()) {
1264 return;
1267 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1269 if (afs && afs->destructive()) {
1270 // set_start (source()->natural_position(), this);
1271 set_position (source()->natural_position(), this);
1275 boost::shared_ptr<AudioSource>
1276 AudioRegion::audio_source (uint32_t n) const
1278 // Guaranteed to succeed (use a static cast for speed?)
1279 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1283 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1285 boost::shared_ptr<Playlist> pl = playlist();
1287 if (!pl) {
1288 return -1;
1291 if (_valid_transients && !force_new) {
1292 results = _transients;
1293 return 0;
1296 SourceList::iterator s;
1298 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1299 if (!(*s)->has_been_analysed()) {
1300 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1301 break;
1305 if (s == _sources.end()) {
1306 /* all sources are analyzed, merge data from each one */
1308 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1310 /* find the set of transients within the bounds of this region */
1312 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1313 (*s)->transients.end(),
1314 _start);
1316 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1317 (*s)->transients.end(),
1318 _start + _length);
1320 /* and add them */
1322 results.insert (results.end(), low, high);
1325 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1327 /* translate all transients to current position */
1329 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1330 (*x) -= _start;
1331 (*x) += _position;
1334 _transients = results;
1335 _valid_transients = true;
1337 return 0;
1340 /* no existing/complete transient info */
1342 static bool analyse_dialog_shown = false; /* global per instance of Ardour */
1344 if (!Config->get_auto_analyse_audio()) {
1345 if (!analyse_dialog_shown) {
1346 pl->session().Dialog (_("\
1347 You have requested an operation that requires audio analysis.\n\n \
1348 You currently have \"auto-analyse-audio\" disabled, which means\n\
1349 that transient data must be generated every time it is required.\n\n\
1350 If you are doing work that will require transient data on a\n\
1351 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1352 +then quit ardour and restart.\n\n\
1353 +This dialog will not display again. But you may notice a slight delay\n\
1354 +in this and future transient-detection operations.\n\
1355 +"));
1356 analyse_dialog_shown = true;
1360 TransientDetector t (pl->session().frame_rate());
1361 bool existing_results = !results.empty();
1363 _transients.clear ();
1364 _valid_transients = false;
1366 for (uint32_t i = 0; i < n_channels(); ++i) {
1368 AnalysisFeatureList these_results;
1370 t.reset ();
1372 if (t.run ("", this, i, these_results)) {
1373 return -1;
1376 /* translate all transients to give absolute position */
1378 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1379 (*i) += _position;
1382 /* merge */
1384 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1387 if (!results.empty()) {
1388 if (existing_results) {
1390 /* merge our transients into the existing ones, then clean up
1391 those.
1394 results.insert (results.end(), _transients.begin(), _transients.end());
1395 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1398 /* make sure ours are clean too */
1400 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1402 } else {
1404 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1405 results = _transients;
1408 _valid_transients = true;
1410 return 0;
1413 /** Find areas of `silence' within a region.
1415 * @param threshold Threshold below which signal is considered silence (as a sample value)
1416 * @param min_length Minimum length of silent period to be reported.
1417 * @return Silent periods; first of pair is the offset within the region, second is the length of the period
1420 std::list<std::pair<frameoffset_t, framecnt_t> >
1421 AudioRegion::find_silence (Sample threshold, framecnt_t min_length, InterThreadInfo& itt) const
1423 framecnt_t const block_size = 64 * 1024;
1424 Sample loudest[block_size];
1425 Sample buf[block_size];
1427 framepos_t pos = _start;
1428 framepos_t const end = _start + _length - 1;
1430 std::list<std::pair<frameoffset_t, framecnt_t> > silent_periods;
1432 bool in_silence = false;
1433 frameoffset_t silence_start = 0;
1434 bool silence;
1436 while (pos < end && !itt.cancel) {
1438 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1439 memset (loudest, 0, sizeof (Sample) * block_size);
1440 for (uint32_t n = 0; n < n_channels(); ++n) {
1442 read_raw_internal (buf, pos, block_size, n);
1443 for (framecnt_t i = 0; i < block_size; ++i) {
1444 loudest[i] = max (loudest[i], abs (buf[i]));
1448 /* now look for silence */
1449 for (framecnt_t i = 0; i < block_size; ++i) {
1450 silence = abs (loudest[i]) < threshold;
1451 if (silence && !in_silence) {
1452 /* non-silence to silence */
1453 in_silence = true;
1454 silence_start = pos + i;
1455 } else if (!silence && in_silence) {
1456 /* silence to non-silence */
1457 in_silence = false;
1458 if (pos + i - 1 - silence_start >= min_length) {
1459 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1464 pos += block_size;
1465 itt.progress = (end-pos)/(double)_length;
1468 if (in_silence && end - 1 - silence_start >= min_length) {
1469 /* last block was silent, so finish off the last period */
1470 silent_periods.push_back (std::make_pair (silence_start, end));
1473 itt.done = true;
1475 return silent_periods;
1480 extern "C" {
1482 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)
1484 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (framecnt_t) npeaks, (framepos_t) start, (framecnt_t) cnt, n_chan,samples_per_unit);
1487 uint32_t region_length_from_c (void *arg)
1490 return ((AudioRegion *) arg)->length();
1493 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1495 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;
1498 } /* extern "C" */