+ PBD::PropertyDescriptor<boost::shared_ptr<AutomationList> > fade_in;
+ PBD::PropertyDescriptor<boost::shared_ptr<AutomationList> > inverse_fade_in;
+ PBD::PropertyDescriptor<boost::shared_ptr<AutomationList> > fade_out;
+ PBD::PropertyDescriptor<boost::shared_ptr<AutomationList> > inverse_fade_out;
+ PBD::PropertyDescriptor<boost::shared_ptr<AutomationList> > envelope;
+ }
+}
+
+/* Curve manipulations */
+
+static void
+reverse_curve (boost::shared_ptr<Evoral::ControlList> dst, boost::shared_ptr<const Evoral::ControlList> src)
+{
+ size_t len = src->back()->when;
+ for (Evoral::ControlList::const_reverse_iterator it = src->rbegin(); it!=src->rend(); it++) {
+ dst->fast_simple_add (len - (*it)->when, (*it)->value);
+ }
+}
+
+static void
+generate_inverse_power_curve (boost::shared_ptr<Evoral::ControlList> dst, boost::shared_ptr<const Evoral::ControlList> src)
+{
+ // calc inverse curve using sum of squares
+ for (Evoral::ControlList::const_iterator it = src->begin(); it!=src->end(); ++it ) {
+ float value = (*it)->value;
+ value = 1 - powf(value,2);
+ value = sqrtf(value);
+ dst->fast_simple_add ( (*it)->when, value );
+ }
+}
+
+static void
+generate_db_fade (boost::shared_ptr<Evoral::ControlList> dst, double len, int num_steps, float dB_drop)
+{
+ dst->clear ();
+ dst->fast_simple_add (0, 1);
+
+ //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++) {
+ coeff *= fade_speed;
+ dst->fast_simple_add (len*(double)i/(double)num_steps, coeff);
+ }
+
+ dst->fast_simple_add (len, GAIN_COEFF_SMALL);
+}
+
+static void
+merge_curves (boost::shared_ptr<Evoral::ControlList> dst,
+ boost::shared_ptr<const Evoral::ControlList> curve1,
+ boost::shared_ptr<const Evoral::ControlList> curve2)
+{
+ Evoral::ControlList::EventList::size_type size = curve1->size();
+
+ //curve lengths must match for now
+ 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 );
+
+ interp = dB_to_coefficient(interp);
+ dst->fast_simple_add ( (*c1)->when, interp );
+ c1++;
+ count++;