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 <boost/scoped_array.hpp>
29 #include <glibmm/thread.h>
31 #include "pbd/basename.h"
32 #include "pbd/xml++.h"
33 #include "pbd/stacktrace.h"
34 #include "pbd/enumwriter.h"
35 #include "pbd/convert.h"
37 #include "evoral/Curve.hpp"
39 #include "ardour/audioregion.h"
40 #include "ardour/debug.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"
49 #include "ardour/progress.h"
55 using namespace ARDOUR
;
59 namespace Properties
{
60 PBD::PropertyDescriptor
<bool> envelope_active
;
61 PBD::PropertyDescriptor
<bool> default_fade_in
;
62 PBD::PropertyDescriptor
<bool> default_fade_out
;
63 PBD::PropertyDescriptor
<bool> fade_in_active
;
64 PBD::PropertyDescriptor
<bool> fade_out_active
;
65 PBD::PropertyDescriptor
<float> scale_amplitude
;
70 AudioRegion::make_property_quarks ()
72 Properties::envelope_active
.property_id
= g_quark_from_static_string (X_("envelope-active"));
73 DEBUG_TRACE (DEBUG::Properties
, string_compose ("quark for envelope-active = %1\n", Properties::envelope_active
.property_id
));
74 Properties::default_fade_in
.property_id
= g_quark_from_static_string (X_("default-fade-in"));
75 DEBUG_TRACE (DEBUG::Properties
, string_compose ("quark for default-fade-in = %1\n", Properties::default_fade_in
.property_id
));
76 Properties::default_fade_out
.property_id
= g_quark_from_static_string (X_("default-fade-out"));
77 DEBUG_TRACE (DEBUG::Properties
, string_compose ("quark for default-fade-out = %1\n", Properties::default_fade_out
.property_id
));
78 Properties::fade_in_active
.property_id
= g_quark_from_static_string (X_("fade-in-active"));
79 DEBUG_TRACE (DEBUG::Properties
, string_compose ("quark for fade-in-active = %1\n", Properties::fade_in_active
.property_id
));
80 Properties::fade_out_active
.property_id
= g_quark_from_static_string (X_("fade-out-active"));
81 DEBUG_TRACE (DEBUG::Properties
, string_compose ("quark for fade-out-active = %1\n", Properties::fade_out_active
.property_id
));
82 Properties::scale_amplitude
.property_id
= g_quark_from_static_string (X_("scale-amplitude"));
83 DEBUG_TRACE (DEBUG::Properties
, string_compose ("quark for scale-amplitude = %1\n", Properties::scale_amplitude
.property_id
));
87 AudioRegion::register_properties ()
89 /* no need to register parent class properties */
91 add_property (_envelope_active
);
92 add_property (_default_fade_in
);
93 add_property (_default_fade_out
);
94 add_property (_fade_in_active
);
95 add_property (_fade_out_active
);
96 add_property (_scale_amplitude
);
99 #define AUDIOREGION_STATE_DEFAULT \
100 _envelope_active (Properties::envelope_active, false) \
101 , _default_fade_in (Properties::default_fade_in, true) \
102 , _default_fade_out (Properties::default_fade_out, true) \
103 , _fade_in_active (Properties::fade_in_active, true) \
104 , _fade_out_active (Properties::fade_out_active, true) \
105 , _scale_amplitude (Properties::scale_amplitude, 1.0)
107 #define AUDIOREGION_COPY_STATE(other) \
108 _envelope_active (Properties::envelope_active, other->_envelope_active) \
109 , _default_fade_in (Properties::default_fade_in, other->_default_fade_in) \
110 , _default_fade_out (Properties::default_fade_out, other->_default_fade_out) \
111 , _fade_in_active (Properties::fade_in_active, other->_fade_in_active) \
112 , _fade_out_active (Properties::fade_out_active, other->_fade_out_active) \
113 , _scale_amplitude (Properties::scale_amplitude, other->_scale_amplitude)
114 /* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
119 register_properties ();
121 suspend_property_changes();
122 set_default_fades ();
123 set_default_envelope ();
124 resume_property_changes();
126 listen_to_my_curves ();
127 connect_to_analysis_changed ();
128 connect_to_header_position_offset_changed ();
131 /** Constructor for use by derived types only */
132 AudioRegion::AudioRegion (Session
& s
, framepos_t start
, framecnt_t len
, std::string name
)
133 : Region (s
, start
, len
, name
, DataType::AUDIO
)
134 , AUDIOREGION_STATE_DEFAULT
136 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation
)))
137 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation
)))
138 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation
)))
139 , _fade_in_suspended (0)
140 , _fade_out_suspended (0)
143 assert (_sources
.size() == _master_sources
.size());
146 /** Basic AudioRegion constructor */
147 AudioRegion::AudioRegion (const SourceList
& srcs
)
149 , AUDIOREGION_STATE_DEFAULT
150 , _automatable(srcs
[0]->session())
151 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation
)))
152 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation
)))
153 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation
)))
154 , _fade_in_suspended (0)
155 , _fade_out_suspended (0)
158 assert (_sources
.size() == _master_sources
.size());
161 AudioRegion::AudioRegion (boost::shared_ptr
<const AudioRegion
> other
)
163 , AUDIOREGION_COPY_STATE (other
)
164 , _automatable (other
->session())
165 , _fade_in (new AutomationList (*other
->_fade_in
))
166 , _fade_out (new AutomationList (*other
->_fade_out
))
167 /* As far as I can see, the _envelope's times are relative to region position, and have nothing
168 to do with sources (and hence _start). So when we copy the envelope, we just use the supplied offset.
170 , _envelope (new AutomationList (*other
->_envelope
, 0, other
->_length
))
171 , _fade_in_suspended (0)
172 , _fade_out_suspended (0)
174 /* don't use init here, because we got fade in/out from the other region
176 register_properties ();
177 listen_to_my_curves ();
178 connect_to_analysis_changed ();
179 connect_to_header_position_offset_changed ();
181 assert(_type
== DataType::AUDIO
);
182 assert (_sources
.size() == _master_sources
.size());
185 AudioRegion::AudioRegion (boost::shared_ptr
<const AudioRegion
> other
, framecnt_t offset
)
186 : Region (other
, offset
)
187 , AUDIOREGION_COPY_STATE (other
)
188 , _automatable (other
->session())
189 , _fade_in (new AutomationList (*other
->_fade_in
))
190 , _fade_out (new AutomationList (*other
->_fade_out
))
191 /* As far as I can see, the _envelope's times are relative to region position, and have nothing
192 to do with sources (and hence _start). So when we copy the envelope, we just use the supplied offset.
194 , _envelope (new AutomationList (*other
->_envelope
, offset
, other
->_length
))
195 , _fade_in_suspended (0)
196 , _fade_out_suspended (0)
198 /* don't use init here, because we got fade in/out from the other region
200 register_properties ();
201 listen_to_my_curves ();
202 connect_to_analysis_changed ();
203 connect_to_header_position_offset_changed ();
205 assert(_type
== DataType::AUDIO
);
206 assert (_sources
.size() == _master_sources
.size());
209 AudioRegion::AudioRegion (boost::shared_ptr
<const AudioRegion
> other
, const SourceList
& srcs
)
210 : Region (boost::static_pointer_cast
<const Region
>(other
), srcs
)
211 , AUDIOREGION_COPY_STATE (other
)
212 , _automatable (other
->session())
213 , _fade_in (new AutomationList (*other
->_fade_in
))
214 , _fade_out (new AutomationList (*other
->_fade_out
))
215 , _envelope (new AutomationList (*other
->_envelope
))
216 , _fade_in_suspended (0)
217 , _fade_out_suspended (0)
219 /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
221 register_properties ();
223 listen_to_my_curves ();
224 connect_to_analysis_changed ();
225 connect_to_header_position_offset_changed ();
227 assert (_sources
.size() == _master_sources
.size());
230 AudioRegion::AudioRegion (SourceList
& srcs
)
232 , AUDIOREGION_STATE_DEFAULT
233 , _automatable(srcs
[0]->session())
234 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation
)))
235 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation
)))
236 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation
)))
237 , _fade_in_suspended (0)
238 , _fade_out_suspended (0)
242 assert(_type
== DataType::AUDIO
);
243 assert (_sources
.size() == _master_sources
.size());
246 AudioRegion::~AudioRegion ()
251 AudioRegion::post_set (const PropertyChange
& /*ignored*/)
254 _sync_position
= _start
;
257 /* return to default fades if the existing ones are too long */
259 if (_left_of_split
) {
260 if (_fade_in
->back()->when
>= _length
) {
261 set_default_fade_in ();
263 set_default_fade_out ();
264 _left_of_split
= false;
267 if (_right_of_split
) {
268 if (_fade_out
->back()->when
>= _length
) {
269 set_default_fade_out ();
272 set_default_fade_in ();
273 _right_of_split
= false;
276 /* If _length changed, adjust our gain envelope accordingly */
277 _envelope
->truncate_end (_length
);
281 AudioRegion::connect_to_analysis_changed ()
283 for (SourceList::const_iterator i
= _sources
.begin(); i
!= _sources
.end(); ++i
) {
284 (*i
)->AnalysisChanged
.connect_same_thread (*this, boost::bind (&AudioRegion::invalidate_transients
, this));
289 AudioRegion::connect_to_header_position_offset_changed ()
291 set
<boost::shared_ptr
<Source
> > unique_srcs
;
293 for (SourceList::const_iterator i
= _sources
.begin(); i
!= _sources
.end(); ++i
) {
295 /* connect only once to HeaderPositionOffsetChanged, even if sources are replicated
298 if (unique_srcs
.find (*i
) == unique_srcs
.end ()) {
299 unique_srcs
.insert (*i
);
300 boost::shared_ptr
<AudioFileSource
> afs
= boost::dynamic_pointer_cast
<AudioFileSource
> (*i
);
302 afs
->HeaderPositionOffsetChanged
.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed
, this));
309 AudioRegion::listen_to_my_curves ()
311 _envelope
->StateChanged
.connect_same_thread (*this, boost::bind (&AudioRegion::envelope_changed
, this));
312 _fade_in
->StateChanged
.connect_same_thread (*this, boost::bind (&AudioRegion::fade_in_changed
, this));
313 _fade_out
->StateChanged
.connect_same_thread (*this, boost::bind (&AudioRegion::fade_out_changed
, this));
317 AudioRegion::set_envelope_active (bool yn
)
319 if (envelope_active() != yn
) {
320 _envelope_active
= yn
;
321 send_change (PropertyChange (Properties::envelope_active
));
326 AudioRegion::read_peaks (PeakData
*buf
, framecnt_t npeaks
, framecnt_t offset
, framecnt_t cnt
, uint32_t chan_n
, double samples_per_unit
) const
328 if (chan_n
>= _sources
.size()) {
332 if (audio_source(chan_n
)->read_peaks (buf
, npeaks
, offset
, cnt
, samples_per_unit
)) {
335 if (_scale_amplitude
!= 1.0f
) {
336 for (framecnt_t n
= 0; n
< npeaks
; ++n
) {
337 buf
[n
].max
*= _scale_amplitude
;
338 buf
[n
].min
*= _scale_amplitude
;
346 AudioRegion::read (Sample
* buf
, framepos_t timeline_position
, framecnt_t cnt
, int channel
) const
348 /* raw read, no fades, no gain, nada */
349 return _read_at (_sources
, _length
, buf
, 0, 0, _position
+ timeline_position
, cnt
, channel
, 0, 0, ReadOps (0));
353 AudioRegion::read_at (Sample
*buf
, Sample
*mixdown_buffer
, float *gain_buffer
,
354 framepos_t file_position
, framecnt_t cnt
, uint32_t chan_n
,
355 framecnt_t read_frames
, framecnt_t skip_frames
) const
357 /* regular diskstream/butler read complete with fades etc */
358 return _read_at (_sources
, _length
, buf
, mixdown_buffer
, gain_buffer
,
359 file_position
, cnt
, chan_n
, read_frames
, skip_frames
, ReadOps (~0));
363 AudioRegion::master_read_at (Sample
*buf
, Sample
*mixdown_buffer
, float *gain_buffer
,
364 framepos_t position
, framecnt_t cnt
, uint32_t chan_n
) const
366 /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
368 return _read_at (_master_sources
, _master_sources
.front()->length(_master_sources
.front()->timeline_position()),
369 buf
, mixdown_buffer
, gain_buffer
, position
, cnt
, chan_n
, 0, 0, ReadOps (0));
373 AudioRegion::_read_at (const SourceList
& /*srcs*/, framecnt_t limit
,
374 Sample
*buf
, Sample
*mixdown_buffer
, float *gain_buffer
,
378 framecnt_t
/*read_frames*/,
379 framecnt_t
/*skip_frames*/,
382 frameoffset_t internal_offset
;
383 frameoffset_t buf_offset
;
385 bool raw
= (rops
== ReadOpsNone
);
387 if (n_channels() == 0) {
391 if (muted() && !raw
) {
392 return 0; /* read nothing */
395 /* precondition: caller has verified that we cover the desired section */
397 if (position
< _position
) {
399 buf_offset
= _position
- position
;
402 internal_offset
= position
- _position
;
406 if (internal_offset
>= limit
) {
407 return 0; /* read nothing */
410 if ((to_read
= min (cnt
, limit
- internal_offset
)) == 0) {
411 return 0; /* read nothing */
414 if (opaque() || raw
) {
415 /* overwrite whatever is there */
416 mixdown_buffer
= buf
+ buf_offset
;
418 mixdown_buffer
+= buf_offset
;
421 if (rops
& ReadOpsCount
) {
422 _read_data_count
= 0;
425 if (chan_n
< n_channels()) {
427 boost::shared_ptr
<AudioSource
> src
= audio_source(chan_n
);
428 if (src
->read (mixdown_buffer
, _start
+ internal_offset
, to_read
) != to_read
) {
429 return 0; /* "read nothing" */
432 if (rops
& ReadOpsCount
) {
433 _read_data_count
+= src
->read_data_count();
438 /* track is N-channel, this region has less channels; silence the ones
442 if (Config
->get_replicate_missing_region_channels()) {
443 /* track is N-channel, this region has less channels, so use a relevant channel
446 uint32_t channel
= n_channels() % chan_n
;
447 boost::shared_ptr
<AudioSource
> src
= audio_source (channel
);
449 if (src
->read (mixdown_buffer
, _start
+ internal_offset
, to_read
) != to_read
) {
450 return 0; /* "read nothing" */
453 /* adjust read data count appropriately since this was a duplicate read */
454 src
->dec_read_data_count (to_read
);
456 memset (mixdown_buffer
, 0, sizeof (Sample
) * cnt
);
460 if (rops
& ReadOpsFades
) {
464 if (_fade_in_active
&& _session
.config
.get_use_region_fades()) {
466 framecnt_t fade_in_length
= (framecnt_t
) _fade_in
->back()->when
;
468 /* see if this read is within the fade in */
470 if (internal_offset
< fade_in_length
) {
474 fi_limit
= min (to_read
, fade_in_length
- internal_offset
);
476 _fade_in
->curve().get_vector (internal_offset
, internal_offset
+fi_limit
, gain_buffer
, fi_limit
);
478 for (framecnt_t n
= 0; n
< fi_limit
; ++n
) {
479 mixdown_buffer
[n
] *= gain_buffer
[n
];
486 if (_fade_out_active
&& _session
.config
.get_use_region_fades()) {
488 /* see if some part of this read is within the fade out */
490 /* ................. >| REGION
496 limit - fade_out_length
499 ^internal_offset + to_read
501 we need the intersection of [internal_offset,internal_offset+to_read] with
502 [limit - fade_out_length, limit]
507 framecnt_t fade_out_length
= (framecnt_t
) _fade_out
->back()->when
;
508 framecnt_t fade_interval_start
= max(internal_offset
, limit
-fade_out_length
);
509 framecnt_t fade_interval_end
= min(internal_offset
+ to_read
, limit
);
511 if (fade_interval_end
> fade_interval_start
) {
512 /* (part of the) the fade out is in this buffer */
514 framecnt_t fo_limit
= fade_interval_end
- fade_interval_start
;
515 framecnt_t curve_offset
= fade_interval_start
- (limit
-fade_out_length
);
516 framecnt_t fade_offset
= fade_interval_start
- internal_offset
;
518 _fade_out
->curve().get_vector (curve_offset
, curve_offset
+fo_limit
, gain_buffer
, fo_limit
);
520 for (framecnt_t n
= 0, m
= fade_offset
; n
< fo_limit
; ++n
, ++m
) {
521 mixdown_buffer
[m
] *= gain_buffer
[n
];
528 /* Regular gain curves and scaling */
530 if ((rops
& ReadOpsOwnAutomation
) && envelope_active()) {
531 _envelope
->curve().get_vector (internal_offset
, internal_offset
+ to_read
, gain_buffer
, to_read
);
533 if ((rops
& ReadOpsOwnScaling
) && _scale_amplitude
!= 1.0f
) {
534 for (framecnt_t n
= 0; n
< to_read
; ++n
) {
535 mixdown_buffer
[n
] *= gain_buffer
[n
] * _scale_amplitude
;
538 for (framecnt_t n
= 0; n
< to_read
; ++n
) {
539 mixdown_buffer
[n
] *= gain_buffer
[n
];
542 } else if ((rops
& ReadOpsOwnScaling
) && _scale_amplitude
!= 1.0f
) {
544 // XXX this should be using what in 2.0 would have been:
545 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
547 for (framecnt_t n
= 0; n
< to_read
; ++n
) {
548 mixdown_buffer
[n
] *= _scale_amplitude
;
552 if (!opaque() && (buf
!= mixdown_buffer
)) {
554 /* gack. the things we do for users.
559 for (framecnt_t n
= 0; n
< to_read
; ++n
) {
560 buf
[n
] += mixdown_buffer
[n
];
568 AudioRegion::state ()
570 XMLNode
& node (Region::state ());
573 LocaleGuard
lg (X_("POSIX"));
575 snprintf (buf
, sizeof (buf
), "%u", (uint32_t) _sources
.size());
576 node
.add_property ("channels", buf
);
578 Stateful::add_properties (node
);
580 child
= node
.add_child ("Envelope");
582 bool default_env
= false;
584 // If there are only two points, the points are in the start of the region and the end of the region
585 // so, if they are both at 1.0f, that means the default region.
587 if (_envelope
->size() == 2 &&
588 _envelope
->front()->value
== 1.0f
&&
589 _envelope
->back()->value
==1.0f
) {
590 if (_envelope
->front()->when
== 0 && _envelope
->back()->when
== _length
) {
596 child
->add_property ("default", "yes");
598 child
->add_child_nocopy (_envelope
->get_state ());
601 child
= node
.add_child (X_("FadeIn"));
603 if (_default_fade_in
) {
604 child
->add_property ("default", "yes");
606 child
->add_child_nocopy (_fade_in
->get_state ());
609 child
= node
.add_child (X_("FadeOut"));
611 if (_default_fade_out
) {
612 child
->add_property ("default", "yes");
614 child
->add_child_nocopy (_fade_out
->get_state ());
621 AudioRegion::_set_state (const XMLNode
& node
, int version
, PropertyChange
& what_changed
, bool send
)
623 const XMLNodeList
& nlist
= node
.children();
624 const XMLProperty
*prop
;
625 LocaleGuard
lg (X_("POSIX"));
626 boost::shared_ptr
<Playlist
> the_playlist (_playlist
.lock());
628 suspend_property_changes ();
631 the_playlist
->freeze ();
635 /* this will set all our State members and stuff controlled by the Region.
636 It should NOT send any changed signals - that is our responsibility.
639 Region::_set_state (node
, version
, what_changed
, false);
641 if ((prop
= node
.property ("scale-gain")) != 0) {
642 float a
= atof (prop
->value().c_str());
643 if (a
!= _scale_amplitude
) {
644 _scale_amplitude
= a
;
645 what_changed
.add (Properties::scale_amplitude
);
649 /* Now find envelope description and other related child items */
651 _envelope
->freeze ();
653 for (XMLNodeConstIterator niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
659 if (child
->name() == "Envelope") {
663 if ((prop
= child
->property ("default")) != 0 || _envelope
->set_state (*child
, version
)) {
664 set_default_envelope ();
667 _envelope
->set_max_xval (_length
);
668 _envelope
->truncate_end (_length
);
671 } else if (child
->name() == "FadeIn") {
675 if ((prop
= child
->property ("default")) != 0 || (prop
= child
->property ("steepness")) != 0) {
676 set_default_fade_in ();
678 XMLNode
* grandchild
= child
->child ("AutomationList");
680 _fade_in
->set_state (*grandchild
, version
);
684 if ((prop
= child
->property ("active")) != 0) {
685 if (string_is_affirmative (prop
->value())) {
686 set_fade_in_active (true);
688 set_fade_in_active (false);
692 } else if (child
->name() == "FadeOut") {
696 if ((prop
= child
->property ("default")) != 0 || (prop
= child
->property ("steepness")) != 0) {
697 set_default_fade_out ();
699 XMLNode
* grandchild
= child
->child ("AutomationList");
701 _fade_out
->set_state (*grandchild
, version
);
705 if ((prop
= child
->property ("active")) != 0) {
706 if (string_is_affirmative (prop
->value())) {
707 set_fade_out_active (true);
709 set_fade_out_active (false);
717 resume_property_changes ();
720 send_change (what_changed
);
724 the_playlist
->thaw ();
731 AudioRegion::set_state (const XMLNode
& node
, int version
)
733 PropertyChange what_changed
;
734 return _set_state (node
, version
, what_changed
, true);
738 AudioRegion::set_fade_in_shape (FadeShape shape
)
740 set_fade_in (shape
, (framecnt_t
) _fade_in
->back()->when
);
744 AudioRegion::set_fade_out_shape (FadeShape shape
)
746 set_fade_out (shape
, (framecnt_t
) _fade_out
->back()->when
);
750 AudioRegion::set_fade_in (boost::shared_ptr
<AutomationList
> f
)
756 send_change (PropertyChange (Properties::fade_in
));
760 AudioRegion::set_fade_in (FadeShape shape
, framecnt_t len
)
767 _fade_in
->fast_simple_add (0.0, 0.0);
768 _fade_in
->fast_simple_add (len
, 1.0);
772 _fade_in
->fast_simple_add (0, 0);
773 _fade_in
->fast_simple_add (len
* 0.389401, 0.0333333);
774 _fade_in
->fast_simple_add (len
* 0.629032, 0.0861111);
775 _fade_in
->fast_simple_add (len
* 0.829493, 0.233333);
776 _fade_in
->fast_simple_add (len
* 0.9447, 0.483333);
777 _fade_in
->fast_simple_add (len
* 0.976959, 0.697222);
778 _fade_in
->fast_simple_add (len
, 1);
782 _fade_in
->fast_simple_add (0, 0);
783 _fade_in
->fast_simple_add (len
* 0.0207373, 0.197222);
784 _fade_in
->fast_simple_add (len
* 0.0645161, 0.525);
785 _fade_in
->fast_simple_add (len
* 0.152074, 0.802778);
786 _fade_in
->fast_simple_add (len
* 0.276498, 0.919444);
787 _fade_in
->fast_simple_add (len
* 0.481567, 0.980556);
788 _fade_in
->fast_simple_add (len
* 0.767281, 1);
789 _fade_in
->fast_simple_add (len
, 1);
793 _fade_in
->fast_simple_add (0, 0);
794 _fade_in
->fast_simple_add (len
* 0.0737327, 0.308333);
795 _fade_in
->fast_simple_add (len
* 0.246544, 0.658333);
796 _fade_in
->fast_simple_add (len
* 0.470046, 0.886111);
797 _fade_in
->fast_simple_add (len
* 0.652074, 0.972222);
798 _fade_in
->fast_simple_add (len
* 0.771889, 0.988889);
799 _fade_in
->fast_simple_add (len
, 1);
803 _fade_in
->fast_simple_add (0, 0);
804 _fade_in
->fast_simple_add (len
* 0.304147, 0.0694444);
805 _fade_in
->fast_simple_add (len
* 0.529954, 0.152778);
806 _fade_in
->fast_simple_add (len
* 0.725806, 0.333333);
807 _fade_in
->fast_simple_add (len
* 0.847926, 0.558333);
808 _fade_in
->fast_simple_add (len
* 0.919355, 0.730556);
809 _fade_in
->fast_simple_add (len
, 1);
814 send_change (PropertyChange (Properties::fade_in
));
818 AudioRegion::set_fade_out (boost::shared_ptr
<AutomationList
> f
)
820 _fade_out
->freeze ();
824 send_change (PropertyChange (Properties::fade_in
));
828 AudioRegion::set_fade_out (FadeShape shape
, framecnt_t len
)
830 _fade_out
->freeze ();
835 _fade_out
->fast_simple_add (len
* 0, 1);
836 _fade_out
->fast_simple_add (len
* 0.023041, 0.697222);
837 _fade_out
->fast_simple_add (len
* 0.0553, 0.483333);
838 _fade_out
->fast_simple_add (len
* 0.170507, 0.233333);
839 _fade_out
->fast_simple_add (len
* 0.370968, 0.0861111);
840 _fade_out
->fast_simple_add (len
* 0.610599, 0.0333333);
841 _fade_out
->fast_simple_add (len
* 1, 0);
845 _fade_out
->fast_simple_add (len
* 0, 1);
846 _fade_out
->fast_simple_add (len
* 0.228111, 0.988889);
847 _fade_out
->fast_simple_add (len
* 0.347926, 0.972222);
848 _fade_out
->fast_simple_add (len
* 0.529954, 0.886111);
849 _fade_out
->fast_simple_add (len
* 0.753456, 0.658333);
850 _fade_out
->fast_simple_add (len
* 0.9262673, 0.308333);
851 _fade_out
->fast_simple_add (len
* 1, 0);
855 _fade_out
->fast_simple_add (len
* 0, 1);
856 _fade_out
->fast_simple_add (len
* 0.305556, 1);
857 _fade_out
->fast_simple_add (len
* 0.548611, 0.991736);
858 _fade_out
->fast_simple_add (len
* 0.759259, 0.931129);
859 _fade_out
->fast_simple_add (len
* 0.918981, 0.68595);
860 _fade_out
->fast_simple_add (len
* 0.976852, 0.22865);
861 _fade_out
->fast_simple_add (len
* 1, 0);
865 _fade_out
->fast_simple_add (len
* 0, 1);
866 _fade_out
->fast_simple_add (len
* 0.080645, 0.730556);
867 _fade_out
->fast_simple_add (len
* 0.277778, 0.289256);
868 _fade_out
->fast_simple_add (len
* 0.470046, 0.152778);
869 _fade_out
->fast_simple_add (len
* 0.695853, 0.0694444);
870 _fade_out
->fast_simple_add (len
* 1, 0);
874 _fade_out
->fast_simple_add (len
* 0, 1);
875 _fade_out
->fast_simple_add (len
* 1, 0);
880 send_change (PropertyChange (Properties::fade_in
));
884 AudioRegion::set_fade_in_length (framecnt_t len
)
890 bool changed
= _fade_in
->extend_to (len
);
893 _default_fade_in
= false;
894 send_change (PropertyChange (Properties::fade_in
));
899 AudioRegion::set_fade_out_length (framecnt_t len
)
905 bool changed
= _fade_out
->extend_to (len
);
908 _default_fade_out
= false;
909 send_change (PropertyChange (Properties::fade_out
));
914 AudioRegion::set_fade_in_active (bool yn
)
916 if (yn
== _fade_in_active
) {
920 _fade_in_active
= yn
;
921 send_change (PropertyChange (Properties::fade_in_active
));
925 AudioRegion::set_fade_out_active (bool yn
)
927 if (yn
== _fade_out_active
) {
930 _fade_out_active
= yn
;
931 send_change (PropertyChange (Properties::fade_out_active
));
935 AudioRegion::fade_in_is_default () const
937 return _fade_in
->size() == 2 && _fade_in
->front()->when
== 0 && _fade_in
->back()->when
== 64;
941 AudioRegion::fade_out_is_default () const
943 return _fade_out
->size() == 2 && _fade_out
->front()->when
== 0 && _fade_out
->back()->when
== 64;
947 AudioRegion::set_default_fade_in ()
949 _fade_in_suspended
= 0;
950 set_fade_in (FadeLinear
, 64);
954 AudioRegion::set_default_fade_out ()
956 _fade_out_suspended
= 0;
957 set_fade_out (FadeLinear
, 64);
961 AudioRegion::set_default_fades ()
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 suspend_property_changes();
991 if (_left_of_split
) {
992 set_default_fade_out ();
993 _left_of_split
= false;
994 } else if (_fade_out
->back()->when
> _length
) {
995 _fade_out
->extend_to (_length
);
996 send_change (PropertyChange (Properties::fade_out
));
999 if (_fade_in
->back()->when
> _length
) {
1000 _fade_in
->extend_to (_length
);
1001 send_change (PropertyChange (Properties::fade_in
));
1004 resume_property_changes();
1008 AudioRegion::recompute_at_start ()
1010 /* as above, but the shift was from the front */
1012 _envelope
->truncate_start (_length
);
1014 suspend_property_changes();
1016 if (_right_of_split
) {
1017 set_default_fade_in ();
1018 _right_of_split
= false;
1019 } else if (_fade_in
->back()->when
> _length
) {
1020 _fade_in
->extend_to (_length
);
1021 send_change (PropertyChange (Properties::fade_in
));
1024 if (_fade_out
->back()->when
> _length
) {
1025 _fade_out
->extend_to (_length
);
1026 send_change (PropertyChange (Properties::fade_out
));
1029 resume_property_changes();
1033 AudioRegion::separate_by_channel (Session
& /*session*/, vector
<boost::shared_ptr
<Region
> >& v
) const
1039 if (_sources
.size() < 2) {
1043 for (SourceList::const_iterator i
= _sources
.begin(); i
!= _sources
.end(); ++i
) {
1045 srcs
.push_back (*i
);
1049 if (_sources
.size() == 2) {
1057 new_name
+= ('0' + n
+ 1);
1060 /* create a copy with just one source. prevent if from being thought of as
1061 "whole file" even if it covers the entire source file(s).
1066 plist
.add (Properties::start
, _start
.val());
1067 plist
.add (Properties::length
, _length
.val());
1068 plist
.add (Properties::name
, new_name
);
1069 plist
.add (Properties::layer
, _layer
.val());
1071 v
.push_back(RegionFactory::create (srcs
, plist
));
1072 v
.back()->set_whole_file (false);
1081 AudioRegion::read_raw_internal (Sample
* buf
, framepos_t pos
, framecnt_t cnt
, int channel
) const
1083 return audio_source(channel
)->read (buf
, pos
, cnt
);
1087 AudioRegion::exportme (Session
& /*session*/, ARDOUR::ExportSpecification
& /*spec*/)
1090 // const framecnt_t blocksize = 4096;
1091 // framecnt_t to_read;
1094 // spec.channels = _sources.size();
1096 // if (spec.prepare (blocksize, session.frame_rate())) {
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) {
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) {
1126 // for (framecnt_t x = 0; x < to_read; ++x) {
1127 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1132 // if (spec.process (to_read)) {
1136 // spec.pos += to_read;
1137 // spec.progress = (double) spec.pos /_length;
1144 // spec.running = false;
1145 // spec.status = status;
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 */
1162 pl
->ContentsChanged();
1165 /* tell everybody else */
1167 send_change (PropertyChange (Properties::scale_amplitude
));
1170 /** @return the maximum (linear) amplitude of the region, or a -ve
1171 * number if the Progress object reports that the process was cancelled.
1174 AudioRegion::maximum_amplitude (Progress
* p
) const
1176 framepos_t fpos
= _start
;
1177 framepos_t
const fend
= _start
+ _length
;
1180 framecnt_t
const blocksize
= 64 * 1024;
1181 Sample buf
[blocksize
];
1183 while (fpos
< fend
) {
1187 framecnt_t
const to_read
= min (fend
- fpos
, blocksize
);
1189 for (n
= 0; n
< n_channels(); ++n
) {
1193 if (read_raw_internal (buf
, fpos
, to_read
, n
) != to_read
) {
1197 maxamp
= compute_peak (buf
, to_read
, maxamp
);
1202 p
->set_progress (float (fpos
- _start
) / _length
);
1203 if (p
->cancelled ()) {
1212 /** Normalize using a given maximum amplitude and target, so that region
1213 * _scale_amplitude becomes target / max_amplitude.
1216 AudioRegion::normalize (float max_amplitude
, float target_dB
)
1218 gain_t target
= dB_to_coefficient (target_dB
);
1220 if (target
== 1.0f
) {
1221 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1222 that we may have clipped.
1224 target
-= FLT_EPSILON
;
1227 if (max_amplitude
== 0.0f
) {
1228 /* don't even try */
1232 if (max_amplitude
== target
) {
1233 /* we can't do anything useful */
1237 set_scale_amplitude (target
/ max_amplitude
);
1241 AudioRegion::fade_in_changed ()
1243 send_change (PropertyChange (Properties::fade_in
));
1247 AudioRegion::fade_out_changed ()
1249 send_change (PropertyChange (Properties::fade_out
));
1253 AudioRegion::envelope_changed ()
1255 send_change (PropertyChange (Properties::envelope
));
1259 AudioRegion::suspend_fade_in ()
1261 if (++_fade_in_suspended
== 1) {
1262 if (fade_in_is_default()) {
1263 set_fade_in_active (false);
1269 AudioRegion::resume_fade_in ()
1271 if (--_fade_in_suspended
== 0 && _fade_in_suspended
) {
1272 set_fade_in_active (true);
1277 AudioRegion::suspend_fade_out ()
1279 if (++_fade_out_suspended
== 1) {
1280 if (fade_out_is_default()) {
1281 set_fade_out_active (false);
1287 AudioRegion::resume_fade_out ()
1289 if (--_fade_out_suspended
== 0 &&_fade_out_suspended
) {
1290 set_fade_out_active (true);
1295 AudioRegion::speed_mismatch (float sr
) const
1297 if (_sources
.empty()) {
1298 /* impossible, but ... */
1302 float fsr
= audio_source()->sample_rate();
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()) {
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::adjust_transients (frameoffset_t delta
)
1337 for (AnalysisFeatureList::iterator x
= _transients
.begin(); x
!= _transients
.end(); ++x
) {
1338 (*x
) = (*x
) + delta
;
1341 send_change (PropertyChange (Properties::valid_transients
));
1347 AudioRegion::update_transient (framepos_t old_position
, framepos_t new_position
)
1349 for (AnalysisFeatureList::iterator x
= _transients
.begin(); x
!= _transients
.end(); ++x
) {
1350 if ((*x
) == old_position
) {
1351 (*x
) = new_position
;
1352 send_change (PropertyChange (Properties::valid_transients
));
1362 AudioRegion::add_transient (framepos_t where
)
1364 _transients
.push_back(where
);
1365 _valid_transients
= true;
1367 send_change (PropertyChange (Properties::valid_transients
));
1371 AudioRegion::remove_transient (framepos_t where
)
1373 _transients
.remove(where
);
1374 _valid_transients
= true;
1376 send_change (PropertyChange (Properties::valid_transients
));
1380 AudioRegion::set_transients (AnalysisFeatureList
& results
)
1382 _transients
.clear();
1383 _transients
= results
;
1384 _valid_transients
= true;
1386 send_change (PropertyChange (Properties::valid_transients
));
1392 AudioRegion::get_transients (AnalysisFeatureList
& results
, bool force_new
)
1394 boost::shared_ptr
<Playlist
> pl
= playlist();
1400 if (_valid_transients
&& !force_new
) {
1401 results
= _transients
;
1405 SourceList::iterator s
;
1407 for (s
= _sources
.begin() ; s
!= _sources
.end(); ++s
) {
1408 if (!(*s
)->has_been_analysed()) {
1409 cerr
<< "For " << name() << " source " << (*s
)->name() << " has not been analyzed\n";
1414 if (s
== _sources
.end()) {
1415 /* all sources are analyzed, merge data from each one */
1417 for (s
= _sources
.begin() ; s
!= _sources
.end(); ++s
) {
1419 /* find the set of transients within the bounds of this region */
1421 AnalysisFeatureList::iterator low
= lower_bound ((*s
)->transients
.begin(),
1422 (*s
)->transients
.end(),
1425 AnalysisFeatureList::iterator high
= upper_bound ((*s
)->transients
.begin(),
1426 (*s
)->transients
.end(),
1431 results
.insert (results
.end(), low
, high
);
1434 TransientDetector::cleanup_transients (results
, pl
->session().frame_rate(), 3.0);
1436 /* translate all transients to current position */
1438 for (AnalysisFeatureList::iterator x
= results
.begin(); x
!= results
.end(); ++x
) {
1443 _transients
= results
;
1444 _valid_transients
= true;
1449 /* no existing/complete transient info */
1451 static bool analyse_dialog_shown
= false; /* global per instance of Ardour */
1453 if (!Config
->get_auto_analyse_audio()) {
1454 if (!analyse_dialog_shown
) {
1455 pl
->session().Dialog (_("\
1456 You have requested an operation that requires audio analysis.\n\n\
1457 You currently have \"auto-analyse-audio\" disabled, which means \
1458 that transient data must be generated every time it is required.\n\n\
1459 If you are doing work that will require transient data on a \
1460 regular basis, you should probably enable \"auto-analyse-audio\" \
1461 then quit ardour and restart.\n\n\
1462 This dialog will not display again. But you may notice a slight delay \
1463 in this and future transient-detection operations.\n\
1465 analyse_dialog_shown
= true;
1469 TransientDetector
t (pl
->session().frame_rate());
1470 bool existing_results
= !results
.empty();
1472 _transients
.clear ();
1473 _valid_transients
= false;
1475 for (uint32_t i
= 0; i
< n_channels(); ++i
) {
1477 AnalysisFeatureList these_results
;
1481 if (t
.run ("", this, i
, these_results
)) {
1485 /* translate all transients to give absolute position */
1487 for (AnalysisFeatureList::iterator i
= these_results
.begin(); i
!= these_results
.end(); ++i
) {
1493 _transients
.insert (_transients
.end(), these_results
.begin(), these_results
.end());
1496 if (!results
.empty()) {
1497 if (existing_results
) {
1499 /* merge our transients into the existing ones, then clean up
1503 results
.insert (results
.end(), _transients
.begin(), _transients
.end());
1504 TransientDetector::cleanup_transients (results
, pl
->session().frame_rate(), 3.0);
1507 /* make sure ours are clean too */
1509 TransientDetector::cleanup_transients (_transients
, pl
->session().frame_rate(), 3.0);
1513 TransientDetector::cleanup_transients (_transients
, pl
->session().frame_rate(), 3.0);
1514 results
= _transients
;
1517 _valid_transients
= true;
1522 /** Find areas of `silence' within a region.
1524 * @param threshold Threshold below which signal is considered silence (as a sample value)
1525 * @param min_length Minimum length of silent period to be reported.
1526 * @return Silent intervals, measured relative to the region start in the source
1530 AudioRegion::find_silence (Sample threshold
, framecnt_t min_length
, InterThreadInfo
& itt
) const
1532 framecnt_t
const block_size
= 64 * 1024;
1533 boost::scoped_array
<Sample
> loudest (new Sample
[block_size
]);
1534 boost::scoped_array
<Sample
> buf (new Sample
[block_size
]);
1536 framepos_t pos
= _start
;
1537 framepos_t
const end
= _start
+ _length
- 1;
1539 AudioIntervalResult silent_periods
;
1541 bool in_silence
= false;
1542 frameoffset_t silence_start
= 0;
1544 while (pos
< end
&& !itt
.cancel
) {
1546 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1547 memset (loudest
.get(), 0, sizeof (Sample
) * block_size
);
1548 for (uint32_t n
= 0; n
< n_channels(); ++n
) {
1550 read_raw_internal (buf
.get(), pos
, block_size
, n
);
1551 for (framecnt_t i
= 0; i
< block_size
; ++i
) {
1552 loudest
[i
] = max (loudest
[i
], abs (buf
[i
]));
1556 /* now look for silence */
1557 for (framecnt_t i
= 0; i
< block_size
; ++i
) {
1558 bool const silence
= abs (loudest
[i
]) < threshold
;
1559 if (silence
&& !in_silence
) {
1560 /* non-silence to silence */
1562 silence_start
= pos
+ i
;
1563 } else if (!silence
&& in_silence
) {
1564 /* silence to non-silence */
1566 if (pos
+ i
- 1 - silence_start
>= min_length
) {
1567 silent_periods
.push_back (std::make_pair (silence_start
, pos
+ i
- 1));
1573 itt
.progress
= (end
-pos
)/(double)_length
;
1576 if (in_silence
&& end
- 1 - silence_start
>= min_length
) {
1577 /* last block was silent, so finish off the last period */
1578 silent_periods
.push_back (std::make_pair (silence_start
, end
));
1583 return silent_periods
;
1590 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
)
1592 return ((AudioRegion
*) arg
)->read_peaks ((PeakData
*) data
, (framecnt_t
) npeaks
, (framepos_t
) start
, (framecnt_t
) cnt
, n_chan
,samples_per_unit
);
1595 uint32_t region_length_from_c (void *arg
)
1598 return ((AudioRegion
*) arg
)->length();
1601 uint32_t sourcefile_length_from_c (void *arg
, double zoom_factor
)
1603 return ( (AudioRegion
*) arg
)->audio_source()->available_peaks (zoom_factor
) ;