summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2010-03-02 00:00:00 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2010-03-02 00:00:00 +0000
commitdb8b575c30845bafc34b87bacd52129c95d1c478 (patch)
tree7a521b7795cc6cc4e41d717a0feabd1aefb83e1f /libs/ardour
parent3540594dc53137eb9e857f9e3c1309382a6d7bef (diff)
the mega-properties/SequenceProperty patch. split is broken at present (right hand starts has start-in-source of zero)
git-svn-id: svn://localhost/ardour2/branches/3.0@6718 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/debug.h59
-rw-r--r--libs/ardour/ardour/playlist.h46
-rw-r--r--libs/ardour/ardour/region.h2
-rw-r--r--libs/ardour/ardour/region_factory.h7
-rw-r--r--libs/ardour/ardour/session.h5
-rw-r--r--libs/ardour/ardour/session_object.h1
-rw-r--r--libs/ardour/ardour/session_playlists.h5
-rw-r--r--libs/ardour/audioregion.cc30
-rw-r--r--libs/ardour/crossfade.cc4
-rw-r--r--libs/ardour/debug.cc116
-rw-r--r--libs/ardour/globals.cc13
-rw-r--r--libs/ardour/midi_playlist.cc1
-rw-r--r--libs/ardour/midi_ring_buffer.cc1
-rw-r--r--libs/ardour/midi_ui.cc1
-rw-r--r--libs/ardour/playlist.cc154
-rw-r--r--libs/ardour/region.cc121
-rw-r--r--libs/ardour/region_factory.cc28
-rw-r--r--libs/ardour/route_group.cc46
-rw-r--r--libs/ardour/session.cc18
-rw-r--r--libs/ardour/session_command.cc10
-rw-r--r--libs/ardour/session_object.cc5
-rw-r--r--libs/ardour/session_playlists.cc20
-rw-r--r--libs/ardour/session_state.cc13
-rw-r--r--libs/ardour/source.cc1
24 files changed, 459 insertions, 248 deletions
diff --git a/libs/ardour/ardour/debug.h b/libs/ardour/ardour/debug.h
index b7ee4c328c..5b4405b7d8 100644
--- a/libs/ardour/ardour/debug.h
+++ b/libs/ardour/ardour/debug.h
@@ -24,51 +24,28 @@
#include <sstream>
-namespace ARDOUR {
-
- extern uint64_t debug_bits;
- void debug_print (const char* prefix, std::string str);
- void set_debug_bits (uint64_t bits);
- int parse_debug_options (const char* str);
- void list_debug_options ();
+#include "pbd/debug.h"
+namespace PBD {
namespace DEBUG {
-
- /* this namespace is so that we can write DEBUG::bit_name */
-
- enum DebugBits {
- MidiSourceIO = 0x1,
- MidiPlaylistIO = 0x2,
- MidiDiskstreamIO = 0x4,
- SnapBBT = 0x8,
- Configuration = 0x10,
- Latency = 0x20,
- Processors = 0x40,
- Graph = 0x80,
- Destruction = 0x100,
- MTC = 0x200,
- Transport = 0x400,
- Slave = 0x800,
- SessionEvents = 0x800,
- MidiIO = 0x1000,
- MackieControl = 0x2000,
- MidiClock = 0x4000,
- Properties = 0x8000
- };
+ extern uint64_t MidiSourceIO;
+ extern uint64_t MidiPlaylistIO;
+ extern uint64_t MidiDiskstreamIO;
+ extern uint64_t SnapBBT;
+ extern uint64_t Configuration;
+ extern uint64_t Latency;
+ extern uint64_t Processors;
+ extern uint64_t Graph;
+ extern uint64_t Destruction;
+ extern uint64_t MTC;
+ extern uint64_t Transport;
+ extern uint64_t Slave;
+ extern uint64_t SessionEvents;
+ extern uint64_t MidiIO;
+ extern uint64_t MackieControl;
+ extern uint64_t MidiClock;
}
-
}
-#ifndef NDEBUG
-#define DEBUG_TRACE(bits,str) if ((bits) & ARDOUR::debug_bits) { ARDOUR::debug_print (# bits, str); }
-#define DEBUG_STR_DECL(id) std::stringstream __debug_str ## id;
-#define DEBUG_STR(id) __debug_str ## id
-#define DEBUG_STR_APPEND(id,s) __debug_str ## id << s;
-#else
-#define DEBUG_TRACE(bits,fmt,...) /*empty*/
-#define DEBUG_STR(a) /* empty */
-#define DEBUG_STR_APPEND(a,b) /* empty */
-#endif
-
#endif /* __ardour_debug_h__ */
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index 38469f4723..3c79ec0ec4 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -36,6 +36,7 @@
#include "pbd/undo.h"
#include "pbd/stateful.h"
#include "pbd/statefuldestructible.h"
+#include "pbd/sequence_property.h"
#include "evoral/types.hpp"
@@ -49,11 +50,43 @@ namespace ARDOUR {
class Session;
class Region;
+class Playlist;
+
+namespace Properties {
+ /* fake the type, since regions are handled by SequenceProperty which doesn't
+ care about such things.
+ */
+ extern PBD::PropertyDescriptor<bool> regions;
+}
+
+class RegionListProperty : public PBD::SequenceProperty<std::list<boost::shared_ptr<Region > > >
+{
+ public:
+ RegionListProperty (Playlist&);
+
+ boost::shared_ptr<Region> lookup_id (const PBD::ID& id);
+ void diff (PBD::PropertyList& before, PBD::PropertyList& after) const;
+
+ private:
+ friend class Playlist;
+ std::list<boost::shared_ptr<Region> > rlist() { return _val; }
+
+ /* we live and die with our playlist, no lifetime management needed */
+ Playlist& _playlist;
+
+ /* create a copy of this RegionListProperty that only
+ has what is needed for use in a history list command. This
+ means that it won't contain the actual region list but
+ will have the added/removed list.
+ */
+ RegionListProperty* copy_for_history () const;
+};
class Playlist : public SessionObject
, public boost::enable_shared_from_this<Playlist> {
public:
typedef std::list<boost::shared_ptr<Region> > RegionList;
+ static void make_property_quarks ();
Playlist (Session&, const XMLNode&, DataType type, bool hidden = false);
Playlist (Session&, std::string name, DataType type, bool hidden = false);
@@ -62,6 +95,13 @@ class Playlist : public SessionObject
virtual ~Playlist ();
+ bool set_property (const PBD::PropertyBase&);
+ void update (const RegionListProperty::ChangeRecord&);
+
+ PBD::PropertyList* property_factory (const XMLNode&) const;
+
+ boost::shared_ptr<Region> region_by_id (const PBD::ID&);
+
void set_region_ownership ();
virtual void clear (bool with_signals=true);
@@ -107,7 +147,7 @@ class Playlist : public SessionObject
boost::shared_ptr<Playlist> copy (std::list<AudioRange>&, bool result_is_hidden = true);
int paste (boost::shared_ptr<Playlist>, framepos_t position, float times);
- const RegionList& region_list () const { return regions; }
+ const RegionListProperty& region_list () const { return regions; }
RegionList* regions_at (framepos_t frame);
RegionList* regions_touched (framepos_t start, framepos_t end);
@@ -192,7 +232,7 @@ class Playlist : public SessionObject
friend class RegionLock;
- RegionList regions; /* the current list of regions in the playlist */
+ RegionListProperty regions; /* the current list of regions in the playlist */
std::set<boost::shared_ptr<Region> > all_regions; /* all regions ever added to this playlist */
PBD::ScopedConnectionList region_state_changed_connections;
DataType _type;
@@ -277,8 +317,6 @@ class Playlist : public SessionObject
virtual XMLNode& state (bool);
- boost::shared_ptr<Region> region_by_id (PBD::ID);
-
bool add_region_internal (boost::shared_ptr<Region>, framepos_t position);
int remove_region_internal (boost::shared_ptr<Region>);
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
index fb827e308d..1da185c6f2 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -91,6 +91,8 @@ class Region
static PBD::Signal2<void,boost::shared_ptr<ARDOUR::Region>, const PBD::PropertyChange&> RegionPropertyChanged;
+ PBD::PropertyList* property_factory (const XMLNode&) const;
+
void unlock_property_changes () { _no_property_changes = false; }
void block_property_changes () { _no_property_changes = true; }
diff --git a/libs/ardour/ardour/region_factory.h b/libs/ardour/ardour/region_factory.h
index 16e48828d4..a01103603a 100644
--- a/libs/ardour/ardour/region_factory.h
+++ b/libs/ardour/ardour/region_factory.h
@@ -21,6 +21,7 @@
#define __ardour_region_factory_h__
#include <map>
+#include <glibmm/thread.h>
#include "pbd/id.h"
@@ -37,8 +38,10 @@ class AudioRegion;
class RegionFactory {
public:
+ typedef std::map<PBD::ID,boost::shared_ptr<Region> > RegionMap;
static boost::shared_ptr<Region> region_by_id (const PBD::ID&);
+ static const RegionMap all_regions() { return region_map; }
static void clear_map ();
/** This is emitted only when a new id is assigned. Therefore,
@@ -75,8 +78,10 @@ class RegionFactory {
static boost::shared_ptr<Region> create (SourceList& srcs, const XMLNode&);
private:
- static std::map<PBD::ID,boost::weak_ptr<Region> > region_map;
+ static Glib::StaticMutex region_map_lock;
+ static RegionMap region_map;
static void map_add (boost::shared_ptr<Region>);
+ static void map_remove (boost::shared_ptr<Region>);
};
}
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index edeeeb11ef..d26c84a795 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -501,6 +501,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
/* region info */
+ boost::shared_ptr<Region> region_by_id (const PBD::ID&) const;
+ boost::shared_ptr<Region> find_whole_file_parent (boost::shared_ptr<Region const>) const;
+
void add_regions (std::vector<boost::shared_ptr<Region> >&);
PBD::Signal1<void,boost::weak_ptr<Region> > RegionAdded;
@@ -511,8 +514,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
std::string new_region_name (std::string);
std::string path_from_region_name (DataType type, std::string name, std::string identifier);
- boost::shared_ptr<Region> find_whole_file_parent (boost::shared_ptr<Region const>);
-
boost::shared_ptr<Region> XMLRegionFactory (const XMLNode&, bool full);
boost::shared_ptr<AudioRegion> XMLAudioRegionFactory (const XMLNode&, bool full);
boost::shared_ptr<MidiRegion> XMLMidiRegionFactory (const XMLNode&, bool full);
diff --git a/libs/ardour/ardour/session_object.h b/libs/ardour/ardour/session_object.h
index d18a1f9d41..3e401a66ce 100644
--- a/libs/ardour/ardour/session_object.h
+++ b/libs/ardour/ardour/session_object.h
@@ -23,6 +23,7 @@
#include <string>
#include "pbd/statefuldestructible.h"
#include "pbd/signals.h"
+#include "pbd/properties.h"
#include "ardour/ardour.h"
#include "ardour/session_handle.h"
diff --git a/libs/ardour/ardour/session_playlists.h b/libs/ardour/ardour/session_playlists.h
index db29ee8c05..d654595d60 100644
--- a/libs/ardour/ardour/session_playlists.h
+++ b/libs/ardour/ardour/session_playlists.h
@@ -31,6 +31,10 @@
class XMLNode;
+namespace PBD {
+ class ID;
+}
+
namespace ARDOUR {
class Playlist;
@@ -44,6 +48,7 @@ public:
~SessionPlaylists ();
boost::shared_ptr<Playlist> by_name (std::string name);
+ boost::shared_ptr<Playlist> by_id (const PBD::ID&);
uint32_t source_use_count (boost::shared_ptr<const Source> src) const;
template<class T> void foreach (T *obj, void (T::*func)(boost::shared_ptr<Playlist>));
void get (std::vector<boost::shared_ptr<Playlist> >&);
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 1288dcbb86..e30a3a5994 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -67,12 +67,18 @@ namespace ARDOUR {
void
AudioRegion::make_property_quarks ()
{
- Properties::envelope_active.id = g_quark_from_static_string (X_("envelope-active"));
- Properties::default_fade_in.id = g_quark_from_static_string (X_("default-fade-in"));
- Properties::default_fade_out.id = g_quark_from_static_string (X_("default-fade-out"));
- Properties::fade_in_active.id = g_quark_from_static_string (X_("fade-in-active"));
- Properties::fade_out_active.id = g_quark_from_static_string (X_("fade-out-active"));
- Properties::scale_amplitude.id = g_quark_from_static_string (X_("scale-amplitude"));
+ Properties::envelope_active.property_id = g_quark_from_static_string (X_("envelope-active"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for envelope-active = %1\n", Properties::envelope_active.property_id));
+ Properties::default_fade_in.property_id = g_quark_from_static_string (X_("default-fade-in"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for default-fade-in = %1\n", Properties::default_fade_in.property_id));
+ Properties::default_fade_out.property_id = g_quark_from_static_string (X_("default-fade-out"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for default-fade-out = %1\n", Properties::default_fade_out.property_id));
+ Properties::fade_in_active.property_id = g_quark_from_static_string (X_("fade-in-active"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for fade-in-active = %1\n", Properties::fade_in_active.property_id));
+ Properties::fade_out_active.property_id = g_quark_from_static_string (X_("fade-out-active"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for fade-out-active = %1\n", Properties::fade_out_active.property_id));
+ Properties::scale_amplitude.property_id = g_quark_from_static_string (X_("scale-amplitude"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for scale-amplitude = %1\n", Properties::scale_amplitude.property_id));
}
void
@@ -690,37 +696,37 @@ AudioRegion::set_property (const PropertyBase& prop)
{
DEBUG_TRACE (DEBUG::Properties, string_compose ("audio region %1 set property %2\n", _name.val(), prop.property_name()));
- if (prop == Properties::envelope_active.id) {
+ if (prop == Properties::envelope_active.property_id) {
bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
if (val != _envelope_active) {
_envelope_active = val;
return true;
}
- } else if (prop == Properties::default_fade_in.id) {
+ } else if (prop == Properties::default_fade_in.property_id) {
bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
if (val != _default_fade_in) {
_default_fade_in = val;
return true;
}
- } else if (prop == Properties::default_fade_out.id) {
+ } else if (prop == Properties::default_fade_out.property_id) {
bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
if (val != _default_fade_out) {
_default_fade_out = val;
return true;
}
- } else if (prop == Properties::fade_in_active.id) {
+ } else if (prop == Properties::fade_in_active.property_id) {
bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
if (val != _fade_in_active) {
_fade_in_active = val;
return true;
}
- } else if (prop == Properties::fade_out_active.id) {
+ } else if (prop == Properties::fade_out_active.property_id) {
bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
if (val != _fade_out_active) {
_fade_out_active = val;
return true;
}
- } else if (prop == Properties::scale_amplitude.id) {
+ } else if (prop == Properties::scale_amplitude.property_id) {
gain_t val = dynamic_cast<const PropertyTemplate<gain_t>*>(&prop)->val();
if (val != _scale_amplitude) {
_scale_amplitude = val;
diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc
index 8275876fe8..4f20db5b35 100644
--- a/libs/ardour/crossfade.cc
+++ b/libs/ardour/crossfade.cc
@@ -20,6 +20,7 @@
#include "pbd/stacktrace.h"
+#include "ardour/debug.h"
#include "ardour/types.h"
#include "ardour/crossfade.h"
#include "ardour/crossfade_compare.h"
@@ -60,7 +61,8 @@ namespace ARDOUR {
void
Crossfade::make_property_quarks ()
{
- Properties::follow_overlap.id = g_quark_from_static_string (X_("follow-overlap"));
+ 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
diff --git a/libs/ardour/debug.cc b/libs/ardour/debug.cc
index 48edc9a8d5..d169850694 100644
--- a/libs/ardour/debug.cc
+++ b/libs/ardour/debug.cc
@@ -23,106 +23,22 @@
#include "ardour/debug.h"
-#include "i18n.h"
-
using namespace std;
-void
-ARDOUR::debug_print (const char* prefix, string str)
-{
- cerr << prefix << ": " << str;
-}
-
-void
-ARDOUR::set_debug_bits (uint64_t bits)
-{
- debug_bits = bits;
-}
-
-int
-ARDOUR::parse_debug_options (const char* str)
-{
- char* p;
- char* sp;
- uint64_t bits = 0;
- char* copy = strdup (str);
-
- p = strtok_r (copy, ",", &sp);
-
- while (p) {
- if (strcasecmp (p, "list") == 0) {
- list_debug_options ();
- free (copy);
- return 1;
- }
-
- if (strcasecmp (p, "all") == 0) {
- ARDOUR::set_debug_bits (~0ULL);
- free (copy);
- return 0;
- }
-
- if (strncasecmp (p, "midisourceio", strlen (p)) == 0) {
- bits |= ARDOUR::DEBUG::MidiSourceIO;
- } else if (strncasecmp (p, "midiplaylistio", strlen (p)) == 0) {
- bits |= ARDOUR::DEBUG::MidiPlaylistIO;
- } else if (strncasecmp (p, "mididiskstreamio", strlen (p)) == 0) {
- bits |= ARDOUR::DEBUG::MidiDiskstreamIO;
- } else if (strncasecmp (p, "snapbbt", strlen (p)) == 0) {
- bits |= ARDOUR::DEBUG::SnapBBT;
- } else if (strncasecmp (p, "configuration", strlen (p)) == 0) {
- bits |= ARDOUR::DEBUG::Configuration;
- } else if (strncasecmp (p, "latency", strlen (p)) == 0) {
- bits |= ARDOUR::DEBUG::Latency;
- } else if (strncasecmp (p, "processors", strlen (p)) == 0) {
- bits |= ARDOUR::DEBUG::Processors;
- } else if (strncasecmp (p, "graph", strlen (p)) == 0) {
- bits |= ARDOUR::DEBUG::Graph;
- } else if (strncasecmp (p, "destruction", strlen (p)) == 0) {
- bits |= ARDOUR::DEBUG::Destruction;
- } else if (strncasecmp (p, "mtc", strlen (p)) == 0) {
- bits |= ARDOUR::DEBUG::MTC;
- } else if (strncasecmp (p, "transport", strlen (p)) == 0) {
- bits |= ARDOUR::DEBUG::Transport;
- } else if (strncasecmp (p, "slave", strlen (p)) == 0) {
- bits |= ARDOUR::DEBUG::Slave;
- } else if (strncasecmp (p, "sessionevents", strlen (p)) == 0) {
- bits |= ARDOUR::DEBUG::SessionEvents;
- } else if (strncasecmp (p, "midiio", strlen (p)) == 0) {
- bits |= ARDOUR::DEBUG::MidiIO;
- } else if (strncasecmp (p, "midiclock", strlen (p)) == 0) {
- bits |= ARDOUR::DEBUG::MidiClock;
- } else if (strncasecmp (p, "properties", strlen (p)) == 0) {
- bits |= ARDOUR::DEBUG::Properties;
- }
-
- p = strtok_r (0, ",", &sp);
- }
-
- free (copy);
- ARDOUR::set_debug_bits (bits);
- return 0;
-}
+uint64_t PBD::DEBUG::MidiSourceIO = PBD::new_debug_bit ("midisourceio");
+uint64_t PBD::DEBUG::MidiPlaylistIO = PBD::new_debug_bit ("midiplaylistio");
+uint64_t PBD::DEBUG::MidiDiskstreamIO = PBD::new_debug_bit ("mididiskstreamio");
+uint64_t PBD::DEBUG::SnapBBT = PBD::new_debug_bit ("snapbbt");
+uint64_t PBD::DEBUG::Configuration = PBD::new_debug_bit ("configuration");
+uint64_t PBD::DEBUG::Latency = PBD::new_debug_bit ("latency");
+uint64_t PBD::DEBUG::Processors = PBD::new_debug_bit ("processors");
+uint64_t PBD::DEBUG::Graph = PBD::new_debug_bit ("graph");
+uint64_t PBD::DEBUG::Destruction = PBD::new_debug_bit ("destruction");
+uint64_t PBD::DEBUG::MTC = PBD::new_debug_bit ("mtc");
+uint64_t PBD::DEBUG::Transport = PBD::new_debug_bit ("transport");
+uint64_t PBD::DEBUG::Slave = PBD::new_debug_bit ("slave");
+uint64_t PBD::DEBUG::SessionEvents = PBD::new_debug_bit ("sessionevents");
+uint64_t PBD::DEBUG::MidiIO = PBD::new_debug_bit ("midiio");
+uint64_t PBD::DEBUG::MackieControl = PBD::new_debug_bit ("mackiecontrol");
+uint64_t PBD::DEBUG::MidiClock = PBD::new_debug_bit ("midiclock");
-void
-ARDOUR::list_debug_options ()
-{
- cerr << _("The following debug options are available. Separate multipe options with commas.\nNames are case-insensitive and can be abbreviated.") << endl << endl;
- cerr << "\tAll" << endl;
- cerr << "\tMidiSourceIO" << endl;
- cerr << "\tMidiPlaylistIO" << endl;
- cerr << "\tMidiDiskstreamIO" << endl;
- cerr << "\tSnapBBT" << endl;
- cerr << "\tConfiguration" << endl;
- cerr << "\tLatency" << endl;
- cerr << "\tGraph" << endl;
- cerr << "\tDestruction" << endl;
- cerr << "\tMTC" << endl;
- cerr << "\tTransport" << endl;
- cerr << "\tSlave" << endl;
- cerr << "\tSessionEvents" << endl;
- cerr << "\tMidiIO" << endl;
- cerr << "\tLatencyCompensation" << endl;
- cerr << "\tMidiClock" << endl;
- cerr << "\tProperties" << endl;
-}
diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc
index ee19f1caac..389bcc196c 100644
--- a/libs/ardour/globals.cc
+++ b/libs/ardour/globals.cc
@@ -68,6 +68,7 @@
#include "ardour/debug.h"
#include "ardour/filesystem_paths.h"
#include "ardour/mix.h"
+#include "ardour/playlist.h"
#include "ardour/plugin_manager.h"
#include "ardour/profile.h"
#include "ardour/region.h"
@@ -95,8 +96,6 @@ using namespace ARDOUR;
using namespace std;
using namespace PBD;
-uint64_t ARDOUR::debug_bits = 0x0;
-
MIDI::Port *ARDOUR::default_mmc_port = 0;
MIDI::Port *ARDOUR::default_mtc_port = 0;
MIDI::Port *ARDOUR::default_midi_port = 0;
@@ -137,9 +136,12 @@ namespace ARDOUR {
void
ARDOUR::make_property_quarks ()
{
- Properties::fade_in.id = g_quark_from_static_string (X_("fade_in_FAKE"));
- Properties::fade_out.id = g_quark_from_static_string (X_("fade_out_FAKE"));
- Properties::envelope.id = g_quark_from_static_string (X_("envelope_FAKE"));
+ Properties::fade_in.property_id = g_quark_from_static_string (X_("fade_in_FAKE"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for fade_in_FAKE = %1\n", Properties::fade_in.property_id));
+ Properties::fade_out.property_id = g_quark_from_static_string (X_("fade_out_FAKE"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for fade_out_FAKE = %1\n", Properties::fade_out.property_id));
+ Properties::envelope.property_id = g_quark_from_static_string (X_("envelope_FAKE"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for envelope_FAKE = %1\n", Properties::envelope.property_id));
}
int
@@ -332,6 +334,7 @@ ARDOUR::init (bool use_vst, bool try_optimization)
Region::make_property_quarks ();
AudioRegion::make_property_quarks ();
RouteGroup::make_property_quarks ();
+ Playlist::make_property_quarks ();
/* this is a useful ready to use PropertyChange that many
things need to check. This avoids having to compose
diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc
index 048a54da93..eec0cde0db 100644
--- a/libs/ardour/midi_playlist.cc
+++ b/libs/ardour/midi_playlist.cc
@@ -39,6 +39,7 @@
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace std;
MidiPlaylist::MidiPlaylist (Session& session, const XMLNode& node, bool hidden)
diff --git a/libs/ardour/midi_ring_buffer.cc b/libs/ardour/midi_ring_buffer.cc
index a050422ae5..2d5eedb6eb 100644
--- a/libs/ardour/midi_ring_buffer.cc
+++ b/libs/ardour/midi_ring_buffer.cc
@@ -25,6 +25,7 @@
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
/** Read a block of MIDI events from buffer into a MidiBuffer.
*
diff --git a/libs/ardour/midi_ui.cc b/libs/ardour/midi_ui.cc
index fb85309ee1..be13209513 100644
--- a/libs/ardour/midi_ui.cc
+++ b/libs/ardour/midi_ui.cc
@@ -34,6 +34,7 @@
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
using namespace Glib;
#include "i18n.h"
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index e128489820..1aef4b8d92 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -46,6 +46,12 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
+namespace ARDOUR {
+namespace Properties {
+PBD::PropertyDescriptor<bool> regions;
+}
+}
+
struct ShowMeTheList {
ShowMeTheList (boost::shared_ptr<Playlist> pl, const string& n) : playlist (pl), name (n) {}
~ShowMeTheList () {
@@ -90,9 +96,66 @@ struct RegionSortByLastLayerOp {
}
};
+void
+Playlist::make_property_quarks ()
+{
+ Properties::regions.property_id = g_quark_from_static_string (X_("regions"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for regions = %1\n", Properties::regions.property_id));
+}
+
+RegionListProperty::RegionListProperty (Playlist& pl)
+ : SequenceProperty<std::list<boost::shared_ptr<Region> > > (Properties::regions.property_id, boost::bind (&Playlist::update, &pl, _1))
+ , _playlist (pl)
+{
+}
+
+boost::shared_ptr<Region>
+RegionListProperty::lookup_id (const ID& id)
+{
+ boost::shared_ptr<Region> ret = _playlist.region_by_id (id);
+
+ if (!ret) {
+ ret = _playlist.session().region_by_id (id);
+ }
+
+ if (!ret) {
+ ret = RegionFactory::region_by_id (id);
+ }
+ return ret;
+}
+
+RegionListProperty*
+RegionListProperty::copy_for_history () const
+{
+ RegionListProperty* copy = new RegionListProperty (_playlist);
+ /* this is all we need */
+ copy->_change = _change;
+ return copy;
+}
+
+void
+RegionListProperty::diff (PropertyList& before, PropertyList& after) const
+{
+ if (_have_old) {
+ RegionListProperty* a = copy_for_history ();
+ RegionListProperty* b = copy_for_history ();
+
+ b->invert_changes ();
+
+ before.add (b);
+ after.add (a);
+
+ cerr << "pdiff on " << _playlist.name() << " before contains "
+ << b->change().added.size() << " adds and " << b->change().removed.size() << " removes\n";
+ cerr << "pdiff on " << _playlist.name() << " after contains "
+ << a->change().added.size() << " adds and " << a->change().removed.size() << " removes\n";
+
+ }
+}
Playlist::Playlist (Session& sess, string nom, DataType type, bool hide)
: SessionObject(sess, nom)
+ , regions (*this)
, _type(type)
{
init (hide);
@@ -103,7 +166,9 @@ Playlist::Playlist (Session& sess, string nom, DataType type, bool hide)
Playlist::Playlist (Session& sess, const XMLNode& node, DataType type, bool hide)
: SessionObject(sess, "unnamed playlist")
- , _type(type)
+ , regions (*this)
+ , _type(type)
+
{
const XMLProperty* prop = node.property("type");
assert(!prop || DataType(prop->value()) == _type);
@@ -116,6 +181,7 @@ Playlist::Playlist (Session& sess, const XMLNode& node, DataType type, bool hide
Playlist::Playlist (boost::shared_ptr<const Playlist> other, string namestr, bool hide)
: SessionObject(other->_session, namestr)
+ , regions (*this)
, _type(other->_type)
, _orig_diskstream_id(other->_orig_diskstream_id)
{
@@ -150,6 +216,7 @@ Playlist::Playlist (boost::shared_ptr<const Playlist> other, string namestr, boo
Playlist::Playlist (boost::shared_ptr<const Playlist> other, framepos_t start, framecnt_t cnt, string str, bool hide)
: SessionObject(other->_session, str)
+ , regions (*this)
, _type(other->_type)
, _orig_diskstream_id(other->_orig_diskstream_id)
{
@@ -256,6 +323,9 @@ Playlist::copy_regions (RegionList& newlist) const
void
Playlist::init (bool hide)
{
+ add_property (regions);
+ _xml_node_name = X_("Playlist");
+
g_atomic_int_set (&block_notifications, 0);
g_atomic_int_set (&ignore_state_changes, 0);
pending_contents_change = false;
@@ -362,7 +432,7 @@ Playlist::release_notifications ()
{
if (g_atomic_int_dec_and_test (&block_notifications)) {
flush_notifications ();
- }
+ }
}
void
@@ -811,7 +881,7 @@ Playlist::partition_internal (framepos_t start, framepos_t end, bool cutting, Re
get operated on as well.
*/
- RegionList copy = regions;
+ RegionList copy = regions.rlist();
for (RegionList::iterator i = copy.begin(); i != copy.end(); i = tmp) {
@@ -1189,7 +1259,7 @@ void
Playlist::shift (framepos_t at, frameoffset_t distance, bool move_intersected, bool ignore_music_glue)
{
RegionLock rlock (this);
- RegionList copy (regions);
+ RegionList copy (regions.rlist());
RegionList fixup;
for (RegionList::iterator r = copy.begin(); r != copy.end(); ++r) {
@@ -1227,7 +1297,7 @@ void
Playlist::split (framepos_t at)
{
RegionLock rlock (this);
- RegionList copy (regions);
+ RegionList copy (regions.rlist());
/* use a copy since this operation can modify the region list
*/
@@ -1406,9 +1476,10 @@ Playlist::region_bounds_changed (const PropertyChange& what_changed, boost::shar
RegionList::iterator i = find (regions.begin(), regions.end(), region);
if (i == regions.end()) {
- warning << string_compose (_("%1: bounds changed received for region (%2)not in playlist"),
- _name, region->name())
- << endmsg;
+ /* the region bounds are being modified but its not currently
+ in the region list. we will use its bounds correctly when/if
+ it is added
+ */
return;
}
@@ -1939,6 +2010,63 @@ Playlist::mark_session_dirty ()
}
}
+bool
+Playlist::set_property (const PropertyBase& prop)
+{
+ if (prop == Properties::regions.property_id) {
+ const RegionListProperty::ChangeRecord& change (dynamic_cast<const RegionListProperty*>(&prop)->change());
+ regions.update (change);
+ return (!change.added.empty() && !change.removed.empty());
+ }
+ return false;
+}
+
+void
+Playlist::update (const RegionListProperty::ChangeRecord& change)
+{
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("Playlist %1 updates from a change record with %2 adds %3 removes\n",
+ name(), change.added.size(), change.removed.size()));
+
+ freeze ();
+ /* add the added regions */
+ for (RegionListProperty::ChangeContainer::iterator i = change.added.begin(); i != change.added.end(); ++i) {
+ add_region ((*i), (*i)->position());
+ }
+ /* remove the removed regions */
+ for (RegionListProperty::ChangeContainer::iterator i = change.removed.begin(); i != change.removed.end(); ++i) {
+ remove_region (*i);
+ }
+ thaw ();
+}
+
+PropertyList*
+Playlist::property_factory (const XMLNode& history_node) const
+{
+ const XMLNodeList& children (history_node.children());
+ PropertyList* prop_list = 0;
+
+ for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
+
+ /* XXX property name needs capitalizing */
+
+ if ((*i)->name() == regions.property_name()) {
+
+ RegionListProperty* rlp = new RegionListProperty (*const_cast<Playlist*> (this));
+
+ if (rlp->load_history_state (**i)) {
+ if (!prop_list) {
+ prop_list = new PropertyList();
+ }
+ prop_list->add (rlp);
+ } else {
+ delete rlp;
+ }
+ }
+ }
+
+ return prop_list;
+}
+
int
Playlist::set_state (const XMLNode& node, int version)
{
@@ -1968,6 +2096,8 @@ Playlist::set_state (const XMLNode& node, int version)
if (prop->name() == X_("name")) {
_name = prop->value();
+ } else if (prop->name() == X_("id")) {
+ _id = prop->value();
} else if (prop->name() == X_("orig_diskstream_id")) {
_orig_diskstream_id = prop->value ();
} else if (prop->name() == X_("frozen")) {
@@ -2053,6 +2183,7 @@ Playlist::state (bool full_state)
XMLNode *node = new XMLNode (X_("Playlist"));
char buf[64];
+ node->add_property (X_("id"), id().to_s());
node->add_property (X_("name"), _name);
node->add_property (X_("type"), _type.to_string());
@@ -2177,7 +2308,7 @@ Playlist::relayer ()
which depends on the layer model
*/
- RegionList copy = regions;
+ RegionList copy = regions.rlist();
/* sort according to the model and the layering mode that we're in */
@@ -2191,6 +2322,7 @@ Playlist::relayer ()
}
+
for (RegionList::iterator i = copy.begin(); i != copy.end(); ++i) {
/* reset the pending explicit relayer flag for every region, now that we're relayering */
@@ -2447,7 +2579,7 @@ Playlist::find_region (const ID& id) const
}
boost::shared_ptr<Region>
-Playlist::region_by_id (ID id)
+Playlist::region_by_id (const ID& id)
{
/* searches all regions ever added to this playlist */
@@ -2627,7 +2759,7 @@ void
Playlist::update_after_tempo_map_change ()
{
RegionLock rlock (const_cast<Playlist*> (this));
- RegionList copy (regions);
+ RegionList copy (regions.rlist());
freeze ();
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index ca89c3cec0..f59d076c59 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -77,27 +77,48 @@ PBD::Signal2<void,boost::shared_ptr<ARDOUR::Region>,const PropertyChange&> Regio
void
Region::make_property_quarks ()
{
- Properties::muted.id = g_quark_from_static_string (X_("muted"));
- Properties::opaque.id = g_quark_from_static_string (X_("opaque"));
- Properties::locked.id = g_quark_from_static_string (X_("locked"));
- Properties::automatic.id = g_quark_from_static_string (X_("automatic"));
- Properties::whole_file.id = g_quark_from_static_string (X_("whole-file"));
- Properties::import.id = g_quark_from_static_string (X_("import"));
- Properties::external.id = g_quark_from_static_string (X_("external"));
- Properties::sync_marked.id = g_quark_from_static_string (X_("sync-marked"));
- Properties::left_of_split.id = g_quark_from_static_string (X_("left-of-split"));
- Properties::right_of_split.id = g_quark_from_static_string (X_("right-of-split"));
- Properties::hidden.id = g_quark_from_static_string (X_("hidden"));
- Properties::position_locked.id = g_quark_from_static_string (X_("position-locked"));
- Properties::start.id = g_quark_from_static_string (X_("start"));
- Properties::length.id = g_quark_from_static_string (X_("length"));
- Properties::position.id = g_quark_from_static_string (X_("position"));
- Properties::sync_position.id = g_quark_from_static_string (X_("sync-position"));
- Properties::layer.id = g_quark_from_static_string (X_("layer"));
- Properties::ancestral_start.id = g_quark_from_static_string (X_("ancestral-start"));
- Properties::ancestral_length.id = g_quark_from_static_string (X_("ancestral-length"));
- Properties::stretch.id = g_quark_from_static_string (X_("stretch"));
- Properties::shift.id = g_quark_from_static_string (X_("shift"));
+ Properties::muted.property_id = g_quark_from_static_string (X_("muted"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for muted = %1\n", Properties::muted.property_id));
+ Properties::opaque.property_id = g_quark_from_static_string (X_("opaque"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for opaque = %1\n", Properties::opaque.property_id));
+ Properties::locked.property_id = g_quark_from_static_string (X_("locked"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for locked = %1\n", Properties::locked.property_id));
+ Properties::automatic.property_id = g_quark_from_static_string (X_("automatic"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for automatic = %1\n", Properties::automatic.property_id));
+ Properties::whole_file.property_id = g_quark_from_static_string (X_("whole-file"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for whole-file = %1\n", Properties::whole_file.property_id));
+ Properties::import.property_id = g_quark_from_static_string (X_("import"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for import = %1\n", Properties::import.property_id));
+ Properties::external.property_id = g_quark_from_static_string (X_("external"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for external = %1\n", Properties::external.property_id));
+ Properties::sync_marked.property_id = g_quark_from_static_string (X_("sync-marked"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for sync-marked = %1\n", Properties::sync_marked.property_id));
+ Properties::left_of_split.property_id = g_quark_from_static_string (X_("left-of-split"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for left-of-split = %1\n", Properties::left_of_split.property_id));
+ Properties::right_of_split.property_id = g_quark_from_static_string (X_("right-of-split"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for right-of-split = %1\n", Properties::right_of_split.property_id));
+ Properties::hidden.property_id = g_quark_from_static_string (X_("hidden"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for hidden = %1\n", Properties::hidden.property_id));
+ Properties::position_locked.property_id = g_quark_from_static_string (X_("position-locked"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for position-locked = %1\n", Properties::position_locked.property_id));
+ Properties::start.property_id = g_quark_from_static_string (X_("start"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for start = %1\n", Properties::start.property_id));
+ Properties::length.property_id = g_quark_from_static_string (X_("length"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for length = %1\n", Properties::length.property_id));
+ Properties::position.property_id = g_quark_from_static_string (X_("position"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for position = %1\n", Properties::position.property_id));
+ Properties::sync_position.property_id = g_quark_from_static_string (X_("sync-position"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for sync-position = %1\n", Properties::sync_position.property_id));
+ Properties::layer.property_id = g_quark_from_static_string (X_("layer"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for layer = %1\n", Properties::layer.property_id));
+ Properties::ancestral_start.property_id = g_quark_from_static_string (X_("ancestral-start"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for ancestral-start = %1\n", Properties::ancestral_start.property_id));
+ Properties::ancestral_length.property_id = g_quark_from_static_string (X_("ancestral-length"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for ancestral-length = %1\n", Properties::ancestral_length.property_id));
+ Properties::stretch.property_id = g_quark_from_static_string (X_("stretch"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for stretch = %1\n", Properties::stretch.property_id));
+ Properties::shift.property_id = g_quark_from_static_string (X_("shift"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for shift = %1\n", Properties::shift.property_id));
}
void
@@ -1516,7 +1537,7 @@ Region::set_property (const PropertyBase& prop)
{
DEBUG_TRACE (DEBUG::Properties, string_compose ("region %1 set property %2\n", _name.val(), prop.property_name()));
- if (prop == Properties::muted.id) {
+ if (prop == Properties::muted.property_id) {
bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
if (val != _muted) {
DEBUG_TRACE (DEBUG::Properties, string_compose ("region %1 muted changed from %2 to %3",
@@ -1524,7 +1545,7 @@ Region::set_property (const PropertyBase& prop)
_muted = val;
return true;
}
- } else if (prop == Properties::opaque.id) {
+ } else if (prop == Properties::opaque.property_id) {
bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
if (val != _opaque) {
DEBUG_TRACE (DEBUG::Properties, string_compose ("region %1 opaque changed from %2 to %3",
@@ -1532,7 +1553,7 @@ Region::set_property (const PropertyBase& prop)
_opaque = val;
return true;
}
- } else if (prop == Properties::locked.id) {
+ } else if (prop == Properties::locked.property_id) {
bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
if (val != _locked) {
DEBUG_TRACE (DEBUG::Properties, string_compose ("region %1 locked changed from %2 to %3",
@@ -1540,61 +1561,61 @@ Region::set_property (const PropertyBase& prop)
_locked = val;
return true;
}
- } else if (prop == Properties::automatic.id) {
+ } else if (prop == Properties::automatic.property_id) {
_automatic = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
- } else if (prop == Properties::whole_file.id) {
+ } else if (prop == Properties::whole_file.property_id) {
_whole_file = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
- } else if (prop == Properties::import.id) {
+ } else if (prop == Properties::import.property_id) {
_import = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
- } else if (prop == Properties::external.id) {
+ } else if (prop == Properties::external.property_id) {
_external = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
- } else if (prop == Properties::sync_marked.id) {
+ } else if (prop == Properties::sync_marked.property_id) {
_sync_marked = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
- } else if (prop == Properties::left_of_split.id) {
+ } else if (prop == Properties::left_of_split.property_id) {
_left_of_split = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
- } else if (prop == Properties::right_of_split.id) {
+ } else if (prop == Properties::right_of_split.property_id) {
_right_of_split = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
- } else if (prop == Properties::hidden.id) {
+ } else if (prop == Properties::hidden.property_id) {
bool val = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
if (val != _hidden) {
_hidden = val;
return true;
}
- } else if (prop == Properties::position_locked.id) {
+ } else if (prop == Properties::position_locked.property_id) {
_position_locked = dynamic_cast<const PropertyTemplate<bool>*>(&prop)->val();
- } else if (prop == Properties::start.id) {
+ } else if (prop == Properties::start.property_id) {
_start = dynamic_cast<const PropertyTemplate<framepos_t>*>(&prop)->val();
- } else if (prop == Properties::length.id) {
+ } else if (prop == Properties::length.property_id) {
framecnt_t val = dynamic_cast<const PropertyTemplate<framecnt_t>* > (&prop)->val();
if (val != _length) {
_length = val;
return true;
}
- } else if (prop == Properties::position.id) {
+ } else if (prop == Properties::position.property_id) {
framepos_t val = dynamic_cast<const PropertyTemplate<framepos_t>*>(&prop)->val();
if (val != _position) {
_position = val;
return true;
}
- } else if (prop == Properties::sync_position.id) {
+ } else if (prop == Properties::sync_position.property_id) {
framepos_t val = dynamic_cast<const PropertyTemplate<framepos_t>*>(&prop)->val();
if (val != _sync_position) {
_sync_position = val;
return true;
}
- } else if (prop == Properties::layer.id) {
+ } else if (prop == Properties::layer.property_id) {
layer_t val = dynamic_cast<const PropertyTemplate<layer_t>*>(&prop)->val();
if (val != _layer) {
_layer = val;
return true;
}
- } else if (prop == Properties::ancestral_start.id) {
+ } else if (prop == Properties::ancestral_start.property_id) {
_ancestral_start = dynamic_cast<const PropertyTemplate<framepos_t>*>(&prop)->val();
- } else if (prop == Properties::ancestral_length.id) {
+ } else if (prop == Properties::ancestral_length.property_id) {
_ancestral_length = dynamic_cast<const PropertyTemplate<framecnt_t>*>(&prop)->val();
- } else if (prop == Properties::stretch.id) {
+ } else if (prop == Properties::stretch.property_id) {
_stretch = dynamic_cast<const PropertyTemplate<float>*>(&prop)->val();
- } else if (prop == Properties::shift.id) {
+ } else if (prop == Properties::shift.property_id) {
_shift = dynamic_cast<const PropertyTemplate<float>*>(&prop)->val();
} else {
return SessionObject::set_property (prop);
@@ -1602,3 +1623,19 @@ Region::set_property (const PropertyBase& prop)
return false;
}
+
+PropertyList*
+Region::property_factory (const XMLNode& history_node) const
+{
+ PropertyList* prop_list = new PropertyList;
+
+ for (OwnedPropertyList::const_iterator i = _properties->begin(); i != _properties->end(); ++i) {
+ PropertyBase* prop = i->second->maybe_clone_self_if_found_in_history_node (history_node);
+
+ if (prop) {
+ prop_list->add (prop);
+ }
+ }
+
+ return prop_list;
+}
diff --git a/libs/ardour/region_factory.cc b/libs/ardour/region_factory.cc
index 348dc72041..d2c5fa1b22 100644
--- a/libs/ardour/region_factory.cc
+++ b/libs/ardour/region_factory.cc
@@ -36,7 +36,8 @@ using namespace ARDOUR;
using namespace PBD;
PBD::Signal1<void,boost::shared_ptr<Region> > RegionFactory::CheckNewRegion;
-map<PBD::ID,boost::weak_ptr<Region> > RegionFactory::region_map;
+Glib::StaticMutex RegionFactory::region_map_lock;
+RegionFactory::RegionMap RegionFactory::region_map;
boost::shared_ptr<Region>
RegionFactory::create (boost::shared_ptr<const Region> region)
@@ -302,23 +303,40 @@ RegionFactory::create (SourceList& srcs, const XMLNode& node)
void
RegionFactory::map_add (boost::shared_ptr<Region> r)
{
- pair<ID,boost::weak_ptr<Region> > p;
+ pair<ID,boost::shared_ptr<Region> > p;
p.first = r->id();
p.second = r;
- region_map.insert (p);
+ {
+ Glib::Mutex::Lock lm (region_map_lock);
+ region_map.insert (p);
+ /* we pay no attention to attempts to delete regions */
+ }
+}
+
+void
+RegionFactory::map_remove (boost::shared_ptr<Region> r)
+{
+ {
+ Glib::Mutex::Lock lm (region_map_lock);
+ RegionMap::iterator i = region_map.find (r->id());
+ if (i != region_map.end()) {
+ region_map.erase (i);
+ }
+ }
}
boost::shared_ptr<Region>
RegionFactory::region_by_id (const PBD::ID& id)
{
- map<ID,boost::weak_ptr<Region> >::iterator i = region_map.find (id);
+ RegionMap::iterator i = region_map.find (id);
if (i == region_map.end()) {
+ cerr << "ID " << id << " not found in region map\n";
return boost::shared_ptr<Region>();
}
- return i->second.lock();
+ return i->second;
}
void
diff --git a/libs/ardour/route_group.cc b/libs/ardour/route_group.cc
index f31820e924..3e9ffe16d6 100644
--- a/libs/ardour/route_group.cc
+++ b/libs/ardour/route_group.cc
@@ -28,6 +28,7 @@
#include "pbd/strsplit.h"
#include "ardour/amp.h"
+#include "ardour/debug.h"
#include "ardour/route_group.h"
#include "ardour/audio_track.h"
#include "ardour/audio_diskstream.h"
@@ -56,15 +57,24 @@ namespace ARDOUR {
void
RouteGroup::make_property_quarks ()
{
- Properties::relative.id = g_quark_from_static_string (X_("relative"));
- Properties::active.id = g_quark_from_static_string (X_("active"));
- Properties::hidden.id = g_quark_from_static_string (X_("hidden"));
- Properties::gain.id = g_quark_from_static_string (X_("gain"));
- Properties::mute.id = g_quark_from_static_string (X_("mute"));
- Properties::solo.id = g_quark_from_static_string (X_("solo"));
- Properties::recenable.id = g_quark_from_static_string (X_("recenable"));
- Properties::select.id = g_quark_from_static_string (X_("select"));
- Properties::edit.id = g_quark_from_static_string (X_("edit"));
+ Properties::relative.property_id = g_quark_from_static_string (X_("relative"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for relative = %1\n", Properties::relative.property_id));
+ Properties::active.property_id = g_quark_from_static_string (X_("active"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for active = %1\n", Properties::active.property_id));
+ Properties::hidden.property_id = g_quark_from_static_string (X_("hidden"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for hidden = %1\n", Properties::hidden.property_id));
+ Properties::gain.property_id = g_quark_from_static_string (X_("gain"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for gain = %1\n", Properties::gain.property_id));
+ Properties::mute.property_id = g_quark_from_static_string (X_("mute"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for mute = %1\n", Properties::mute.property_id));
+ Properties::solo.property_id = g_quark_from_static_string (X_("solo"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for solo = %1\n", Properties::solo.property_id));
+ Properties::recenable.property_id = g_quark_from_static_string (X_("recenable"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for recenable = %1\n", Properties::recenable.property_id));
+ Properties::select.property_id = g_quark_from_static_string (X_("select"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for select = %1\n", Properties::select.property_id));
+ Properties::edit.property_id = g_quark_from_static_string (X_("edit"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for edit = %1\n", Properties::edit.property_id));
}
#define ROUTE_GROUP_DEFAULT_PROPERTIES _relative (Properties::relative, false) \
@@ -432,23 +442,23 @@ RouteGroup::destroy_subgroup ()
bool
RouteGroup::enabled_property (PBD::PropertyID prop)
{
- if (Properties::relative.id == prop) {
+ if (Properties::relative.property_id == prop) {
return is_relative();
- } else if (Properties::active.id == prop) {
+ } else if (Properties::active.property_id == prop) {
return is_active();
- } else if (Properties::hidden.id == prop) {
+ } else if (Properties::hidden.property_id == prop) {
return is_hidden();
- } else if (Properties::gain.id == prop) {
+ } else if (Properties::gain.property_id == prop) {
return is_gain();
- } else if (Properties::mute.id == prop) {
+ } else if (Properties::mute.property_id == prop) {
return is_mute();
- } else if (Properties::solo.id == prop) {
+ } else if (Properties::solo.property_id == prop) {
return is_solo();
- } else if (Properties::recenable.id == prop) {
+ } else if (Properties::recenable.property_id == prop) {
return is_recenable();
- } else if (Properties::select.id == prop) {
+ } else if (Properties::select.property_id == prop) {
return is_select();
- } else if (Properties::edit.id == prop) {
+ } else if (Properties::edit.property_id == prop) {
return is_edit();
}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index c549244e64..0c2f12d91d 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -2803,9 +2803,9 @@ Session::remove_region (boost::weak_ptr<Region> weak_region)
}
boost::shared_ptr<Region>
-Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
+Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
{
- RegionList::iterator i;
+ RegionList::const_iterator i;
boost::shared_ptr<Region> region;
Glib::Mutex::Lock lm (region_lock);
@@ -2825,6 +2825,20 @@ Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
return boost::shared_ptr<Region> ();
}
+boost::shared_ptr<Region>
+Session::region_by_id (const PBD::ID& id) const
+{
+ Glib::Mutex::Lock lm (region_lock);
+
+ RegionList::const_iterator i = regions.find (id);
+
+ if (i != regions.end()) {
+ return i->second;
+ }
+
+ return boost::shared_ptr<Region> ();
+}
+
int
Session::destroy_region (boost::shared_ptr<Region> region)
{
diff --git a/libs/ardour/session_command.cc b/libs/ardour/session_command.cc
index 6c2621fdb9..3ff68a06fb 100644
--- a/libs/ardour/session_command.cc
+++ b/libs/ardour/session_command.cc
@@ -146,7 +146,15 @@ Session::stateful_diff_command_factory (XMLNode* n)
if (r) {
return new StatefulDiffCommand (r, *n);
}
- }
+
+ } else if (obj_T == typeid (AudioPlaylist).name() || obj_T == typeid (MidiPlaylist).name()) {
+ boost::shared_ptr<Playlist> p = playlists->by_id (id);
+ if (p) {
+ return new StatefulDiffCommand (p, *n);
+ } else {
+ cerr << "Playlist with ID = " << id << " not found\n";
+ }
+ }
/* we failed */
diff --git a/libs/ardour/session_object.cc b/libs/ardour/session_object.cc
index b245b43ae5..3e71b6a73e 100644
--- a/libs/ardour/session_object.cc
+++ b/libs/ardour/session_object.cc
@@ -34,13 +34,14 @@ namespace ARDOUR {
void
SessionObject::make_property_quarks ()
{
- Properties::name.id = g_quark_from_static_string (X_("name"));
+ Properties::name.property_id = g_quark_from_static_string (X_("name"));
+ DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for name = %1\n", Properties::name.property_id));
}
bool
SessionObject::set_property (const PropertyBase& prop)
{
- if (prop == Properties::name.id) {
+ if (prop == Properties::name.property_id) {
std::string str = dynamic_cast<const PropertyTemplate<std::string>*>(&prop)->val();
if (_name != str) {
DEBUG_TRACE (DEBUG::Properties, string_compose ("session object named %1 renamed %2\n",
diff --git a/libs/ardour/session_playlists.cc b/libs/ardour/session_playlists.cc
index 17ed6a4e30..2f8ae9a8f0 100644
--- a/libs/ardour/session_playlists.cc
+++ b/libs/ardour/session_playlists.cc
@@ -167,6 +167,26 @@ SessionPlaylists::by_name (string name)
return boost::shared_ptr<Playlist>();
}
+boost::shared_ptr<Playlist>
+SessionPlaylists::by_id (const PBD::ID& id)
+{
+ Glib::Mutex::Lock lm (lock);
+
+ for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+ if ((*i)->id() == id) {
+ return* i;
+ }
+ }
+
+ for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
+ if ((*i)->id() == id) {
+ return* i;
+ }
+ }
+
+ return boost::shared_ptr<Playlist>();
+}
+
void
SessionPlaylists::unassigned (std::list<boost::shared_ptr<Playlist> > & list)
{
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 434410b39e..014200da1c 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -991,7 +991,7 @@ Session::state(bool full_state)
if (full_state) {
Glib::Mutex::Lock rl (region_lock);
-
+#if 0
for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
/* only store regions not attached to playlists */
@@ -1000,6 +1000,17 @@ Session::state(bool full_state)
child->add_child_nocopy (i->second->state (true));
}
}
+#else
+ const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
+ for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
+ boost::shared_ptr<Region> r = i->second;
+ /* only store regions not attached to playlists */
+ if (r->playlist() == 0) {
+ child->add_child_nocopy (r->state (true));
+ }
+ }
+#endif
+
}
child = node->add_child ("DiskStreams");
diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc
index 239c3729c9..5ec9631e40 100644
--- a/libs/ardour/source.cc
+++ b/libs/ardour/source.cc
@@ -45,6 +45,7 @@
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
Source::Source (Session& s, DataType type, const string& name, Flag flags)
: SessionObject(s, name)