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.
28 #include <glibmm/thread.h>
30 #include "pbd/basename.h"
31 #include "pbd/xml++.h"
32 #include "pbd/stacktrace.h"
33 #include "pbd/enumwriter.h"
34 #include "pbd/convert.h"
36 #include "evoral/Curve.hpp"
38 #include "ardour/audioregion.h"
39 #include "ardour/debug.h"
40 #include "ardour/session.h"
41 #include "ardour/gain.h"
42 #include "ardour/dB.h"
43 #include "ardour/playlist.h"
44 #include "ardour/audiofilesource.h"
45 #include "ardour/region_factory.h"
46 #include "ardour/runtime_functions.h"
47 #include "ardour/transient_detector.h"
53 using namespace ARDOUR
;
57 namespace Properties
{
58 PBD::PropertyDescriptor
<bool> envelope_active
;
59 PBD::PropertyDescriptor
<bool> default_fade_in
;
60 PBD::PropertyDescriptor
<bool> default_fade_out
;
61 PBD::PropertyDescriptor
<bool> fade_in_active
;
62 PBD::PropertyDescriptor
<bool> fade_out_active
;
63 PBD::PropertyDescriptor
<float> scale_amplitude
;
68 AudioRegion::make_property_quarks ()
70 Properties::envelope_active
.property_id
= g_quark_from_static_string (X_("envelope-active"));
71 DEBUG_TRACE (DEBUG::Properties
, string_compose ("quark for envelope-active = %1\n", Properties::envelope_active
.property_id
));
72 Properties::default_fade_in
.property_id
= g_quark_from_static_string (X_("default-fade-in"));
73 DEBUG_TRACE (DEBUG::Properties
, string_compose ("quark for default-fade-in = %1\n", Properties::default_fade_in
.property_id
));
74 Properties::default_fade_out
.property_id
= g_quark_from_static_string (X_("default-fade-out"));
75 DEBUG_TRACE (DEBUG::Properties
, string_compose ("quark for default-fade-out = %1\n", Properties::default_fade_out
.property_id
));
76 Properties::fade_in_active
.property_id
= g_quark_from_static_string (X_("fade-in-active"));
77 DEBUG_TRACE (DEBUG::Properties
, string_compose ("quark for fade-in-active = %1\n", Properties::fade_in_active
.property_id
));
78 Properties::fade_out_active
.property_id
= g_quark_from_static_string (X_("fade-out-active"));
79 DEBUG_TRACE (DEBUG::Properties
, string_compose ("quark for fade-out-active = %1\n", Properties::fade_out_active
.property_id
));
80 Properties::scale_amplitude
.property_id
= g_quark_from_static_string (X_("scale-amplitude"));
81 DEBUG_TRACE (DEBUG::Properties
, string_compose ("quark for scale-amplitude = %1\n", Properties::scale_amplitude
.property_id
));
85 AudioRegion::register_properties ()
87 /* no need to register parent class properties */
89 add_property (_envelope_active
);
90 add_property (_default_fade_in
);
91 add_property (_default_fade_out
);
92 add_property (_fade_in_active
);
93 add_property (_fade_out_active
);
94 add_property (_scale_amplitude
);
97 #define AUDIOREGION_STATE_DEFAULT \
98 _envelope_active (Properties::envelope_active, false) \
99 , _default_fade_in (Properties::default_fade_in, true) \
100 , _default_fade_out (Properties::default_fade_out, true) \
101 , _fade_in_active (Properties::fade_in_active, true) \
102 , _fade_out_active (Properties::fade_out_active, true) \
103 , _scale_amplitude (Properties::scale_amplitude, 1.0)
105 #define AUDIOREGION_COPY_STATE(other) \
106 _envelope_active (other->_envelope_active) \
107 , _default_fade_in (other->_default_fade_in) \
108 , _default_fade_out (other->_default_fade_out) \
109 , _fade_in_active (other->_fade_in_active) \
110 , _fade_out_active (other->_fade_out_active) \
111 , _scale_amplitude (other->_scale_amplitude)
112 /* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
117 register_properties ();
119 set_default_fades ();
120 set_default_envelope ();
122 listen_to_my_curves ();
123 connect_to_analysis_changed ();
124 connect_to_header_position_offset_changed ();
127 /** Constructor for use by derived types only */
128 AudioRegion::AudioRegion (Session
& s
, framepos_t start
, framecnt_t len
, std::string name
)
129 : Region (s
, start
, len
, name
, DataType::AUDIO
)
130 , AUDIOREGION_STATE_DEFAULT
132 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation
)))
133 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation
)))
134 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation
)))
135 , _fade_in_suspended (0)
136 , _fade_out_suspended (0)
139 assert (_sources
.size() == _master_sources
.size());
142 /** Basic AudioRegion constructor */
143 AudioRegion::AudioRegion (const SourceList
& srcs
)
145 , AUDIOREGION_STATE_DEFAULT
146 , _automatable(srcs
[0]->session())
147 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation
)))
148 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation
)))
149 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation
)))
150 , _fade_in_suspended (0)
151 , _fade_out_suspended (0)
154 assert (_sources
.size() == _master_sources
.size());
157 AudioRegion::AudioRegion (boost::shared_ptr
<const AudioRegion
> other
, nframes64_t offset
, bool offset_relative
)
158 : Region (other
, offset
, offset_relative
)
159 , AUDIOREGION_COPY_STATE (other
)
160 , _automatable (other
->session())
161 , _fade_in (new AutomationList (*other
->_fade_in
))
162 , _fade_out (new AutomationList (*other
->_fade_out
))
163 /* XXX is this guaranteed to work for all values of offset+offset_relative? */
164 , _envelope (new AutomationList (*other
->_envelope
, _start
, _start
+ _length
))
165 , _fade_in_suspended (0)
166 , _fade_out_suspended (0)
168 /* don't use init here, because we got fade in/out from the other region
170 register_properties ();
171 listen_to_my_curves ();
172 connect_to_analysis_changed ();
173 connect_to_header_position_offset_changed ();
175 assert(_type
== DataType::AUDIO
);
176 assert (_sources
.size() == _master_sources
.size());
179 AudioRegion::AudioRegion (boost::shared_ptr
<const AudioRegion
> other
, const SourceList
& srcs
)
180 : Region (boost::static_pointer_cast
<const Region
>(other
), srcs
)
181 , AUDIOREGION_COPY_STATE (other
)
182 , _automatable (other
->session())
183 , _fade_in (new AutomationList (*other
->_fade_in
))
184 , _fade_out (new AutomationList (*other
->_fade_out
))
185 , _envelope (new AutomationList (*other
->_envelope
))
186 , _fade_in_suspended (0)
187 , _fade_out_suspended (0)
189 /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */
191 register_properties ();
193 listen_to_my_curves ();
194 connect_to_analysis_changed ();
195 connect_to_header_position_offset_changed ();
197 assert (_sources
.size() == _master_sources
.size());
200 AudioRegion::AudioRegion (SourceList
& srcs
)
202 , AUDIOREGION_STATE_DEFAULT
203 , _automatable(srcs
[0]->session())
204 , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation
)))
205 , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation
)))
206 , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation
)))
207 , _fade_in_suspended (0)
208 , _fade_out_suspended (0)
212 assert(_type
== DataType::AUDIO
);
213 assert (_sources
.size() == _master_sources
.size());
216 AudioRegion::~AudioRegion ()
221 AudioRegion::post_set ()
224 _sync_position
= _start
;
227 /* return to default fades if the existing ones are too long */
229 if (_left_of_split
) {
230 if (_fade_in
->back()->when
>= _length
) {
231 set_default_fade_in ();
233 set_default_fade_out ();
234 _left_of_split
= false;
237 if (_right_of_split
) {
238 if (_fade_out
->back()->when
>= _length
) {
239 set_default_fade_out ();
242 set_default_fade_in ();
243 _right_of_split
= false;
246 /* If _length changed, adjust our gain envelope accordingly */
247 _envelope
->truncate_end (_length
);
251 AudioRegion::connect_to_analysis_changed ()
253 for (SourceList::const_iterator i
= _sources
.begin(); i
!= _sources
.end(); ++i
) {
254 (*i
)->AnalysisChanged
.connect_same_thread (*this, boost::bind (&AudioRegion::invalidate_transients
, this));
259 AudioRegion::connect_to_header_position_offset_changed ()
261 set
<boost::shared_ptr
<Source
> > unique_srcs
;
263 for (SourceList::const_iterator i
= _sources
.begin(); i
!= _sources
.end(); ++i
) {
265 /* connect only once to HeaderPositionOffsetChanged, even if sources are replicated
268 if (unique_srcs
.find (*i
) == unique_srcs
.end ()) {
269 unique_srcs
.insert (*i
);
270 boost::shared_ptr
<AudioFileSource
> afs
= boost::dynamic_pointer_cast
<AudioFileSource
> (*i
);
272 afs
->HeaderPositionOffsetChanged
.connect_same_thread (*this, boost::bind (&AudioRegion::source_offset_changed
, this));
279 AudioRegion::listen_to_my_curves ()
281 _envelope
->StateChanged
.connect_same_thread (*this, boost::bind (&AudioRegion::envelope_changed
, this));
282 _fade_in
->StateChanged
.connect_same_thread (*this, boost::bind (&AudioRegion::fade_in_changed
, this));
283 _fade_out
->StateChanged
.connect_same_thread (*this, boost::bind (&AudioRegion::fade_out_changed
, this));
287 AudioRegion::set_envelope_active (bool yn
)
289 if (envelope_active() != yn
) {
290 _envelope_active
= yn
;
291 send_change (PropertyChange (Properties::envelope_active
));
296 AudioRegion::read_peaks (PeakData
*buf
, nframes_t npeaks
, nframes_t offset
, nframes_t cnt
, uint32_t chan_n
, double samples_per_unit
) const
298 if (chan_n
>= _sources
.size()) {
302 if (audio_source(chan_n
)->read_peaks (buf
, npeaks
, offset
, cnt
, samples_per_unit
)) {
305 if (_scale_amplitude
!= 1.0f
) {
306 for (nframes_t n
= 0; n
< npeaks
; ++n
) {
307 buf
[n
].max
*= _scale_amplitude
;
308 buf
[n
].min
*= _scale_amplitude
;
316 AudioRegion::read (Sample
* buf
, framepos_t timeline_position
, framecnt_t cnt
, int channel
) const
318 /* raw read, no fades, no gain, nada */
319 return _read_at (_sources
, _length
, buf
, 0, 0, _position
+ timeline_position
, cnt
, channel
, 0, 0, ReadOps (0));
323 AudioRegion::read_at (Sample
*buf
, Sample
*mixdown_buffer
, float *gain_buffer
,
324 framepos_t file_position
, framecnt_t cnt
, uint32_t chan_n
,
325 framecnt_t read_frames
, framecnt_t skip_frames
) const
327 /* regular diskstream/butler read complete with fades etc */
328 return _read_at (_sources
, _length
, buf
, mixdown_buffer
, gain_buffer
,
329 file_position
, cnt
, chan_n
, read_frames
, skip_frames
, ReadOps (~0));
333 AudioRegion::master_read_at (Sample
*buf
, Sample
*mixdown_buffer
, float *gain_buffer
,
334 framepos_t position
, framecnt_t cnt
, uint32_t chan_n
) const
336 /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
338 return _read_at (_master_sources
, _master_sources
.front()->length(_master_sources
.front()->timeline_position()),
339 buf
, mixdown_buffer
, gain_buffer
, position
, cnt
, chan_n
, 0, 0, ReadOps (0));
343 AudioRegion::_read_at (const SourceList
& /*srcs*/, framecnt_t limit
,
344 Sample
*buf
, Sample
*mixdown_buffer
, float *gain_buffer
,
348 framecnt_t
/*read_frames*/,
349 framecnt_t
/*skip_frames*/,
352 frameoffset_t internal_offset
;
353 frameoffset_t buf_offset
;
355 bool raw
= (rops
== ReadOpsNone
);
357 if (muted() && !raw
) {
358 return 0; /* read nothing */
361 /* precondition: caller has verified that we cover the desired section */
363 if (position
< _position
) {
365 buf_offset
= _position
- position
;
368 internal_offset
= position
- _position
;
372 if (internal_offset
>= limit
) {
373 return 0; /* read nothing */
376 if ((to_read
= min (cnt
, limit
- internal_offset
)) == 0) {
377 return 0; /* read nothing */
380 if (opaque() || raw
) {
381 /* overwrite whatever is there */
382 mixdown_buffer
= buf
+ buf_offset
;
384 mixdown_buffer
+= buf_offset
;
387 if (rops
& ReadOpsCount
) {
388 _read_data_count
= 0;
391 if (chan_n
< n_channels()) {
393 boost::shared_ptr
<AudioSource
> src
= audio_source(chan_n
);
394 if (src
->read (mixdown_buffer
, _start
+ internal_offset
, to_read
) != to_read
) {
395 return 0; /* "read nothing" */
398 if (rops
& ReadOpsCount
) {
399 _read_data_count
+= src
->read_data_count();
404 /* track is N-channel, this region has less channels; silence the ones
408 memset (mixdown_buffer
, 0, sizeof (Sample
) * cnt
);
411 if (rops
& ReadOpsFades
) {
415 if (_fade_in_active
&& _session
.config
.get_use_region_fades()) {
417 nframes_t fade_in_length
= (nframes_t
) _fade_in
->back()->when
;
419 /* see if this read is within the fade in */
421 if (internal_offset
< fade_in_length
) {
425 fi_limit
= min (to_read
, fade_in_length
- internal_offset
);
428 _fade_in
->curve().get_vector (internal_offset
, internal_offset
+fi_limit
, gain_buffer
, fi_limit
);
430 for (nframes_t n
= 0; n
< fi_limit
; ++n
) {
431 mixdown_buffer
[n
] *= gain_buffer
[n
];
438 if (_fade_out_active
&& _session
.config
.get_use_region_fades()) {
440 /* see if some part of this read is within the fade out */
442 /* ................. >| REGION
448 limit - fade_out_length
451 ^internal_offset + to_read
453 we need the intersection of [internal_offset,internal_offset+to_read] with
454 [limit - fade_out_length, limit]
459 nframes_t fade_out_length
= (nframes_t
) _fade_out
->back()->when
;
460 nframes_t fade_interval_start
= max(internal_offset
, limit
-fade_out_length
);
461 nframes_t fade_interval_end
= min(internal_offset
+ to_read
, limit
);
463 if (fade_interval_end
> fade_interval_start
) {
464 /* (part of the) the fade out is in this buffer */
466 nframes_t fo_limit
= fade_interval_end
- fade_interval_start
;
467 nframes_t curve_offset
= fade_interval_start
- (limit
-fade_out_length
);
468 nframes_t fade_offset
= fade_interval_start
- internal_offset
;
470 _fade_out
->curve().get_vector (curve_offset
, curve_offset
+fo_limit
, gain_buffer
, fo_limit
);
472 for (nframes_t n
= 0, m
= fade_offset
; n
< fo_limit
; ++n
, ++m
) {
473 mixdown_buffer
[m
] *= gain_buffer
[n
];
480 /* Regular gain curves and scaling */
482 if ((rops
& ReadOpsOwnAutomation
) && envelope_active()) {
483 _envelope
->curve().get_vector (internal_offset
, internal_offset
+ to_read
, gain_buffer
, to_read
);
485 if ((rops
& ReadOpsOwnScaling
) && _scale_amplitude
!= 1.0f
) {
486 for (nframes_t n
= 0; n
< to_read
; ++n
) {
487 mixdown_buffer
[n
] *= gain_buffer
[n
] * _scale_amplitude
;
490 for (nframes_t n
= 0; n
< to_read
; ++n
) {
491 mixdown_buffer
[n
] *= gain_buffer
[n
];
494 } else if ((rops
& ReadOpsOwnScaling
) && _scale_amplitude
!= 1.0f
) {
496 // XXX this should be using what in 2.0 would have been:
497 // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude);
499 for (nframes_t n
= 0; n
< to_read
; ++n
) {
500 mixdown_buffer
[n
] *= _scale_amplitude
;
506 /* gack. the things we do for users.
511 for (nframes_t n
= 0; n
< to_read
; ++n
) {
512 buf
[n
] += mixdown_buffer
[n
];
520 AudioRegion::state (bool full
)
522 XMLNode
& node (Region::state (full
));
525 LocaleGuard
lg (X_("POSIX"));
527 snprintf (buf
, sizeof (buf
), "%u", (uint32_t) _sources
.size());
528 node
.add_property ("channels", buf
);
531 Stateful::add_properties (node
);
534 child
= node
.add_child ("Envelope");
537 bool default_env
= false;
539 // If there are only two points, the points are in the start of the region and the end of the region
540 // so, if they are both at 1.0f, that means the default region.
542 if (_envelope
->size() == 2 &&
543 _envelope
->front()->value
== 1.0f
&&
544 _envelope
->back()->value
==1.0f
) {
545 if (_envelope
->front()->when
== 0 && _envelope
->back()->when
== _length
) {
551 child
->add_property ("default", "yes");
553 child
->add_child_nocopy (_envelope
->get_state ());
557 child
->add_property ("default", "yes");
564 AudioRegion::_set_state (const XMLNode
& node
, int version
, PropertyChange
& what_changed
, bool send
)
566 const XMLNodeList
& nlist
= node
.children();
567 const XMLProperty
*prop
;
568 LocaleGuard
lg (X_("POSIX"));
569 boost::shared_ptr
<Playlist
> the_playlist (_playlist
.lock());
571 suspend_property_changes ();
574 the_playlist
->freeze ();
578 /* this will set all our State members and stuff controlled by the Region.
579 It should NOT send any changed signals - that is our responsibility.
582 Region::_set_state (node
, version
, what_changed
, false);
584 if ((prop
= node
.property ("scale-gain")) != 0) {
585 float a
= atof (prop
->value().c_str());
586 if (a
!= _scale_amplitude
) {
587 _scale_amplitude
= a
;
588 what_changed
.add (Properties::scale_amplitude
);
592 /* Now find envelope description and other related child items */
594 _envelope
->freeze ();
596 for (XMLNodeConstIterator niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
602 if (child
->name() == "Envelope") {
606 if ((prop
= child
->property ("default")) != 0 || _envelope
->set_state (*child
, version
)) {
607 set_default_envelope ();
610 _envelope
->set_max_xval (_length
);
611 _envelope
->truncate_end (_length
);
614 } else if (child
->name() == "FadeIn") {
618 if ((prop
= child
->property ("default")) != 0 || (prop
= child
->property ("steepness")) != 0) {
619 set_default_fade_in ();
621 XMLNode
* grandchild
= child
->child ("AutomationList");
623 _fade_in
->set_state (*grandchild
, version
);
627 if ((prop
= child
->property ("active")) != 0) {
628 if (string_is_affirmative (prop
->value())) {
629 set_fade_in_active (true);
631 set_fade_in_active (false);
635 } else if (child
->name() == "FadeOut") {
639 if ((prop
= child
->property ("default")) != 0 || (prop
= child
->property ("steepness")) != 0) {
640 set_default_fade_out ();
642 XMLNode
* grandchild
= child
->child ("AutomationList");
644 _fade_out
->set_state (*grandchild
, version
);
648 if ((prop
= child
->property ("active")) != 0) {
649 if (string_is_affirmative (prop
->value())) {
650 set_fade_out_active (true);
652 set_fade_out_active (false);
660 resume_property_changes ();
663 send_change (what_changed
);
667 the_playlist
->thaw ();
674 AudioRegion::set_state (const XMLNode
& node
, int version
)
676 PropertyChange what_changed
;
677 return _set_state (node
, version
, what_changed
, true);
681 AudioRegion::set_fade_in_shape (FadeShape shape
)
683 set_fade_in (shape
, (nframes_t
) _fade_in
->back()->when
);
687 AudioRegion::set_fade_out_shape (FadeShape shape
)
689 set_fade_out (shape
, (nframes_t
) _fade_out
->back()->when
);
693 AudioRegion::set_fade_in (boost::shared_ptr
<AutomationList
> f
)
699 send_change (PropertyChange (Properties::fade_in
));
703 AudioRegion::set_fade_in (FadeShape shape
, framecnt_t len
)
710 _fade_in
->fast_simple_add (0.0, 0.0);
711 _fade_in
->fast_simple_add (len
, 1.0);
715 _fade_in
->fast_simple_add (0, 0);
716 _fade_in
->fast_simple_add (len
* 0.389401, 0.0333333);
717 _fade_in
->fast_simple_add (len
* 0.629032, 0.0861111);
718 _fade_in
->fast_simple_add (len
* 0.829493, 0.233333);
719 _fade_in
->fast_simple_add (len
* 0.9447, 0.483333);
720 _fade_in
->fast_simple_add (len
* 0.976959, 0.697222);
721 _fade_in
->fast_simple_add (len
, 1);
725 _fade_in
->fast_simple_add (0, 0);
726 _fade_in
->fast_simple_add (len
* 0.0207373, 0.197222);
727 _fade_in
->fast_simple_add (len
* 0.0645161, 0.525);
728 _fade_in
->fast_simple_add (len
* 0.152074, 0.802778);
729 _fade_in
->fast_simple_add (len
* 0.276498, 0.919444);
730 _fade_in
->fast_simple_add (len
* 0.481567, 0.980556);
731 _fade_in
->fast_simple_add (len
* 0.767281, 1);
732 _fade_in
->fast_simple_add (len
, 1);
736 _fade_in
->fast_simple_add (0, 0);
737 _fade_in
->fast_simple_add (len
* 0.0737327, 0.308333);
738 _fade_in
->fast_simple_add (len
* 0.246544, 0.658333);
739 _fade_in
->fast_simple_add (len
* 0.470046, 0.886111);
740 _fade_in
->fast_simple_add (len
* 0.652074, 0.972222);
741 _fade_in
->fast_simple_add (len
* 0.771889, 0.988889);
742 _fade_in
->fast_simple_add (len
, 1);
746 _fade_in
->fast_simple_add (0, 0);
747 _fade_in
->fast_simple_add (len
* 0.304147, 0.0694444);
748 _fade_in
->fast_simple_add (len
* 0.529954, 0.152778);
749 _fade_in
->fast_simple_add (len
* 0.725806, 0.333333);
750 _fade_in
->fast_simple_add (len
* 0.847926, 0.558333);
751 _fade_in
->fast_simple_add (len
* 0.919355, 0.730556);
752 _fade_in
->fast_simple_add (len
, 1);
760 AudioRegion::set_fade_out (boost::shared_ptr
<AutomationList
> f
)
762 _fade_out
->freeze ();
766 send_change (PropertyChange (Properties::fade_in
));
770 AudioRegion::set_fade_out (FadeShape shape
, framecnt_t len
)
772 _fade_out
->freeze ();
777 _fade_out
->fast_simple_add (len
* 0, 1);
778 _fade_out
->fast_simple_add (len
* 0.023041, 0.697222);
779 _fade_out
->fast_simple_add (len
* 0.0553, 0.483333);
780 _fade_out
->fast_simple_add (len
* 0.170507, 0.233333);
781 _fade_out
->fast_simple_add (len
* 0.370968, 0.0861111);
782 _fade_out
->fast_simple_add (len
* 0.610599, 0.0333333);
783 _fade_out
->fast_simple_add (len
* 1, 0);
787 _fade_out
->fast_simple_add (len
* 0, 1);
788 _fade_out
->fast_simple_add (len
* 0.228111, 0.988889);
789 _fade_out
->fast_simple_add (len
* 0.347926, 0.972222);
790 _fade_out
->fast_simple_add (len
* 0.529954, 0.886111);
791 _fade_out
->fast_simple_add (len
* 0.753456, 0.658333);
792 _fade_out
->fast_simple_add (len
* 0.9262673, 0.308333);
793 _fade_out
->fast_simple_add (len
* 1, 0);
797 _fade_out
->fast_simple_add (len
* 0, 1);
798 _fade_out
->fast_simple_add (len
* 0.305556, 1);
799 _fade_out
->fast_simple_add (len
* 0.548611, 0.991736);
800 _fade_out
->fast_simple_add (len
* 0.759259, 0.931129);
801 _fade_out
->fast_simple_add (len
* 0.918981, 0.68595);
802 _fade_out
->fast_simple_add (len
* 0.976852, 0.22865);
803 _fade_out
->fast_simple_add (len
* 1, 0);
807 _fade_out
->fast_simple_add (len
* 0, 1);
808 _fade_out
->fast_simple_add (len
* 0.080645, 0.730556);
809 _fade_out
->fast_simple_add (len
* 0.277778, 0.289256);
810 _fade_out
->fast_simple_add (len
* 0.470046, 0.152778);
811 _fade_out
->fast_simple_add (len
* 0.695853, 0.0694444);
812 _fade_out
->fast_simple_add (len
* 1, 0);
816 _fade_out
->fast_simple_add (len
* 0, 1);
817 _fade_out
->fast_simple_add (len
* 1, 0);
825 AudioRegion::set_fade_in_length (framecnt_t len
)
831 bool changed
= _fade_in
->extend_to (len
);
834 _default_fade_in
= false;
835 send_change (PropertyChange (Properties::fade_in
));
840 AudioRegion::set_fade_out_length (framecnt_t len
)
846 bool changed
= _fade_out
->extend_to (len
);
849 _default_fade_out
= false;
850 send_change (PropertyChange (Properties::fade_out
));
855 AudioRegion::set_fade_in_active (bool yn
)
857 if (yn
== _fade_in_active
) {
861 _fade_in_active
= yn
;
862 send_change (PropertyChange (Properties::fade_in_active
));
866 AudioRegion::set_fade_out_active (bool yn
)
868 if (yn
== _fade_out_active
) {
871 _fade_out_active
= yn
;
872 send_change (PropertyChange (Properties::fade_out_active
));
876 AudioRegion::fade_in_is_default () const
878 return _fade_in
->size() == 2 && _fade_in
->front()->when
== 0 && _fade_in
->back()->when
== 64;
882 AudioRegion::fade_out_is_default () const
884 return _fade_out
->size() == 2 && _fade_out
->front()->when
== 0 && _fade_out
->back()->when
== 64;
888 AudioRegion::set_default_fade_in ()
890 _fade_in_suspended
= 0;
891 set_fade_in (Linear
, 64);
895 AudioRegion::set_default_fade_out ()
897 _fade_out_suspended
= 0;
898 set_fade_out (Linear
, 64);
902 AudioRegion::set_default_fades ()
904 set_default_fade_in ();
905 set_default_fade_out ();
909 AudioRegion::set_default_envelope ()
911 _envelope
->freeze ();
913 _envelope
->fast_simple_add (0, 1.0f
);
914 _envelope
->fast_simple_add (_length
, 1.0f
);
919 AudioRegion::recompute_at_end ()
921 /* our length has changed. recompute a new final point by interpolating
922 based on the the existing curve.
925 _envelope
->freeze ();
926 _envelope
->truncate_end (_length
);
927 _envelope
->set_max_xval (_length
);
930 if (_left_of_split
) {
931 set_default_fade_out ();
932 _left_of_split
= false;
933 } else if (_fade_out
->back()->when
> _length
) {
934 _fade_out
->extend_to (_length
);
935 send_change (PropertyChange (Properties::fade_out
));
938 if (_fade_in
->back()->when
> _length
) {
939 _fade_in
->extend_to (_length
);
940 send_change (PropertyChange (Properties::fade_in
));
945 AudioRegion::recompute_at_start ()
947 /* as above, but the shift was from the front */
949 _envelope
->truncate_start (_length
);
951 if (_right_of_split
) {
952 set_default_fade_in ();
953 _right_of_split
= false;
954 } else if (_fade_in
->back()->when
> _length
) {
955 _fade_in
->extend_to (_length
);
956 send_change (PropertyChange (Properties::fade_in
));
959 if (_fade_out
->back()->when
> _length
) {
960 _fade_out
->extend_to (_length
);
961 send_change (PropertyChange (Properties::fade_out
));
966 AudioRegion::separate_by_channel (Session
& /*session*/, vector
<boost::shared_ptr
<Region
> >& v
) const
972 if (_sources
.size() < 2) {
976 for (SourceList::const_iterator i
= _sources
.begin(); i
!= _sources
.end(); ++i
) {
982 if (_sources
.size() == 2) {
990 new_name
+= ('0' + n
+ 1);
993 /* create a copy with just one source. prevent if from being thought of as
994 "whole file" even if it covers the entire source file(s).
999 plist
.add (Properties::start
, _start
.val());
1000 plist
.add (Properties::length
, _length
.val());
1001 plist
.add (Properties::name
, new_name
);
1002 plist
.add (Properties::layer
, _layer
.val());
1004 v
.push_back(RegionFactory::create (srcs
, plist
));
1005 v
.back()->set_whole_file (false);
1014 AudioRegion::read_raw_internal (Sample
* buf
, framepos_t pos
, framecnt_t cnt
, int channel
) const
1016 return audio_source()->read (buf
, pos
, cnt
, channel
);
1020 AudioRegion::exportme (Session
& /*session*/, ARDOUR::ExportSpecification
& /*spec*/)
1023 // const nframes_t blocksize = 4096;
1024 // nframes_t to_read;
1027 // spec.channels = _sources.size();
1029 // if (spec.prepare (blocksize, session.frame_rate())) {
1034 // spec.total_frames = _length;
1036 // while (spec.pos < _length && !spec.stop) {
1039 // /* step 1: interleave */
1041 // to_read = min (_length - spec.pos, blocksize);
1043 // if (spec.channels == 1) {
1045 // if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
1051 // Sample buf[blocksize];
1053 // for (uint32_t chan = 0; chan < spec.channels; ++chan) {
1055 // if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
1059 // for (nframes_t x = 0; x < to_read; ++x) {
1060 // spec.dataF[chan+(x*spec.channels)] = buf[x];
1065 // if (spec.process (to_read)) {
1069 // spec.pos += to_read;
1070 // spec.progress = (double) spec.pos /_length;
1077 // spec.running = false;
1078 // spec.status = status;
1086 AudioRegion::set_scale_amplitude (gain_t g
)
1088 boost::shared_ptr
<Playlist
> pl (playlist());
1090 _scale_amplitude
= g
;
1092 /* tell the diskstream we're in */
1095 pl
->ContentsChanged();
1098 /* tell everybody else */
1100 send_change (PropertyChange (Properties::scale_amplitude
));
1104 AudioRegion::normalize_to (float target_dB
)
1106 const framecnt_t blocksize
= 64 * 1024;
1107 Sample buf
[blocksize
];
1112 gain_t target
= dB_to_coefficient (target_dB
);
1114 if (target
== 1.0f
) {
1115 /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear
1116 that we may have clipped.
1118 target
-= FLT_EPSILON
;
1122 fend
= _start
+ _length
;
1124 /* first pass: find max amplitude */
1126 while (fpos
< fend
) {
1130 to_read
= min (fend
- fpos
, blocksize
);
1132 for (n
= 0; n
< n_channels(); ++n
) {
1136 if (read_raw_internal (buf
, fpos
, to_read
, 0) != to_read
) {
1140 maxamp
= compute_peak (buf
, to_read
, maxamp
);
1146 if (maxamp
== 0.0f
) {
1147 /* don't even try */
1151 if (maxamp
== target
) {
1152 /* we can't do anything useful */
1156 /* compute scale factor */
1158 _scale_amplitude
= target
/maxamp
;
1160 /* tell the diskstream we're in */
1162 boost::shared_ptr
<Playlist
> pl (playlist());
1165 pl
->ContentsChanged();
1168 /* tell everybody else */
1170 send_change (PropertyChange (Properties::scale_amplitude
));
1174 AudioRegion::fade_in_changed ()
1176 send_change (PropertyChange (Properties::fade_in
));
1180 AudioRegion::fade_out_changed ()
1182 send_change (PropertyChange (Properties::fade_out
));
1186 AudioRegion::envelope_changed ()
1188 send_change (PropertyChange (Properties::envelope
));
1192 AudioRegion::suspend_fade_in ()
1194 if (++_fade_in_suspended
== 1) {
1195 if (fade_in_is_default()) {
1196 set_fade_in_active (false);
1202 AudioRegion::resume_fade_in ()
1204 if (--_fade_in_suspended
== 0 && _fade_in_suspended
) {
1205 set_fade_in_active (true);
1210 AudioRegion::suspend_fade_out ()
1212 if (++_fade_out_suspended
== 1) {
1213 if (fade_out_is_default()) {
1214 set_fade_out_active (false);
1220 AudioRegion::resume_fade_out ()
1222 if (--_fade_out_suspended
== 0 &&_fade_out_suspended
) {
1223 set_fade_out_active (true);
1228 AudioRegion::speed_mismatch (float sr
) const
1230 if (_sources
.empty()) {
1231 /* impossible, but ... */
1235 float fsr
= audio_source()->sample_rate();
1241 AudioRegion::source_offset_changed ()
1243 /* XXX this fixes a crash that should not occur. It does occur
1244 becauses regions are not being deleted when a session
1245 is unloaded. That bug must be fixed.
1248 if (_sources
.empty()) {
1252 boost::shared_ptr
<AudioFileSource
> afs
= boost::dynamic_pointer_cast
<AudioFileSource
>(_sources
.front());
1254 if (afs
&& afs
->destructive()) {
1255 // set_start (source()->natural_position(), this);
1256 set_position (source()->natural_position(), this);
1260 boost::shared_ptr
<AudioSource
>
1261 AudioRegion::audio_source (uint32_t n
) const
1263 // Guaranteed to succeed (use a static cast for speed?)
1264 return boost::dynamic_pointer_cast
<AudioSource
>(source(n
));
1268 AudioRegion::adjust_transients (nframes64_t delta
)
1270 for (AnalysisFeatureList::iterator x
= _transients
.begin(); x
!= _transients
.end(); ++x
) {
1271 (*x
) = (*x
) + delta
;
1274 send_change (PropertyChange (Properties::valid_transients
));
1280 AudioRegion::update_transient (nframes64_t old_position
, nframes64_t new_position
)
1282 for (AnalysisFeatureList::iterator x
= _transients
.begin(); x
!= _transients
.end(); ++x
) {
1283 if ((*x
) == old_position
) {
1284 (*x
) = new_position
;
1285 send_change (PropertyChange (Properties::valid_transients
));
1295 AudioRegion::add_transient (nframes64_t where
)
1297 _transients
.push_back(where
);
1298 _valid_transients
= true;
1300 send_change (PropertyChange (Properties::valid_transients
));
1304 AudioRegion::remove_transient (nframes64_t where
)
1306 _transients
.remove(where
);
1307 _valid_transients
= true;
1309 send_change (PropertyChange (Properties::valid_transients
));
1313 AudioRegion::set_transients (AnalysisFeatureList
& results
)
1315 _transients
.clear();
1316 _transients
= results
;
1317 _valid_transients
= true;
1319 send_change (PropertyChange (Properties::valid_transients
));
1325 AudioRegion::get_transients (AnalysisFeatureList
& results
, bool force_new
)
1327 boost::shared_ptr
<Playlist
> pl
= playlist();
1333 if (_valid_transients
&& !force_new
) {
1334 results
= _transients
;
1338 SourceList::iterator s
;
1340 for (s
= _sources
.begin() ; s
!= _sources
.end(); ++s
) {
1341 if (!(*s
)->has_been_analysed()) {
1342 cerr
<< "For " << name() << " source " << (*s
)->name() << " has not been analyzed\n";
1347 if (s
== _sources
.end()) {
1348 /* all sources are analyzed, merge data from each one */
1350 for (s
= _sources
.begin() ; s
!= _sources
.end(); ++s
) {
1352 /* find the set of transients within the bounds of this region */
1354 AnalysisFeatureList::iterator low
= lower_bound ((*s
)->transients
.begin(),
1355 (*s
)->transients
.end(),
1358 AnalysisFeatureList::iterator high
= upper_bound ((*s
)->transients
.begin(),
1359 (*s
)->transients
.end(),
1364 results
.insert (results
.end(), low
, high
);
1367 TransientDetector::cleanup_transients (results
, pl
->session().frame_rate(), 3.0);
1369 /* translate all transients to current position */
1371 for (AnalysisFeatureList::iterator x
= results
.begin(); x
!= results
.end(); ++x
) {
1376 _transients
= results
;
1377 _valid_transients
= true;
1382 /* no existing/complete transient info */
1384 static bool analyse_dialog_shown
= false; /* global per instance of Ardour */
1386 if (!Config
->get_auto_analyse_audio()) {
1387 if (!analyse_dialog_shown
) {
1388 pl
->session().Dialog (_("\
1389 You have requested an operation that requires audio analysis.\n\n \
1390 You currently have \"auto-analyse-audio\" disabled, which means\n\
1391 that transient data must be generated every time it is required.\n\n\
1392 If you are doing work that will require transient data on a\n\
1393 regular basis, you should probably enable \"auto-analyse-audio\"\n\
1394 +then quit ardour and restart.\n\n\
1395 +This dialog will not display again. But you may notice a slight delay\n\
1396 +in this and future transient-detection operations.\n\
1398 analyse_dialog_shown
= true;
1402 TransientDetector
t (pl
->session().frame_rate());
1403 bool existing_results
= !results
.empty();
1405 _transients
.clear ();
1406 _valid_transients
= false;
1408 for (uint32_t i
= 0; i
< n_channels(); ++i
) {
1410 AnalysisFeatureList these_results
;
1414 if (t
.run ("", this, i
, these_results
)) {
1418 /* translate all transients to give absolute position */
1420 for (AnalysisFeatureList::iterator i
= these_results
.begin(); i
!= these_results
.end(); ++i
) {
1426 _transients
.insert (_transients
.end(), these_results
.begin(), these_results
.end());
1429 if (!results
.empty()) {
1430 if (existing_results
) {
1432 /* merge our transients into the existing ones, then clean up
1436 results
.insert (results
.end(), _transients
.begin(), _transients
.end());
1437 TransientDetector::cleanup_transients (results
, pl
->session().frame_rate(), 3.0);
1440 /* make sure ours are clean too */
1442 TransientDetector::cleanup_transients (_transients
, pl
->session().frame_rate(), 3.0);
1446 TransientDetector::cleanup_transients (_transients
, pl
->session().frame_rate(), 3.0);
1447 results
= _transients
;
1450 _valid_transients
= true;
1455 /** Find areas of `silence' within a region.
1457 * @param threshold Threshold below which signal is considered silence (as a sample value)
1458 * @param min_length Minimum length of silent period to be reported.
1459 * @return Silent periods; first of pair is the offset within the region, second is the length of the period
1462 std::list
<std::pair
<frameoffset_t
, framecnt_t
> >
1463 AudioRegion::find_silence (Sample threshold
, framecnt_t min_length
, InterThreadInfo
& itt
) const
1465 framecnt_t
const block_size
= 64 * 1024;
1466 Sample loudest
[block_size
];
1467 Sample buf
[block_size
];
1469 framepos_t pos
= _start
;
1470 framepos_t
const end
= _start
+ _length
- 1;
1472 std::list
<std::pair
<frameoffset_t
, framecnt_t
> > silent_periods
;
1474 bool in_silence
= false;
1475 frameoffset_t silence_start
= 0;
1478 while (pos
< end
&& !itt
.cancel
) {
1480 /* fill `loudest' with the loudest absolute sample at each instant, across all channels */
1481 memset (loudest
, 0, sizeof (Sample
) * block_size
);
1482 for (uint32_t n
= 0; n
< n_channels(); ++n
) {
1484 read_raw_internal (buf
, pos
, block_size
, n
);
1485 for (framecnt_t i
= 0; i
< block_size
; ++i
) {
1486 loudest
[i
] = max (loudest
[i
], abs (buf
[i
]));
1490 /* now look for silence */
1491 for (framecnt_t i
= 0; i
< block_size
; ++i
) {
1492 silence
= abs (loudest
[i
]) < threshold
;
1493 if (silence
&& !in_silence
) {
1494 /* non-silence to silence */
1496 silence_start
= pos
+ i
;
1497 } else if (!silence
&& in_silence
) {
1498 /* silence to non-silence */
1500 if (pos
+ i
- 1 - silence_start
>= min_length
) {
1501 silent_periods
.push_back (std::make_pair (silence_start
, pos
+ i
- 1));
1507 itt
.progress
= (end
-pos
)/(double)_length
;
1510 if (in_silence
&& end
- 1 - silence_start
>= min_length
) {
1511 /* last block was silent, so finish off the last period */
1512 silent_periods
.push_back (std::make_pair (silence_start
, end
));
1517 return silent_periods
;
1524 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
)
1526 return ((AudioRegion
*) arg
)->read_peaks ((PeakData
*) data
, (framecnt_t
) npeaks
, (framepos_t
) start
, (framecnt_t
) cnt
, n_chan
,samples_per_unit
);
1529 uint32_t region_length_from_c (void *arg
)
1532 return ((AudioRegion
*) arg
)->length();
1535 uint32_t sourcefile_length_from_c (void *arg
, double zoom_factor
)
1537 return ( (AudioRegion
*) arg
)->audio_source()->available_peaks (zoom_factor
) ;