summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2012-04-30 14:49:33 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2012-04-30 14:49:33 +0000
commitf99dc6d2ab5acd69268f993ea2bb628d70728426 (patch)
treef28a577170fdddd8ed7bc2a517a2533e4026abd3 /libs/ardour
parent10ee558254802189bf4d82255e0439b45e92bb87 (diff)
add explicit inverse fade in/out curves for use when doing constant power xfading
git-svn-id: svn://localhost/ardour2/branches/3.0@12123 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/audioregion.h2
-rw-r--r--libs/ardour/audioregion.cc136
2 files changed, 129 insertions, 9 deletions
diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h
index 87d515d399..1a8b2c9d79 100644
--- a/libs/ardour/ardour/audioregion.h
+++ b/libs/ardour/ardour/audioregion.h
@@ -233,7 +233,9 @@ class AudioRegion : public Region
Automatable _automatable;
boost::shared_ptr<AutomationList> _fade_in;
+ boost::shared_ptr<AutomationList> _inverse_fade_in;
boost::shared_ptr<AutomationList> _fade_out;
+ boost::shared_ptr<AutomationList> _inverse_fade_out;
boost::shared_ptr<AutomationList> _envelope;
uint32_t _fade_in_suspended;
uint32_t _fade_out_suspended;
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 79ee58b410..590572644a 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -551,11 +551,34 @@ AudioRegion::_read_at (const SourceList& srcs, framecnt_t limit,
*/
if (fade_in_limit != 0) {
- _fade_in->curve().get_vector (internal_offset, internal_offset + fade_in_limit, gain_buffer, fade_in_limit);
+ if (_inverse_fade_in) {
- /* Fade the current data out */
- for (framecnt_t n = 0; n < fade_in_limit; ++n) {
- buf[n] *= 1 - gain_buffer[n];
+ /* explicit inverse fade in curve (e.g. for constant
+ * power), so we have to fetch it.
+ */
+
+ _inverse_fade_in->curve().get_vector (internal_offset, internal_offset + fade_in_limit, gain_buffer, fade_in_limit);
+
+ /* Fade the data from lower layers out */
+ for (framecnt_t n = 0; n < fade_in_limit; ++n) {
+ buf[n] *= gain_buffer[n];
+ }
+
+ /* refill gain buffer with the fade in */
+
+ _fade_in->curve().get_vector (internal_offset, internal_offset + fade_in_limit, gain_buffer, fade_in_limit);
+
+ } else {
+
+ /* no explicit inverse fade in, so just use (1 - fade
+ * in) for the fade out of lower layers
+ */
+
+ _fade_in->curve().get_vector (internal_offset, internal_offset + fade_in_limit, gain_buffer, fade_in_limit);
+
+ for (framecnt_t n = 0; n < fade_in_limit; ++n) {
+ buf[n] *= 1 - gain_buffer[n];
+ }
}
/* Mix our newly-read data in, with the fade */
@@ -565,15 +588,36 @@ AudioRegion::_read_at (const SourceList& srcs, framecnt_t limit,
}
if (fade_out_limit != 0) {
+
framecnt_t const curve_offset = fade_interval_start - (limit - _fade_out->back()->when);
- _fade_out->curve().get_vector (curve_offset, curve_offset + fade_out_limit, gain_buffer, fade_out_limit);
- /* Fade the current data in */
- for (framecnt_t n = 0, m = fade_out_offset; n < fade_out_limit; ++n, ++m) {
- buf[m] *= 1 - gain_buffer[n];
+ if (_inverse_fade_out) {
+
+ _inverse_fade_out->curve().get_vector (curve_offset, curve_offset + fade_out_limit, gain_buffer, fade_out_limit);
+
+ /* Fade the data from lower levels out */
+ for (framecnt_t n = 0, m = fade_out_offset; n < fade_out_limit; ++n, ++m) {
+ buf[m] *= gain_buffer[n];
+ }
+
+ /* fetch the actual fade out */
+
+ _fade_out->curve().get_vector (curve_offset, curve_offset + fade_out_limit, gain_buffer, fade_out_limit);
+
+ } else {
+
+ /* no explicit inverse fade out, so just use (1 - fade
+ * out) for the fade in of lower layers
+ */
+
+ _fade_out->curve().get_vector (curve_offset, curve_offset + fade_out_limit, gain_buffer, fade_out_limit);
+
+ for (framecnt_t n = 0, m = fade_out_offset; n < fade_out_limit; ++n, ++m) {
+ buf[m] *= 1 - gain_buffer[n];
+ }
}
- /* Mix our newly-read data in, with the fade */
+ /* Mix our newly-read data out, with the fade */
for (framecnt_t n = 0, m = fade_out_offset; n < fade_out_limit; ++n, ++m) {
buf[m] += mixdown_buffer[m] * gain_buffer[n];
}
@@ -788,6 +832,7 @@ AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
case FadeLinear:
_fade_in->fast_simple_add (0.0, 0.0);
_fade_in->fast_simple_add (len, 1.0);
+ _inverse_fade_in.reset ();
break;
case FadeFast:
@@ -798,6 +843,7 @@ AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
_fade_in->fast_simple_add (len * 0.9447, 0.483333);
_fade_in->fast_simple_add (len * 0.976959, 0.697222);
_fade_in->fast_simple_add (len, 1);
+ _inverse_fade_in.reset ();
break;
case FadeSlow:
@@ -809,6 +855,7 @@ AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
_fade_in->fast_simple_add (len * 0.481567, 0.980556);
_fade_in->fast_simple_add (len * 0.767281, 1);
_fade_in->fast_simple_add (len, 1);
+ _inverse_fade_in.reset ();
break;
case FadeLogA:
@@ -819,6 +866,7 @@ AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
_fade_in->fast_simple_add (len * 0.652074, 0.972222);
_fade_in->fast_simple_add (len * 0.771889, 0.988889);
_fade_in->fast_simple_add (len, 1);
+ _inverse_fade_in.reset ();
break;
case FadeLogB:
@@ -829,6 +877,7 @@ AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
_fade_in->fast_simple_add (len * 0.847926, 0.558333);
_fade_in->fast_simple_add (len * 0.919355, 0.730556);
_fade_in->fast_simple_add (len, 1);
+ _inverse_fade_in.reset ();
break;
case FadeConstantPowerMinus3dB:
@@ -839,6 +888,22 @@ AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
_fade_in->fast_simple_add ((len * 0.666667), 0.851507);
_fade_in->fast_simple_add ((len * 0.833333), 0.948859);
_fade_in->fast_simple_add (len, 1.0);
+
+ /* setup complementary fade out for lower layers */
+
+ if (!_inverse_fade_in) {
+ _inverse_fade_in.reset (new AutomationList (Evoral::Parameter (FadeInAutomation)));
+ }
+
+ _inverse_fade_in->clear ();
+ _inverse_fade_in->fast_simple_add (0.0, 1.0);
+ _inverse_fade_in->fast_simple_add ((len * 0.166667), 0.948859);
+ _inverse_fade_in->fast_simple_add ((len * 0.333333), 0.851507);
+ _inverse_fade_in->fast_simple_add ((len * 0.500000), 0.707946);
+ _inverse_fade_in->fast_simple_add ((len * 0.666667), 0.518174);
+ _inverse_fade_in->fast_simple_add ((len * 0.833333), 0.282192);
+ _inverse_fade_in->fast_simple_add (len, 0.0);
+
break;
case FadeConstantPowerMinus6dB:
@@ -849,6 +914,22 @@ AudioRegion::set_fade_in (FadeShape shape, framecnt_t len)
_fade_in->fast_simple_add ((len * 0.666667), 0.666186);
_fade_in->fast_simple_add ((len * 0.833333), 0.833033);
_fade_in->fast_simple_add (len, 1.0);
+
+ /* setup complementary fade out for lower layers */
+
+ if (!_inverse_fade_in) {
+ _inverse_fade_in.reset (new AutomationList (Evoral::Parameter (FadeInAutomation)));
+ }
+
+ _inverse_fade_in->clear ();
+ _inverse_fade_in->fast_simple_add (0.0, 1.0);
+ _inverse_fade_in->fast_simple_add ((len * 0.166667), 0.833033);
+ _inverse_fade_in->fast_simple_add ((len * 0.333333), 0.666186);
+ _inverse_fade_in->fast_simple_add ((len * 0.500000), 0.499459);
+ _inverse_fade_in->fast_simple_add ((len * 0.666667), 0.332853);
+ _inverse_fade_in->fast_simple_add ((len * 0.833333), 0.166366);
+ _inverse_fade_in->fast_simple_add (len, 0.0);
+
break;
}
@@ -881,6 +962,7 @@ AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
_fade_out->fast_simple_add (len * 0.370968, 0.0861111);
_fade_out->fast_simple_add (len * 0.610599, 0.0333333);
_fade_out->fast_simple_add (1.0, 0.0);
+ _inverse_fade_out.reset ();
break;
case FadeLogA:
@@ -891,6 +973,7 @@ AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
_fade_out->fast_simple_add (len * 0.753456, 0.658333);
_fade_out->fast_simple_add (len * 0.9262673, 0.308333);
_fade_out->fast_simple_add (len, 0.0);
+ _inverse_fade_out.reset ();
break;
case FadeSlow:
@@ -901,6 +984,7 @@ AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
_fade_out->fast_simple_add (len * 0.918981, 0.68595);
_fade_out->fast_simple_add (len * 0.976852, 0.22865);
_fade_out->fast_simple_add (len, 0.0);
+ _inverse_fade_out.reset ();
break;
case FadeLogB:
@@ -910,11 +994,13 @@ AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
_fade_out->fast_simple_add (len * 0.470046, 0.152778);
_fade_out->fast_simple_add (len * 0.695853, 0.0694444);
_fade_out->fast_simple_add (len, 0.0);
+ _inverse_fade_out.reset ();
break;
case FadeLinear:
_fade_out->fast_simple_add (0.0, 1.0);
_fade_out->fast_simple_add (len, 0.0);
+ _inverse_fade_out.reset ();
break;
case FadeConstantPowerMinus3dB:
@@ -925,6 +1011,22 @@ AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
_fade_out->fast_simple_add ((len * 0.666667), 0.518174);
_fade_out->fast_simple_add ((len * 0.833333), 0.282192);
_fade_out->fast_simple_add (len, 0.0);
+
+ /* setup complementary fade in for lower layers */
+
+ if (!_inverse_fade_out) {
+ _inverse_fade_out.reset (new AutomationList (Evoral::Parameter (FadeInAutomation)));
+ }
+
+ _inverse_fade_out->clear ();
+ _inverse_fade_out->fast_simple_add (0.0, 0.0);
+ _inverse_fade_out->fast_simple_add ((len * 0.166667), 0.166366);
+ _inverse_fade_out->fast_simple_add ((len * 0.333333), 0.332853);
+ _inverse_fade_out->fast_simple_add ((len * 0.500000), 0.499459);
+ _inverse_fade_out->fast_simple_add ((len * 0.666667), 0.666186);
+ _inverse_fade_out->fast_simple_add ((len * 0.833333), 0.833033);
+ _inverse_fade_out->fast_simple_add (len, 1.0);
+
break;
case FadeConstantPowerMinus6dB:
@@ -935,6 +1037,22 @@ AudioRegion::set_fade_out (FadeShape shape, framecnt_t len)
_fade_out->fast_simple_add ((len * 0.666667), 0.332853);
_fade_out->fast_simple_add ((len * 0.833333), 0.166366);
_fade_out->fast_simple_add (len, 0.0);
+
+ /* setup complementary fade in for lower layers */
+
+ if (!_inverse_fade_out) {
+ _inverse_fade_out.reset (new AutomationList (Evoral::Parameter (FadeInAutomation)));
+ }
+
+ _inverse_fade_out->clear ();
+ _inverse_fade_out->fast_simple_add (0.0, 0.0);
+ _inverse_fade_out->fast_simple_add ((len * 0.166667), 0.166366);
+ _inverse_fade_out->fast_simple_add ((len * 0.333333), 0.332853);
+ _inverse_fade_out->fast_simple_add ((len * 0.500000), 0.499459);
+ _inverse_fade_out->fast_simple_add ((len * 0.666667), 0.666186);
+ _inverse_fade_out->fast_simple_add ((len * 0.833333), 0.833033);
+ _inverse_fade_out->fast_simple_add (len, 1.0);
+
break;
}