diff options
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/audiofilesource.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/audioplaylist.h | 31 | ||||
-rw-r--r-- | libs/ardour/ardour/audioregion.h | 20 | ||||
-rw-r--r-- | libs/ardour/ardour/configuration_vars.h | 11 | ||||
-rw-r--r-- | libs/ardour/ardour/crossfade.h | 27 | ||||
-rw-r--r-- | libs/ardour/ardour/midi_playlist.h | 31 | ||||
-rw-r--r-- | libs/ardour/ardour/playlist.h | 22 | ||||
-rw-r--r-- | libs/ardour/ardour/region.h | 29 | ||||
-rw-r--r-- | libs/ardour/audio_playlist.cc | 273 | ||||
-rw-r--r-- | libs/ardour/audiofilesource.cc | 4 | ||||
-rw-r--r-- | libs/ardour/audioregion.cc | 175 | ||||
-rw-r--r-- | libs/ardour/auditioner.cc | 6 | ||||
-rw-r--r-- | libs/ardour/crossfade.cc | 163 | ||||
-rw-r--r-- | libs/ardour/diskstream.cc | 1 | ||||
-rw-r--r-- | libs/ardour/midi_playlist.cc | 129 | ||||
-rw-r--r-- | libs/ardour/midi_region.cc | 48 | ||||
-rw-r--r-- | libs/ardour/playlist.cc | 171 | ||||
-rw-r--r-- | libs/ardour/region.cc | 284 | ||||
-rw-r--r-- | libs/ardour/session.cc | 13 | ||||
-rw-r--r-- | libs/ardour/session_command.cc | 102 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 78 | ||||
-rw-r--r-- | libs/ardour/sndfilesource.cc | 4 |
22 files changed, 466 insertions, 1158 deletions
diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h index 6184a45302..af5f5cdb60 100644 --- a/libs/ardour/ardour/audiofilesource.h +++ b/libs/ardour/ardour/audiofilesource.h @@ -81,8 +81,6 @@ class AudioFileSource : public AudioSource { void mark_take (string); string take_id() const { return _take_id; } - static void set_bwf_country_code (string x); - static void set_bwf_organization_code (string x); static void set_bwf_serial_number (int); static void set_search_path (string); diff --git a/libs/ardour/ardour/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h index 341b08930c..383ec73531 100644 --- a/libs/ardour/ardour/audioplaylist.h +++ b/libs/ardour/ardour/audioplaylist.h @@ -38,19 +38,6 @@ class AudioPlaylist : public ARDOUR::Playlist { public: typedef std::list<Crossfade*> Crossfades; - - private: - - struct State : public ARDOUR::StateManager::State { - RegionList regions; - std::list<UndoAction> region_states; - - Crossfades crossfades; - std::list<UndoAction> crossfade_states; - - State (std::string why) : ARDOUR::StateManager::State (why) {} - ~State (); - }; public: AudioPlaylist (Session&, const XMLNode&, bool hidden = false); @@ -58,35 +45,21 @@ class AudioPlaylist : public ARDOUR::Playlist AudioPlaylist (const AudioPlaylist&, string name, bool hidden = false); AudioPlaylist (const AudioPlaylist&, nframes_t start, nframes_t cnt, string name, bool hidden = false); - void clear (bool with_save = true); + void clear (bool with_signals=true); nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, nframes_t start, nframes_t cnt, uint32_t chan_n=0); int set_state (const XMLNode&); - UndoAction get_memento() const; sigc::signal<void,Crossfade *> NewCrossfade; template<class T> void foreach_crossfade (T *t, void (T::*func)(Crossfade *)); void crossfades_at (nframes_t frame, Crossfades&); - template<class T> void apply_to_history (T& obj, void (T::*method)(const ARDOUR::StateManager::StateMap&, state_id_t)) { - RegionLock rlock (this); - (obj.*method) (states, _current_state_id); - } - bool destroy_region (boost::shared_ptr<Region>); - void drop_all_states (); - protected: - /* state management */ - - StateManager::State* state_factory (std::string) const; - Change restore_state (StateManager::State&); - void send_state_change (Change); - /* playlist "callbacks" */ void notify_crossfade_added (Crossfade *); void flush_notifications (); @@ -101,7 +74,7 @@ class AudioPlaylist : public ARDOUR::Playlist ~AudioPlaylist (); /* public should use unref() */ private: - Crossfades _crossfades; + Crossfades _crossfades; /* xfades currently in use */ Crossfades _pending_xfade_adds; void crossfade_invalidated (Crossfade*); diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h index 3ac62da2ca..e14cfd0180 100644 --- a/libs/ardour/ardour/audioregion.h +++ b/libs/ardour/ardour/audioregion.h @@ -42,18 +42,6 @@ class Session; class AudioFilter; class AudioSource; -struct AudioRegionState : public RegionState -{ - AudioRegionState (std::string why); - - Curve _fade_in; - Curve _fade_out; - Curve _envelope; - gain_t _scale_amplitude; - uint32_t _fade_in_disabled; - uint32_t _fade_out_disabled; -}; - class AudioRegion : public Region { public: @@ -125,8 +113,6 @@ class AudioRegion : public Region int separate_by_channel (ARDOUR::Session&, vector<AudioRegion*>&) const; - UndoAction get_memento() const; - /* filter */ int apply (AudioFilter&); @@ -159,9 +145,6 @@ class AudioRegion : public Region void set_default_fade_out (); void set_default_envelope (); - StateManager::State* state_factory (std::string why) const; - Change restore_state (StateManager::State&); - void recompute_gain_at_end (); void recompute_gain_at_start (); @@ -185,6 +168,9 @@ class AudioRegion : public Region gain_t _scale_amplitude; uint32_t _fade_in_disabled; uint32_t _fade_out_disabled; + + protected: + int set_live_state (const XMLNode&, Change&, bool send); }; } /* namespace ARDOUR */ diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h index 7301b31d8a..fe65e9d433 100644 --- a/libs/ardour/ardour/configuration_vars.h +++ b/libs/ardour/ardour/configuration_vars.h @@ -45,11 +45,11 @@ CONFIG_VARIABLE (bool, use_overlap_equivalency, "use-overlap-equivalency", true) /* crossfades */ -CONFIG_VARIABLE (CrossfadeModel, xfade_model, "xfade-model", ShortCrossfade) +CONFIG_VARIABLE (CrossfadeModel, xfade_model, "xfade-model", FullCrossfade) CONFIG_VARIABLE (bool, auto_xfade, "auto-xfade", true) CONFIG_VARIABLE (float, short_xfade_seconds, "short-xfade-seconds", 0.015) -CONFIG_VARIABLE (bool, crossfades_active, "crossfades-active", false) -CONFIG_VARIABLE (bool, crossfades_visible, "crossfades-visible", false) +CONFIG_VARIABLE (bool, xfades_active, "xfades-active", true) +CONFIG_VARIABLE (bool, xfades_visible, "xfades-visible", true) CONFIG_VARIABLE (uint32_t, destructive_xfade_msecs, "destructive-xfade-msecs", 2) /* editing related */ @@ -121,6 +121,11 @@ CONFIG_VARIABLE (bool, verify_remove_last_capture, "verify-remove-last-capture", CONFIG_VARIABLE (bool, no_new_session_dialog, "no-new-session-dialog", false) CONFIG_VARIABLE (bool, use_vst, "use-vst", true) +/* BWAV */ + +CONFIG_VARIABLE (string, bwf_country_code, "bwf-country-code", "US") +CONFIG_VARIABLE (string, bwf_organization_code, "bwf-organization-code", "US") + /* these variables have custom set() methods (e.g. path globbing) */ CONFIG_VARIABLE_SPECIAL(std::string, raid_path, "raid-path", "", path_expand) diff --git a/libs/ardour/ardour/crossfade.h b/libs/ardour/ardour/crossfade.h index 7fd7323b36..d29ba47056 100644 --- a/libs/ardour/ardour/crossfade.h +++ b/libs/ardour/ardour/crossfade.h @@ -33,7 +33,6 @@ #include <ardour/ardour.h> #include <ardour/curve.h> #include <ardour/audioregion.h> -#include <ardour/state_manager.h> #include <ardour/crossfade_compare.h> namespace ARDOUR { @@ -41,19 +40,7 @@ namespace ARDOUR { class AudioRegion; class Playlist; -struct CrossfadeState : public StateManager::State { - CrossfadeState (std::string reason) : StateManager::State (reason) {} - - UndoAction fade_in_memento; - UndoAction fade_out_memento; - nframes_t position; - nframes_t length; - AnchorPoint anchor_point; - bool follow_overlap; - bool active; -}; - -class Crossfade : public PBD::StatefulDestructible, public StateManager +class Crossfade : public PBD::StatefulDestructible { public: @@ -121,7 +108,10 @@ class Crossfade : public PBD::StatefulDestructible, public StateManager nframes_t overlap_length() const; nframes_t position() const { return _position; } + void invalidate(); + sigc::signal<void,Crossfade*> Invalidated; + sigc::signal<void,Change> StateChanged; bool covers (nframes_t frame) const { return _position <= frame && frame < _position + _length; @@ -129,8 +119,6 @@ class Crossfade : public PBD::StatefulDestructible, public StateManager OverlapType coverage (nframes_t start, nframes_t end) const; - UndoAction get_memento() const; - static void set_buffer_size (nframes_t); bool active () const { return _active; } @@ -149,6 +137,7 @@ class Crossfade : public PBD::StatefulDestructible, public StateManager static void set_short_xfade_length (nframes_t n); static Change ActiveChanged; + static Change FollowOverlapChanged; private: friend struct CrossfadeComparePtr; @@ -172,15 +161,11 @@ class Crossfade : public PBD::StatefulDestructible, public StateManager static Sample* crossfade_buffer_out; static Sample* crossfade_buffer_in; - void initialize (bool savestate=true); + void initialize (); int compute (boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>, CrossfadeModel); bool update (bool force); - StateManager::State* state_factory (std::string why) const; - Change restore_state (StateManager::State&); - void member_changed (ARDOUR::Change); - }; diff --git a/libs/ardour/ardour/midi_playlist.h b/libs/ardour/ardour/midi_playlist.h index 36793b70ea..6f89d23404 100644 --- a/libs/ardour/ardour/midi_playlist.h +++ b/libs/ardour/ardour/midi_playlist.h @@ -37,18 +37,6 @@ class MidiRingBuffer; class MidiPlaylist : public ARDOUR::Playlist { -private: - - struct State : public ARDOUR::StateManager::State - { - RegionList regions; - std::list<UndoAction> region_states; - - State (std::string why) : ARDOUR::StateManager::State (why) - {} - ~State (); - }; - public: MidiPlaylist (Session&, const XMLNode&, bool hidden = false); MidiPlaylist (Session&, string name, bool hidden = false); @@ -56,31 +44,16 @@ public: MidiPlaylist (const MidiPlaylist&, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden = false); - jack_nframes_t read (MidiRingBuffer& buf, - jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0); + nframes_t read (MidiRingBuffer& buf, + jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0); int set_state (const XMLNode&); UndoAction get_memento() const; - template<class T> - void apply_to_history (T& obj, void (T::*method)(const ARDOUR::StateManager::StateMap&, state_id_t)) - { - RegionLock rlock (this); - (obj.*method) (states, _current_state_id); - } - bool destroy_region (boost::shared_ptr<Region>); - void drop_all_states (); - protected: - /* state management */ - - StateManager::State* state_factory (std::string) const; - Change restore_state (StateManager::State&); - void send_state_change (Change); - /* playlist "callbacks" */ void flush_notifications (); diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index d7b13ef684..93b30f42ef 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -40,7 +40,6 @@ #include <ardour/ardour.h> #include <ardour/crossfade_compare.h> #include <ardour/location.h> -#include <ardour/state_manager.h> #include <ardour/data_type.h> namespace ARDOUR { @@ -48,7 +47,7 @@ namespace ARDOUR { class Session; class Region; -class Playlist : public StateManager, public PBD::StatefulDestructible { +class Playlist : public PBD::StatefulDestructible { public: typedef list<boost::shared_ptr<Region> > RegionList; @@ -57,9 +56,8 @@ class Playlist : public StateManager, public PBD::StatefulDestructible { Playlist (const Playlist&, string name, bool hidden = false); Playlist (const Playlist&, nframes_t start, nframes_t cnt, string name, bool hidden = false); - virtual void clear (bool with_save = true); + virtual void clear (bool with_signals=true); virtual void dump () const; - virtual UndoAction get_memento() const = 0; void ref(); void unref(); @@ -83,7 +81,7 @@ class Playlist : public StateManager, public PBD::StatefulDestructible { /* Editing operations */ - void add_region (boost::shared_ptr<Region>, nframes_t position, float times = 1, bool with_save = true); + void add_region (boost::shared_ptr<Region>, nframes_t position, float times = 1); void remove_region (boost::shared_ptr<Region>); void get_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&); void get_region_list_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&); @@ -114,8 +112,6 @@ class Playlist : public StateManager, public PBD::StatefulDestructible { int set_state (const XMLNode&); XMLNode& get_template (); - sigc::signal<void,boost::shared_ptr<Region> > RegionAdded; - sigc::signal<void,boost::shared_ptr<Region> > RegionRemoved; sigc::signal<void,Playlist*,bool> InUse; sigc::signal<void> Modified; sigc::signal<void> NameChanged; @@ -172,20 +168,21 @@ class Playlist : public StateManager, public PBD::StatefulDestructible { friend class RegionLock; RegionList regions; /* the current list of regions in the playlist */ + std::set<boost::shared_ptr<Region> > all_regions; /* all regions ever added to this playlist */ string _name; Session& _session; DataType _type; mutable gint block_notifications; mutable gint ignore_state_changes; mutable Glib::Mutex region_lock; - RegionList pending_removals; - RegionList pending_adds; + std::set<boost::shared_ptr<Region> > pending_adds; + std::set<boost::shared_ptr<Region> > pending_removes; RegionList pending_bounds; bool pending_modified; bool pending_length; bool save_on_thaw; string last_save_reason; - bool in_set_state; + uint32_t in_set_state; bool _hidden; bool _splicing; bool _nudging; @@ -248,10 +245,7 @@ class Playlist : public StateManager, public PBD::StatefulDestructible { virtual XMLNode& state (bool); - /* override state_manager::save_state so we can check in_set_state() */ - - void save_state (std::string why); - void maybe_save_state (std::string why); + boost::shared_ptr<Region> region_by_id (PBD::ID); void add_region_internal (boost::shared_ptr<Region>, nframes_t position, bool delay_sort = false); diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index 96663f79c8..627e556cad 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -29,7 +29,6 @@ #include <pbd/statefuldestructible.h> #include <ardour/ardour.h> -#include <ardour/state_manager.h> #include <ardour/data_type.h> class XMLNode; @@ -44,21 +43,7 @@ enum RegionEditState { EditChangesID = 2 }; -struct RegionState : public StateManager::State -{ - RegionState (std::string why) : StateManager::State (why) {} - - nframes_t _start; - nframes_t _length; - nframes_t _position; - uint32_t _flags; - nframes_t _sync_position; - layer_t _layer; - string _name; - mutable RegionEditState _first_edit; -}; - -class Region : public PBD::StatefulDestructible, public StateManager, public boost::enable_shared_from_this<Region> +class Region : public PBD::StatefulDestructible, public boost::enable_shared_from_this<Region> { public: typedef std::vector<boost::shared_ptr<Source> > SourceList; @@ -96,6 +81,8 @@ class Region : public PBD::StatefulDestructible, public StateManager, public boo static Change LayerChanged; static Change HiddenChanged; + sigc::signal<void,Change> StateChanged; + virtual ~Region(); /* Note: changing the name of a Region does not constitute an edit */ @@ -181,8 +168,6 @@ class Region : public PBD::StatefulDestructible, public StateManager, public boo ARDOUR::Playlist* playlist() const { return _playlist; } - virtual UndoAction get_memento() const = 0; - void set_playlist (ARDOUR::Playlist*); void source_deleted (boost::shared_ptr<Source>); @@ -198,6 +183,7 @@ class Region : public PBD::StatefulDestructible, public StateManager, public boo XMLNode& get_state (); virtual XMLNode& state (bool); virtual int set_state (const XMLNode&); + virtual int set_live_state (const XMLNode&, Change&, bool send); boost::shared_ptr<Region> get_parent(); @@ -220,15 +206,8 @@ class Region : public PBD::StatefulDestructible, public StateManager, public boo protected: XMLNode& get_short_state (); /* used only by Session */ - /* state management */ - void send_change (Change); - /* derived classes need these during their own state management calls */ - - void store_state (RegionState&) const; - Change restore_and_return_flags (RegionState&); - void trim_to_internal (nframes_t position, nframes_t length, void *src); bool copied() const { return _flags & Copied; } diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc index 7c4052d8ac..94b80df178 100644 --- a/libs/ardour/audio_playlist.cc +++ b/libs/ardour/audio_playlist.cc @@ -39,21 +39,15 @@ using namespace sigc; using namespace std; using namespace PBD; -AudioPlaylist::State::~State () -{ -} - AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden) : Playlist (session, node, DataType::AUDIO, hidden) { const XMLProperty* prop = node.property("type"); assert(!prop || DataType(prop->value()) == DataType::AUDIO); - in_set_state = true; + in_set_state++; set_state (node); - in_set_state = false; - - save_state (_("initial state")); + in_set_state--; if (!hidden) { PlaylistCreated (this); /* EMIT SIGNAL */ @@ -63,8 +57,6 @@ AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden) : Playlist (session, name, DataType::AUDIO, hidden) { - save_state (_("initial state")); - if (!hidden) { PlaylistCreated (this); /* EMIT SIGNAL */ } @@ -74,8 +66,6 @@ AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden) AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, string name, bool hidden) : Playlist (other, name, hidden) { - save_state (_("initial state")); - RegionList::const_iterator in_o = other.regions.begin(); RegionList::iterator in_n = regions.begin(); @@ -121,8 +111,6 @@ AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, string name, bool hidd AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, nframes_t start, nframes_t cnt, string name, bool hidden) : Playlist (other, start, cnt, name, hidden) { - save_state (_("initial state")); - /* this constructor does NOT notify others (session) */ } @@ -135,27 +123,24 @@ AudioPlaylist::~AudioPlaylist () /* drop connections to signals */ notify_callbacks (); + - for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end(); ++x) { - all_xfades.insert (*x); - } - - for (StateMap::iterator i = states.begin(); i != states.end(); ++i) { + cerr << "deleting crossfades " << _crossfades.size() << endl; - AudioPlaylist::State* apstate = dynamic_cast<AudioPlaylist::State*> (*i); + for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end(); ) { + Crossfades::iterator tmp; - for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) { - all_xfades.insert (*xf); - } + tmp = x; + ++tmp; - delete apstate; - } + delete *x; - /* delete every crossfade */ + cerr << _crossfades.size() << " to go\n"; - for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) { - delete *axf; + x = tmp; } + + cerr << "done\n"; } struct RegionSortByLayer { @@ -258,6 +243,10 @@ AudioPlaylist::remove_dependents (boost::shared_ptr<Region> region) { Crossfades::iterator i, tmp; boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region); + + if (in_set_state) { + return; + } if (r == 0) { fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist") @@ -269,9 +258,9 @@ AudioPlaylist::remove_dependents (boost::shared_ptr<Region> region) tmp = i; tmp++; + if ((*i)->involves (r)) { - /* do not delete crossfades */ - _crossfades.erase (i); + delete *i; } i = tmp; @@ -386,6 +375,8 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh) return; } + cerr << "Check dependents of " << r->name() << endl; + if ((region = boost::dynamic_pointer_cast<AudioRegion> (r)) == 0) { fatal << _("programming error: non-audio Region tested for overlap in audio playlist") << endmsg; @@ -450,8 +441,8 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh) add_crossfade (*xfade); } else { - - xfade = new Crossfade (other, region, Config->get_xfade_model(), Config->get_crossfades_active()); + + xfade = new Crossfade (other, region, Config->get_xfade_model(), Config->get_xfades_active()); add_crossfade (*xfade); } } @@ -473,7 +464,10 @@ AudioPlaylist::add_crossfade (Crossfade& xfade) { Crossfades::iterator ci; + cerr << "adding xfade involving " << xfade.in()->name() << " and " << xfade.out()->name() << endl; + for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) { + cerr << "\tcompare to " << (*ci)->in()->name() << " and " << (*ci)->out()->name() << endl; if (*(*ci) == xfade) { // Crossfade::operator==() break; } @@ -520,9 +514,10 @@ AudioPlaylist::set_state (const XMLNode& node) XMLNodeList nlist; XMLNodeConstIterator niter; - if (!in_set_state) { - Playlist::set_state (node); - } + in_set_state++; + freeze (); + + Playlist::set_state (node); nlist = node.children(); @@ -530,155 +525,49 @@ AudioPlaylist::set_state (const XMLNode& node) child = *niter; - if (child->name() == "Crossfade") { - - Crossfade *xfade; - - try { - xfade = new Crossfade (*((const Playlist *)this), *child); - } - - catch (failed_constructor& err) { - // cout << string_compose (_("could not create crossfade object in playlist %1"), - // _name) - // << endl; - continue; - } - - Crossfades::iterator ci; - - for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) { - if (*(*ci) == *xfade) { - break; - } - } - - if (ci == _crossfades.end()) { - _crossfades.push_back (xfade); - xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated)); - xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed)); - NewCrossfade(xfade); - } else { - delete xfade; - } - } - - } - - return 0; -} - -void -AudioPlaylist::drop_all_states () -{ - set<Crossfade*> all_xfades; - set<boost::shared_ptr<Region> > all_regions; - - /* find every region we've ever used, and add it to the set of - all regions. same for xfades; - */ - - for (StateMap::iterator i = states.begin(); i != states.end(); ++i) { - - AudioPlaylist::State* apstate = dynamic_cast<AudioPlaylist::State*> (*i); - - for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) { - all_regions.insert (*r); - } - - for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) { - all_xfades.insert (*xf); + if (child->name() != "Crossfade") { + continue; } - } - /* now remove from the "all" lists every region that is in the current list. */ - - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - set<boost::shared_ptr<Region> >::iterator x = all_regions.find (*i); - if (x != all_regions.end()) { - all_regions.erase (x); + try { + Crossfade* xfade = new Crossfade (*((const Playlist *)this), *child); + _crossfades.push_back (xfade); + xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated)); + xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed)); + NewCrossfade(xfade); } - } - - /* ditto for every crossfade */ - - for (list<Crossfade*>::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) { - set<Crossfade*>::iterator x = all_xfades.find (*i); - if (x != all_xfades.end()) { - all_xfades.erase (x); + + catch (failed_constructor& err) { + // cout << string_compose (_("could not create crossfade object in playlist %1"), + // _name) + // << endl; + continue; } } - /* delete every crossfade that is left (ditto as per regions) */ - - for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) { - delete *axf; - } + thaw (); + in_set_state++; - /* Now do the generic thing ... */ - - StateManager::drop_all_states (); + return 0; } -StateManager::State* -AudioPlaylist::state_factory (std::string why) const +void +AudioPlaylist::clear (bool with_signals) { - State* state = new State (why); - - state->regions = regions; - state->region_states.clear (); - for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) { - state->region_states.push_back ((*i)->get_memento()); - } - - state->crossfades = _crossfades; - state->crossfade_states.clear (); - for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) { - state->crossfade_states.push_back ((*i)->get_memento()); - } - return state; -} - -Change -AudioPlaylist::restore_state (StateManager::State& state) -{ - { - RegionLock rlock (this); - State* apstate = dynamic_cast<State*> (&state); - - in_set_state = true; - - regions = apstate->regions; + for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ) { - for (list<UndoAction>::iterator s = apstate->region_states.begin(); s != apstate->region_states.end(); ++s) { - (*s) (); - } + Crossfades::iterator tmp; + tmp = i; + ++tmp; - _crossfades = apstate->crossfades; - - for (list<UndoAction>::iterator s = apstate->crossfade_states.begin(); s != apstate->crossfade_states.end(); ++s) { - (*s) (); - } + delete *i; - in_set_state = false; + i = tmp; } - notify_length_changed (); - return Change (~0); -} - -UndoAction -AudioPlaylist::get_memento () const -{ - return sigc::bind (mem_fun (*(const_cast<AudioPlaylist*> (this)), &StateManager::use_state), _current_state_id); -} - -void -AudioPlaylist::clear (bool with_save) -{ _crossfades.clear (); - Playlist::clear (with_save); + Playlist::clear (with_signals); } XMLNode& @@ -779,52 +668,6 @@ AudioPlaylist::destroy_region (boost::shared_ptr<Region> region) c = ctmp; } - for (StateMap::iterator s = states.begin(); s != states.end(); ) { - StateMap::iterator tmp; - - tmp = s; - ++tmp; - - State* astate = dynamic_cast<State*> (*s); - - for (c = astate->crossfades.begin(); c != astate->crossfades.end(); ) { - - ctmp = c; - ++ctmp; - - if ((*c)->involves (r)) { - unique_xfades.insert (*c); - _crossfades.erase (c); - } - - c = ctmp; - } - - list<UndoAction>::iterator rsi, rsitmp; - RegionList::iterator ri, ritmp; - - for (ri = astate->regions.begin(), rsi = astate->region_states.begin(); - ri != astate->regions.end() && rsi != astate->region_states.end();) { - - - ritmp = ri; - ++ritmp; - - rsitmp = rsi; - ++rsitmp; - - if (region == (*ri)) { - astate->regions.erase (ri); - astate->region_states.erase (rsi); - } - - ri = ritmp; - rsi = rsitmp; - } - - s = tmp; - } - for (set<Crossfade*>::iterator c = unique_xfades.begin(); c != unique_xfades.end(); ++c) { delete *c; } @@ -850,8 +693,6 @@ AudioPlaylist::crossfade_changed (Change ignored) that occured. */ - maybe_save_state (_("xfade change")); - notify_modified (); } @@ -873,8 +714,6 @@ AudioPlaylist::region_changed (Change what_changed, boost::shared_ptr<Region> re parent_wants_notify = Playlist::region_changed (what_changed, region); - maybe_save_state (_("region modified")); - if ((parent_wants_notify || (what_changed & our_interests))) { notify_modified (); } diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc index 0ba2904f57..3078521466 100644 --- a/libs/ardour/audiofilesource.cc +++ b/libs/ardour/audiofilesource.cc @@ -59,10 +59,6 @@ string AudioFileSource::search_path; sigc::signal<void> AudioFileSource::HeaderPositionOffsetChanged; uint64_t AudioFileSource::header_position_offset = 0; -/* XXX turn this into a Config option */ -char AudioFileSource::bwf_country_code[3] = "US"; -/* XXX turn this into a Config option */ -char AudioFileSource::bwf_organization_code[4] = "LAS"; /* XXX maybe this too */ char AudioFileSource::bwf_serial_number[13] = "000000000000"; diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index d7724f3a39..31776d7be5 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -58,14 +58,6 @@ Change AudioRegion::EnvelopeActiveChanged = ARDOUR::new_change(); Change AudioRegion::ScaleAmplitudeChanged = ARDOUR::new_change(); Change AudioRegion::EnvelopeChanged = ARDOUR::new_change(); -AudioRegionState::AudioRegionState (string why) - : RegionState (why) - , _fade_in (0.0, 2.0, 1.0, false) - , _fade_out (0.0, 2.0, 1.0, false) - , _envelope (0.0, 2.0, 1.0, false) -{ -} - /** Basic AudioRegion constructor (one channel) */ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length) : Region (src, start, length, PBD::basename_nosuffix(src->name()), DataType::AUDIO, 0, Region::Flag(Region::DefaultFlags|Region::External)), @@ -83,8 +75,6 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, n set_default_fades (); set_default_envelope (); - save_state ("initial state"); - _envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed)); } @@ -104,7 +94,6 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, n set_default_fades (); set_default_envelope (); - save_state ("initial state"); _envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed)); } @@ -120,7 +109,6 @@ AudioRegion::AudioRegion (SourceList& srcs, nframes_t start, nframes_t length, c set_default_fades (); set_default_envelope (); - save_state ("initial state"); _envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed)); } @@ -160,8 +148,6 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t _scale_amplitude = other->_scale_amplitude; - save_state ("initial state"); - _envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed)); assert(_type == DataType::AUDIO); @@ -179,8 +165,6 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other) _fade_in_disabled = 0; _fade_out_disabled = 0; - save_state ("initial state"); - _envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed)); assert(_type == DataType::AUDIO); @@ -203,8 +187,6 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& nod throw failed_constructor(); } - save_state ("initial state"); - _envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed)); assert(_type == DataType::AUDIO); @@ -223,8 +205,6 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node) throw failed_constructor(); } - save_state ("initial state"); - _envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed)); assert(_type == DataType::AUDIO); @@ -232,92 +212,11 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node) AudioRegion::~AudioRegion () { + cerr << "====== " << _name << " DESTRUCTOR @ " << this << endl; notify_callbacks (); GoingAway (); /* EMIT SIGNAL */ } -StateManager::State* -AudioRegion::state_factory (std::string why) const -{ - AudioRegionState* state = new AudioRegionState (why); - - Region::store_state (*state); - - state->_fade_in = _fade_in; - state->_fade_out = _fade_out; - state->_envelope = _envelope; - state->_scale_amplitude = _scale_amplitude; - state->_fade_in_disabled = _fade_in_disabled; - state->_fade_out_disabled = _fade_out_disabled; - - return state; -} - -Change -AudioRegion::restore_state (StateManager::State& sstate) -{ - AudioRegionState* state = dynamic_cast<AudioRegionState*> (&sstate); - - Change what_changed = Region::restore_and_return_flags (*state); - - if (_flags != Flag (state->_flags)) { - - uint32_t old_flags = _flags; - - _flags = Flag (state->_flags); - - if ((old_flags ^ state->_flags) & EnvelopeActive) { - what_changed = Change (what_changed|EnvelopeActiveChanged); - } - } - - if (!(_fade_in == state->_fade_in)) { - _fade_in = state->_fade_in; - what_changed = Change (what_changed|FadeInChanged); - } - - if (!(_fade_out == state->_fade_out)) { - _fade_out = state->_fade_out; - what_changed = Change (what_changed|FadeOutChanged); - } - - if (_scale_amplitude != state->_scale_amplitude) { - _scale_amplitude = state->_scale_amplitude; - what_changed = Change (what_changed|ScaleAmplitudeChanged); - } - - if (_fade_in_disabled != state->_fade_in_disabled) { - if (_fade_in_disabled == 0 && state->_fade_in_disabled) { - set_fade_in_active (false); - } else if (_fade_in_disabled && state->_fade_in_disabled == 0) { - set_fade_in_active (true); - } - _fade_in_disabled = state->_fade_in_disabled; - } - - if (_fade_out_disabled != state->_fade_out_disabled) { - if (_fade_out_disabled == 0 && state->_fade_out_disabled) { - set_fade_out_active (false); - } else if (_fade_out_disabled && state->_fade_out_disabled == 0) { - set_fade_out_active (true); - } - _fade_out_disabled = state->_fade_out_disabled; - } - - /* XXX need a way to test stored state versus current for envelopes */ - - _envelope = state->_envelope; - what_changed = Change (what_changed); - - return what_changed; -} - -UndoAction -AudioRegion::get_memento() const -{ - return sigc::bind (mem_fun (*(const_cast<AudioRegion *> (this)), &StateManager::use_state), _current_state_id); -} - void AudioRegion::set_envelope_active (bool yn) { @@ -330,11 +229,7 @@ AudioRegion::set_envelope_active (bool yn) snprintf (buf, sizeof (buf), "envelope off"); _flags = Flag (_flags & ~EnvelopeActive); } - if (!_frozen) { - save_state (buf); - } send_change (EnvelopeActiveChanged); - } } @@ -555,6 +450,8 @@ AudioRegion::state (bool full) } else { _fade_in.store_state (*child); } + + child->add_property (X_("active"), _fade_in_disabled ? X_("no") : X_("yes")); child = node.add_child (X_("FadeOut")); @@ -563,6 +460,8 @@ AudioRegion::state (bool full) } else { _fade_out.store_state (*child); } + + child->add_property (X_("active"), _fade_out_disabled ? X_("no") : X_("yes")); } child = node.add_child ("Envelope"); @@ -585,6 +484,7 @@ AudioRegion::state (bool full) } else { _envelope.store_state (*child); } + } else { child->add_property ("default", "yes"); } @@ -597,14 +497,16 @@ AudioRegion::state (bool full) } int -AudioRegion::set_state (const XMLNode& node) +AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool send) { const XMLNodeList& nlist = node.children(); const XMLProperty *prop; LocaleGuard lg (X_("POSIX")); - Region::set_state (node); + Region::set_live_state (node, what_changed, false); + uint32_t old_flags = _flags; + if ((prop = node.property ("flags")) != 0) { _flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16)); @@ -612,6 +514,16 @@ AudioRegion::set_state (const XMLNode& node) _flags = Flag (_flags & ~Region::RightOfSplit); } + if ((old_flags ^ _flags) & Muted) { + what_changed = Change (what_changed|MuteChanged); + } + if ((old_flags ^ _flags) & Opaque) { + what_changed = Change (what_changed|OpacityChanged); + } + if ((old_flags ^ _flags) & Locked) { + what_changed = Change (what_changed|LockChanged); + } + if ((prop = node.property ("scale-gain")) != 0) { _scale_amplitude = atof (prop->value().c_str()); } else { @@ -647,7 +559,6 @@ AudioRegion::set_state (const XMLNode& node) if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) { set_default_fade_in (); } else { - _fade_in.load_state (*child); } @@ -663,9 +574,24 @@ AudioRegion::set_state (const XMLNode& node) } } + if (send) { + send_change (what_changed); + } + return 0; } +int +AudioRegion::set_state (const XMLNode& node) +{ + /* Region::set_state() calls the virtual set_live_state(), + which will get us back to AudioRegion::set_live_state() + to handle the relevant stuff. + */ + + return Region::set_state (node); +} + void AudioRegion::set_fade_in_shape (FadeShape shape) { @@ -735,10 +661,6 @@ AudioRegion::set_fade_in (FadeShape shape, nframes_t len) _fade_in.thaw (); _fade_in_shape = shape; - if (!_frozen) { - save_state (_("fade in change")); - } - send_change (FadeInChanged); } @@ -797,10 +719,6 @@ AudioRegion::set_fade_out (FadeShape shape, nframes_t len) _fade_out.thaw (); _fade_out_shape = shape; - if (!_frozen) { - save_state (_("fade in change")); - } - send_change (FadeOutChanged); } @@ -811,13 +729,6 @@ AudioRegion::set_fade_in_length (nframes_t len) if (changed) { _flags = Flag (_flags & ~DefaultFadeIn); - - if (!_frozen) { - char buf[64]; - snprintf (buf, sizeof (buf), "fade in length changed to %u", len); - save_state (buf); - } - send_change (FadeInChanged); } } @@ -829,12 +740,6 @@ AudioRegion::set_fade_out_length (nframes_t len) if (changed) { _flags = Flag (_flags & ~DefaultFadeOut); - - if (!_frozen) { - char buf[64]; - snprintf (buf, sizeof (buf), "fade out length changed to %u", len); - save_state (buf); - } } send_change (FadeOutChanged); @@ -970,7 +875,8 @@ AudioRegion::separate_by_channel (Session& session, vector<AudioRegion*>& v) con int AudioRegion::apply (AudioFilter& filter) { - return filter.run (boost::shared_ptr<AudioRegion> (this)); + boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (shared_from_this()); + return filter.run (ar); } int @@ -1110,12 +1016,6 @@ AudioRegion::normalize_to (float target_dB) _scale_amplitude = target/maxamp; - if (!_frozen) { - char buf[64]; - snprintf (buf, sizeof (buf), _("normalized to %.2fdB"), target_dB); - save_state (buf); - } - /* tell the diskstream we're in */ if (_playlist) { @@ -1130,7 +1030,6 @@ AudioRegion::normalize_to (float target_dB) void AudioRegion::envelope_changed (Change ignored) { - save_state (_("envelope change")); send_change (EnvelopeChanged); } diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc index 3887e5ecc7..34cf5637b6 100644 --- a/libs/ardour/auditioner.cc +++ b/libs/ardour/auditioner.cc @@ -80,7 +80,7 @@ Auditioner::prepare_playlist () AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(_diskstream->playlist()); assert(apl); - apl->clear (false); + apl->clear (); return *apl; } @@ -128,8 +128,8 @@ Auditioner::audition_region (boost::shared_ptr<Region> region) boost::shared_ptr<AudioRegion> the_region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region))); the_region->set_position (0, this); - _diskstream->playlist()->clear (false); - _diskstream->playlist()->add_region (the_region, 0, 1, false); + _diskstream->playlist()->clear (); + _diskstream->playlist()->add_region (the_region, 0, 1); while (_diskstream->n_channels().get(DataType::AUDIO) < the_region->n_channels()) { audio_diskstream()->add_channel (); diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc index 32a9e2b533..739ea1cc0e 100644 --- a/libs/ardour/crossfade.cc +++ b/libs/ardour/crossfade.cc @@ -37,6 +37,7 @@ using namespace PBD; nframes_t Crossfade::_short_xfade_length = 0; Change Crossfade::ActiveChanged = new_change(); +Change Crossfade::FollowOverlapChanged = new_change(); /* XXX if and when we ever implement parallel processing of the process() callback, these will need to be handled on a per-thread basis. @@ -82,8 +83,16 @@ Crossfade::Crossfade (boost::shared_ptr<AudioRegion> in, boost::shared_ptr<Audio _length = length; _position = position; _anchor_point = ap; - _follow_overlap = false; - _active = true; + + switch (Config->get_xfade_model()) { + case ShortCrossfade: + _follow_overlap = false; + break; + default: + _follow_overlap = true; + } + + _active = Config->get_xfades_active (); _fixed = true; initialize (); @@ -151,28 +160,24 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node) } _length = 0; - initialize(false); + initialize(); if (set_state (node)) { throw failed_constructor(); } - - save_state ("initial"); } Crossfade::Crossfade (const Crossfade &orig, boost::shared_ptr<AudioRegion> newin, boost::shared_ptr<AudioRegion> newout) : _fade_in(orig._fade_in), _fade_out(orig._fade_out) { - _active = orig._active; - _in_update = orig._in_update; - _length = orig._length; - _position = orig._position; - _anchor_point = orig._anchor_point; - _follow_overlap = orig._follow_overlap; - _fixed = orig._fixed; - _follow_overlap = orig._follow_overlap; - _short_xfade_length = orig._short_xfade_length; + _active = orig._active; + _in_update = orig._in_update; + _length = orig._length; + _position = orig._position; + _anchor_point = orig._anchor_point; + _follow_overlap = orig._follow_overlap; + _fixed = orig._fixed; _in = newin; _out = newout; @@ -192,13 +197,13 @@ Crossfade::Crossfade (const Crossfade &orig, boost::shared_ptr<AudioRegion> newi Crossfade::~Crossfade () { - for (StateMap::iterator i = states.begin(); i != states.end(); ++i) { - delete *i; - } + cerr << "Deleting xfade @ " << this << endl; + Invalidated (this); + cerr << "invalidation signal sent\n"; } void -Crossfade::initialize (bool savestate) +Crossfade::initialize () { _in_update = false; @@ -225,14 +230,10 @@ Crossfade::initialize (bool savestate) _fade_in.add (_length, 1.0); _fade_in.thaw (); -// _in->StateChanged.connect (slot (*this, &Crossfade::member_changed)); -// _out->StateChanged.connect (slot (*this, &Crossfade::member_changed)); + _in->StateChanged.connect (sigc::mem_fun (*this, &Crossfade::member_changed)); + _out->StateChanged.connect (sigc::mem_fun (*this, &Crossfade::member_changed)); overlap_type = _in->coverage (_out->position(), _out->last_frame()); - - if (savestate) { - save_state ("initial"); - } } int @@ -488,8 +489,7 @@ Crossfade::set_active (bool yn) { if (_active != yn) { _active = yn; - save_state (_("active changed")); - send_state_changed (ActiveChanged); + StateChanged (ActiveChanged); } } @@ -535,7 +535,6 @@ bool Crossfade::update (bool force) { nframes_t newlen; - bool save = false; if (_follow_overlap) { newlen = _out->first_frame() + _out->length() - _in->first_frame(); @@ -559,41 +558,32 @@ Crossfade::update (bool force) _length = newlen; - save = true; - } switch (_anchor_point) { case StartOfIn: if (_position != _in->first_frame()) { _position = _in->first_frame(); - save = true; } break; case EndOfIn: if (_position != _in->last_frame() - _length) { _position = _in->last_frame() - _length; - save = true; } break; case EndOfOut: if (_position != _out->last_frame() - _length) { _position = _out->last_frame() - _length; - save = true; } } - if (save) { - save_state ("updated"); - } - /* UI's may need to know that the overlap changed even though the xfade length did not. */ - send_state_changed (BoundsChanged); /* EMIT SIGNAL */ + StateChanged (BoundsChanged); /* EMIT SIGNAL */ _in_update = false; @@ -612,65 +602,6 @@ Crossfade::member_changed (Change what_changed) } } -Change -Crossfade::restore_state (StateManager::State& state) -{ - CrossfadeState* xfstate = dynamic_cast<CrossfadeState*> (&state); - Change what_changed = Change (0); - - _in_update = true; - - xfstate->fade_in_memento (); - xfstate->fade_out_memento (); - - if (_length != xfstate->length) { - what_changed = Change (what_changed|LengthChanged); - _length = xfstate->length; - } - if (_active != xfstate->active) { - what_changed = Change (what_changed|ActiveChanged); - _active = xfstate->active; - } - if (_position != xfstate->position) { - what_changed = Change (what_changed|PositionChanged); - _position = xfstate->position; - } - - /* XXX what to do about notifications for these? I don't - think (G)UI cares about them because they are - implicit in the bounds. - */ - - _follow_overlap = xfstate->follow_overlap; - _anchor_point = xfstate->anchor_point; - - _in_update = false; - - return Change (what_changed); -} - -StateManager::State* -Crossfade::state_factory (std::string why) const -{ - CrossfadeState* state = new CrossfadeState (why); - - state->fade_in_memento = _fade_in.get_memento (); - state->fade_out_memento = _fade_out.get_memento (); - state->active = _active; - state->length = _length; - state->position = _position; - state->follow_overlap = _follow_overlap; - state->anchor_point = _anchor_point; - - return state; -} - -UndoAction -Crossfade::get_memento() const -{ - return sigc::bind (mem_fun (*(const_cast<Crossfade *> (this)), &StateManager::use_state), _current_state_id); -} - XMLNode& Crossfade::get_state () { @@ -733,16 +664,26 @@ Crossfade::set_state (const XMLNode& node) XMLNode* fo; const XMLProperty* prop; LocaleGuard lg (X_("POSIX")); + Change what_changed = Change (0); + nframes_t val; if ((prop = node.property ("position")) != 0) { - _position = atoi (prop->value().c_str()); + sscanf (prop->value().c_str(), "%" PRIu32, &val); + if (val != _position) { + _position = val; + what_changed = Change (what_changed | PositionChanged); + } } else { warning << _("old-style crossfade information - no position information") << endmsg; _position = _in->first_frame(); } if ((prop = node.property ("active")) != 0) { - _active = (prop->value() == "yes"); + bool x = (prop->value() == "yes"); + if (x != _active) { + _active = x; + what_changed = Change (what_changed | ActiveChanged); + } } else { _active = true; } @@ -767,7 +708,11 @@ Crossfade::set_state (const XMLNode& node) if ((prop = node.property ("length")) != 0) { - _length = atol (prop->value().c_str()); + sscanf (prop->value().c_str(), "%" PRIu32, &val); + if (val != _length) { + _length = atol (prop->value().c_str()); + what_changed = Change (what_changed | LengthChanged); + } } else { @@ -790,6 +735,7 @@ Crossfade::set_state (const XMLNode& node) /* fade in */ + _fade_in.freeze (); _fade_in.clear (); children = fi->children(); @@ -808,9 +754,12 @@ Crossfade::set_state (const XMLNode& node) _fade_in.add (x, y); } } + + _fade_in.thaw (); /* fade out */ + _fade_in.freeze (); _fade_out.clear (); children = fo->children(); @@ -831,6 +780,10 @@ Crossfade::set_state (const XMLNode& node) } } + _fade_out.thaw (); + + StateChanged (what_changed); /* EMIT SIGNAL */ + return 0; } @@ -854,6 +807,8 @@ Crossfade::set_follow_overlap (bool yn) } else { set_length (_out->first_frame() + _out->length() - _in->first_frame()); } + + StateChanged (FollowOverlapChanged); } nframes_t @@ -887,9 +842,7 @@ Crossfade::set_length (nframes_t len) _length = len; - save_state ("length changed"); - - send_state_changed (LengthChanged); + StateChanged (LengthChanged); return len; } @@ -908,3 +861,9 @@ Crossfade::set_short_xfade_length (nframes_t n) { _short_xfade_length = n; } + +void +Crossfade::invalidate () +{ + Invalidated (this); /* EMIT SIGNAL */ +} diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc index da9c5c3588..e9f8499981 100644 --- a/libs/ardour/diskstream.cc +++ b/libs/ardour/diskstream.cc @@ -329,7 +329,6 @@ Diskstream::use_playlist (Playlist* playlist) reset_write_sources (false); } - plstate_connection = _playlist->StateChanged.connect (mem_fun (*this, &Diskstream::playlist_changed)); plmod_connection = _playlist->Modified.connect (mem_fun (*this, &Diskstream::playlist_modified)); plgone_connection = _playlist->GoingAway.connect (bind (mem_fun (*this, &Diskstream::playlist_deleted), _playlist)); } diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc index 7f2781d707..b2318bbe96 100644 --- a/libs/ardour/midi_playlist.cc +++ b/libs/ardour/midi_playlist.cc @@ -40,9 +40,6 @@ using namespace ARDOUR; using namespace sigc; using namespace std; -MidiPlaylist::State::~State () -{} - MidiPlaylist::MidiPlaylist (Session& session, const XMLNode& node, bool hidden) : Playlist (session, node, DataType::MIDI, hidden) { @@ -53,8 +50,6 @@ MidiPlaylist::MidiPlaylist (Session& session, const XMLNode& node, bool hidden) set_state (node); in_set_state = false; - save_state (_("initial state")); - if (!hidden) { PlaylistCreated (this); /* EMIT SIGNAL */ } @@ -63,8 +58,6 @@ MidiPlaylist::MidiPlaylist (Session& session, const XMLNode& node, bool hidden) MidiPlaylist::MidiPlaylist (Session& session, string name, bool hidden) : Playlist (session, name, DataType::MIDI, hidden) { - save_state (_("initial state")); - if (!hidden) { PlaylistCreated (this); /* EMIT SIGNAL */ } @@ -75,7 +68,6 @@ MidiPlaylist::MidiPlaylist (const MidiPlaylist& other, string name, bool hidden) : Playlist (other, name, hidden) { throw; // nope - save_state (_("initial state")); /* list<Region*>::const_iterator in_o = other.regions.begin(); @@ -122,20 +114,12 @@ MidiPlaylist::MidiPlaylist (const MidiPlaylist& other, string name, bool hidden) MidiPlaylist::MidiPlaylist (const MidiPlaylist& other, jack_nframes_t start, jack_nframes_t dur, string name, bool hidden) : Playlist (other, start, dur, name, hidden) { - save_state (_("initial state")); - /* this constructor does NOT notify others (session) */ } MidiPlaylist::~MidiPlaylist () { GoingAway (); /* EMIT SIGNAL */ - - for (StateMap::iterator i = states.begin(); i != states.end(); ++i) { - - MidiPlaylist::State* apstate = dynamic_cast<MidiPlaylist::State*> (*i); - delete apstate; - } } struct RegionSortByLayer { @@ -283,84 +267,6 @@ MidiPlaylist::set_state (const XMLNode& node) return 0; } -void -MidiPlaylist::drop_all_states () -{ - set<boost::shared_ptr<Region> > all_regions; - - /* find every region we've ever used, and add it to the set of - all regions. same for xfades; - */ - - for (StateMap::iterator i = states.begin(); i != states.end(); ++i) { - - MidiPlaylist::State* apstate = dynamic_cast<MidiPlaylist::State*> (*i); - - for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) { - all_regions.insert (*r); - } - } - - /* now remove from the "all" lists every region that is in the current list. */ - - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - set<boost::shared_ptr<Region> >::iterator x = all_regions.find (*i); - if (x != all_regions.end()) { - all_regions.erase (x); - } - } - - /* Now do the generic thing ... */ - - StateManager::drop_all_states (); -} - -StateManager::State* -MidiPlaylist::state_factory (std::string why) const -{ - State* state = new State (why); - - state->regions = regions; - state->region_states.clear (); - for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) { - state->region_states.push_back ((*i)->get_memento()); - } - - return state; -} - -Change -MidiPlaylist::restore_state (StateManager::State& state) -{ - { - RegionLock rlock (this); - State* apstate = dynamic_cast<State*> (&state); - - in_set_state = true; - - regions = apstate->regions; - - for (list<UndoAction>::iterator s = apstate-> - region_states.begin(); - s != apstate->region_states.end(); - ++s) { - (*s) (); - } - - in_set_state = false; - } - - notify_length_changed (); - return Change (~0); -} - -UndoAction -MidiPlaylist::get_memento () const -{ - return sigc::bind (mem_fun (*(const_cast<MidiPlaylist*> (this)), &StateManager::use_state), _current_state_id); -} - - XMLNode& MidiPlaylist::state (bool full_state) { @@ -422,39 +328,6 @@ MidiPlaylist::destroy_region (boost::shared_ptr<Region> region) } } - for (StateMap::iterator s = states.begin(); s != states.end(); ) { - StateMap::iterator tmp; - - tmp = s; - ++tmp; - - State* astate = dynamic_cast<State*> (*s); - - list<UndoAction>::iterator rsi, rsitmp; - RegionList::iterator ri, ritmp; - - for (ri = astate->regions.begin(), rsi = astate->region_states.begin(); - ri != astate->regions.end() && rsi != astate->region_states.end();) { - - - ritmp = ri; - ++ritmp; - - rsitmp = rsi; - ++rsitmp; - - if (region == (*ri)) { - astate->regions.erase (ri); - astate->region_states.erase (rsi); - } - - ri = ritmp; - rsi = rsitmp; - } - - s = tmp; - } - if (changed) { /* overload this, it normally means "removed", not destroyed */ @@ -484,8 +357,6 @@ MidiPlaylist::region_changed (Change what_changed, boost::shared_ptr<Region> reg parent_wants_notify = Playlist::region_changed (what_changed, region); - maybe_save_state (_("region modified")); - if ((parent_wants_notify || (what_changed & our_interests))) { notify_modified (); } diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc index c0d63cc2ba..f881b65d2a 100644 --- a/libs/ardour/midi_region.cc +++ b/libs/ardour/midi_region.cc @@ -51,8 +51,6 @@ using namespace ARDOUR; MidiRegion::MidiRegion (boost::shared_ptr<MidiSource> src, jack_nframes_t start, jack_nframes_t length) : Region (src, start, length, PBD::basename_nosuffix(src->name()), DataType::MIDI, 0, Region::Flag(Region::DefaultFlags|Region::External)) { - save_state ("initial state"); - assert(_name.find("/") == string::npos); } @@ -60,8 +58,6 @@ MidiRegion::MidiRegion (boost::shared_ptr<MidiSource> src, jack_nframes_t start, MidiRegion::MidiRegion (boost::shared_ptr<MidiSource> src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags) : Region (src, start, length, name, DataType::MIDI, layer, flags) { - save_state ("initial state"); - assert(_name.find("/") == string::npos); } @@ -69,8 +65,6 @@ MidiRegion::MidiRegion (boost::shared_ptr<MidiSource> src, jack_nframes_t start, MidiRegion::MidiRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags) : Region (srcs, start, length, name, DataType::MIDI, layer, flags) { - save_state ("initial state"); - assert(_name.find("/") == string::npos); } @@ -79,16 +73,12 @@ MidiRegion::MidiRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t l MidiRegion::MidiRegion (boost::shared_ptr<const MidiRegion> other, jack_nframes_t offset, jack_nframes_t length, const string& name, layer_t layer, Flag flags) : Region (other, offset, length, name, layer, flags) { - save_state ("initial state"); - assert(_name.find("/") == string::npos); } MidiRegion::MidiRegion (boost::shared_ptr<const MidiRegion> other) : Region (other) { - save_state ("initial state"); - assert(_name.find("/") == string::npos); } @@ -99,8 +89,6 @@ MidiRegion::MidiRegion (boost::shared_ptr<MidiSource> src, const XMLNode& node) throw failed_constructor(); } - save_state ("initial state"); - assert(_name.find("/") == string::npos); assert(_type == DataType::MIDI); } @@ -112,8 +100,6 @@ MidiRegion::MidiRegion (SourceList& srcs, const XMLNode& node) throw failed_constructor(); } - save_state ("initial state"); - assert(_name.find("/") == string::npos); assert(_type == DataType::MIDI); } @@ -123,40 +109,6 @@ MidiRegion::~MidiRegion () GoingAway (); /* EMIT SIGNAL */ } -StateManager::State* -MidiRegion::state_factory (std::string why) const -{ - RegionState* state = new RegionState (why); - - Region::store_state (*state); - - return state; -} - -Change -MidiRegion::restore_state (StateManager::State& sstate) -{ - RegionState* state = dynamic_cast<RegionState*> (&sstate); - Change what_changed = Region::restore_and_return_flags (*state); - - if (_flags != Flag (state->_flags)) { - - //uint32_t old_flags = _flags; - - _flags = Flag (state->_flags); - } - - what_changed = Change (what_changed); - - return what_changed; -} - -UndoAction -MidiRegion::get_memento() const -{ - return sigc::bind (mem_fun (*(const_cast<MidiRegion *> (this)), &StateManager::use_state), _current_state_id); -} - jack_nframes_t MidiRegion::read_at (MidiRingBuffer& out, jack_nframes_t position, jack_nframes_t dur, diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index 56fed3d7a3..ee60a53d66 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -104,25 +104,24 @@ Playlist::Playlist (const Playlist& other, string namestr, bool hide) RegionList tmp; other.copy_regions (tmp); - in_set_state = true; + in_set_state++; for (list<boost::shared_ptr<Region> >::iterator x = tmp.begin(); x != tmp.end(); ++x) { add_region_internal( (*x), (*x)->position() ); } - in_set_state = false; + in_set_state--; _splicing = other._splicing; _nudging = other._nudging; _edit_mode = other._edit_mode; - in_set_state = false; + in_set_state = 0; in_flush = false; in_partition = false; subcnt = 0; _read_data_count = 0; _frozen = other._frozen; - save_on_thaw = false; layer_op_counter = other.layer_op_counter; freeze_length = other.freeze_length; @@ -236,14 +235,13 @@ Playlist::init (bool hide) _hidden = hide; _splicing = false; _nudging = false; - in_set_state = false; + in_set_state = 0; _edit_mode = Config->get_edit_mode(); in_flush = false; in_partition = false; subcnt = 0; _read_data_count = 0; _frozen = false; - save_on_thaw = false; layer_op_counter = 0; freeze_length = 0; @@ -340,9 +338,10 @@ void Playlist::notify_region_removed (boost::shared_ptr<Region> r) { if (holding_state ()) { - pending_removals.insert (pending_removals.end(), r); + pending_removes.insert (r); + pending_modified = true; + pending_length = true; } else { - RegionRemoved (r); /* EMIT SIGNAL */ /* this might not be true, but we have to act as though it could be. */ @@ -354,13 +353,15 @@ Playlist::notify_region_removed (boost::shared_ptr<Region> r) void Playlist::notify_region_added (boost::shared_ptr<Region> r) { + /* the length change might not be true, but we have to act + as though it could be. + */ + if (holding_state()) { - pending_adds.insert (pending_adds.end(), r); + pending_adds.insert (r); + pending_modified = true; + pending_length = true; } else { - RegionAdded (r); /* EMIT SIGNAL */ - /* this might not be true, but we have to act - as though it could be. - */ LengthChanged (); /* EMIT SIGNAL */ Modified (); /* EMIT SIGNAL */ } @@ -380,9 +381,8 @@ Playlist::notify_length_changed () void Playlist::flush_notifications () { - RegionList::iterator r; - RegionList::iterator a; set<boost::shared_ptr<Region> > dependent_checks_needed; + set<boost::shared_ptr<Region> >::iterator s; uint32_t n = 0; if (in_flush) { @@ -413,19 +413,17 @@ Playlist::flush_notifications () /* don't increment n again - its the same list */ } - for (a = pending_adds.begin(); a != pending_adds.end(); ++a) { - dependent_checks_needed.insert (*a); - RegionAdded (*a); /* EMIT SIGNAL */ + for (s = pending_adds.begin(); s != pending_adds.end(); ++s) { + dependent_checks_needed.insert (*s); n++; } - for (set<boost::shared_ptr<Region> >::iterator x = dependent_checks_needed.begin(); x != dependent_checks_needed.end(); ++x) { - check_dependents (*x, false); + for (s = dependent_checks_needed.begin(); s != dependent_checks_needed.end(); ++s) { + check_dependents (*s, false); } - for (r = pending_removals.begin(); r != pending_removals.end(); ++r) { - remove_dependents (*r); - RegionRemoved (*r); /* EMIT SIGNAL */ + for (s = pending_removes.begin(); s != pending_removes.end(); ++s) { + remove_dependents (*s); n++; } @@ -445,14 +443,9 @@ Playlist::flush_notifications () } pending_adds.clear (); - pending_removals.clear (); + pending_removes.clear (); pending_bounds.clear (); - if (save_on_thaw) { - save_on_thaw = false; - save_state (last_save_reason); - } - in_flush = false; } @@ -461,7 +454,7 @@ Playlist::flush_notifications () *************************************************************/ void -Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, float times, bool with_save) +Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, float times) { RegionLock rlock (this); @@ -500,10 +493,6 @@ Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, floa boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags()); add_region_internal (sub, pos, true); } - - if (with_save) { - maybe_save_state (_("add region")); - } } void @@ -522,6 +511,7 @@ Playlist::add_region_internal (boost::shared_ptr<Region> region, nframes_t posit timestamp_layer_op (region); regions.insert (upper_bound (regions.begin(), regions.end(), region, cmp), region); + all_regions.insert (region); if (!holding_state () && !in_set_state) { /* layers get assigned from XML state */ @@ -554,8 +544,6 @@ Playlist::replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Regio if (!holding_state ()) { possibly_splice_unlocked (); } - - maybe_save_state (_("replace region")); } void @@ -567,8 +555,6 @@ Playlist::remove_region (boost::shared_ptr<Region> region) if (!holding_state ()) { possibly_splice_unlocked (); } - - maybe_save_state (_("remove region")); } int @@ -577,7 +563,7 @@ Playlist::remove_region_internal (boost::shared_ptr<Region>region, bool delay_so RegionList::iterator i; nframes_t old_length = 0; - // cerr << "removing region " << region->name() << endl; + cerr << "removing region " << region->name() << " holding = " << holding_state() << endl; if (!holding_state()) { old_length = _get_maximum_extent(); @@ -639,8 +625,6 @@ Playlist::partition (nframes_t start, nframes_t end, bool just_top_level) for (RegionList::iterator i = thawlist.begin(); i != thawlist.end(); ++i) { (*i)->thaw ("separation"); } - - maybe_save_state (_("separate")); } void @@ -904,8 +888,6 @@ Playlist::cut (nframes_t start, nframes_t cnt, bool result_is_hidden) (*i)->thaw ("playlist cut"); } - maybe_save_state (_("cut")); - return the_copy; } @@ -965,8 +947,6 @@ Playlist::paste (Playlist& other, nframes_t position, float times) } - maybe_save_state (_("paste")); - return 0; } @@ -993,8 +973,6 @@ Playlist::duplicate (boost::shared_ptr<Region> region, nframes_t position, float boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags()); add_region_internal (sub, pos, true); } - - maybe_save_state (_("duplicate")); } void @@ -1048,8 +1026,6 @@ Playlist::split_region (boost::shared_ptr<Region> region, nframes_t playlist_pos if (remove_region_internal (region, true)) { return; } - - maybe_save_state (_("split")); } void @@ -1199,24 +1175,21 @@ Playlist::region_changed (Change what_changed, boost::shared_ptr<Region> region) } void -Playlist::clear (bool with_save) +Playlist::clear (bool with_signals) { - RegionList::iterator i; - RegionList tmp; - { RegionLock rl (this); - tmp = regions; + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + pending_removes.insert (*i); + } regions.clear (); } - - for (i = tmp.begin(); i != tmp.end(); ++i) { - notify_region_removed (*i); - } - if (with_save) { - maybe_save_state (_("clear")); + if (with_signals) { + LengthChanged (); + Modified (); } + } /*********************************************************************** @@ -1346,8 +1319,6 @@ Playlist::mark_session_dirty () int Playlist::set_state (const XMLNode& node) { - in_set_state = true; - XMLNode *child; XMLNodeList nlist; XMLNodeConstIterator niter; @@ -1357,13 +1328,15 @@ Playlist::set_state (const XMLNode& node) boost::shared_ptr<Region> region; string region_name; - clear (false); + in_set_state++; if (node.name() != "Playlist") { - in_set_state = false; + in_set_state--; return -1; } + freeze (); + plist = node.properties(); for (piter = plist.begin(); piter != plist.end(); ++piter) { @@ -1379,6 +1352,8 @@ Playlist::set_state (const XMLNode& node) } } + clear (false); + nlist = node.children(); for (niter = nlist.begin(); niter != nlist.end(); ++niter) { @@ -1392,19 +1367,29 @@ Playlist::set_state (const XMLNode& node) continue; } - if ((region = RegionFactory::create (_session, *child, true)) == 0) { - error << _("Playlist: cannot create region from state file") << endmsg; + ID id = prop->value (); + + if ((region = region_by_id (id))) { + + Change what_changed = Change (0); + + if (region->set_live_state (*child, what_changed, true)) { + error << _("Playlist: cannot reset region state from XML") << endmsg; + continue; + } + + } else if ((region = RegionFactory::create (_session, *child, true)) == 0) { + error << _("Playlist: cannot create region from XML") << endmsg; continue; } - add_region (region, region->position(), 1.0, false); + add_region (region, region->position(), 1.0); // So that layer_op ordering doesn't get screwed up region->set_last_layer_op( region->layer()); } } - /* update dependents, which was not done during add_region_internal due to in_set_state being true @@ -1413,8 +1398,12 @@ Playlist::set_state (const XMLNode& node) for (RegionList::iterator r = regions.begin(); r != regions.end(); ++r) { check_dependents (*r, false); } - - in_set_state = false; + + notify_modified (); + + thaw (); + + in_set_state--; return 0; } @@ -1447,7 +1436,11 @@ Playlist::state (bool full_state) if (full_state) { RegionLock rlock (this, false); + cerr << _name << " getting region state for " << regions.size() << endl; + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + cerr << "\t" << " now at " << (*i) << endl; + cerr << "\t\t" << (*i)->name() << endl; node->add_child_nocopy ((*i)->get_state()); } } @@ -1754,7 +1747,6 @@ Playlist::nudge_after (nframes_t start, nframes_t distance, bool forwards) if (moved) { _nudging = false; - maybe_save_state (_("nudged")); notify_length_changed (); } @@ -1764,26 +1756,31 @@ boost::shared_ptr<Region> Playlist::find_region (const ID& id) const { RegionLock rlock (const_cast<Playlist*> (this)); - RegionList::const_iterator i; - boost::shared_ptr<Region> ret; - for (i = regions.begin(); i != regions.end(); ++i) { + /* searches all regions currently in use by the playlist */ + + for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) { if ((*i)->id() == id) { - ret = *i; + return *i; } } - return ret; + return boost::shared_ptr<Region> (); } - -void -Playlist::save_state (std::string why) + +boost::shared_ptr<Region> +Playlist::region_by_id (ID id) { - if (!in_set_state) { - StateManager::save_state (why); + /* searches all regions ever added to this playlist */ + + for (set<boost::shared_ptr<Region> >::iterator i = all_regions.begin(); i != all_regions.end(); ++i) { + if ((*i)->id() == id) { + return *i; + } } + return boost::shared_ptr<Region> (); } - + void Playlist::dump () const { @@ -1819,13 +1816,3 @@ Playlist::timestamp_layer_op (boost::shared_ptr<Region> region) region->set_last_layer_op (++layer_op_counter); } -void -Playlist::maybe_save_state (string why) -{ - if (holding_state ()) { - save_on_thaw = true; - last_save_reason = why; - } else { - save_state (why); - } -} diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index d55a8aea1a..3853559e10 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -28,6 +28,7 @@ #include <glibmm/thread.h> #include <pbd/xml++.h> +#include <pbd/stacktrace.h> #include <ardour/region.h> #include <ardour/playlist.h> @@ -66,8 +67,6 @@ Region::Region (boost::shared_ptr<Source> src, jack_nframes_t start, jack_nframe , _last_layer_op(0) , _playlist(0) { - _current_state_id = 0; - _sources.push_back (src); _master_sources.push_back (src); src->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), src)); @@ -92,7 +91,6 @@ Region::Region (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, c , _last_layer_op(0) , _playlist(0) { - _current_state_id = 0; set<boost::shared_ptr<Source> > unique_srcs; @@ -129,8 +127,6 @@ Region::Region (boost::shared_ptr<const Region> other, nframes_t offset, nframes , _last_layer_op(0) , _playlist(0) { - _current_state_id = 0; - if (other->_sync_position < offset) _sync_position = other->_sync_position; @@ -173,8 +169,6 @@ Region::Region (boost::shared_ptr<const Region> other) , _last_layer_op(other->_last_layer_op) , _playlist(0) { - _current_state_id = 0; - other->_first_edit = EditChangesName; if (other->_extra_xml) { @@ -218,7 +212,6 @@ Region::Region (SourceList& srcs, const XMLNode& node) , _playlist(0) { - _current_state_id = 0; set<boost::shared_ptr<Source> > unique_srcs; @@ -261,7 +254,6 @@ Region::Region (boost::shared_ptr<Source> src, const XMLNode& node) { _sources.push_back (src); - _current_state_id = 0; if (set_state (node)) { throw failed_constructor(); @@ -283,69 +275,7 @@ Region::set_playlist (Playlist* pl) } void -Region::store_state (RegionState& state) const -{ - state._start = _start; - state._length = _length; - state._position = _position; - state._flags = _flags; - state._sync_position = _sync_position; - state._layer = _layer; - state._name = _name; - state._first_edit = _first_edit; -} - -Change -Region::restore_and_return_flags (RegionState& state) -{ - Change what_changed = Change (0); - - { - Glib::Mutex::Lock lm (_lock); - - if (_start != state._start) { - what_changed = Change (what_changed|StartChanged); - _start = state._start; - } - if (_length != state._length) { - what_changed = Change (what_changed|LengthChanged); - _length = state._length; - } - if (_position != state._position) { - what_changed = Change (what_changed|PositionChanged); - _position = state._position; - } - if (_sync_position != state._sync_position) { - _sync_position = state._sync_position; - what_changed = Change (what_changed|SyncOffsetChanged); - } - if (_layer != state._layer) { - what_changed = Change (what_changed|LayerChanged); - _layer = state._layer; - } - - uint32_t old_flags = _flags; - _flags = Flag (state._flags); - - if ((old_flags ^ state._flags) & Muted) { - what_changed = Change (what_changed|MuteChanged); - } - if ((old_flags ^ state._flags) & Opaque) { - what_changed = Change (what_changed|OpacityChanged); - } - if ((old_flags ^ state._flags) & Locked) { - what_changed = Change (what_changed|LockChanged); - } - - _first_edit = state._first_edit; - } - - return what_changed; -} - -void Region::set_name (string str) - { if (_name != str) { _name = str; @@ -383,10 +313,6 @@ Region::set_length (nframes_t len, void *src) if (!_frozen) { recompute_at_end (); - - char buf[64]; - snprintf (buf, sizeof (buf), "length set to %u", len); - save_state (buf); } send_change (LengthChanged); @@ -454,12 +380,6 @@ Region::set_position (nframes_t pos, void *src) if (max_frames - _length < _position) { _length = max_frames - _position; } - - if (!_frozen) { - char buf[64]; - snprintf (buf, sizeof (buf), "position set to %u", pos); - save_state (buf); - } } /* do this even if the position is the same. this helps out @@ -478,15 +398,9 @@ Region::set_position_on_top (nframes_t pos, void *src) if (_position != pos) { _position = pos; - - if (!_frozen) { - char buf[64]; - snprintf (buf, sizeof (buf), "position set to %u", pos); - save_state (buf); - } } - _playlist->raise_region_to_top (boost::shared_ptr<Region>(this)); + _playlist->raise_region_to_top (shared_from_this ()); /* do this even if the position is the same. this helps out a GUI that has moved its representation already. @@ -520,12 +434,6 @@ Region::nudge_position (long n, void *src) } } - if (!_frozen) { - char buf[64]; - snprintf (buf, sizeof (buf), "position set to %u", _position); - save_state (buf); - } - send_change (PositionChanged); } @@ -550,12 +458,6 @@ Region::set_start (nframes_t pos, void *src) _flags = Region::Flag (_flags & ~WholeFile); first_edit (); - if (!_frozen) { - char buf[64]; - snprintf (buf, sizeof (buf), "start set to %u", pos); - save_state (buf); - } - send_change (StartChanged); } } @@ -606,12 +508,6 @@ Region::trim_start (nframes_t new_position, void *src) _flags = Region::Flag (_flags & ~WholeFile); first_edit (); - if (!_frozen) { - char buf[64]; - snprintf (buf, sizeof (buf), "slipped start to %u", _start); - save_state (buf); - } - send_change (StartChanged); } @@ -745,13 +641,6 @@ Region::trim_to_internal (nframes_t position, nframes_t length, void *src) } if (what_changed) { - - if (!_frozen) { - char buf[64]; - snprintf (buf, sizeof (buf), "trimmed to %u-%u", _position, _position+_length-1); - save_state (buf); - } - send_change (what_changed); } } @@ -782,16 +671,6 @@ Region::set_muted (bool yn) _flags = Flag (_flags & ~Muted); } - if (!_frozen) { - char buf[64]; - if (yn) { - snprintf (buf, sizeof (buf), "muted"); - } else { - snprintf (buf, sizeof (buf), "unmuted"); - } - save_state (buf); - } - send_change (MuteChanged); } } @@ -800,16 +679,10 @@ void Region::set_opaque (bool yn) { if (opaque() != yn) { - if (!_frozen) { - char buf[64]; - if (yn) { - snprintf (buf, sizeof (buf), "opaque"); - _flags = Flag (_flags|Opaque); - } else { - snprintf (buf, sizeof (buf), "translucent"); - _flags = Flag (_flags & ~Opaque); - } - save_state (buf); + if (yn) { + _flags = Flag (_flags|Opaque); + } else { + _flags = Flag (_flags & ~Opaque); } send_change (OpacityChanged); } @@ -819,16 +692,10 @@ void Region::set_locked (bool yn) { if (locked() != yn) { - if (!_frozen) { - char buf[64]; - if (yn) { - snprintf (buf, sizeof (buf), "locked"); - _flags = Flag (_flags|Locked); - } else { - snprintf (buf, sizeof (buf), "unlocked"); - _flags = Flag (_flags & ~Locked); - } - save_state (buf); + if (yn) { + _flags = Flag (_flags|Locked); + } else { + _flags = Flag (_flags & ~Locked); } send_change (LockChanged); } @@ -847,10 +714,7 @@ Region::set_sync_position (nframes_t absolute_pos) _flags = Flag (_flags|SyncMarked); if (!_frozen) { - char buf[64]; maybe_uncopy (); - snprintf (buf, sizeof (buf), "sync point set to %u", _sync_position); - save_state (buf); } send_change (SyncOffsetChanged); } @@ -864,7 +728,6 @@ Region::clear_sync_position () if (!_frozen) { maybe_uncopy (); - save_state ("sync point removed"); } send_change (SyncOffsetChanged); } @@ -928,7 +791,7 @@ Region::raise () return; } - _playlist->raise_region (boost::shared_ptr<Region>(this)); + _playlist->raise_region (shared_from_this ()); } void @@ -938,7 +801,7 @@ Region::lower () return; } - _playlist->lower_region (boost::shared_ptr<Region>(this)); + _playlist->lower_region (shared_from_this ()); } void @@ -949,7 +812,7 @@ Region::raise_to_top () return; } - _playlist->raise_region_to_top (boost::shared_ptr<Region>(this)); + _playlist->raise_region_to_top (shared_from_this()); } void @@ -959,7 +822,7 @@ Region::lower_to_bottom () return; } - _playlist->lower_region_to_bottom (boost::shared_ptr<Region>(this)); + _playlist->lower_region_to_bottom (shared_from_this()); } void @@ -968,12 +831,6 @@ Region::set_layer (layer_t l) if (_layer != l) { _layer = l; - if (!_frozen) { - char buf[64]; - snprintf (buf, sizeof (buf), "layer set to %" PRIu32, _layer); - save_state (buf); - } - send_change (LayerChanged); } } @@ -983,7 +840,8 @@ Region::state (bool full_state) { XMLNode *node = new XMLNode ("Region"); char buf[64]; - + char* fe; + _id.print (buf, sizeof (buf)); node->add_property ("id", buf); node->add_property ("name", _name); @@ -994,6 +852,20 @@ Region::state (bool full_state) node->add_property ("length", buf); snprintf (buf, sizeof (buf), "%u", _position); node->add_property ("position", buf); + + switch (_first_edit) { + case EditChangesNothing: + fe = X_("nothing"); + break; + case EditChangesName: + fe = X_("name"); + break; + case EditChangesID: + fe = X_("id"); + break; + } + + node->add_property ("first_edit", fe); /* note: flags are stored by derived classes */ @@ -1012,25 +884,18 @@ Region::get_state () } int -Region::set_state (const XMLNode& node) +Region::set_live_state (const XMLNode& node, Change& what_changed, bool send) { const XMLNodeList& nlist = node.children(); const XMLProperty *prop; + nframes_t val; - if (_extra_xml) { - delete _extra_xml; - _extra_xml = 0; - } - - if ((prop = node.property ("id")) == 0) { - error << _("Session: XMLNode describing a Region is incomplete (no id)") << endmsg; - return -1; - } - - _id = prop->value(); + /* this is responsible for setting those aspects of Region state + that are mutable after construction. + */ if ((prop = node.property ("name")) == 0) { - error << _("Session: XMLNode describing a Region is incomplete (no name)") << endmsg; + error << _("XMLNode describing a Region is incomplete (no name)") << endmsg; return -1; } @@ -1043,29 +908,65 @@ Region::set_state (const XMLNode& node) } if ((prop = node.property ("start")) != 0) { - sscanf (prop->value().c_str(), "%" PRIu32, &_start); + sscanf (prop->value().c_str(), "%" PRIu32, &val); + if (val != _start) { + what_changed = Change (what_changed|StartChanged); + _start = val; + } + } else { + _start = 0; } if ((prop = node.property ("length")) != 0) { - sscanf (prop->value().c_str(), "%" PRIu32, &_length); + sscanf (prop->value().c_str(), "%" PRIu32, &val); + if (val != _length) { + what_changed = Change (what_changed|LengthChanged); + _length = val; + } + } else { + _length = 1; } if ((prop = node.property ("position")) != 0) { - sscanf (prop->value().c_str(), "%" PRIu32, &_position); + sscanf (prop->value().c_str(), "%" PRIu32, &val); + if (val != _position) { + what_changed = Change (what_changed|PositionChanged); + _position = val; + } + } else { + _position = 0; } if ((prop = node.property ("layer")) != 0) { - _layer = (layer_t) atoi (prop->value().c_str()); + layer_t x; + x = (layer_t) atoi (prop->value().c_str()); + if (x != _layer) { + what_changed = Change (what_changed|LayerChanged); + _layer = x; + } + } else { + _layer = 0; } - /* note: derived classes set flags */ - if ((prop = node.property ("sync-position")) != 0) { - sscanf (prop->value().c_str(), "%" PRIu32, &_sync_position); + sscanf (prop->value().c_str(), "%" PRIu32, &val); + if (val != _sync_position) { + what_changed = Change (what_changed|SyncOffsetChanged); + _sync_position = val; + } } else { _sync_position = _start; } + + /* XXX FIRST EDIT !!! */ + /* note: derived classes set flags */ + + if (_extra_xml) { + delete _extra_xml; + _extra_xml = 0; + } + for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) { XMLNode *child; @@ -1078,7 +979,31 @@ Region::set_state (const XMLNode& node) } } + if (send) { + send_change (what_changed); + } + + return 0; +} + +int +Region::set_state (const XMLNode& node) +{ + const XMLProperty *prop; + Change what_changed = Change (0); + + /* ID is not allowed to change, ever */ + + if ((prop = node.property ("id")) == 0) { + error << _("Session: XMLNode describing a Region is incomplete (no id)") << endmsg; + return -1; + } + + _id = prop->value(); + _first_edit = EditChangesNothing; + + set_live_state (node, what_changed, true); return 0; } @@ -1118,7 +1043,6 @@ Region::thaw (const string& why) recompute_at_end (); } - save_state (why); StateChanged (what_changed); } @@ -1133,7 +1057,7 @@ Region::send_change (Change what_changed) } } - StateManager::send_state_changed (what_changed); + StateChanged (what_changed); } void diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index ae5466dda8..11cb658008 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -469,12 +469,21 @@ Session::~Session () cerr << "delete regions\n"; #endif /* TRACK_DESTRUCTION */ - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + for (RegionList::iterator i = regions.begin(); i != regions.end(); ) { + RegionList::iterator tmp; + + tmp = i; + ++tmp; + + cerr << "dropping refs on a region (" << i->second->name() << " @ " << i->second << ") with UC = " << i->second.use_count() << endl; i->second->drop_references (); + cerr << "AFTER: UC = " << i->second.use_count() << endl; + + i = tmp; } regions.clear (); - + #ifdef TRACK_DESTRUCTION cerr << "delete routes\n"; #endif /* TRACK_DESTRUCTION */ diff --git a/libs/ardour/session_command.cc b/libs/ardour/session_command.cc index fb15304e9f..d71ba34fc7 100644 --- a/libs/ardour/session_command.cc +++ b/libs/ardour/session_command.cc @@ -28,74 +28,62 @@ Command *Session::memento_command_factory(XMLNode *n) id = PBD::ID(n->property("obj_id")->value()); /* get before/after */ - if (n->name() == "MementoCommand") - { - before = new XMLNode(*n->children().front()); - after = new XMLNode(*n->children().back()); - child = before; - } else if (n->name() == "MementoUndoCommand") - { - before = new XMLNode(*n->children().front()); - child = before; - } - else if (n->name() == "MementoRedoCommand") - { - after = new XMLNode(*n->children().front()); - child = after; - } + if (n->name() == "MementoCommand") { + before = new XMLNode(*n->children().front()); + after = new XMLNode(*n->children().back()); + child = before; + } else if (n->name() == "MementoUndoCommand") { + before = new XMLNode(*n->children().front()); + child = before; + } else if (n->name() == "MementoRedoCommand") { + after = new XMLNode(*n->children().front()); + child = after; + } else if (n->name() == "PlaylistCommand") { + before = new XMLNode(*n->children().front()); + after = new XMLNode(*n->children().back()); + child = before; + } + if (!child) { error << _("Tried to reconstitute a MementoCommand with no contents, failing. id=") << id.to_s() << endmsg; return 0; - } - - - /* create command */ + } + + + /* create command */ string obj_T = n->children().front()->name(); - if (obj_T == "AudioRegion" || obj_T == "MidiRegion" || obj_T == "Region") - { - if (regions.count(id)) - return new MementoCommand<Region>(*regions[id], before, after); + if (obj_T == "AudioRegion" || obj_T == "MidiRegion" || obj_T == "Region") { + if (regions.count(id)) + return new MementoCommand<Region>(*regions[id], before, after); + } else if (obj_T == "AudioSource" || obj_T == "MidiSource") { + if (sources.count(id)) + return new MementoCommand<Source>(*sources[id], before, after); + } else if (obj_T == "Location") { + return new MementoCommand<Location>(*_locations.get_location_by_id(id), before, after); + } else if (obj_T == "Locations") { + return new MementoCommand<Locations>(_locations, before, after); + } else if (obj_T == "TempoMap") { + return new MementoCommand<TempoMap>(*_tempo_map, before, after); + } else if (obj_T == "Playlist" || obj_T == "AudioPlaylist") { + if (Playlist *pl = playlist_by_name(child->property("name")->value())) + return new MementoCommand<Playlist>(*pl, before, after); + } else if (obj_T == "Route") { // includes AudioTrack + return new MementoCommand<Route>(*route_by_id(id), before, after); + } else if (obj_T == "Curve") { + if (curves.count(id)) + return new MementoCommand<Curve>(*curves[id], before, after); + } else if (obj_T == "AutomationList") { + if (automation_lists.count(id)) + return new MementoCommand<AutomationList>(*automation_lists[id], before, after); + } else if (registry.count(id)) { // For Editor and AutomationLine which are off-limits here + return new MementoCommand<StatefulDestructible>(*registry[id], before, after); } - else if (obj_T == "Source" || obj_T == "AudioSource" || obj_T == "MidiSource") - { - if (sources.count(id)) - return new MementoCommand<Source>(*sources[id], before, after); - } - else if (obj_T == "Location") - return new MementoCommand<Location>(*_locations.get_location_by_id(id), before, after); - else if (obj_T == "Locations") - return new MementoCommand<Locations>(_locations, before, after); - else if (obj_T == "TempoMap") - return new MementoCommand<TempoMap>(*_tempo_map, before, after); - else if (obj_T == "Playlist" || obj_T == "MidiPlaylist" || obj_T == "AudioPlaylist") - { - if (Playlist *pl = playlist_by_name(child->property("name")->value())) - return new MementoCommand<Playlist>(*pl, before, after); - } - else if (obj_T == "Route") // inlcudes AudioTrack - return new MementoCommand<Route>(*route_by_id(id), before, after); - else if (obj_T == "Curve") - { - if (curves.count(id)) - return new MementoCommand<Curve>(*curves[id], before, after); - } - else if (obj_T == "AutomationList") - { - if (automation_lists.count(id)) - return new MementoCommand<AutomationList>(*automation_lists[id], before, after); - } - // For Editor and AutomationLine which are off-limits here - else if (registry.count(id)) - return new MementoCommand<StatefulDestructible>(*registry[id], before, after); - /* we failed */ error << _("could not reconstitute MementoCommand from XMLNode. id=") << id.to_s() << endmsg; return 0; - - return 0; } // solo diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index cd78a9c362..ff79a47e6b 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -2551,13 +2551,7 @@ Session::cleanup_sources (Session::cleanup_report& rep) delete *x; } - /* step 2: clear the undo/redo history for all playlists */ - - for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) { - (*x)->drop_all_states (); - } - - /* step 3: find all un-referenced sources */ + /* step 2: find all un-referenced sources */ rep.paths.clear (); rep.space = 0; @@ -2587,7 +2581,7 @@ Session::cleanup_sources (Session::cleanup_report& rep) i = tmp; } - /* Step 4: get rid of all regions in the region list that use any dead sources + /* Step 3: get rid of all regions in the region list that use any dead sources in case the sources themselves don't go away (they might be referenced in other snapshots). */ @@ -2979,41 +2973,39 @@ Session::restore_history (string snapshot_name) /* replace history */ history.clear(); - for (XMLNodeConstIterator it = tree.root()->children().begin(); - it != tree.root()->children().end(); - it++) - { - XMLNode *t = *it; - UndoTransaction* ut = new UndoTransaction (); - struct timeval tv; - - ut->set_name(t->property("name")->value()); - stringstream ss(t->property("tv_sec")->value()); - ss >> tv.tv_sec; - ss.str(t->property("tv_usec")->value()); - ss >> tv.tv_usec; - ut->set_timestamp(tv); - - for (XMLNodeConstIterator child_it = t->children().begin(); - child_it != t->children().end(); - child_it++) - { - XMLNode *n = *child_it; - Command *c; - if (n->name() == "MementoCommand" || - n->name() == "MementoUndoCommand" || - n->name() == "MementoRedoCommand") - { - c = memento_command_factory(n); - if (c) - ut->add_command(c); - } - else - { - error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg; - } - } - history.add(ut); + + for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) { + + XMLNode *t = *it; + UndoTransaction* ut = new UndoTransaction (); + struct timeval tv; + + ut->set_name(t->property("name")->value()); + stringstream ss(t->property("tv_sec")->value()); + ss >> tv.tv_sec; + ss.str(t->property("tv_usec")->value()); + ss >> tv.tv_usec; + ut->set_timestamp(tv); + + for (XMLNodeConstIterator child_it = t->children().begin(); + child_it != t->children().end(); + child_it++) + { + XMLNode *n = *child_it; + Command *c; + + if (n->name() == "MementoCommand" || + n->name() == "MementoUndoCommand" || + n->name() == "MementoRedoCommand") { + if ((c = memento_command_factory(n))) { + ut->add_command(c); + } + } else { + error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg; + } + } + + history.add (ut); } return 0; diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index dcc0b82c0e..fcc6a33d81 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -442,8 +442,8 @@ SndFileSource::setup_broadcast_info (nframes_t when, struct tm& now, time_t tnow int random_code = random() % 999999999; snprintf (_broadcast_info->originator_reference, sizeof (_broadcast_info->originator_reference), "%2s%3s%12s%02d%02d%02d%9d", - bwf_country_code, - bwf_organization_code, + Config->get_bwf_country_code().c_str(), + Config->get_bwf_organization_code().c_str(), bwf_serial_number, now.tm_hour, now.tm_min, |