X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fcrossfade.cc;h=d2271030a5933c4c0c5c051c9a8106c885e3ac0f;hb=b6f1f02131d99392899cd394f1fb408438b1dd58;hp=2d46c0c01ae042dc48392aef9d6f6071a603a7cb;hpb=e488378d42777b436c6a2708d9dff2def51a5271;p=ardour.git diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc index 2d46c0c01a..d2271030a5 100644 --- a/libs/ardour/crossfade.cc +++ b/libs/ardour/crossfade.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2003-2006 Paul Davis + Copyright (C) 2003-2006 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,10 +17,10 @@ */ -#include #include "pbd/stacktrace.h" +#include "ardour/debug.h" #include "ardour/types.h" #include "ardour/crossfade.h" #include "ardour/crossfade_compare.h" @@ -29,6 +29,7 @@ #include "ardour/utils.h" #include "ardour/session.h" #include "ardour/source.h" +#include "ardour/region_factory.h" #include "i18n.h" #include @@ -37,9 +38,7 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -nframes_t Crossfade::_short_xfade_length = 0; -Change Crossfade::ActiveChanged = new_change(); -Change Crossfade::FollowOverlapChanged = new_change(); +framecnt_t Crossfade::_short_xfade_length = 0; /* XXX if and when we ever implement parallel processing of the process() callback, these will need to be handled on a per-thread basis. @@ -48,8 +47,27 @@ Change Crossfade::FollowOverlapChanged = new_change(); Sample* Crossfade::crossfade_buffer_out = 0; Sample* Crossfade::crossfade_buffer_in = 0; + +#define CROSSFADE_DEFAULT_PROPERTIES \ + _active (Properties::active, _session.config.get_xfades_active ()) \ + , _follow_overlap (Properties::follow_overlap, false) + + +namespace ARDOUR { + namespace Properties { + PropertyDescriptor follow_overlap; + } +} + +void +Crossfade::make_property_quarks () +{ + Properties::follow_overlap.property_id = g_quark_from_static_string (X_("follow-overlap")); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for follow-overlap = %1\n", Properties::follow_overlap.property_id)); +} + void -Crossfade::set_buffer_size (nframes_t sz) +Crossfade::set_buffer_size (framecnt_t sz) { delete [] crossfade_buffer_out; crossfade_buffer_out = 0; @@ -69,30 +87,30 @@ Crossfade::operator== (const Crossfade& other) return (_in == other._in) && (_out == other._out); } -Crossfade::Crossfade (boost::shared_ptr in, boost::shared_ptr out, - nframes_t length, - nframes_t position, +Crossfade::Crossfade (boost::shared_ptr in, boost::shared_ptr out, + framecnt_t length, + framepos_t position, AnchorPoint ap) - : AudioRegion (in->session(), position, length, "foobar"), - _fade_in (Evoral::Parameter(FadeInAutomation)), // linear (gain coefficient) => -inf..+6dB - _fade_out (Evoral::Parameter(FadeOutAutomation)) // linear (gain coefficient) => -inf..+6dB + : AudioRegion (in->session(), position, length, in->name() + string ("<>") + out->name()) + , CROSSFADE_DEFAULT_PROPERTIES + , _fade_in (Evoral::Parameter(FadeInAutomation)) // linear (gain coefficient) => -inf..+6dB + , _fade_out (Evoral::Parameter(FadeOutAutomation)) // linear (gain coefficient) => -inf..+6dB { _in = in; _out = out; _anchor_point = ap; - _follow_overlap = false; - - _active = _session.config.get_xfades_active (); _fixed = true; + _follow_overlap = false; initialize (); } Crossfade::Crossfade (boost::shared_ptr a, boost::shared_ptr b, CrossfadeModel model, bool act) - : AudioRegion (a->session(), 0, 0, "foobar"), - _fade_in (Evoral::Parameter(FadeInAutomation)), // linear (gain coefficient) => -inf..+6dB - _fade_out (Evoral::Parameter(FadeOutAutomation)) // linear (gain coefficient) => -inf..+6dB + : AudioRegion (a->session(), 0, 0, a->name() + string ("<>") + b->name()) + , CROSSFADE_DEFAULT_PROPERTIES + , _fade_in (Evoral::Parameter(FadeInAutomation)) // linear (gain coefficient) => -inf..+6dB + , _fade_out (Evoral::Parameter(FadeOutAutomation)) // linear (gain coefficient) => -inf..+6dB { _in_update = false; _fixed = false; @@ -107,14 +125,15 @@ Crossfade::Crossfade (boost::shared_ptr a, boost::shared_ptr -inf..+6dB - _fade_out (Evoral::Parameter(FadeOutAutomation)) // linear (gain coefficient) => -inf..+6dB +Crossfade::Crossfade (const Playlist& playlist, XMLNode const & node) + : AudioRegion (playlist.session(), 0, 0, "unnamed crossfade") + , CROSSFADE_DEFAULT_PROPERTIES + , _fade_in (Evoral::Parameter(FadeInAutomation)) // linear (gain coefficient) => -inf..+6dB + , _fade_out (Evoral::Parameter(FadeOutAutomation)) // linear (gain coefficient) => -inf..+6dB { boost::shared_ptr r; - XMLProperty* prop; + XMLProperty const * prop; LocaleGuard lg (X_("POSIX")); /* we have to find the in/out regions before we can do anything else */ @@ -123,15 +142,24 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node) error << _("Crossfade: no \"in\" region in state") << endmsg; throw failed_constructor(); } - + PBD::ID id (prop->value()); - if ((r = playlist.find_region (id)) == 0) { - error << string_compose (_("Crossfade: no \"in\" region %1 found in playlist %2"), id, playlist.name()) + r = playlist.find_region (id); + + if (!r) { + /* the `in' region is not in a playlist, which probably means that this crossfade + is in the undo record, so we have to find the region in the global region map. + */ + r = RegionFactory::region_by_id (id); + } + + if (!r) { + error << string_compose (_("Crossfade: no \"in\" region %1 found in playlist %2 nor in region map"), id, playlist.name()) << endmsg; throw failed_constructor(); } - + if ((_in = boost::dynamic_pointer_cast (r)) == 0) { throw failed_constructor(); } @@ -143,12 +171,18 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node) PBD::ID id2 (prop->value()); - if ((r = playlist.find_region (id2)) == 0) { - error << string_compose (_("Crossfade: no \"out\" region %1 found in playlist %2"), id2, playlist.name()) + r = playlist.find_region (id2); + + if (!r) { + r = RegionFactory::region_by_id (id2); + } + + if (!r) { + error << string_compose (_("Crossfade: no \"out\" region %1 found in playlist %2 nor in region map"), id2, playlist.name()) << endmsg; throw failed_constructor(); } - + if ((_out = boost::dynamic_pointer_cast (r)) == 0) { throw failed_constructor(); } @@ -156,29 +190,30 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node) _length = 0; initialize(); _active = true; - - if (set_state (node)) { + + if (set_state (node, Stateful::loading_state_version)) { throw failed_constructor(); } } Crossfade::Crossfade (boost::shared_ptr orig, boost::shared_ptr newin, boost::shared_ptr newout) - : AudioRegion (boost::dynamic_pointer_cast (orig)), - _fade_in (orig->_fade_in), - _fade_out (orig->_fade_out) + : AudioRegion (boost::dynamic_pointer_cast (orig), 0, true) + , CROSSFADE_DEFAULT_PROPERTIES + , _fade_in (orig->_fade_in) + , _fade_out (orig->_fade_out) { _active = orig->_active; _in_update = orig->_in_update; _anchor_point = orig->_anchor_point; _follow_overlap = orig->_follow_overlap; _fixed = orig->_fixed; - + _in = newin; _out = newout; // copied from Crossfade::initialize() _in_update = false; - + _out->suspend_fade_out (); _in->suspend_fade_in (); @@ -192,7 +227,6 @@ Crossfade::Crossfade (boost::shared_ptr orig, boost::shared_ptr