#include <cstdlib>
-
#include "ardour/types.h"
#include "ardour/debug.h"
#include "ardour/configuration.h"
using namespace std;
using namespace PBD;
+namespace ARDOUR {
+ namespace Properties {
+ PBD::PropertyDescriptor<bool> crossfades;
+ }
+}
+
+void
+AudioPlaylist::make_property_quarks ()
+{
+ Properties::crossfades.property_id = g_quark_from_static_string (X_("crossfades"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for crossfades = %1\n", Properties::crossfades.property_id));
+}
+
+CrossfadeListProperty::CrossfadeListProperty (AudioPlaylist& pl)
+ : SequenceProperty<std::list<boost::shared_ptr<Crossfade> > > (Properties::crossfades.property_id, boost::bind (&AudioPlaylist::update, &pl, _1))
+ , _playlist (pl)
+{
+
+}
+
+CrossfadeListProperty::CrossfadeListProperty (CrossfadeListProperty const & p)
+ : PBD::SequenceProperty<std::list<boost::shared_ptr<Crossfade> > > (p)
+ , _playlist (p._playlist)
+{
+
+}
+
+
+CrossfadeListProperty *
+CrossfadeListProperty::create () const
+{
+ return new CrossfadeListProperty (_playlist);
+}
+
+CrossfadeListProperty *
+CrossfadeListProperty::clone () const
+{
+ return new CrossfadeListProperty (*this);
+}
+
+void
+CrossfadeListProperty::get_content_as_xml (boost::shared_ptr<Crossfade> xfade, XMLNode & node) const
+{
+ /* Crossfades are not written to any state when they are no
+ longer in use, so we must write their state here.
+ */
+
+ XMLNode& c = xfade->get_state ();
+ node.add_child_nocopy (c);
+}
+
+boost::shared_ptr<Crossfade>
+CrossfadeListProperty::get_content_from_xml (XMLNode const & node) const
+{
+ XMLNodeList const c = node.children ();
+ assert (c.size() == 1);
+ return boost::shared_ptr<Crossfade> (new Crossfade (_playlist, *c.front()));
+}
+
+
AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden)
: Playlist (session, node, DataType::AUDIO, hidden)
+ , _crossfades (*this)
{
#ifndef NDEBUG
const XMLProperty* prop = node.property("type");
assert(!prop || DataType(prop->value()) == DataType::AUDIO);
#endif
+ add_property (_crossfades);
+
in_set_state++;
set_state (node, Stateful::loading_state_version);
in_set_state--;
AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden)
: Playlist (session, name, DataType::AUDIO, hidden)
+ , _crossfades (*this)
{
+ add_property (_crossfades);
}
AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, string name, bool hidden)
: Playlist (other, name, hidden)
+ , _crossfades (*this)
{
+ add_property (_crossfades);
+
RegionList::const_iterator in_o = other->regions.begin();
RegionList::iterator in_n = regions.begin();
}
}
-AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, nframes_t start, nframes_t cnt, string name, bool hidden)
+AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, framepos_t start, framecnt_t cnt, string name, bool hidden)
: Playlist (other, start, cnt, name, hidden)
+ , _crossfades (*this)
{
+ add_property (_crossfades);
+
/* this constructor does NOT notify others (session) */
}
}
};
-ARDOUR::nframes_t
-AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t start,
- nframes_t cnt, unsigned chan_n)
+ARDOUR::framecnt_t
+AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, framepos_t start,
+ framecnt_t cnt, unsigned chan_n)
{
- nframes_t ret = cnt;
- nframes_t end;
- nframes_t read_frames;
- nframes_t skip_frames;
+ framecnt_t ret = cnt;
/* optimizing this memset() away involves a lot of conditionals
that may well cause more of a hit due to cache misses
Glib::RecMutex::Lock rm (region_lock);
- end = start + cnt - 1;
- read_frames = 0;
- skip_frames = 0;
+ framepos_t const end = start + cnt - 1;
+ framecnt_t read_frames = 0;
+ framecnt_t skip_frames = 0;
_read_data_count = 0;
_read_data_count = 0;
touched_regions = 0;
try {
- nframes_t xfade_length;
+ framecnt_t xfade_length;
switch (c) {
case OverlapNone:
break;
}
void
-AudioPlaylist::crossfades_at (nframes_t frame, Crossfades& clist)
+AudioPlaylist::crossfades_at (framepos_t frame, Crossfades& clist)
{
RegionLock rlock (this);
for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
- nframes_t start, end;
-
- start = (*i)->position();
- end = start + (*i)->overlap_length(); // not length(), important difference
+ framepos_t const start = (*i)->position ();
+ framepos_t const end = start + (*i)->overlap_length(); // not length(), important difference
if (frame >= start && frame <= end) {
clist.push_back (*i);
s (*i);
}
}
+
+void
+AudioPlaylist::update (const CrossfadeListProperty::ChangeRecord& change)
+{
+ for (CrossfadeListProperty::ChangeContainer::const_iterator i = change.added.begin(); i != change.added.end(); ++i) {
+ add_crossfade (*i);
+ }
+
+ /* don't remove crossfades here; they will be dealt with by the dependency code */
+}
+
+boost::shared_ptr<Crossfade>
+AudioPlaylist::find_crossfade (const PBD::ID& id) const
+{
+ Crossfades::const_iterator i = _crossfades.begin ();
+ while (i != _crossfades.end() && (*i)->id() != id) {
+ ++i;
+ }
+
+ if (i == _crossfades.end()) {
+ return boost::shared_ptr<Crossfade> ();
+ }
+
+ return *i;
+}