Fix angle bracket project-local include paths.
[ardour2.git] / libs / ardour / audioregion.cc
bloba5c52ce671315c6c877c35f16099d6a7f9ce27c7
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>
27 #include <sigc++/bind.h>
28 #include <sigc++/class_slot.h>
30 #include <glibmm/thread.h>
32 #include "pbd/basename.h"
33 #include "pbd/xml++.h"
34 #include "pbd/stacktrace.h"
35 #include "pbd/enumwriter.h"
36 #include "pbd/convert.h"
38 #include "evoral/Curve.hpp"
40 #include "ardour/audioregion.h"
41 #include "ardour/session.h"
42 #include "ardour/gain.h"
43 #include "ardour/dB.h"
44 #include "ardour/playlist.h"
45 #include "ardour/audiofilesource.h"
46 #include "ardour/region_factory.h"
47 #include "ardour/runtime_functions.h"
48 #include "ardour/transient_detector.h"
50 #include "i18n.h"
51 #include <locale.h>
53 using namespace std;
54 using namespace ARDOUR;
55 using namespace PBD;
57 /* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
59 Change AudioRegion::FadeInChanged = ARDOUR::new_change();
60 Change AudioRegion::FadeOutChanged = ARDOUR::new_change();
61 Change AudioRegion::FadeInActiveChanged = ARDOUR::new_change();
62 Change AudioRegion::FadeOutActiveChanged = ARDOUR::new_change();
63 Change AudioRegion::EnvelopeActiveChanged = ARDOUR::new_change();
64 Change AudioRegion::ScaleAmplitudeChanged = ARDOUR::new_change();
65 Change AudioRegion::EnvelopeChanged = ARDOUR::new_change();
67 void
68 AudioRegion::init ()
70 _scale_amplitude = 1.0;
72 set_default_fades ();
73 set_default_envelope ();
75 listen_to_my_curves ();
76 connect_to_analysis_changed ();
79 /** Constructor for use by derived types only */
80 AudioRegion::AudioRegion (Session& s, nframes_t start, nframes_t length, string name)
81 : Region (s, start, length, name, DataType::AUDIO)
82 , _automatable(s)
83 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
84 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
85 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
87 init ();
88 assert (_sources.size() == _master_sources.size());
91 /** Basic AudioRegion constructor (one channel) */
92 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length)
93 : Region (src, start, length, PBD::basename_nosuffix(src->name()), DataType::AUDIO, 0, Region::Flag(Region::DefaultFlags|Region::External))
94 , _automatable(src->session())
95 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
96 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
97 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
99 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
100 if (afs) {
101 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
104 init ();
105 assert (_sources.size() == _master_sources.size());
108 /* Basic AudioRegion constructor (one channel) */
109 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
110 : Region (src, start, length, name, DataType::AUDIO, layer, flags)
111 , _automatable(src->session())
112 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
113 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
114 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
116 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
117 if (afs) {
118 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
121 init ();
122 assert (_sources.size() == _master_sources.size());
125 /** Basic AudioRegion constructor (many channels) */
126 AudioRegion::AudioRegion (const SourceList& srcs, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
127 : Region (srcs, start, length, name, DataType::AUDIO, layer, flags)
128 , _automatable(srcs[0]->session())
129 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
130 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
131 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
133 init ();
134 connect_to_analysis_changed ();
135 assert (_sources.size() == _master_sources.size());
138 /** Create a new AudioRegion, that is part of an existing one */
139 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags)
140 : Region (other, offset, length, name, layer, flags)
141 , _automatable(other->session())
142 , _fade_in (new AutomationList(*other->_fade_in))
143 , _fade_out (new AutomationList(*other->_fade_out))
144 , _envelope (new AutomationList(*other->_envelope, offset, offset + length))
146 connect_to_header_position_offset_changed ();
148 /* return to default fades if the existing ones are too long */
150 if (_flags & LeftOfSplit) {
151 if (_fade_in->back()->when >= _length) {
152 set_default_fade_in ();
153 } else {
154 _fade_in_disabled = other->_fade_in_disabled;
156 set_default_fade_out ();
157 _flags = Flag (_flags & ~Region::LeftOfSplit);
160 if (_flags & RightOfSplit) {
161 if (_fade_out->back()->when >= _length) {
162 set_default_fade_out ();
163 } else {
164 _fade_out_disabled = other->_fade_out_disabled;
166 set_default_fade_in ();
167 _flags = Flag (_flags & ~Region::RightOfSplit);
170 _scale_amplitude = other->_scale_amplitude;
172 assert(_type == DataType::AUDIO);
174 listen_to_my_curves ();
175 connect_to_analysis_changed ();
177 assert (_sources.size() == _master_sources.size());
180 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
181 : Region (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))
187 assert(_type == DataType::AUDIO);
188 _scale_amplitude = other->_scale_amplitude;
190 listen_to_my_curves ();
191 connect_to_analysis_changed ();
193 assert (_sources.size() == _master_sources.size());
196 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& /*srcs*/,
197 nframes_t length, const string& name, layer_t layer, Flag flags)
198 : Region (other, length, name, layer, flags)
199 , _automatable (other->session())
200 , _fade_in (new AutomationList (*other->_fade_in))
201 , _fade_out (new AutomationList (*other->_fade_out))
202 , _envelope (new AutomationList (*other->_envelope))
204 /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
206 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
208 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> ((*i));
209 if (afs) {
210 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
214 _scale_amplitude = other->_scale_amplitude;
216 _fade_in_disabled = 0;
217 _fade_out_disabled = 0;
219 listen_to_my_curves ();
220 connect_to_analysis_changed ();
222 assert (_sources.size() == _master_sources.size());
225 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node)
226 : Region (src, node)
227 , _automatable(src->session())
228 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
229 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
230 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
232 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
233 if (afs) {
234 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
237 init ();
239 if (set_state (node, Stateful::loading_state_version)) {
240 throw failed_constructor();
243 assert(_type == DataType::AUDIO);
244 connect_to_analysis_changed ();
246 assert (_sources.size() == _master_sources.size());
249 AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
250 : Region (srcs, node)
251 , _automatable(srcs[0]->session())
252 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
253 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
254 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
256 init ();
258 if (set_state (node, Stateful::loading_state_version)) {
259 throw failed_constructor();
262 assert(_type == DataType::AUDIO);
263 connect_to_analysis_changed ();
264 assert (_sources.size() == _master_sources.size());
267 AudioRegion::~AudioRegion ()
271 void
272 AudioRegion::connect_to_analysis_changed ()
274 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
275 (*i)->AnalysisChanged.connect (mem_fun (*this, &AudioRegion::invalidate_transients));
279 void
280 AudioRegion::connect_to_header_position_offset_changed ()
282 set<boost::shared_ptr<Source> > unique_srcs;
284 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
286 if (unique_srcs.find (*i) == unique_srcs.end ()) {
287 unique_srcs.insert (*i);
288 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
289 if (afs) {
290 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
296 void
297 AudioRegion::listen_to_my_curves ()
299 _envelope->StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
300 _fade_in->StateChanged.connect (mem_fun (*this, &AudioRegion::fade_in_changed));
301 _fade_out->StateChanged.connect (mem_fun (*this, &AudioRegion::fade_out_changed));
304 void
305 AudioRegion::set_envelope_active (bool yn)
307 if (envelope_active() != yn) {
308 char buf[64];
309 if (yn) {
310 snprintf (buf, sizeof (buf), "envelope active");
311 _flags = Flag (_flags|EnvelopeActive);
312 } else {
313 snprintf (buf, sizeof (buf), "envelope off");
314 _flags = Flag (_flags & ~EnvelopeActive);
316 send_change (EnvelopeActiveChanged);
320 ARDOUR::nframes_t
321 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
323 if (chan_n >= _sources.size()) {
324 return 0;
327 if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
328 return 0;
329 } else {
330 if (_scale_amplitude != 1.0) {
331 for (nframes_t n = 0; n < npeaks; ++n) {
332 buf[n].max *= _scale_amplitude;
333 buf[n].min *= _scale_amplitude;
336 return cnt;
340 nframes_t
341 AudioRegion::read (Sample* buf, sframes_t timeline_position, nframes_t cnt, int channel) const
343 /* raw read, no fades, no gain, nada */
344 return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
347 nframes_t
348 AudioRegion::read_with_ops (Sample* buf, sframes_t file_position, nframes_t cnt, int channel, ReadOps rops) const
350 return _read_at (_sources, _length, buf, 0, 0, file_position, cnt, channel, 0, 0, rops);
353 nframes_t
354 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
355 sframes_t file_position, nframes_t cnt, uint32_t chan_n,
356 nframes_t read_frames, nframes_t skip_frames) const
358 /* regular diskstream/butler read complete with fades etc */
359 return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer,
360 file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
363 nframes_t
364 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
365 sframes_t position, nframes_t cnt, uint32_t chan_n) const
367 /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
369 return _read_at (_master_sources, _master_sources.front()->length(_master_sources.front()->timeline_position()),
370 buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0, ReadOps (0));
373 nframes_t
374 AudioRegion::_read_at (const SourceList& /*srcs*/, nframes_t limit,
375 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
376 sframes_t position, nframes_t cnt,
377 uint32_t chan_n,
378 nframes_t /*read_frames*/,
379 nframes_t /*skip_frames*/,
380 ReadOps rops) const
382 nframes_t internal_offset;
383 nframes_t buf_offset;
384 nframes_t to_read;
385 bool raw = (rops == ReadOpsNone);
387 if (muted() && !raw) {
388 return 0; /* read nothing */
391 /* precondition: caller has verified that we cover the desired section */
393 if (position < _position) {
394 internal_offset = 0;
395 buf_offset = _position - position;
396 cnt -= buf_offset;
397 } else {
398 internal_offset = position - _position;
399 buf_offset = 0;
402 if (internal_offset >= limit) {
403 return 0; /* read nothing */
406 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
407 return 0; /* read nothing */
410 if (opaque() || raw) {
411 /* overwrite whatever is there */
412 mixdown_buffer = buf + buf_offset;
413 } else {
414 mixdown_buffer += buf_offset;
417 if (rops & ReadOpsCount) {
418 _read_data_count = 0;
421 if (chan_n < n_channels()) {
423 boost::shared_ptr<AudioSource> src = audio_source(chan_n);
424 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
425 return 0; /* "read nothing" */
428 if (rops & ReadOpsCount) {
429 _read_data_count += src->read_data_count();
432 } else {
434 /* track is N-channel, this region has less channels; silence the ones
435 we don't have.
438 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
441 if (rops & ReadOpsFades) {
443 /* fade in */
445 if ((_flags & FadeIn) && _session.config.get_use_region_fades()) {
447 nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
449 /* see if this read is within the fade in */
451 if (internal_offset < fade_in_length) {
453 nframes_t fi_limit;
455 fi_limit = min (to_read, fade_in_length - internal_offset);
458 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
460 for (nframes_t n = 0; n < fi_limit; ++n) {
461 mixdown_buffer[n] *= gain_buffer[n];
466 /* fade out */
468 if ((_flags & FadeOut) && _session.config.get_use_region_fades()) {
470 /* see if some part of this read is within the fade out */
472 /* ................. >| REGION
473 limit
475 { } FADE
476 fade_out_length
478 limit - fade_out_length
479 |--------------|
480 ^internal_offset
481 ^internal_offset + to_read
483 we need the intersection of [internal_offset,internal_offset+to_read] with
484 [limit - fade_out_length, limit]
489 nframes_t fade_out_length = (nframes_t) _fade_out->back()->when;
490 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
491 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
493 if (fade_interval_end > fade_interval_start) {
494 /* (part of the) the fade out is in this buffer */
496 nframes_t fo_limit = fade_interval_end - fade_interval_start;
497 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
498 nframes_t fade_offset = fade_interval_start - internal_offset;
500 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
502 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
503 mixdown_buffer[m] *= gain_buffer[n];
510 /* Regular gain curves and scaling */
512 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
513 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
515 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
516 for (nframes_t n = 0; n < to_read; ++n) {
517 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
519 } else {
520 for (nframes_t n = 0; n < to_read; ++n) {
521 mixdown_buffer[n] *= gain_buffer[n];
524 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
526 // XXX this should be using what in 2.0 would have been:
527 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
529 for (nframes_t n = 0; n < to_read; ++n) {
530 mixdown_buffer[n] *= _scale_amplitude;
534 if (!opaque()) {
536 /* gack. the things we do for users.
539 buf += buf_offset;
541 for (nframes_t n = 0; n < to_read; ++n) {
542 buf[n] += mixdown_buffer[n];
546 return to_read;
549 XMLNode&
550 AudioRegion::state (bool full)
552 XMLNode& node (Region::state (full));
553 XMLNode *child;
554 char buf[64];
555 char buf2[64];
556 LocaleGuard lg (X_("POSIX"));
558 node.add_property ("flags", enum_2_string (_flags));
560 snprintf (buf, sizeof(buf), "%.12g", _scale_amplitude);
561 node.add_property ("scale-gain", buf);
563 // XXX these should move into Region
565 for (uint32_t n=0; n < _sources.size(); ++n) {
566 snprintf (buf2, sizeof(buf2), "source-%d", n);
567 _sources[n]->id().print (buf, sizeof (buf));
568 node.add_property (buf2, buf);
571 for (uint32_t n=0; n < _master_sources.size(); ++n) {
572 snprintf (buf2, sizeof(buf2), "master-source-%d", n);
573 _master_sources[n]->id().print (buf, sizeof (buf));
574 node.add_property (buf2, buf);
577 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
578 node.add_property ("channels", buf);
580 if (full) {
582 child = node.add_child (X_("FadeIn"));
584 if ((_flags & DefaultFadeIn)) {
585 child->add_property (X_("default"), X_("yes"));
586 } else {
587 child->add_child_nocopy (_fade_in->get_state ());
590 child->add_property (X_("active"), _fade_in_disabled ? X_("no") : X_("yes"));
592 child = node.add_child (X_("FadeOut"));
594 if ((_flags & DefaultFadeOut)) {
595 child->add_property (X_("default"), X_("yes"));
596 } else {
597 child->add_child_nocopy (_fade_out->get_state ());
600 child->add_property (X_("active"), _fade_out_disabled ? X_("no") : X_("yes"));
603 child = node.add_child ("Envelope");
605 if (full) {
606 bool default_env = false;
608 // If there are only two points, the points are in the start of the region and the end of the region
609 // so, if they are both at 1.0f, that means the default region.
611 if (_envelope->size() == 2 &&
612 _envelope->front()->value == 1.0f &&
613 _envelope->back()->value==1.0f) {
614 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
615 default_env = true;
619 if (default_env) {
620 child->add_property ("default", "yes");
621 } else {
622 child->add_child_nocopy (_envelope->get_state ());
625 } else {
626 child->add_property ("default", "yes");
629 if (full && _extra_xml) {
630 node.add_child_copy (*_extra_xml);
633 return node;
637 AudioRegion::set_live_state (const XMLNode& node, int version, Change& what_changed, bool send)
639 const XMLNodeList& nlist = node.children();
640 const XMLProperty *prop;
641 LocaleGuard lg (X_("POSIX"));
643 Region::set_live_state (node, version, what_changed, false);
645 uint32_t old_flags = _flags;
647 if ((prop = node.property ("flags")) != 0) {
648 _flags = Flag (string_2_enum (prop->value(), _flags));
650 //_flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16));
652 _flags = Flag (_flags & ~Region::LeftOfSplit);
653 _flags = Flag (_flags & ~Region::RightOfSplit);
656 /* leave this flag setting in place, no matter what */
658 if ((old_flags & DoNotSendPropertyChanges)) {
659 _flags = Flag (_flags | DoNotSendPropertyChanges);
662 /* find out if any flags changed that we signal about */
664 if ((old_flags ^ _flags) & Muted) {
665 what_changed = Change (what_changed|MuteChanged);
667 if ((old_flags ^ _flags) & Opaque) {
668 what_changed = Change (what_changed|OpacityChanged);
670 if ((old_flags ^ _flags) & Locked) {
671 what_changed = Change (what_changed|LockChanged);
674 if ((prop = node.property ("scale-gain")) != 0) {
675 _scale_amplitude = atof (prop->value().c_str());
676 what_changed = Change (what_changed|ScaleAmplitudeChanged);
677 } else {
678 _scale_amplitude = 1.0;
681 /* Now find envelope description and other misc child items */
683 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
685 XMLNode *child;
686 XMLProperty *prop;
688 child = (*niter);
690 if (child->name() == "Envelope") {
692 _envelope->clear ();
694 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child, version)) {
695 set_default_envelope ();
698 _envelope->set_max_xval (_length);
699 _envelope->truncate_end (_length);
701 } else if (child->name() == "FadeIn") {
703 _fade_in->clear ();
705 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
706 set_default_fade_in ();
707 } else {
708 XMLNode* grandchild = child->child ("AutomationList");
709 if (grandchild) {
710 _fade_in->set_state (*grandchild, version);
714 if ((prop = child->property ("active")) != 0) {
715 if (string_is_affirmative (prop->value())) {
716 set_fade_in_active (true);
717 } else {
718 set_fade_in_active (true);
722 } else if (child->name() == "FadeOut") {
724 _fade_out->clear ();
726 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
727 set_default_fade_out ();
728 } else {
729 XMLNode* grandchild = child->child ("AutomationList");
730 if (grandchild) {
731 _fade_out->set_state (*grandchild, version);
735 if ((prop = child->property ("active")) != 0) {
736 if (string_is_affirmative (prop->value())) {
737 set_fade_out_active (true);
738 } else {
739 set_fade_out_active (false);
746 if (send) {
747 send_change (what_changed);
750 return 0;
754 AudioRegion::set_state (const XMLNode& node, int version)
756 /* Region::set_state() calls the virtual set_live_state(),
757 which will get us back to AudioRegion::set_live_state()
758 to handle the relevant stuff.
761 return Region::set_state (node, version);
764 void
765 AudioRegion::set_fade_in_shape (FadeShape shape)
767 set_fade_in (shape, (nframes_t) _fade_in->back()->when);
770 void
771 AudioRegion::set_fade_out_shape (FadeShape shape)
773 set_fade_out (shape, (nframes_t) _fade_out->back()->when);
776 void
777 AudioRegion::set_fade_in (FadeShape shape, nframes_t len)
779 _fade_in->freeze ();
780 _fade_in->clear ();
782 switch (shape) {
783 case Linear:
784 _fade_in->fast_simple_add (0.0, 0.0);
785 _fade_in->fast_simple_add (len, 1.0);
786 break;
788 case Fast:
789 _fade_in->fast_simple_add (0, 0);
790 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
791 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
792 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
793 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
794 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
795 _fade_in->fast_simple_add (len, 1);
796 break;
798 case Slow:
799 _fade_in->fast_simple_add (0, 0);
800 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
801 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
802 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
803 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
804 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
805 _fade_in->fast_simple_add (len * 0.767281, 1);
806 _fade_in->fast_simple_add (len, 1);
807 break;
809 case LogA:
810 _fade_in->fast_simple_add (0, 0);
811 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
812 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
813 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
814 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
815 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
816 _fade_in->fast_simple_add (len, 1);
817 break;
819 case LogB:
820 _fade_in->fast_simple_add (0, 0);
821 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
822 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
823 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
824 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
825 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
826 _fade_in->fast_simple_add (len, 1);
827 break;
830 _fade_in->thaw ();
831 _fade_in_shape = shape;
833 send_change (FadeInChanged);
836 void
837 AudioRegion::set_fade_out (FadeShape shape, nframes_t len)
839 _fade_out->freeze ();
840 _fade_out->clear ();
842 switch (shape) {
843 case Fast:
844 _fade_out->fast_simple_add (len * 0, 1);
845 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
846 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
847 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
848 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
849 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
850 _fade_out->fast_simple_add (len * 1, 0);
851 break;
853 case LogA:
854 _fade_out->fast_simple_add (len * 0, 1);
855 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
856 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
857 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
858 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
859 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
860 _fade_out->fast_simple_add (len * 1, 0);
861 break;
863 case Slow:
864 _fade_out->fast_simple_add (len * 0, 1);
865 _fade_out->fast_simple_add (len * 0.305556, 1);
866 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
867 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
868 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
869 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
870 _fade_out->fast_simple_add (len * 1, 0);
871 break;
873 case LogB:
874 _fade_out->fast_simple_add (len * 0, 1);
875 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
876 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
877 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
878 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
879 _fade_out->fast_simple_add (len * 1, 0);
880 break;
882 case Linear:
883 _fade_out->fast_simple_add (len * 0, 1);
884 _fade_out->fast_simple_add (len * 1, 0);
885 break;
888 _fade_out->thaw ();
889 _fade_out_shape = shape;
891 send_change (FadeOutChanged);
894 void
895 AudioRegion::set_fade_in_length (nframes_t len)
897 if (len > _length) {
898 len = _length - 1;
901 bool changed = _fade_in->extend_to (len);
903 if (changed) {
904 _flags = Flag (_flags & ~DefaultFadeIn);
905 send_change (FadeInChanged);
909 void
910 AudioRegion::set_fade_out_length (nframes_t len)
912 if (len > _length) {
913 len = _length - 1;
916 bool changed = _fade_out->extend_to (len);
918 if (changed) {
919 _flags = Flag (_flags & ~DefaultFadeOut);
920 send_change (FadeOutChanged);
924 void
925 AudioRegion::set_fade_in_active (bool yn)
927 if (yn == (_flags & FadeIn)) {
928 return;
930 if (yn) {
931 _flags = Flag (_flags|FadeIn);
932 } else {
933 _flags = Flag (_flags & ~FadeIn);
936 send_change (FadeInActiveChanged);
939 void
940 AudioRegion::set_fade_out_active (bool yn)
942 if (yn == (_flags & FadeOut)) {
943 return;
945 if (yn) {
946 _flags = Flag (_flags | FadeOut);
947 } else {
948 _flags = Flag (_flags & ~FadeOut);
951 send_change (FadeOutActiveChanged);
954 bool
955 AudioRegion::fade_in_is_default () const
957 return _fade_in_shape == Linear && _fade_in->back()->when == 64;
960 bool
961 AudioRegion::fade_out_is_default () const
963 return _fade_out_shape == Linear && _fade_out->back()->when == 64;
966 void
967 AudioRegion::set_default_fade_in ()
969 _fade_in_disabled = 0;
970 set_fade_in (Linear, 64);
973 void
974 AudioRegion::set_default_fade_out ()
976 _fade_out_disabled = 0;
977 set_fade_out (Linear, 64);
980 void
981 AudioRegion::set_default_fades ()
983 set_default_fade_in ();
984 set_default_fade_out ();
987 void
988 AudioRegion::set_default_envelope ()
990 _envelope->freeze ();
991 _envelope->clear ();
992 _envelope->fast_simple_add (0, 1.0f);
993 _envelope->fast_simple_add (_length, 1.0f);
994 _envelope->thaw ();
997 void
998 AudioRegion::recompute_at_end ()
1000 /* our length has changed. recompute a new final point by interpolating
1001 based on the the existing curve.
1004 _envelope->freeze ();
1005 _envelope->truncate_end (_length);
1006 _envelope->set_max_xval (_length);
1007 _envelope->thaw ();
1009 if (_fade_in->back()->when > _length) {
1010 _fade_in->extend_to (_length);
1011 send_change (FadeInChanged);
1014 if (_fade_out->back()->when > _length) {
1015 _fade_out->extend_to (_length);
1016 send_change (FadeOutChanged);
1020 void
1021 AudioRegion::recompute_at_start ()
1023 /* as above, but the shift was from the front */
1025 _envelope->truncate_start (_length);
1027 if (_fade_in->back()->when > _length) {
1028 _fade_in->extend_to (_length);
1029 send_change (FadeInChanged);
1032 if (_fade_out->back()->when > _length) {
1033 _fade_out->extend_to (_length);
1034 send_change (FadeOutChanged);
1039 AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr<Region> >& v) const
1041 SourceList srcs;
1042 string new_name;
1043 int n = 0;
1045 if (_sources.size() < 2) {
1046 return 0;
1049 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
1050 srcs.clear ();
1051 srcs.push_back (*i);
1053 new_name = _name;
1055 if (_sources.size() == 2) {
1056 if (n == 0) {
1057 new_name += "-L";
1058 } else {
1059 new_name += "-R";
1061 } else {
1062 new_name += '-';
1063 new_name += ('0' + n + 1);
1066 /* create a copy with just one source. prevent if from being thought of as
1067 "whole file" even if it covers the entire source file(s).
1070 Flag f = Flag (_flags & ~WholeFile);
1072 v.push_back(RegionFactory::create (srcs, _start, _length, new_name, _layer, f));
1074 ++n;
1077 return 0;
1080 nframes_t
1081 AudioRegion::read_raw_internal (Sample* buf, sframes_t pos, nframes_t cnt, int channel) const
1083 return audio_source()->read (buf, pos, cnt, channel);
1087 AudioRegion::exportme (Session& /*session*/, ARDOUR::ExportSpecification& /*spec*/)
1089 // TODO EXPORT
1090 // const nframes_t blocksize = 4096;
1091 // nframes_t to_read;
1092 // int status = -1;
1094 // spec.channels = _sources.size();
1096 // if (spec.prepare (blocksize, session.frame_rate())) {
1097 // goto out;
1098 // }
1100 // spec.pos = 0;
1101 // spec.total_frames = _length;
1103 // while (spec.pos < _length && !spec.stop) {
1106 // /* step 1: interleave */
1108 // to_read = min (_length - spec.pos, blocksize);
1110 // if (spec.channels == 1) {
1112 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1113 // goto out;
1114 // }
1116 // } else {
1118 // Sample buf[blocksize];
1120 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1122 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1123 // goto out;
1124 // }
1126 // for (nframes_t x = 0; x < to_read; ++x) {
1127 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1128 // }
1129 // }
1130 // }
1132 // if (spec.process (to_read)) {
1133 // goto out;
1134 // }
1136 // spec.pos += to_read;
1137 // spec.progress = (double) spec.pos /_length;
1139 // }
1141 // status = 0;
1143 // out:
1144 // spec.running = false;
1145 // spec.status = status;
1146 // spec.clear();
1148 // return status;
1149 return 0;
1152 void
1153 AudioRegion::set_scale_amplitude (gain_t g)
1155 boost::shared_ptr<Playlist> pl (playlist());
1157 _scale_amplitude = g;
1159 /* tell the diskstream we're in */
1161 if (pl) {
1162 pl->Modified();
1165 /* tell everybody else */
1167 send_change (ScaleAmplitudeChanged);
1170 void
1171 AudioRegion::normalize_to (float target_dB)
1173 const nframes_t blocksize = 64 * 1024;
1174 Sample buf[blocksize];
1175 nframes_t fpos;
1176 nframes_t fend;
1177 nframes_t to_read;
1178 double maxamp = 0;
1179 gain_t target = dB_to_coefficient (target_dB);
1181 if (target == 1.0f) {
1182 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1183 that we may have clipped.
1185 target -= FLT_EPSILON;
1188 fpos = _start;
1189 fend = _start + _length;
1191 /* first pass: find max amplitude */
1193 while (fpos < fend) {
1195 uint32_t n;
1197 to_read = min (fend - fpos, blocksize);
1199 for (n = 0; n < n_channels(); ++n) {
1201 /* read it in */
1203 if (read_raw_internal (buf, fpos, to_read, 0) != to_read) {
1204 return;
1207 maxamp = compute_peak (buf, to_read, maxamp);
1210 fpos += to_read;
1213 if (maxamp == 0.0f) {
1214 /* don't even try */
1215 return;
1218 if (maxamp == target) {
1219 /* we can't do anything useful */
1220 return;
1223 /* compute scale factor */
1225 _scale_amplitude = target/maxamp;
1227 /* tell the diskstream we're in */
1229 boost::shared_ptr<Playlist> pl (playlist());
1231 if (pl) {
1232 pl->Modified();
1235 /* tell everybody else */
1237 send_change (ScaleAmplitudeChanged);
1240 void
1241 AudioRegion::fade_in_changed ()
1243 send_change (FadeInChanged);
1246 void
1247 AudioRegion::fade_out_changed ()
1249 send_change (FadeOutChanged);
1252 void
1253 AudioRegion::envelope_changed ()
1255 send_change (EnvelopeChanged);
1258 void
1259 AudioRegion::suspend_fade_in ()
1261 if (++_fade_in_disabled == 1) {
1262 if (fade_in_is_default()) {
1263 set_fade_in_active (false);
1268 void
1269 AudioRegion::resume_fade_in ()
1271 if (--_fade_in_disabled == 0 && _fade_in_disabled) {
1272 set_fade_in_active (true);
1276 void
1277 AudioRegion::suspend_fade_out ()
1279 if (++_fade_out_disabled == 1) {
1280 if (fade_out_is_default()) {
1281 set_fade_out_active (false);
1286 void
1287 AudioRegion::resume_fade_out ()
1289 if (--_fade_out_disabled == 0 &&_fade_out_disabled) {
1290 set_fade_out_active (true);
1294 bool
1295 AudioRegion::speed_mismatch (float sr) const
1297 if (_sources.empty()) {
1298 /* impossible, but ... */
1299 return false;
1302 float fsr = audio_source()->sample_rate();
1304 return fsr != sr;
1307 void
1308 AudioRegion::source_offset_changed ()
1310 /* XXX this fixes a crash that should not occur. It does occur
1311 becauses regions are not being deleted when a session
1312 is unloaded. That bug must be fixed.
1315 if (_sources.empty()) {
1316 return;
1319 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1321 if (afs && afs->destructive()) {
1322 // set_start (source()->natural_position(), this);
1323 set_position (source()->natural_position(), this);
1327 boost::shared_ptr<AudioSource>
1328 AudioRegion::audio_source (uint32_t n) const
1330 // Guaranteed to succeed (use a static cast for speed?)
1331 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1335 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1337 boost::shared_ptr<Playlist> pl = playlist();
1339 if (!pl) {
1340 return -1;
1343 if (_valid_transients && !force_new) {
1344 results = _transients;
1345 return 0;
1348 SourceList::iterator s;
1350 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1351 if (!(*s)->has_been_analysed()) {
1352 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1353 break;
1357 if (s == _sources.end()) {
1358 /* all sources are analyzed, merge data from each one */
1360 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1362 /* find the set of transients within the bounds of this region */
1364 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1365 (*s)->transients.end(),
1366 _start);
1368 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1369 (*s)->transients.end(),
1370 _start + _length);
1372 /* and add them */
1374 results.insert (results.end(), low, high);
1377 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1379 /* translate all transients to current position */
1381 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1382 (*x) -= _start;
1383 (*x) += _position;
1386 _transients = results;
1387 _valid_transients = true;
1389 return 0;
1392 /* no existing/complete transient info */
1394 if (!Config->get_auto_analyse_audio()) {
1395 pl->session().Dialog (_("\
1396 You have requested an operation that requires audio analysis.\n\n\
1397 You currently have \"auto-analyse-audio\" disabled, which means\n\
1398 that transient data must be generated every time it is required.\n\n\
1399 If you are doing work that will require transient data on a\n\
1400 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1401 then quit ardour and restart."));
1404 TransientDetector t (pl->session().frame_rate());
1405 bool existing_results = !results.empty();
1407 _transients.clear ();
1408 _valid_transients = false;
1410 for (uint32_t i = 0; i < n_channels(); ++i) {
1412 AnalysisFeatureList these_results;
1414 t.reset ();
1416 if (t.run ("", this, i, these_results)) {
1417 return -1;
1420 /* translate all transients to give absolute position */
1422 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1423 (*i) += _position;
1426 /* merge */
1428 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1431 if (!results.empty()) {
1432 if (existing_results) {
1434 /* merge our transients into the existing ones, then clean up
1435 those.
1438 results.insert (results.end(), _transients.begin(), _transients.end());
1439 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1442 /* make sure ours are clean too */
1444 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1446 } else {
1448 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1449 results = _transients;
1452 _valid_transients = true;
1454 return 0;
1457 /** Find areas of `silence' within a region.
1459 * @param threshold Threshold below which signal is considered silence (as a sample value)
1460 * @param min_length Minimum length of silent period to be reported.
1461 * @return Silent periods; first of pair is the offset within the region, second is the length of the period
1464 std::list<std::pair<nframes_t, nframes_t> >
1465 AudioRegion::find_silence (Sample threshold, nframes_t min_length) const
1467 nframes_t const block_size = 64 * 1024;
1468 Sample loudest[block_size];
1469 Sample buf[block_size];
1471 nframes_t pos = _start;
1472 nframes_t const end = _start + _length - 1;
1474 std::list<std::pair<nframes_t, nframes_t> > silent_periods;
1476 bool in_silence = false;
1477 nframes_t silence_start = 0;
1478 bool silence;
1480 while (pos < end) {
1482 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1483 memset (loudest, 0, sizeof (Sample) * block_size);
1484 for (uint32_t n = 0; n < n_channels(); ++n) {
1486 read_raw_internal (buf, pos, block_size, n);
1487 for (nframes_t i = 0; i < block_size; ++i) {
1488 loudest[i] = max (loudest[i], abs (buf[i]));
1492 /* now look for silence */
1493 for (nframes_t i = 0; i < block_size; ++i) {
1494 silence = abs (loudest[i]) < threshold;
1495 if (silence && !in_silence) {
1496 /* non-silence to silence */
1497 in_silence = true;
1498 silence_start = pos + i;
1499 } else if (!silence && in_silence) {
1500 /* silence to non-silence */
1501 in_silence = false;
1502 if (pos + i - 1 - silence_start >= min_length) {
1503 silent_periods.push_back (std::make_pair (silence_start, pos + i - 1));
1508 pos += block_size;
1511 if (in_silence && end - 1 - silence_start >= min_length) {
1512 /* last block was silent, so finish off the last period */
1513 silent_periods.push_back (std::make_pair (silence_start, end));
1516 return silent_periods;
1520 extern "C" {
1522 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)
1524 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (nframes_t) npeaks, (nframes_t) start, (nframes_t) cnt, n_chan,samples_per_unit);
1527 uint32_t region_length_from_c (void *arg)
1530 return ((AudioRegion *) arg)->length();
1533 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1535 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;
1538 } /* extern "C" */