diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc index 5c25377a35..49bfd1bb03 100644 --- a/gtk2_ardour/audio_region_view.cc +++ b/gtk2_ardour/audio_region_view.cc @@ -558,8 +558,10 @@ AudioRegionView::reset_fade_in_shape_width (framecnt_t width) } if (audio_region()->fade_in_is_xfade()) { - fade_in_handle->hide (); - fade_in_shape->hide (); + if (fade_in_handle) { + fade_in_handle->hide (); + fade_in_shape->hide (); + } redraw_start_xfade (); return; } else { @@ -664,8 +666,10 @@ AudioRegionView::reset_fade_out_shape_width (framecnt_t width) } if (audio_region()->fade_out_is_xfade()) { - fade_out_handle->hide (); - fade_out_shape->hide (); + if (fade_out_handle) { + fade_out_handle->hide (); + fade_out_shape->hide (); + } redraw_end_xfade (); return; } else { diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index 025cd3a715..40b3cac47c 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -693,6 +693,7 @@ AudioRegion::state () } child = node.add_child (X_("FadeIn")); + child->add_property ("is-xfade", (_fade_in_is_xfade ? "yes" : "no")); if (_default_fade_in) { child->add_property ("default", "yes"); @@ -700,7 +701,13 @@ AudioRegion::state () child->add_child_nocopy (_fade_in->get_state ()); } + if (_inverse_fade_in) { + child = node.add_child (X_("InvFadeIn")); + child->add_child_nocopy (_inverse_fade_in->get_state ()); + } + child = node.add_child (X_("FadeOut")); + child->add_property ("is-xfade", (_fade_out_is_xfade ? "yes" : "no")); if (_default_fade_out) { child->add_property ("default", "yes"); @@ -708,6 +715,11 @@ AudioRegion::state () child->add_child_nocopy (_fade_out->get_state ()); } + if (_inverse_fade_out) { + child = node.add_child (X_("InvFadeOut")); + child->add_child_nocopy (_inverse_fade_out->get_state ()); + } + return node; } @@ -765,7 +777,7 @@ AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_ _fade_in->clear (); - if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) { + if (((prop = child->property ("default")) != 0 && string_is_affirmative (prop->value())) || (prop = child->property ("steepness")) != 0) { set_default_fade_in (); } else { XMLNode* grandchild = child->child ("AutomationList"); @@ -774,6 +786,12 @@ AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_ } } + if ((prop = child->property ("is-xfade")) != 0) { + _fade_in_is_xfade = string_is_affirmative (prop->value()); + } else { + _fade_in_is_xfade = false; + } + if ((prop = child->property ("active")) != 0) { if (string_is_affirmative (prop->value())) { set_fade_in_active (true); @@ -786,7 +804,7 @@ AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_ _fade_out->clear (); - if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) { + if (((prop = child->property ("default")) != 0 && (string_is_affirmative (prop->value()))) || (prop = child->property ("steepness")) != 0) { set_default_fade_out (); } else { XMLNode* grandchild = child->child ("AutomationList"); @@ -795,7 +813,13 @@ AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_ } } - if ((prop = child->property ("active")) != 0) { + if ((prop = child->property ("is-xfade")) != 0) { + _fade_out_is_xfade = string_is_affirmative (prop->value()); + } else { + _fade_out_is_xfade = false; + } + + if ((prop = child->property ("active")) != 0) { if (string_is_affirmative (prop->value())) { set_fade_out_active (true); } else { @@ -803,6 +827,22 @@ AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_ } } + } else if (child->name() == "InvFadeIn") { + XMLNode* grandchild = child->child ("AutomationList"); + if (grandchild) { + if (!_inverse_fade_in) { + _inverse_fade_in.reset (new AutomationList (Evoral::Parameter (FadeInAutomation))); + } + _inverse_fade_in->set_state (*grandchild, version); + } + } else if (child->name() == "InvFadeOut") { + XMLNode* grandchild = child->child ("AutomationList"); + if (grandchild) { + if (!_inverse_fade_out) { + _inverse_fade_out.reset (new AutomationList (Evoral::Parameter (FadeOutAutomation))); + } + _inverse_fade_out->set_state (*grandchild, version); + } } } @@ -845,6 +885,7 @@ AudioRegion::set_fade_in (boost::shared_ptr f) _fade_in->freeze (); *_fade_in = *f; _fade_in->thaw (); + _default_fade_in = false; send_change (PropertyChange (Properties::fade_in)); } @@ -960,6 +1001,7 @@ AudioRegion::set_fade_in (FadeShape shape, framecnt_t len) break; } + _default_fade_in = false; _fade_in->thaw (); send_change (PropertyChange (Properties::fade_in)); } @@ -970,6 +1012,7 @@ AudioRegion::set_fade_out (boost::shared_ptr f) _fade_out->freeze (); *_fade_out = *f; _fade_out->thaw (); + _default_fade_out = false; send_change (PropertyChange (Properties::fade_in)); } @@ -1083,6 +1126,7 @@ AudioRegion::set_fade_out (FadeShape shape, framecnt_t len) break; } + _default_fade_out = false; _fade_out->thaw (); send_change (PropertyChange (Properties::fade_in)); }