//generate a fade-out curve by successively applying a gain drop
float fade_speed = dB_to_coefficient(dB_drop / (float) num_steps);
+ float coeff = GAIN_COEFF_UNITY;
for (int i = 1; i < (num_steps-1); i++) {
- float coeff = GAIN_COEFF_UNITY;
- for (int j = 0; j < i; j++) {
- coeff *= fade_speed;
- }
+ coeff *= fade_speed;
dst->fast_simple_add (len*(double)i/(double)num_steps, coeff);
}
if (size != curve2->size()) {
return;
}
-
+
Evoral::ControlList::const_iterator c1 = curve1->begin();
int count = 0;
for (Evoral::ControlList::const_iterator c2 = curve2->begin(); c2!=curve2->end(); c2++ ) {
float v1 = accurate_coefficient_to_dB((*c1)->value);
float v2 = accurate_coefficient_to_dB((*c2)->value);
-
+
double interp = v1 * ( 1.0-( (double)count / (double)size) );
interp += v2 * ( (double)count / (double)size );
*/
assert (cnt >= 0);
-
+
if (n_channels() == 0) {
return 0;
}
of any fade out that we are dealing with
*/
frameoffset_t fade_out_offset = 0;
-
+
/* Amount (length) of fade out that we are dealing with in this read */
framecnt_t fade_out_limit = 0;
framecnt_t fade_interval_start = 0;
/* Fade in */
-
+
if (_fade_in_active && _session.config.get_use_region_fades()) {
-
+
framecnt_t fade_in_length = (framecnt_t) _fade_in->back()->when;
/* see if this read is within the fade in */
-
+
if (internal_offset < fade_in_length) {
fade_in_limit = min (to_read, fade_in_length - internal_offset);
}
}
-
+
/* Fade out */
-
+
if (_fade_out_active && _session.config.get_use_region_fades()) {
-
+
/* see if some part of this read is within the fade out */
/* ................. >| REGION
fade_interval_start = max (internal_offset, _length - framecnt_t (_fade_out->back()->when));
framecnt_t fade_interval_end = min(internal_offset + to_read, _length.val());
-
+
if (fade_interval_end > fade_interval_start) {
/* (part of the) the fade out is in this buffer */
fade_out_limit = fade_interval_end - fade_interval_start;
/* 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];
}
if (opaque()) {
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 in */
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 (which is
* actually a fade in), 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];
}
buf[m] += mixdown_buffer[m] * gain_buffer[n];
}
}
-
+
/* MIX OR COPY THE REGION BODY FROM mixdown_buffer INTO buf */
framecnt_t const N = to_read - fade_in_limit - fade_out_limit;
if (to_read == 0) {
return 0;
}
-
+
if (chan_n < n_channels()) {
boost::shared_ptr<AudioSource> src = boost::dynamic_pointer_cast<AudioSource> (srcs[chan_n]);
}
} else {
-
+
/* use silence */
memset (buf, 0, sizeof (Sample) * to_read);
}
_fade_out->set_state (*grandchild, version);
}
}
-
+
if ((prop = child->property ("active")) != 0) {
if (string_is_affirmative (prop->value())) {
set_fade_out_active (true);
set_fade_out_active (false);
}
}
-
+
} else if ( (child->name() == "InverseFadeIn") || (child->name() == "InvFadeIn") ) {
XMLNode* grandchild = child->child ("AutomationList");
if (grandchild) {
_fade_in->fast_simple_add (len, GAIN_COEFF_UNITY);
reverse_curve (_inverse_fade_in.val(), _fade_in.val());
break;
-
+
case FadeSymmetric:
//start with a nearly linear cuve
_fade_in->fast_simple_add (0, 1);
_fade_out->fast_simple_add (len, GAIN_COEFF_SMALL);
reverse_curve (_inverse_fade_out.val(), _fade_out.val());
break;
-
+
case FadeFast:
generate_db_fade (_fade_out.val(), len, num_steps, -60);
generate_inverse_power_curve (_inverse_fade_out.val(), _fade_out.val());
break;
-
+
case FadeSlow:
generate_db_fade (c1, len, num_steps, -1); //start off with a slow fade
generate_db_fade (c2, len, num_steps, -80); //end with a fast fade
_fade_out->fast_simple_add (len, GAIN_COEFF_SMALL);
reverse_curve (_inverse_fade_out.val(), _fade_out.val());
break;
-
+
case FadeSymmetric:
//start with a nearly linear cuve
_fade_out->fast_simple_add (0, 1);
if (len > _length) {
len = _length - 1;
}
-
+
if (len < 64) {
len = 64;
}
bool changed = _fade_out->extend_to (len);
if (changed) {
-
+
if (_inverse_fade_out) {
_inverse_fade_out->extend_to (len);
}
while (pos < end && !itt.cancel) {
framecnt_t cur_samples = 0;
+ framecnt_t const to_read = min (end - pos, block_size);
/* fill `loudest' with the loudest absolute sample at each instant, across all channels */
memset (loudest.get(), 0, sizeof (Sample) * block_size);
+
for (uint32_t n = 0; n < n_channels(); ++n) {
- cur_samples = read_raw_internal (buf.get(), pos, block_size, n);
+ cur_samples = read_raw_internal (buf.get(), pos, to_read, n);
for (framecnt_t i = 0; i < cur_samples; ++i) {
loudest[i] = max (loudest[i], abs (buf[i]));
}
} else {
rl = pl->regions_at (last_frame());
}
-
+
RegionList::iterator i;
boost::shared_ptr<Region> other;
uint32_t n = 0;
}
return min (length(), min (maxlen, len));
-
+
}