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.
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>
54 using namespace ARDOUR;
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();
70 _scale_amplitude = 1.0;
73 set_default_envelope ();
75 listen_to_my_curves ();
76 listen_to_my_sources ();
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)
83 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
84 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
85 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
90 /** Basic AudioRegion constructor (one channel) */
91 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length)
92 : Region (src, start, length, PBD::basename_nosuffix(src->name()), DataType::AUDIO, 0, Region::Flag(Region::DefaultFlags|Region::External))
93 , _automatable(src->session())
94 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
95 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
96 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
98 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
100 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
106 /* Basic AudioRegion constructor (one channel) */
107 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
108 : Region (src, start, length, name, DataType::AUDIO, layer, flags)
109 , _automatable(src->session())
110 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
111 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
112 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
114 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
116 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
122 /** Basic AudioRegion constructor (many channels) */
123 AudioRegion::AudioRegion (const SourceList& srcs, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags)
124 : Region (srcs, start, length, name, DataType::AUDIO, layer, flags)
125 , _automatable(srcs[0]->session())
126 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
127 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
128 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
131 listen_to_my_sources ();
134 /** Create a new AudioRegion, that is part of an existing one */
135 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags)
136 : Region (other, offset, length, name, layer, flags)
137 , _automatable(other->session())
138 , _fade_in (new AutomationList(*other->_fade_in))
139 , _fade_out (new AutomationList(*other->_fade_out))
140 , _envelope (new AutomationList(*other->_envelope, offset, offset + length))
142 set<boost::shared_ptr<Source> > unique_srcs;
144 for (SourceList::const_iterator i= other->_sources.begin(); i != other->_sources.end(); ++i) {
145 _sources.push_back (*i);
147 pair<set<boost::shared_ptr<Source> >::iterator,bool> result;
149 result = unique_srcs.insert (*i);
152 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i);
154 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
159 /* return to default fades if the existing ones are too long */
161 if (_flags & LeftOfSplit) {
162 if (_fade_in->back()->when >= _length) {
163 set_default_fade_in ();
165 _fade_in_disabled = other->_fade_in_disabled;
167 set_default_fade_out ();
168 _flags = Flag (_flags & ~Region::LeftOfSplit);
171 if (_flags & RightOfSplit) {
172 if (_fade_out->back()->when >= _length) {
173 set_default_fade_out ();
175 _fade_out_disabled = other->_fade_out_disabled;
177 set_default_fade_in ();
178 _flags = Flag (_flags & ~Region::RightOfSplit);
181 _scale_amplitude = other->_scale_amplitude;
183 assert(_type == DataType::AUDIO);
185 listen_to_my_curves ();
186 listen_to_my_sources ();
189 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
191 , _automatable (other->session())
192 , _fade_in (new AutomationList (*other->_fade_in))
193 , _fade_out (new AutomationList (*other->_fade_out))
194 , _envelope (new AutomationList (*other->_envelope))
196 assert(_type == DataType::AUDIO);
197 _scale_amplitude = other->_scale_amplitude;
199 set_default_fades ();
201 listen_to_my_curves ();
202 listen_to_my_sources ();
205 AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& srcs,
206 nframes_t length, const string& name, layer_t layer, Flag flags)
207 : Region (other, length, name, layer, flags)
208 , _automatable (other->session())
209 , _fade_in (new AutomationList (*other->_fade_in))
210 , _fade_out (new AutomationList (*other->_fade_out))
211 , _envelope (new AutomationList (*other->_envelope))
213 /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
215 set<boost::shared_ptr<AudioSource> > unique_srcs;
217 for (SourceList::const_iterator i=srcs.begin(); i != srcs.end(); ++i) {
219 _sources.push_back (*i);
220 _master_sources.push_back (*i);
222 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> ((*i));
224 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
228 _scale_amplitude = other->_scale_amplitude;
230 _fade_in_disabled = 0;
231 _fade_out_disabled = 0;
233 listen_to_my_curves ();
234 listen_to_my_sources ();
237 AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node)
239 , _automatable(src->session())
240 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
241 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
242 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
244 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
246 afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed));
251 if (set_state (node)) {
252 throw failed_constructor();
255 assert(_type == DataType::AUDIO);
256 listen_to_my_sources ();
259 AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
260 : Region (srcs, node)
261 , _automatable(srcs[0]->session())
262 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation)))
263 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation)))
264 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation)))
268 if (set_state (node)) {
269 throw failed_constructor();
272 assert(_type == DataType::AUDIO);
273 listen_to_my_sources ();
276 AudioRegion::~AudioRegion ()
281 AudioRegion::listen_to_my_sources ()
283 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
284 (*i)->AnalysisChanged.connect (mem_fun (*this, &AudioRegion::invalidate_transients));
289 AudioRegion::listen_to_my_curves ()
291 _envelope->StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
292 _fade_in->StateChanged.connect (mem_fun (*this, &AudioRegion::fade_in_changed));
293 _fade_out->StateChanged.connect (mem_fun (*this, &AudioRegion::fade_out_changed));
297 AudioRegion::set_envelope_active (bool yn)
299 if (envelope_active() != yn) {
302 snprintf (buf, sizeof (buf), "envelope active");
303 _flags = Flag (_flags|EnvelopeActive);
305 snprintf (buf, sizeof (buf), "envelope off");
306 _flags = Flag (_flags & ~EnvelopeActive);
308 send_change (EnvelopeActiveChanged);
313 AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const
315 if (chan_n >= _sources.size()) {
319 if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
322 if (_scale_amplitude != 1.0) {
323 for (nframes_t n = 0; n < npeaks; ++n) {
324 buf[n].max *= _scale_amplitude;
325 buf[n].min *= _scale_amplitude;
333 AudioRegion::read (Sample* buf, sframes_t timeline_position, nframes_t cnt, int channel) const
335 /* raw read, no fades, no gain, nada */
336 return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
340 AudioRegion::read_with_ops (Sample* buf, sframes_t file_position, nframes_t cnt, int channel, ReadOps rops) const
342 return _read_at (_sources, _length, buf, 0, 0, file_position, cnt, channel, 0, 0, rops);
346 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
347 sframes_t file_position, nframes_t cnt, uint32_t chan_n,
348 nframes_t read_frames, nframes_t skip_frames) const
350 /* regular diskstream/butler read complete with fades etc */
351 return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer, file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
355 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
356 sframes_t position, nframes_t cnt, uint32_t chan_n) const
358 return _read_at (_master_sources, _master_sources.front()->length(), buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0);
362 AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
363 Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
364 sframes_t position, nframes_t cnt,
366 nframes_t read_frames,
367 nframes_t skip_frames,
370 nframes_t internal_offset;
371 nframes_t buf_offset;
373 bool raw = (rops == ReadOpsNone);
375 if (muted() && !raw) {
376 return 0; /* read nothing */
379 /* precondition: caller has verified that we cover the desired section */
381 if (position < _position) {
383 buf_offset = _position - position;
386 internal_offset = position - _position;
390 if (internal_offset >= limit) {
391 return 0; /* read nothing */
394 if ((to_read = min (cnt, limit - internal_offset)) == 0) {
395 return 0; /* read nothing */
398 if (opaque() || raw) {
399 /* overwrite whatever is there */
400 mixdown_buffer = buf + buf_offset;
402 mixdown_buffer += buf_offset;
405 if (rops & ReadOpsCount) {
406 _read_data_count = 0;
409 if (chan_n < n_channels()) {
411 boost::shared_ptr<AudioSource> src = audio_source(chan_n);
412 if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
413 return 0; /* "read nothing" */
416 if (rops & ReadOpsCount) {
417 _read_data_count += src->read_data_count();
422 /* track is N-channel, this region has less channels; silence the ones
426 memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
429 if (rops & ReadOpsFades) {
433 if ((_flags & FadeIn) && Config->get_use_region_fades()) {
435 nframes_t fade_in_length = (nframes_t) _fade_in->back()->when;
437 /* see if this read is within the fade in */
439 if (internal_offset < fade_in_length) {
443 fi_limit = min (to_read, fade_in_length - internal_offset);
446 _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
448 for (nframes_t n = 0; n < fi_limit; ++n) {
449 mixdown_buffer[n] *= gain_buffer[n];
456 if ((_flags & FadeOut) && Config->get_use_region_fades()) {
458 /* see if some part of this read is within the fade out */
460 /* ................. >| REGION
466 limit - fade_out_length
469 ^internal_offset + to_read
471 we need the intersection of [internal_offset,internal_offset+to_read] with
472 [limit - fade_out_length, limit]
477 nframes_t fade_out_length = (nframes_t) _fade_out->back()->when;
478 nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
479 nframes_t fade_interval_end = min(internal_offset + to_read, limit);
481 if (fade_interval_end > fade_interval_start) {
482 /* (part of the) the fade out is in this buffer */
484 nframes_t fo_limit = fade_interval_end - fade_interval_start;
485 nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
486 nframes_t fade_offset = fade_interval_start - internal_offset;
488 _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
490 for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
491 mixdown_buffer[m] *= gain_buffer[n];
498 /* Regular gain curves and scaling */
500 if ((rops & ReadOpsOwnAutomation) && envelope_active()) {
501 _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read);
503 if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
504 for (nframes_t n = 0; n < to_read; ++n) {
505 mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude;
508 for (nframes_t n = 0; n < to_read; ++n) {
509 mixdown_buffer[n] *= gain_buffer[n];
512 } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) {
514 // XXX this should be using what in 2.0 would have been:
515 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
517 for (nframes_t n = 0; n < to_read; ++n) {
518 mixdown_buffer[n] *= _scale_amplitude;
524 /* gack. the things we do for users.
529 for (nframes_t n = 0; n < to_read; ++n) {
530 buf[n] += mixdown_buffer[n];
538 AudioRegion::state (bool full)
540 XMLNode& node (Region::state (full));
544 LocaleGuard lg (X_("POSIX"));
546 node.add_property ("flags", enum_2_string (_flags));
548 snprintf (buf, sizeof(buf), "%.12g", _scale_amplitude);
549 node.add_property ("scale-gain", buf);
551 // XXX these should move into Region
553 for (uint32_t n=0; n < _sources.size(); ++n) {
554 snprintf (buf2, sizeof(buf2), "source-%d", n);
555 _sources[n]->id().print (buf, sizeof (buf));
556 node.add_property (buf2, buf);
559 for (uint32_t n=0; n < _master_sources.size(); ++n) {
560 snprintf (buf2, sizeof(buf2), "master-source-%d", n);
561 _master_sources[n]->id().print (buf, sizeof (buf));
562 node.add_property (buf2, buf);
565 snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size());
566 node.add_property ("channels", buf);
570 child = node.add_child (X_("FadeIn"));
572 if ((_flags & DefaultFadeIn)) {
573 child->add_property (X_("default"), X_("yes"));
575 child->add_child_nocopy (_fade_in->get_state ());
578 child->add_property (X_("active"), _fade_in_disabled ? X_("no") : X_("yes"));
580 child = node.add_child (X_("FadeOut"));
582 if ((_flags & DefaultFadeOut)) {
583 child->add_property (X_("default"), X_("yes"));
585 child->add_child_nocopy (_fade_out->get_state ());
588 child->add_property (X_("active"), _fade_out_disabled ? X_("no") : X_("yes"));
591 child = node.add_child ("Envelope");
594 bool default_env = false;
596 // If there are only two points, the points are in the start of the region and the end of the region
597 // so, if they are both at 1.0f, that means the default region.
599 if (_envelope->size() == 2 &&
600 _envelope->front()->value == 1.0f &&
601 _envelope->back()->value==1.0f) {
602 if (_envelope->front()->when == 0 && _envelope->back()->when == _length) {
608 child->add_property ("default", "yes");
610 child->add_child_nocopy (_envelope->get_state ());
614 child->add_property ("default", "yes");
617 if (full && _extra_xml) {
618 node.add_child_copy (*_extra_xml);
625 AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool send)
627 const XMLNodeList& nlist = node.children();
628 const XMLProperty *prop;
629 LocaleGuard lg (X_("POSIX"));
631 Region::set_live_state (node, what_changed, false);
633 uint32_t old_flags = _flags;
635 if ((prop = node.property ("flags")) != 0) {
636 _flags = Flag (string_2_enum (prop->value(), _flags));
638 //_flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16));
640 _flags = Flag (_flags & ~Region::LeftOfSplit);
641 _flags = Flag (_flags & ~Region::RightOfSplit);
644 if ((old_flags ^ _flags) & Muted) {
645 what_changed = Change (what_changed|MuteChanged);
647 if ((old_flags ^ _flags) & Opaque) {
648 what_changed = Change (what_changed|OpacityChanged);
650 if ((old_flags ^ _flags) & Locked) {
651 what_changed = Change (what_changed|LockChanged);
654 if ((prop = node.property ("scale-gain")) != 0) {
655 _scale_amplitude = atof (prop->value().c_str());
656 what_changed = Change (what_changed|ScaleAmplitudeChanged);
658 _scale_amplitude = 1.0;
661 /* Now find envelope description and other misc child items */
663 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
670 if (child->name() == "Envelope") {
674 if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child)) {
675 set_default_envelope ();
678 _envelope->set_max_xval (_length);
679 _envelope->truncate_end (_length);
681 } else if (child->name() == "FadeIn") {
685 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
686 set_default_fade_in ();
688 XMLNode* grandchild = child->child ("AutomationList");
690 _fade_in->set_state (*grandchild);
694 if ((prop = child->property ("active")) != 0) {
695 if (prop->value() == "yes") {
696 set_fade_in_active (true);
698 set_fade_in_active (true);
702 } else if (child->name() == "FadeOut") {
706 if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) {
707 set_default_fade_out ();
709 XMLNode* grandchild = child->child ("AutomationList");
711 _fade_out->set_state (*grandchild);
715 if ((prop = child->property ("active")) != 0) {
716 if (prop->value() == "yes") {
717 set_fade_out_active (true);
719 set_fade_out_active (false);
727 send_change (what_changed);
734 AudioRegion::set_state (const XMLNode& node)
736 /* Region::set_state() calls the virtual set_live_state(),
737 which will get us back to AudioRegion::set_live_state()
738 to handle the relevant stuff.
741 return Region::set_state (node);
745 AudioRegion::set_fade_in_shape (FadeShape shape)
747 set_fade_in (shape, (nframes_t) _fade_in->back()->when);
751 AudioRegion::set_fade_out_shape (FadeShape shape)
753 set_fade_out (shape, (nframes_t) _fade_out->back()->when);
757 AudioRegion::set_fade_in (FadeShape shape, nframes_t len)
764 _fade_in->fast_simple_add (0.0, 0.0);
765 _fade_in->fast_simple_add (len, 1.0);
769 _fade_in->fast_simple_add (0, 0);
770 _fade_in->fast_simple_add (len * 0.389401, 0.0333333);
771 _fade_in->fast_simple_add (len * 0.629032, 0.0861111);
772 _fade_in->fast_simple_add (len * 0.829493, 0.233333);
773 _fade_in->fast_simple_add (len * 0.9447, 0.483333);
774 _fade_in->fast_simple_add (len * 0.976959, 0.697222);
775 _fade_in->fast_simple_add (len, 1);
779 _fade_in->fast_simple_add (0, 0);
780 _fade_in->fast_simple_add (len * 0.0207373, 0.197222);
781 _fade_in->fast_simple_add (len * 0.0645161, 0.525);
782 _fade_in->fast_simple_add (len * 0.152074, 0.802778);
783 _fade_in->fast_simple_add (len * 0.276498, 0.919444);
784 _fade_in->fast_simple_add (len * 0.481567, 0.980556);
785 _fade_in->fast_simple_add (len * 0.767281, 1);
786 _fade_in->fast_simple_add (len, 1);
790 _fade_in->fast_simple_add (0, 0);
791 _fade_in->fast_simple_add (len * 0.0737327, 0.308333);
792 _fade_in->fast_simple_add (len * 0.246544, 0.658333);
793 _fade_in->fast_simple_add (len * 0.470046, 0.886111);
794 _fade_in->fast_simple_add (len * 0.652074, 0.972222);
795 _fade_in->fast_simple_add (len * 0.771889, 0.988889);
796 _fade_in->fast_simple_add (len, 1);
800 _fade_in->fast_simple_add (0, 0);
801 _fade_in->fast_simple_add (len * 0.304147, 0.0694444);
802 _fade_in->fast_simple_add (len * 0.529954, 0.152778);
803 _fade_in->fast_simple_add (len * 0.725806, 0.333333);
804 _fade_in->fast_simple_add (len * 0.847926, 0.558333);
805 _fade_in->fast_simple_add (len * 0.919355, 0.730556);
806 _fade_in->fast_simple_add (len, 1);
811 _fade_in_shape = shape;
813 send_change (FadeInChanged);
817 AudioRegion::set_fade_out (FadeShape shape, nframes_t len)
819 _fade_out->freeze ();
824 _fade_out->fast_simple_add (len * 0, 1);
825 _fade_out->fast_simple_add (len * 0.023041, 0.697222);
826 _fade_out->fast_simple_add (len * 0.0553, 0.483333);
827 _fade_out->fast_simple_add (len * 0.170507, 0.233333);
828 _fade_out->fast_simple_add (len * 0.370968, 0.0861111);
829 _fade_out->fast_simple_add (len * 0.610599, 0.0333333);
830 _fade_out->fast_simple_add (len * 1, 0);
834 _fade_out->fast_simple_add (len * 0, 1);
835 _fade_out->fast_simple_add (len * 0.228111, 0.988889);
836 _fade_out->fast_simple_add (len * 0.347926, 0.972222);
837 _fade_out->fast_simple_add (len * 0.529954, 0.886111);
838 _fade_out->fast_simple_add (len * 0.753456, 0.658333);
839 _fade_out->fast_simple_add (len * 0.9262673, 0.308333);
840 _fade_out->fast_simple_add (len * 1, 0);
844 _fade_out->fast_simple_add (len * 0, 1);
845 _fade_out->fast_simple_add (len * 0.305556, 1);
846 _fade_out->fast_simple_add (len * 0.548611, 0.991736);
847 _fade_out->fast_simple_add (len * 0.759259, 0.931129);
848 _fade_out->fast_simple_add (len * 0.918981, 0.68595);
849 _fade_out->fast_simple_add (len * 0.976852, 0.22865);
850 _fade_out->fast_simple_add (len * 1, 0);
854 _fade_out->fast_simple_add (len * 0, 1);
855 _fade_out->fast_simple_add (len * 0.080645, 0.730556);
856 _fade_out->fast_simple_add (len * 0.277778, 0.289256);
857 _fade_out->fast_simple_add (len * 0.470046, 0.152778);
858 _fade_out->fast_simple_add (len * 0.695853, 0.0694444);
859 _fade_out->fast_simple_add (len * 1, 0);
863 _fade_out->fast_simple_add (len * 0, 1);
864 _fade_out->fast_simple_add (len * 1, 0);
869 _fade_out_shape = shape;
871 send_change (FadeOutChanged);
875 AudioRegion::set_fade_in_length (nframes_t len)
881 bool changed = _fade_in->extend_to (len);
884 _flags = Flag (_flags & ~DefaultFadeIn);
885 send_change (FadeInChanged);
890 AudioRegion::set_fade_out_length (nframes_t len)
896 bool changed = _fade_out->extend_to (len);
899 _flags = Flag (_flags & ~DefaultFadeOut);
900 send_change (FadeOutChanged);
905 AudioRegion::set_fade_in_active (bool yn)
907 if (yn == (_flags & FadeIn)) {
911 _flags = Flag (_flags|FadeIn);
913 _flags = Flag (_flags & ~FadeIn);
916 send_change (FadeInActiveChanged);
920 AudioRegion::set_fade_out_active (bool yn)
922 if (yn == (_flags & FadeOut)) {
926 _flags = Flag (_flags | FadeOut);
928 _flags = Flag (_flags & ~FadeOut);
931 send_change (FadeOutActiveChanged);
935 AudioRegion::fade_in_is_default () const
937 return _fade_in_shape == Linear && _fade_in->back()->when == 64;
941 AudioRegion::fade_out_is_default () const
943 return _fade_out_shape == Linear && _fade_out->back()->when == 64;
947 AudioRegion::set_default_fade_in ()
949 set_fade_in (Linear, 64);
953 AudioRegion::set_default_fade_out ()
955 set_fade_out (Linear, 64);
959 AudioRegion::set_default_fades ()
961 _fade_in_disabled = 0;
962 _fade_out_disabled = 0;
963 set_default_fade_in ();
964 set_default_fade_out ();
968 AudioRegion::set_default_envelope ()
970 _envelope->freeze ();
972 _envelope->fast_simple_add (0, 1.0f);
973 _envelope->fast_simple_add (_length, 1.0f);
978 AudioRegion::recompute_at_end ()
980 /* our length has changed. recompute a new final point by interpolating
981 based on the the existing curve.
984 _envelope->freeze ();
985 _envelope->truncate_end (_length);
986 _envelope->set_max_xval (_length);
989 if (_fade_in->back()->when > _length) {
990 _fade_in->extend_to (_length);
991 send_change (FadeInChanged);
994 if (_fade_out->back()->when > _length) {
995 _fade_out->extend_to (_length);
996 send_change (FadeOutChanged);
1001 AudioRegion::recompute_at_start ()
1003 /* as above, but the shift was from the front */
1005 _envelope->truncate_start (_length);
1007 if (_fade_in->back()->when > _length) {
1008 _fade_in->extend_to (_length);
1009 send_change (FadeInChanged);
1012 if (_fade_out->back()->when > _length) {
1013 _fade_out->extend_to (_length);
1014 send_change (FadeOutChanged);
1019 AudioRegion::separate_by_channel (Session& session, vector<boost::shared_ptr<Region> >& v) const
1025 if (_sources.size() < 2) {
1029 for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
1031 srcs.push_back (*i);
1035 if (_sources.size() == 2) {
1043 new_name += ('0' + n + 1);
1046 /* create a copy with just one source. prevent if from being thought of as
1047 "whole file" even if it covers the entire source file(s).
1050 Flag f = Flag (_flags & ~WholeFile);
1052 v.push_back(RegionFactory::create (srcs, _start, _length, new_name, _layer, f));
1061 AudioRegion::read_raw_internal (Sample* buf, sframes_t pos, nframes_t cnt) const
1063 return audio_source()->read (buf, pos, cnt);
1067 AudioRegion::exportme (Session& session, ARDOUR::ExportSpecification& spec)
1070 // const nframes_t blocksize = 4096;
1071 // nframes_t to_read;
1074 // spec.channels = _sources.size();
1076 // if (spec.prepare (blocksize, session.frame_rate())) {
1081 // spec.total_frames = _length;
1083 // while (spec.pos < _length && !spec.stop) {
1086 // /* step 1: interleave */
1088 // to_read = min (_length - spec.pos, blocksize);
1090 // if (spec.channels == 1) {
1092 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1098 // Sample buf[blocksize];
1100 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1102 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1106 // for (nframes_t x = 0; x < to_read; ++x) {
1107 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1112 // if (spec.process (to_read)) {
1116 // spec.pos += to_read;
1117 // spec.progress = (double) spec.pos /_length;
1124 // spec.running = false;
1125 // spec.status = status;
1133 AudioRegion::set_scale_amplitude (gain_t g)
1135 boost::shared_ptr<Playlist> pl (playlist());
1137 _scale_amplitude = g;
1139 /* tell the diskstream we're in */
1145 /* tell everybody else */
1147 send_change (ScaleAmplitudeChanged);
1151 AudioRegion::normalize_to (float target_dB)
1153 const nframes_t blocksize = 64 * 1024;
1154 Sample buf[blocksize];
1159 gain_t target = dB_to_coefficient (target_dB);
1161 if (target == 1.0f) {
1162 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1163 that we may have clipped.
1165 target -= FLT_EPSILON;
1169 fend = _start + _length;
1171 /* first pass: find max amplitude */
1173 while (fpos < fend) {
1177 to_read = min (fend - fpos, blocksize);
1179 for (n = 0; n < n_channels(); ++n) {
1183 if (read_raw_internal (buf, fpos, to_read) != to_read) {
1187 maxamp = compute_peak (buf, to_read, maxamp);
1193 if (maxamp == 0.0f) {
1194 /* don't even try */
1198 if (maxamp == target) {
1199 /* we can't do anything useful */
1203 /* compute scale factor */
1205 _scale_amplitude = target/maxamp;
1207 /* tell the diskstream we're in */
1209 boost::shared_ptr<Playlist> pl (playlist());
1215 /* tell everybody else */
1217 send_change (ScaleAmplitudeChanged);
1221 AudioRegion::fade_in_changed ()
1223 send_change (FadeInChanged);
1227 AudioRegion::fade_out_changed ()
1229 send_change (FadeOutChanged);
1233 AudioRegion::envelope_changed ()
1235 send_change (EnvelopeChanged);
1239 AudioRegion::suspend_fade_in ()
1241 if (++_fade_in_disabled == 1) {
1242 if (fade_in_is_default()) {
1243 set_fade_in_active (false);
1249 AudioRegion::resume_fade_in ()
1251 if (--_fade_in_disabled == 0 && _fade_in_disabled) {
1252 set_fade_in_active (true);
1257 AudioRegion::suspend_fade_out ()
1259 if (++_fade_out_disabled == 1) {
1260 if (fade_out_is_default()) {
1261 set_fade_out_active (false);
1267 AudioRegion::resume_fade_out ()
1269 if (--_fade_out_disabled == 0 &&_fade_out_disabled) {
1270 set_fade_out_active (true);
1275 AudioRegion::speed_mismatch (float sr) const
1277 if (_sources.empty()) {
1278 /* impossible, but ... */
1282 float fsr = audio_source()->sample_rate();
1288 AudioRegion::source_offset_changed ()
1290 /* XXX this fixes a crash that should not occur. It does occur
1291 becauses regions are not being deleted when a session
1292 is unloaded. That bug must be fixed.
1295 if (_sources.empty()) {
1299 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front());
1301 if (afs && afs->destructive()) {
1302 // set_start (source()->natural_position(), this);
1303 set_position (source()->natural_position(), this);
1307 boost::shared_ptr<AudioSource>
1308 AudioRegion::audio_source (uint32_t n) const
1310 // Guaranteed to succeed (use a static cast for speed?)
1311 return boost::dynamic_pointer_cast<AudioSource>(source(n));
1315 AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new)
1317 boost::shared_ptr<Playlist> pl = playlist();
1323 if (_valid_transients && !force_new) {
1324 results = _transients;
1328 SourceList::iterator s;
1330 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1331 if (!(*s)->has_been_analysed()) {
1332 cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n";
1337 if (s == _sources.end()) {
1338 /* all sources are analyzed, merge data from each one */
1340 for (s = _sources.begin() ; s != _sources.end(); ++s) {
1342 /* find the set of transients within the bounds of this region */
1344 AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(),
1345 (*s)->transients.end(),
1348 AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(),
1349 (*s)->transients.end(),
1354 results.insert (results.end(), low, high);
1357 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1359 /* translate all transients to current position */
1361 for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) {
1366 _transients = results;
1367 _valid_transients = true;
1372 /* no existing/complete transient info */
1374 if (!Config->get_auto_analyse_audio()) {
1375 pl->session().Dialog (_("\
1376 You have requested an operation that requires audio analysis.\n\n\
1377 You currently have \"auto-analyse-audio\" disabled, which means\n\
1378 that transient data must be generated every time it is required.\n\n\
1379 If you are doing work that will require transient data on a\n\
1380 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1381 then quit ardour and restart."));
1384 TransientDetector t (pl->session().frame_rate());
1385 bool existing_results = !results.empty();
1387 _transients.clear ();
1388 _valid_transients = false;
1390 for (uint32_t i = 0; i < n_channels(); ++i) {
1392 AnalysisFeatureList these_results;
1396 if (t.run ("", this, i, these_results)) {
1400 /* translate all transients to give absolute position */
1402 for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) {
1408 _transients.insert (_transients.end(), these_results.begin(), these_results.end());
1411 if (!results.empty()) {
1412 if (existing_results) {
1414 /* merge our transients into the existing ones, then clean up
1418 results.insert (results.end(), _transients.begin(), _transients.end());
1419 TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0);
1422 /* make sure ours are clean too */
1424 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1428 TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0);
1429 results = _transients;
1432 _valid_transients = true;
1439 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)
1441 return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (nframes_t) npeaks, (nframes_t) start, (nframes_t) cnt, n_chan,samples_per_unit);
1444 uint32_t region_length_from_c (void *arg)
1447 return ((AudioRegion *) arg)->length();
1450 uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
1452 return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;