/* see if some part of this read is within the fade out */
/* ................. >| REGION
- _length
-
- { } FADE
- fade_out_length
- ^
- _length - fade_out_length
- |--------------|
- ^internal_offset
- ^internal_offset + to_read
-
- we need the intersection of [internal_offset,internal_offset+to_read] with
- [_length - fade_out_length, _length]
-
- */
-
+ * _length
+ *
+ * { } FADE
+ * fade_out_length
+ * ^
+ * _length - fade_out_length
+ *
+ * |--------------|
+ * ^internal_offset
+ * ^internal_offset + to_read
+ *
+ * we need the intersection of [internal_offset,internal_offset+to_read] with
+ * [_length - fade_out_length, _length]
+ *
+ */
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());
/* copy an existing channel's data in for this non-existant one */
- uint32_t channel = n_channels() % chan_n;
+ uint32_t channel = chan_n % n_channels();
boost::shared_ptr<AudioSource> src = boost::dynamic_pointer_cast<AudioSource> (srcs[channel]);
if (src->read (buf, _start + internal_offset, to_read) != to_read) {
return _set_state (node, version, what_changed, true);
}
+void
+AudioRegion::fade_range (framepos_t start, framepos_t end)
+{
+ framepos_t s, e;
+
+ switch (coverage (start, end)) {
+ case Evoral::OverlapStart:
+ s = _position;
+ e = end;
+ set_fade_in (FadeConstantPower, e - s);
+ break;
+ case Evoral::OverlapEnd:
+ s = start;
+ e = _position + _length;
+ set_fade_out (FadeConstantPower, e - s);
+ break;
+ case Evoral::OverlapInternal:
+ /* needs addressing, perhaps. Difficult to do if we can't
+ * control one edge of the fade relative to the relevant edge
+ * of the region, which we cannot - fades are currently assumed
+ * to start/end at the start/end of the region
+ */
+ break;
+ default:
+ return;
+ }
+}
+
void
AudioRegion::set_fade_in_shape (FadeShape shape)
{
_fade_in->clear ();
_inverse_fade_in->clear ();
+ const int num_steps = 32;
+
switch (shape) {
case FadeLinear:
- _fade_in->fast_simple_add (0.0, 0.0);
+ _fade_in->fast_simple_add (0.0, VERY_SMALL_SIGNAL);
_fade_in->fast_simple_add (len, 1.0);
reverse_curve (_inverse_fade_in.val(), _fade_in.val());
break;
case FadeFast:
- generate_db_fade (_fade_in.val(), len, 10, -60);
+ generate_db_fade (_fade_in.val(), len, num_steps, -60);
reverse_curve (c1, _fade_in.val());
_fade_in->copy_events (*c1);
generate_inverse_power_curve (_inverse_fade_in.val(), _fade_in.val());
break;
case FadeSlow:
- generate_db_fade (c1, len, 10, -1); // start off with a slow fade
- generate_db_fade (c2, len, 10, -80); // end with a fast fade
+ 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
merge_curves (_fade_in.val(), c1, c2);
reverse_curve (c3, _fade_in.val());
_fade_in->copy_events (*c3);
break;
case FadeConstantPower:
- for (int i = 0; i < 9; ++i) {
- float dist = (float) i / 10.0f;
- _fade_in->fast_simple_add (len*dist, sin (dist*M_PI/2));
+ _fade_in->fast_simple_add (0.0, VERY_SMALL_SIGNAL);
+ for (int i = 1; i < num_steps; ++i) {
+ const float dist = i / (num_steps + 1.f);
+ _fade_in->fast_simple_add (len * dist, sin (dist * M_PI / 2.0));
}
_fade_in->fast_simple_add (len, 1.0);
reverse_curve (_inverse_fade_in.val(), _fade_in.val());
case FadeSymmetric:
//start with a nearly linear cuve
_fade_in->fast_simple_add (0, 1);
- _fade_in->fast_simple_add (0.5*len, 0.6);
+ _fade_in->fast_simple_add (0.5 * len, 0.6);
//now generate a fade-out curve by successively applying a gain drop
- const float breakpoint = 0.7; //linear for first 70%
- const int num_steps = 9;
- for (int i = 2; i < num_steps; i++) {
- float coeff = (1.0-breakpoint);
- for (int j = 0; j < i; j++) {
- coeff *= 0.5; //6dB drop per step
- }
- _fade_in->fast_simple_add (len* (breakpoint+((1.0-breakpoint)*(double)i/(double)num_steps)), coeff);
+ const double breakpoint = 0.7; //linear for first 70%
+ for (int i = 2; i < 9; ++i) {
+ const float coeff = (1.f - breakpoint) * powf (0.5, i);
+ _fade_in->fast_simple_add (len * (breakpoint + ((1.0 - breakpoint) * (double)i / 9.0)), coeff);
}
_fade_in->fast_simple_add (len, VERY_SMALL_SIGNAL);
reverse_curve (c3, _fade_in.val());
break;
}
+ _fade_in->set_interpolation(Evoral::ControlList::Curved);
+ _inverse_fade_in->set_interpolation(Evoral::ControlList::Curved);
+
_default_fade_in = false;
_fade_in->thaw ();
send_change (PropertyChange (Properties::fade_in));
_fade_out->clear ();
_inverse_fade_out->clear ();
+ const int num_steps = 32;
+
switch (shape) {
case FadeLinear:
_fade_out->fast_simple_add (0.0, 1.0);
break;
case FadeFast:
- generate_db_fade (_fade_out.val(), len, 10, -60);
+ 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, 10, -1); //start off with a slow fade
- generate_db_fade (c2, len, 10, -80); //end with a fast fade
+ 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
merge_curves (_fade_out.val(), c1, c2);
generate_inverse_power_curve (_inverse_fade_out.val(), _fade_out.val());
break;
//constant-power fades use a sin/cos relationship
//the cutoff is abrupt but it has the benefit of being symmetrical
_fade_out->fast_simple_add (0.0, 1.0);
- for (int i = 1; i < 9; i++ ) {
- float dist = (float)i/10.0;
- _fade_out->fast_simple_add ((len * dist), cos(dist*M_PI/2));
+ for (int i = 1; i < num_steps; ++i) {
+ const float dist = i / (num_steps + 1.f);
+ _fade_out->fast_simple_add (len * dist, cos (dist * M_PI / 2.0));
}
_fade_out->fast_simple_add (len, VERY_SMALL_SIGNAL);
reverse_curve (_inverse_fade_out.val(), _fade_out.val());
case FadeSymmetric:
//start with a nearly linear cuve
_fade_out->fast_simple_add (0, 1);
- _fade_out->fast_simple_add (0.5*len, 0.6);
-
+ _fade_out->fast_simple_add (0.5 * len, 0.6);
//now generate a fade-out curve by successively applying a gain drop
- const float breakpoint = 0.7; //linear for first 70%
- const int num_steps = 9;
- for (int i = 2; i < num_steps; i++) {
- float coeff = (1.0-breakpoint);
- for (int j = 0; j < i; j++) {
- coeff *= 0.5; //6dB drop per step
- }
- _fade_out->fast_simple_add (len* (breakpoint+((1.0-breakpoint)*(double)i/(double)num_steps)), coeff);
+ const double breakpoint = 0.7; //linear for first 70%
+ for (int i = 2; i < 9; ++i) {
+ const float coeff = (1.f - breakpoint) * powf (0.5, i);
+ _fade_out->fast_simple_add (len * (breakpoint + ((1.0 - breakpoint) * (double)i / 9.0)), coeff);
}
_fade_out->fast_simple_add (len, VERY_SMALL_SIGNAL);
reverse_curve (_inverse_fade_out.val(), _fade_out.val());
break;
}
+ _fade_out->set_interpolation(Evoral::ControlList::Curved);
+ _inverse_fade_out->set_interpolation(Evoral::ControlList::Curved);
+
_default_fade_out = false;
_fade_out->thaw ();
send_change (PropertyChange (Properties::fade_out));
AudioRegion::set_default_fade_in ()
{
_fade_in_suspended = 0;
- set_fade_in (FadeLinear, 64);
+ set_fade_in (Config->get_default_fade_shape(), 64);
}
void
AudioRegion::set_default_fade_out ()
{
_fade_out_suspended = 0;
- set_fade_out (FadeLinear, 64);
+ set_fade_out (Config->get_default_fade_shape(), 64);
}
void
if (!Config->get_auto_analyse_audio()) {
if (!analyse_dialog_shown) {
- pl->session().Dialog (_("\
+ pl->session().Dialog (string_compose (_("\
You have requested an operation that requires audio analysis.\n\n\
You currently have \"auto-analyse-audio\" disabled, which means \
that transient data must be generated every time it is required.\n\n\
If you are doing work that will require transient data on a \
regular basis, you should probably enable \"auto-analyse-audio\" \
-then quit ardour and restart.\n\n\
+then quit %1 and restart.\n\n\
This dialog will not display again. But you may notice a slight delay \
in this and future transient-detection operations.\n\
-"));
+"), PROGRAM_NAME));
analyse_dialog_shown = true;
}
}