diff options
Diffstat (limited to 'libs/ardour')
95 files changed, 841 insertions, 213 deletions
diff --git a/libs/ardour/amp.cc b/libs/ardour/amp.cc index 99a6587dcf..bf3e7cee68 100644 --- a/libs/ardour/amp.cc +++ b/libs/ardour/amp.cc @@ -335,7 +335,7 @@ Amp::state (bool full_state) } int -Amp::set_state (const XMLNode& node) +Amp::set_state (const XMLNode& node, int version) { const XMLProperty* prop; diff --git a/libs/ardour/ardour/amp.h b/libs/ardour/ardour/amp.h index f0a65c4ef5..3cd1bf13dd 100644 --- a/libs/ardour/ardour/amp.h +++ b/libs/ardour/ardour/amp.h @@ -55,7 +55,7 @@ public: void apply_gain_automation(bool yn) { _apply_gain_automation = yn; } XMLNode& state (bool full); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); static void apply_gain (BufferSet& bufs, nframes_t nframes, gain_t initial, gain_t target); static void apply_simple_gain(BufferSet& bufs, nframes_t nframes, gain_t target); diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h index a8072695ff..507b148d82 100644 --- a/libs/ardour/ardour/audio_diskstream.h +++ b/libs/ardour/ardour/audio_diskstream.h @@ -126,7 +126,7 @@ class AudioDiskstream : public Diskstream /* stateful */ XMLNode& get_state(void); - int set_state(const XMLNode& node); + int set_state(const XMLNode& node, int version = 3000); void monitor_input (bool); diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h index bdbc4b8165..585d1a1e72 100644 --- a/libs/ardour/ardour/audio_track.h +++ b/libs/ardour/ardour/audio_track.h @@ -33,7 +33,7 @@ class AudioTrack : public Track { public: AudioTrack (Session&, std::string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal); - AudioTrack (Session&, const XMLNode&); + AudioTrack (Session&, const XMLNode&, int); ~AudioTrack (); int set_mode (TrackMode m); @@ -55,12 +55,12 @@ class AudioTrack : public Track boost::shared_ptr<Region> bounce (InterThreadInfo&); boost::shared_ptr<Region> bounce_range (nframes_t start, nframes_t end, InterThreadInfo&, bool enable_processing); - int set_state(const XMLNode& node); + int set_state(const XMLNode&, int version = 3000); protected: XMLNode& state (bool full); - - int _set_state (const XMLNode&, bool call_base); + + int _set_state (const XMLNode&, int, bool call_base); private: int set_diskstream (boost::shared_ptr<AudioDiskstream>, void *); diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h index 4da7943a2d..6b93ced905 100644 --- a/libs/ardour/ardour/audiofilesource.h +++ b/libs/ardour/ardour/audiofilesource.h @@ -72,7 +72,7 @@ public: int setup_peakfile (); XMLNode& get_state (); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); bool can_truncate_peaks() const { return !destructive(); } bool can_be_analysed() const { return _length > 0; } diff --git a/libs/ardour/ardour/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h index 32fc77f2d6..25595def8c 100644 --- a/libs/ardour/ardour/audioplaylist.h +++ b/libs/ardour/ardour/audioplaylist.h @@ -50,7 +50,7 @@ class AudioPlaylist : public ARDOUR::Playlist 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&); + int set_state (const XMLNode&, int version = 3000); sigc::signal<void,boost::shared_ptr<Crossfade> > NewCrossfade; diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h index ff718bb4b0..5e9031c897 100644 --- a/libs/ardour/ardour/audioregion.h +++ b/libs/ardour/ardour/audioregion.h @@ -107,7 +107,7 @@ class AudioRegion : public Region virtual nframes_t read_raw_internal (Sample*, sframes_t, nframes_t, int channel) const; XMLNode& state (bool); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); static void set_default_fade (float steepness, nframes_t len); bool fade_in_is_default () const; diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h index bc06642c33..eebd1dd5d9 100644 --- a/libs/ardour/ardour/audiosource.h +++ b/libs/ardour/ardour/audiosource.h @@ -79,7 +79,7 @@ class AudioSource : virtual public Source, mutable sigc::signal<void,nframes_t,nframes_t> PeakRangeReady; XMLNode& get_state (); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); int rename_peakfile (Glib::ustring newpath); void touch_peakfile (); diff --git a/libs/ardour/ardour/automation_list.h b/libs/ardour/ardour/automation_list.h index 9b899e8cd1..5f074385a3 100644 --- a/libs/ardour/ardour/automation_list.h +++ b/libs/ardour/ardour/automation_list.h @@ -79,8 +79,8 @@ class AutomationList : public PBD::StatefulDestructible, public Evoral::ControlL void stop_touch (); bool touching() const { return _touching; } - XMLNode& get_state(void); - int set_state (const XMLNode &s); + XMLNode& get_state (); + int set_state (const XMLNode &, int version = 3000); XMLNode& state (bool full); XMLNode& serialize_events (); diff --git a/libs/ardour/ardour/configuration.h b/libs/ardour/ardour/configuration.h index d00cadb179..bd164a08e9 100644 --- a/libs/ardour/ardour/configuration.h +++ b/libs/ardour/ardour/configuration.h @@ -34,7 +34,7 @@ class Configuration : public PBD::Stateful virtual ~Configuration(); virtual void map_parameters (sigc::slot<void, std::string> s) = 0; - virtual int set_state (XMLNode const &) = 0; + virtual int set_state (XMLNode const &, int) = 0; virtual XMLNode & get_state () = 0; virtual XMLNode & get_variables () = 0; virtual void set_variables (XMLNode const &) = 0; diff --git a/libs/ardour/ardour/control_protocol_manager.h b/libs/ardour/ardour/control_protocol_manager.h index bceece9adf..d1f059dc62 100644 --- a/libs/ardour/ardour/control_protocol_manager.h +++ b/libs/ardour/ardour/control_protocol_manager.h @@ -70,7 +70,7 @@ struct ControlProtocolInfo { void set_protocol_states (const XMLNode&); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); XMLNode& get_state (void); private: diff --git a/libs/ardour/ardour/crossfade.h b/libs/ardour/ardour/crossfade.h index 577bee8257..8a7773c035 100644 --- a/libs/ardour/ardour/crossfade.h +++ b/libs/ardour/ardour/crossfade.h @@ -75,7 +75,7 @@ class Crossfade : public ARDOUR::AudioRegion bool operator== (const ARDOUR::Crossfade&); XMLNode& get_state (void); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); boost::shared_ptr<ARDOUR::AudioRegion> in() const { return _in; } boost::shared_ptr<ARDOUR::AudioRegion> out() const { return _out; } diff --git a/libs/ardour/ardour/delivery.h b/libs/ardour/ardour/delivery.h index 9224d2755c..ef78c9bd45 100644 --- a/libs/ardour/ardour/delivery.h +++ b/libs/ardour/ardour/delivery.h @@ -89,7 +89,7 @@ public: static sigc::signal<void,nframes_t> CycleStart; XMLNode& state (bool full); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); /* Panning */ diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h index 6932913958..5427dc644d 100644 --- a/libs/ardour/ardour/diskstream.h +++ b/libs/ardour/ardour/diskstream.h @@ -130,8 +130,8 @@ class Diskstream : public SessionObject, public boost::noncopyable /* Stateful */ virtual XMLNode& get_state(void) = 0; - virtual int set_state(const XMLNode& node) = 0; - + virtual int set_state(const XMLNode&, int version = 3000) = 0; + virtual void monitor_input (bool) {} nframes_t capture_offset() const { return _capture_offset; } diff --git a/libs/ardour/ardour/file_source.h b/libs/ardour/ardour/file_source.h index 7844bb513a..5a9c2a9c56 100644 --- a/libs/ardour/ardour/file_source.h +++ b/libs/ardour/ardour/file_source.h @@ -46,7 +46,7 @@ public: bool is_embedded () const { return _is_embedded; } uint16_t channel() const { return _channel; } - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); int set_source_name (const Glib::ustring& newname, bool destructive); diff --git a/libs/ardour/ardour/internal_return.h b/libs/ardour/ardour/internal_return.h index 4d2839cb12..e896200c93 100644 --- a/libs/ardour/ardour/internal_return.h +++ b/libs/ardour/ardour/internal_return.h @@ -38,7 +38,7 @@ class InternalReturn : public Return XMLNode& state(bool full); XMLNode& get_state(void); - int set_state(const XMLNode& node); + int set_state(const XMLNode&, int version = 3000); void run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nframes_t nframes); bool configure_io (ChanCount in, ChanCount out); diff --git a/libs/ardour/ardour/internal_send.h b/libs/ardour/ardour/internal_send.h index ef7d3d3d54..d62be9eafa 100644 --- a/libs/ardour/ardour/internal_send.h +++ b/libs/ardour/ardour/internal_send.h @@ -38,8 +38,8 @@ class InternalSend : public Send XMLNode& state(bool full); XMLNode& get_state(void); - int set_state(const XMLNode& node); - + int set_state(const XMLNode& node, int version = 3000); + void run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nframes_t nframes); bool feeds (boost::shared_ptr<Route> other) const; bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index 0be1493dbb..9a13ced942 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -137,7 +137,8 @@ class IO : public SessionObject, public Latent virtual XMLNode& state (bool full); XMLNode& get_state (void); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); + int set_state_2X (const XMLNode&, int, bool); static int disable_connecting (void); static int enable_connecting (void); @@ -156,6 +157,8 @@ class IO : public SessionObject, public Latent static bool connecting_legal; XMLNode *pending_state_node; + int pending_state_node_version; + bool pending_state_node_in; /* three utility functions - this just seems to be simplest place to put them */ @@ -203,9 +206,11 @@ class IO : public SessionObject, public Latent void bundle_changed (Bundle::Change); - int get_port_counts (const XMLNode& node, ChanCount& n, boost::shared_ptr<Bundle>& c); - int create_ports (const XMLNode&); - int make_connections (const XMLNode&); + int get_port_counts (const XMLNode& node, int version, ChanCount& n, boost::shared_ptr<Bundle>& c); + int get_port_counts_2X (const XMLNode& node, int version, ChanCount& n, boost::shared_ptr<Bundle>& c); + int create_ports (const XMLNode&, int version); + int make_connections (const XMLNode&, int, bool); + int make_connections_2X (const XMLNode &, int, bool); boost::shared_ptr<Bundle> find_possible_bundle (const std::string &desired_name); diff --git a/libs/ardour/ardour/io_processor.h b/libs/ardour/ardour/io_processor.h index dc376b9a42..fdb0429bca 100644 --- a/libs/ardour/ardour/io_processor.h +++ b/libs/ardour/ardour/io_processor.h @@ -72,8 +72,8 @@ class IOProcessor : public Processor sigc::signal<void,IOProcessor*,uint32_t> AutomationChanged; XMLNode& state (bool full_state); - int set_state (const XMLNode&); - + int set_state (const XMLNode&, int version = 3000); + protected: boost::shared_ptr<IO> _input; boost::shared_ptr<IO> _output; diff --git a/libs/ardour/ardour/ladspa_plugin.h b/libs/ardour/ardour/ladspa_plugin.h index 8128fccf94..b08f3e5afa 100644 --- a/libs/ardour/ardour/ladspa_plugin.h +++ b/libs/ardour/ardour/ladspa_plugin.h @@ -99,7 +99,7 @@ class LadspaPlugin : public ARDOUR::Plugin bool parameter_is_toggled(uint32_t) const; XMLNode& get_state(); - int set_state(const XMLNode& node); + int set_state (const XMLNode&, int version = 3000); bool save_preset(std::string name); bool has_editor() const { return false; } @@ -133,6 +133,7 @@ class LadspaPlugin : public ARDOUR::Plugin void init (void *mod, uint32_t index, nframes_t rate); void run_in_place (nframes_t nsamples); void latency_compute_run (); + int set_state_2X (const XMLNode&, int version = 3000); }; class LadspaPluginInfo : public PluginInfo { diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h index 2a583719cc..cbc0782a4a 100644 --- a/libs/ardour/ardour/location.h +++ b/libs/ardour/ardour/location.h @@ -71,7 +71,7 @@ class Location : public PBD::StatefulDestructible } Location (const Location& other); - Location (const XMLNode&); + Location (const XMLNode&, int version = 3000); Location* operator= (const Location& other); bool locked() const { return _locked; } @@ -125,7 +125,7 @@ class Location : public PBD::StatefulDestructible XMLNode& cd_info_node (const std::string &, const std::string &); XMLNode& get_state (void); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); private: std::string _name; @@ -155,7 +155,7 @@ class Locations : public PBD::StatefulDestructible void clear_ranges (); XMLNode& get_state (void); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); Location *get_location_by_id(PBD::ID); Location* auto_loop_location () const; diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h index 7035cdfd02..aab752d591 100644 --- a/libs/ardour/ardour/midi_diskstream.h +++ b/libs/ardour/ardour/midi_diskstream.h @@ -75,7 +75,7 @@ class MidiDiskstream : public Diskstream /* stateful */ XMLNode& get_state(void); - int set_state(const XMLNode& node); + int set_state(const XMLNode&, int version = 3000); void monitor_input (bool); diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h index 6ea4a4cd30..a5b0e36b26 100644 --- a/libs/ardour/ardour/midi_model.h +++ b/libs/ardour/ardour/midi_model.h @@ -69,8 +69,8 @@ public: void operator()(); void undo(); - - int set_state (const XMLNode&); + + int set_state (const XMLNode&, int version = 3000); XMLNode& get_state (); void add(const boost::shared_ptr< Evoral::Note<TimeType> > note); @@ -113,8 +113,8 @@ public: void operator()(); void undo(); - - int set_state (const XMLNode&); + + int set_state (const XMLNode&, int version = 3000); XMLNode& get_state (); void change (const boost::shared_ptr<Evoral::Note<TimeType> > note, diff --git a/libs/ardour/ardour/midi_playlist.h b/libs/ardour/ardour/midi_playlist.h index 11c1288e92..dc315edb12 100644 --- a/libs/ardour/ardour/midi_playlist.h +++ b/libs/ardour/ardour/midi_playlist.h @@ -50,7 +50,7 @@ public: nframes_t read (MidiRingBuffer<nframes_t>& buf, nframes_t start, nframes_t cnt, uint32_t chan_n=0); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); bool destroy_region (boost::shared_ptr<Region>); diff --git a/libs/ardour/ardour/midi_region.h b/libs/ardour/ardour/midi_region.h index 50fc1516df..ddb3109ff6 100644 --- a/libs/ardour/ardour/midi_region.h +++ b/libs/ardour/ardour/midi_region.h @@ -68,7 +68,7 @@ class MidiRegion : public Region NoteMode mode = Sustained) const; XMLNode& state (bool); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); int separate_by_channel (ARDOUR::Session&, std::vector< boost::shared_ptr<Region> >&) const; diff --git a/libs/ardour/ardour/midi_source.h b/libs/ardour/ardour/midi_source.h index 7056748786..8a09aad6c8 100644 --- a/libs/ardour/ardour/midi_source.h +++ b/libs/ardour/ardour/midi_source.h @@ -91,7 +91,7 @@ class MidiSource : virtual public Source mutable sigc::signal<void,sframes_t,nframes_t> ViewDataRangeReady; XMLNode& get_state (); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); bool length_mutable() const { return true; } diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h index a4054e6b00..9f19c6590c 100644 --- a/libs/ardour/ardour/midi_track.h +++ b/libs/ardour/ardour/midi_track.h @@ -35,7 +35,7 @@ class MidiTrack : public Track { public: MidiTrack (Session&, string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal); - MidiTrack (Session&, const XMLNode&); + MidiTrack (Session&, const XMLNode&, int); ~MidiTrack (); int roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame, @@ -59,7 +59,7 @@ public: boost::shared_ptr<Region> bounce_range ( nframes_t start, nframes_t end, InterThreadInfo&, bool enable_processing); - int set_state(const XMLNode& node); + int set_state(const XMLNode&, int version = 3000); void midi_panic(void); bool write_immediate_event(size_t size, const uint8_t* buf); @@ -92,8 +92,8 @@ public: protected: XMLNode& state (bool full); - - int _set_state (const XMLNode&, bool call_base); + + int _set_state (const XMLNode&, int, bool call_base); private: void write_out_of_band_data ( diff --git a/libs/ardour/ardour/mute_master.h b/libs/ardour/ardour/mute_master.h index 1b06b4bf7c..39ad9ffd61 100644 --- a/libs/ardour/ardour/mute_master.h +++ b/libs/ardour/ardour/mute_master.h @@ -65,7 +65,7 @@ class MuteMaster : public AutomationControl sigc::signal<void> MutePointChanged; XMLNode& get_state(); - int set_state(const XMLNode& node); + int set_state(const XMLNode&, int version = 3000); private: AutomationList* _automation; diff --git a/libs/ardour/ardour/named_selection.h b/libs/ardour/ardour/named_selection.h index 2dcfbd131c..4911dd8c50 100644 --- a/libs/ardour/ardour/named_selection.h +++ b/libs/ardour/ardour/named_selection.h @@ -44,7 +44,7 @@ struct NamedSelection : public PBD::Stateful XMLNode& get_state (void); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); static sigc::signal<void,NamedSelection*> NamedSelectionCreated; }; diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h index c211aafc8c..6a435ec235 100644 --- a/libs/ardour/ardour/panner.h +++ b/libs/ardour/ardour/panner.h @@ -36,7 +36,6 @@ namespace ARDOUR { -class Route; class Session; class Panner; class BufferSet; @@ -74,7 +73,7 @@ class StreamPanner : public sigc::trackable, public PBD::Stateful sigc::signal<void> Changed; /* for position */ sigc::signal<void> StateChanged; /* for mute */ - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); virtual XMLNode& state (bool full_state) = 0; Panner & get_parent() { return parent; } @@ -149,9 +148,9 @@ class EqualPowerStereoPanner : public BaseStereoPanner static StreamPanner* factory (Panner&, Evoral::Parameter param); static std::string name; - XMLNode& state (bool full_state); - XMLNode& get_state (void); - int set_state (const XMLNode&); + XMLNode& state (bool full_state); + XMLNode& get_state (void); + int set_state (const XMLNode&, int version = 3000); private: void update (); @@ -172,7 +171,7 @@ class Multi2dPanner : public StreamPanner XMLNode& state (bool full_state); XMLNode& get_state (void); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); /* old school automation loading */ @@ -229,7 +228,7 @@ public: XMLNode& get_state (void); XMLNode& state (bool full); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); static bool equivalent (pan_t a, pan_t b) { return fabsf (a - b) < 0.002; // about 1 degree of arc for a stereo panner diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index 56c755bebb..01bb12db8d 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -124,7 +124,7 @@ class Playlist : public SessionObject, void foreach_region (sigc::slot<void, boost::shared_ptr<Region> >); XMLNode& get_state (); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); XMLNode& get_template (); sigc::signal<void,bool> InUse; diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h index 69b4ab1f8f..82111a5a4d 100644 --- a/libs/ardour/ardour/plugin_insert.h +++ b/libs/ardour/ardour/plugin_insert.h @@ -45,14 +45,14 @@ class PluginInsert : public Processor { public: PluginInsert (Session&, boost::shared_ptr<Plugin>); - PluginInsert (Session&, const XMLNode&); + PluginInsert (Session&, const XMLNode&, int version = 3000); ~PluginInsert (); static const std::string port_automation_node_name; XMLNode& state(bool); XMLNode& get_state(void); - int set_state(const XMLNode&); + int set_state(const XMLNode&, int version = 3000); void run (BufferSet& in, sframes_t start_frame, sframes_t end_frame, nframes_t nframes); void silence (nframes_t nframes); diff --git a/libs/ardour/ardour/port_insert.h b/libs/ardour/ardour/port_insert.h index 18f54b0216..73dacf7d68 100644 --- a/libs/ardour/ardour/port_insert.h +++ b/libs/ardour/ardour/port_insert.h @@ -44,12 +44,12 @@ class PortInsert : public IOProcessor { public: PortInsert (Session&, boost::shared_ptr<MuteMaster> mm); - PortInsert (Session&, boost::shared_ptr<MuteMaster> mm, const XMLNode&); + PortInsert (Session&, boost::shared_ptr<MuteMaster> mm, const XMLNode&, int version = 3000); ~PortInsert (); XMLNode& state(bool full); XMLNode& get_state(void); - int set_state(const XMLNode&); + int set_state (const XMLNode&, int version = 3000); void run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nframes_t nframes); diff --git a/libs/ardour/ardour/processor.h b/libs/ardour/ardour/processor.h index 21b7966fba..1e78777edd 100644 --- a/libs/ardour/ardour/processor.h +++ b/libs/ardour/ardour/processor.h @@ -91,8 +91,8 @@ class Processor : public SessionObject, public AutomatableControls, public Laten virtual XMLNode& state (bool full); XMLNode& get_state (void); - int set_state (const XMLNode&); - + int set_state (const XMLNode&, int version = 3000); + void *get_gui () const { return _gui; } void set_gui (void *p) { _gui = p; } @@ -109,6 +109,9 @@ protected: ChanCount _configured_input; ChanCount _configured_output; void* _gui; /* generic, we don't know or care what this is */ + +private: + int set_state_2X (const XMLNode&, int version); }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/rc_configuration.h b/libs/ardour/ardour/rc_configuration.h index d12a9c63e7..d0dc042bb1 100644 --- a/libs/ardour/ardour/rc_configuration.h +++ b/libs/ardour/ardour/rc_configuration.h @@ -37,7 +37,7 @@ class RCConfiguration : public Configuration RCConfiguration(); void map_parameters (sigc::slot<void, std::string>); - int set_state (XMLNode const &); + int set_state (XMLNode const &, int version = 3000); XMLNode& get_state (); XMLNode& get_variables (); void set_variables (XMLNode const &); diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index dab4f5df6f..d341489249 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -241,7 +241,7 @@ class Region XMLNode& get_state (); virtual XMLNode& state (bool); - virtual int set_state (const XMLNode&); + virtual int set_state (const XMLNode&, int version = 3000); virtual int set_live_state (const XMLNode&, Change&, bool send); virtual boost::shared_ptr<Region> get_parent() const; diff --git a/libs/ardour/ardour/return.h b/libs/ardour/ardour/return.h index 1a33795a37..3232e93295 100644 --- a/libs/ardour/ardour/return.h +++ b/libs/ardour/ardour/return.h @@ -54,7 +54,7 @@ public: XMLNode& state(bool full); XMLNode& get_state(void); - int set_state(const XMLNode& node); + int set_state(const XMLNode&, int version = 3000); uint32_t pans_required() const { return _configured_input.n_audio(); } diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 1ecdb51488..ac3c6f89f3 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -68,7 +68,7 @@ class Route : public SessionObject, public AutomatableControls Route (Session&, std::string name, Flag flags = Flag(0), DataType default_type = DataType::AUDIO); - Route (Session&, const XMLNode&, DataType default_type = DataType::AUDIO); + Route (Session&, const XMLNode&, int, DataType default_type = DataType::AUDIO); virtual ~Route(); boost::shared_ptr<IO> input() const { return _input; } @@ -251,7 +251,7 @@ class Route : public SessionObject, public AutomatableControls /* stateful */ XMLNode& get_state(); - int set_state(const XMLNode& node); + int set_state (const XMLNode&, int version = 3000); virtual XMLNode& get_template(); XMLNode& get_processor_state (); @@ -384,8 +384,8 @@ class Route : public SessionObject, public AutomatableControls uint32_t pans_required() const; ChanCount n_process_buffers (); - - virtual int _set_state (const XMLNode&, bool call_base); + + virtual int _set_state (const XMLNode&, int, bool call_base); boost::shared_ptr<Amp> _amp; boost::shared_ptr<PeakMeter> _meter; @@ -393,6 +393,8 @@ class Route : public SessionObject, public AutomatableControls private: void init (); + int _set_state_2X (const XMLNode&, int); + void set_processor_state_2X (XMLNodeList const &, int); static uint32_t order_key_cnt; @@ -407,7 +409,8 @@ class Route : public SessionObject, public AutomatableControls int configure_processors (ProcessorStreams*); int configure_processors_unlocked (ProcessorStreams*); - bool add_processor_from_xml (const XMLNode&, ProcessorList::iterator iter); + bool add_processor_from_xml (const XMLNode&, ProcessorList::iterator iter); + bool add_processor_from_xml_2X (const XMLNode&, int, ProcessorList::iterator iter); void placement_range (Placement p, ProcessorList::iterator& start, ProcessorList::iterator& end); }; diff --git a/libs/ardour/ardour/route_group.h b/libs/ardour/ardour/route_group.h index 194aa84582..124f3c9b3f 100644 --- a/libs/ardour/ardour/route_group.h +++ b/libs/ardour/ardour/route_group.h @@ -130,9 +130,9 @@ public: sigc::signal<void,void*> FlagsChanged; XMLNode& get_state (); - - int set_state (const XMLNode&); - + + int set_state (const XMLNode&, int version = 3000); + private: Session& _session; std::list<Route *> routes; @@ -142,6 +142,7 @@ private: Property _properties; void remove_when_going_away (Route*); + int set_state_2X (const XMLNode&, int); }; } /* namespace */ diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h index 6b872df9fe..13b7adbbf2 100644 --- a/libs/ardour/ardour/send.h +++ b/libs/ardour/ardour/send.h @@ -38,7 +38,7 @@ class Send : public Delivery { public: Send (Session&, boost::shared_ptr<MuteMaster>, Delivery::Role r = Delivery::Send); - Send (Session&, boost::shared_ptr<MuteMaster>, const XMLNode&, Delivery::Role r = Delivery::Send); + Send (Session&, boost::shared_ptr<MuteMaster>, const XMLNode&, int version = 3000, Delivery::Role r = Delivery::Send); virtual ~Send (); uint32_t bit_slot() const { return _bitslot; } @@ -53,7 +53,7 @@ class Send : public Delivery XMLNode& state(bool full); XMLNode& get_state(void); - int set_state(const XMLNode& node); + int set_state(const XMLNode&, int version = 3000); uint32_t pans_required() const { return _configured_input.n_audio(); } diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 5055ebc709..c5b793730c 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -305,7 +305,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable typedef std::list<boost::shared_ptr<Diskstream> > DiskstreamList; - int load_routes (const XMLNode&); + int load_routes (const XMLNode&, int); boost::shared_ptr<RouteList> get_routes() const { return routes.reader (); } @@ -468,7 +468,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable static std::vector<std::string*>* possible_states (std::string path); XMLNode& get_state(); - int set_state(const XMLNode& node); // not idempotent + int set_state(const XMLNode& node, int version = 3000); // not idempotent XMLNode& get_template(); /// The instant xml file is written to the session directory @@ -849,7 +849,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable public: GlobalRouteStateCommand (Session&, void*); GlobalRouteStateCommand (Session&, const XMLNode& node); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); XMLNode& get_state (); protected: @@ -899,7 +899,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable void operator()(); void undo(); XMLNode &get_state(); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); void mark(); protected: @@ -1439,7 +1439,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable /* edit/mix groups */ - int load_route_groups (const XMLNode&); + int load_route_groups (const XMLNode&, int); std::list<RouteGroup *> _route_groups; @@ -1458,7 +1458,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable void add_routes (RouteList&, bool save); uint32_t destructive_index; - boost::shared_ptr<Route> XMLRouteFactory (const XMLNode&); + boost::shared_ptr<Route> XMLRouteFactory (const XMLNode&, int); /* mixer stuff */ diff --git a/libs/ardour/ardour/session_configuration.h b/libs/ardour/ardour/session_configuration.h index fc7af8c450..20e14f37d5 100644 --- a/libs/ardour/ardour/session_configuration.h +++ b/libs/ardour/ardour/session_configuration.h @@ -30,7 +30,7 @@ public: SessionConfiguration (); void map_parameters (sigc::slot<void, std::string>); - int set_state (XMLNode const &); + int set_state (XMLNode const &, int version = 3000); XMLNode& get_state (); XMLNode& get_variables (); void set_variables (XMLNode const &); diff --git a/libs/ardour/ardour/session_metadata.h b/libs/ardour/ardour/session_metadata.h index cfa1fb6f29..7813788e55 100644 --- a/libs/ardour/ardour/session_metadata.h +++ b/libs/ardour/ardour/session_metadata.h @@ -107,7 +107,7 @@ class SessionMetadata : public PBD::StatefulDestructible /*** Serialization ***/ XMLNode & get_state (); - int set_state (const XMLNode &); + int set_state (const XMLNode &, int version = 3000); private: diff --git a/libs/ardour/ardour/smf_source.h b/libs/ardour/ardour/smf_source.h index 993a340a70..3c6364532a 100644 --- a/libs/ardour/ardour/smf_source.h +++ b/libs/ardour/ardour/smf_source.h @@ -58,7 +58,7 @@ public: void mark_streaming_write_completed (); XMLNode& get_state (); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); void load_model (bool lock=true, bool force_reload=false); void destroy_model (); diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h index ae581f760d..c34c5a9158 100644 --- a/libs/ardour/ardour/source.h +++ b/libs/ardour/ardour/source.h @@ -76,8 +76,8 @@ class Source : public SessionObject, public boost::noncopyable virtual void session_saved() {} XMLNode& get_state (); - int set_state (const XMLNode&); - + int set_state (const XMLNode&, int version = 3000); + bool destructive() const { return (_flags & Destructive); } bool writable () const { return (_flags & Writable); } virtual bool set_destructive (bool /*yn*/) { return false; } diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h index 69b7198408..742919c77a 100644 --- a/libs/ardour/ardour/tempo.h +++ b/libs/ardour/ardour/tempo.h @@ -212,7 +212,7 @@ class TempoMap : public PBD::StatefulDestructible void set_length (nframes_t frames); XMLNode& get_state (void); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version = 3000); void dump (std::ostream&) const; void clear (); diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h index 1b191a1d3e..74cbe399df 100644 --- a/libs/ardour/ardour/track.h +++ b/libs/ardour/ardour/track.h @@ -82,7 +82,7 @@ class Track : public Route XMLNode& get_state(); XMLNode& get_template(); - virtual int set_state(const XMLNode& node) = 0; + virtual int set_state (const XMLNode&, int version = 3000) = 0; static void zero_diskstream_id_in_xml (XMLNode&); boost::shared_ptr<PBD::Controllable> rec_enable_control() { return _rec_enable_control; } @@ -96,7 +96,7 @@ class Track : public Route sigc::signal<void> FreezeChange; protected: - Track (Session& sess, const XMLNode& node, DataType default_type = DataType::AUDIO); + Track (Session& sess, const XMLNode& node, int, DataType default_type = DataType::AUDIO); virtual XMLNode& state (bool full) = 0; diff --git a/libs/ardour/ardour/user_bundle.h b/libs/ardour/ardour/user_bundle.h index fa37392fc0..f590ec1ebe 100644 --- a/libs/ardour/ardour/user_bundle.h +++ b/libs/ardour/ardour/user_bundle.h @@ -38,7 +38,7 @@ class UserBundle : public Bundle, public PBD::Stateful { XMLNode& get_state (); private: - int set_state (XMLNode const &); + int set_state (XMLNode const &, int version = 3000); }; } diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 55664eb352..bb0b715f3b 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -1909,7 +1909,7 @@ AudioDiskstream::get_state () } int -AudioDiskstream::set_state (const XMLNode& node) +AudioDiskstream::set_state (const XMLNode& node, int version) { const XMLProperty* prop; XMLNodeList nlist = node.children(); diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc index a140d19da1..812aa8783b 100644 --- a/libs/ardour/audio_playlist.cc +++ b/libs/ardour/audio_playlist.cc @@ -558,7 +558,7 @@ AudioPlaylist::crossfade_invalidated (boost::shared_ptr<Region> r) } int -AudioPlaylist::set_state (const XMLNode& node) +AudioPlaylist::set_state (const XMLNode& node, int version) { XMLNode *child; XMLNodeList nlist; diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index 1d4412b950..600cad6aa2 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -56,10 +56,10 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode use_new_diskstream (); } -AudioTrack::AudioTrack (Session& sess, const XMLNode& node) - : Track (sess, node) +AudioTrack::AudioTrack (Session& sess, const XMLNode& node, int version) + : Track (sess, node, version) { - _set_state (node, false); + _set_state (node, version, false); } AudioTrack::~AudioTrack () @@ -233,19 +233,19 @@ AudioTrack::audio_diskstream() const } int -AudioTrack::set_state (const XMLNode& node) +AudioTrack::set_state (const XMLNode& node, int version) { - return _set_state (node, true); + return _set_state (node, version, true); } int -AudioTrack::_set_state (const XMLNode& node, bool call_base) +AudioTrack::_set_state (const XMLNode& node, int version, bool call_base) { const XMLProperty *prop; XMLNodeConstIterator iter; if (call_base) { - if (Route::_set_state (node, call_base)) { + if (Route::_set_state (node, version, call_base)) { return -1; } } diff --git a/libs/ardour/audio_track_importer.cc b/libs/ardour/audio_track_importer.cc index 364d681217..146722b3c0 100644 --- a/libs/ardour/audio_track_importer.cc +++ b/libs/ardour/audio_track_importer.cc @@ -290,7 +290,7 @@ AudioTrackImporter::_move () XMLNode routes ("Routes"); routes.add_child_copy (xml_track); - session.load_routes (routes); + session.load_routes (routes, 3000); } bool diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc index 0412ee0966..5430d300fb 100644 --- a/libs/ardour/audiofilesource.cc +++ b/libs/ardour/audiofilesource.cc @@ -258,7 +258,7 @@ AudioFileSource::get_state () } int -AudioFileSource::set_state (const XMLNode& node) +AudioFileSource::set_state (const XMLNode& node, int version) { if (Source::set_state (node)) { return -1; diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index 38fede7c51..47dfc6c902 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -751,7 +751,7 @@ AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool sen } int -AudioRegion::set_state (const XMLNode& node) +AudioRegion::set_state (const XMLNode& node, int version) { /* Region::set_state() calls the virtual set_live_state(), which will get us back to AudioRegion::set_live_state() diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index f9864d69b3..d50ad0c6b7 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -118,7 +118,7 @@ AudioSource::get_state () } int -AudioSource::set_state (const XMLNode& node) +AudioSource::set_state (const XMLNode& node, int version) { const XMLProperty* prop; diff --git a/libs/ardour/automation_list.cc b/libs/ardour/automation_list.cc index 2f06f267c1..be3c38f29b 100644 --- a/libs/ardour/automation_list.cc +++ b/libs/ardour/automation_list.cc @@ -352,7 +352,7 @@ AutomationList::deserialize_events (const XMLNode& node) } int -AutomationList::set_state (const XMLNode& node) +AutomationList::set_state (const XMLNode& node, int version) { XMLNodeList nlist = node.children(); XMLNode* nsos; diff --git a/libs/ardour/control_protocol_manager.cc b/libs/ardour/control_protocol_manager.cc index 18e6534c84..8546a41e66 100644 --- a/libs/ardour/control_protocol_manager.cc +++ b/libs/ardour/control_protocol_manager.cc @@ -288,7 +288,7 @@ ControlProtocolManager::cpi_by_name (string name) } int -ControlProtocolManager::set_state (const XMLNode& node) +ControlProtocolManager::set_state (const XMLNode& node, int version) { XMLNodeList clist; XMLNodeConstIterator citer; diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc index f12b32228d..65ad1e25fb 100644 --- a/libs/ardour/crossfade.cc +++ b/libs/ardour/crossfade.cc @@ -720,7 +720,7 @@ Crossfade::get_state () } int -Crossfade::set_state (const XMLNode& node) +Crossfade::set_state (const XMLNode& node, int version) { XMLNodeConstIterator i; XMLNodeList children; diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc index b132a48960..5f264c5b7e 100644 --- a/libs/ardour/delivery.cc +++ b/libs/ardour/delivery.cc @@ -372,7 +372,7 @@ Delivery::state (bool full_state) } int -Delivery::set_state (const XMLNode& node) +Delivery::set_state (const XMLNode& node, int version) { const XMLProperty* prop; diff --git a/libs/ardour/file_source.cc b/libs/ardour/file_source.cc index f5b06ee046..22e9061d9c 100644 --- a/libs/ardour/file_source.cc +++ b/libs/ardour/file_source.cc @@ -104,7 +104,7 @@ FileSource::init (const ustring& pathstr, bool must_exist) } int -FileSource::set_state (const XMLNode& node) +FileSource::set_state (const XMLNode& node, int version) { const XMLProperty* prop; diff --git a/libs/ardour/internal_return.cc b/libs/ardour/internal_return.cc index b9efaf9a18..9f828ab47b 100644 --- a/libs/ardour/internal_return.cc +++ b/libs/ardour/internal_return.cc @@ -131,7 +131,7 @@ InternalReturn::get_state() } int -InternalReturn::set_state (const XMLNode& node) +InternalReturn::set_state (const XMLNode& node, int version) { return Return::set_state (node); } diff --git a/libs/ardour/internal_send.cc b/libs/ardour/internal_send.cc index 7d1f316c78..abc6ced05c 100644 --- a/libs/ardour/internal_send.cc +++ b/libs/ardour/internal_send.cc @@ -171,7 +171,7 @@ InternalSend::get_state() } int -InternalSend::set_state (const XMLNode& node) +InternalSend::set_state (const XMLNode& node, int version) { const XMLProperty* prop; diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index 9811cfed3a..f49692a910 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -515,8 +515,14 @@ IO::state (bool /*full_state*/) } int -IO::set_state (const XMLNode& node) +IO::set_state (const XMLNode& node, int version) { + /* callers for version < 3000 need to call set_state_2X directly, as A3 IOs + * are input OR output, not both, so the direction needs to be specified + * by the caller. + */ + assert (version >= 3000); + const XMLProperty* prop; XMLNodeConstIterator iter; LocaleGuard lg (X_("POSIX")); @@ -547,19 +553,21 @@ IO::set_state (const XMLNode& node) _direction = (Direction) string_2_enum (prop->value(), _direction); } - if (create_ports (node)) { + if (create_ports (node, version)) { return -1; } if (connecting_legal) { - if (make_connections (node)) { + if (make_connections (node, version, false)) { return -1; } } else { pending_state_node = new XMLNode (node); + pending_state_node_version = version; + pending_state_node_in = false; connection_legal_c = ConnectingLegal.connect (mem_fun (*this, &IO::connecting_became_legal)); } @@ -568,6 +576,58 @@ IO::set_state (const XMLNode& node) } int +IO::set_state_2X (const XMLNode& node, int version, bool in) +{ + const XMLProperty* prop; + XMLNodeConstIterator iter; + LocaleGuard lg (X_("POSIX")); + + /* force use of non-localized representation of decimal point, + since we use it a lot in XML files and so forth. + */ + + if (node.name() != state_node_name) { + error << string_compose(_("incorrect XML node \"%1\" passed to IO object"), node.name()) << endmsg; + return -1; + } + + if ((prop = node.property ("name")) != 0) { + set_name (prop->value()); + } + + if ((prop = node.property (X_("default-type"))) != 0) { + _default_type = DataType(prop->value()); + assert(_default_type != DataType::NIL); + } + + if ((prop = node.property ("id")) != 0) { + _id = prop->value (); + } + + _direction = in ? Input : Output; + + if (create_ports (node, version)) { + return -1; + } + + if (connecting_legal) { + + if (make_connections_2X (node, version, in)) { + return -1; + } + + } else { + + pending_state_node = new XMLNode (node); + pending_state_node_version = version; + pending_state_node_in = in; + connection_legal_c = ConnectingLegal.connect (mem_fun (*this, &IO::connecting_became_legal)); + } + + return 0; +} + +int IO::connecting_became_legal () { int ret; @@ -576,7 +636,7 @@ IO::connecting_became_legal () connection_legal_c.disconnect (); - ret = make_connections (*pending_state_node); + ret = make_connections (*pending_state_node, pending_state_node_version, pending_state_node_in); delete pending_state_node; pending_state_node = 0; @@ -679,8 +739,36 @@ IO::find_possible_bundle (const string &desired_name) } int -IO::get_port_counts (const XMLNode& node, ChanCount& n, boost::shared_ptr<Bundle>& c) +IO::get_port_counts_2X (XMLNode const & node, int version, ChanCount& n, boost::shared_ptr<Bundle>& c) +{ + XMLProperty const * prop; + XMLNodeList children = node.children (); + + uint32_t n_audio = 0; + + for (XMLNodeIterator i = children.begin(); i != children.end(); ++i) { + + if ((prop = node.property ("inputs")) != 0 && _direction == Input) { + n_audio = count (prop->value().begin(), prop->value().end(), '{'); + } else if ((prop = node.property ("outputs")) != 0 && _direction == Output) { + n_audio = count (prop->value().begin(), prop->value().end(), '{'); + } + } + + ChanCount cnt; + cnt.set_audio (n_audio); + n = ChanCount::max (n, cnt); + + return 0; +} + +int +IO::get_port_counts (const XMLNode& node, int version, ChanCount& n, boost::shared_ptr<Bundle>& c) { + if (version < 3000) { + return get_port_counts_2X (node, version, n, c); + } + XMLProperty const * prop; XMLNodeConstIterator iter; uint32_t n_audio = 0; @@ -728,13 +816,13 @@ IO::get_port_counts (const XMLNode& node, ChanCount& n, boost::shared_ptr<Bundle } int -IO::create_ports (const XMLNode& node) +IO::create_ports (const XMLNode& node, int version) { ChanCount n; boost::shared_ptr<Bundle> c; - - get_port_counts (node, n, c); - + + get_port_counts (node, version, n, c); + if (ensure_ports (n, true, true, this)) { error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg; return -1; @@ -746,8 +834,12 @@ IO::create_ports (const XMLNode& node) } int -IO::make_connections (const XMLNode& node) +IO::make_connections (const XMLNode& node, int version, bool in) { + if (version < 3000) { + return make_connections_2X (node, version, in); + } + const XMLProperty* prop; for (XMLNodeConstIterator i = node.children().begin(); i != node.children().end(); ++i) { @@ -798,6 +890,101 @@ IO::make_connections (const XMLNode& node) return 0; } + +int +IO::make_connections_2X (const XMLNode& node, int version, bool in) +{ + const XMLProperty* prop; + + /* XXX: bundles ("connections" as was) */ + + if ((prop = node.property ("inputs")) != 0 && in) { + + string::size_type ostart = 0; + string::size_type start = 0; + string::size_type end = 0; + int i = 0; + int n; + vector<string> ports; + + string const str = prop->value (); + + while ((start = str.find_first_of ('{', ostart)) != string::npos) { + start += 1; + + if ((end = str.find_first_of ('}', start)) == string::npos) { + error << string_compose(_("IO: badly formed string in XML node for inputs \"%1\""), str) << endmsg; + return -1; + } + + if ((n = parse_io_string (str.substr (start, end - start), ports)) < 0) { + error << string_compose(_("bad input string in XML node \"%1\""), str) << endmsg; + + return -1; + + } else if (n > 0) { + + + for (int x = 0; x < n; ++x) { + /* XXX: this is a bit of a hack; need to check if it's always valid */ + string::size_type const p = ports[x].find ("/out"); + if (p != string::npos) { + ports[x].replace (p, 4, "/audio_out"); + } + nth(i)->connect (ports[x]); + } + } + + ostart = end+1; + i++; + } + + } + + if ((prop = node.property ("outputs")) != 0 && !in) { + + string::size_type ostart = 0; + string::size_type start = 0; + string::size_type end = 0; + int i = 0; + int n; + vector<string> ports; + + string const str = prop->value (); + + while ((start = str.find_first_of ('{', ostart)) != string::npos) { + start += 1; + + if ((end = str.find_first_of ('}', start)) == string::npos) { + error << string_compose(_("IO: badly formed string in XML node for outputs \"%1\""), str) << endmsg; + return -1; + } + + if ((n = parse_io_string (str.substr (start, end - start), ports)) < 0) { + error << string_compose(_("IO: bad output string in XML node \"%1\""), str) << endmsg; + + return -1; + + } else if (n > 0) { + + for (int x = 0; x < n; ++x) { + /* XXX: this is a bit of a hack; need to check if it's always valid */ + string::size_type const p = ports[x].find ("/in"); + if (p != string::npos) { + ports[x].replace (p, 3, "/audio_in"); + } + nth(i)->connect (ports[x]); + } + } + + ostart = end+1; + i++; + } + } + + return 0; +} + int IO::set_ports (const string& str) { diff --git a/libs/ardour/io_processor.cc b/libs/ardour/io_processor.cc index af07f7242a..2f42c724bf 100644 --- a/libs/ardour/io_processor.cc +++ b/libs/ardour/io_processor.cc @@ -147,7 +147,7 @@ IOProcessor::state (bool full_state) } int -IOProcessor::set_state (const XMLNode& node) +IOProcessor::set_state (const XMLNode& node, int version) { const XMLProperty *prop; const XMLNode *io_node = 0; diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc index 70a8390de1..6e2acfbe09 100644 --- a/libs/ardour/ladspa_plugin.cc +++ b/libs/ardour/ladspa_plugin.cc @@ -378,8 +378,12 @@ LadspaPlugin::save_preset (string name) } int -LadspaPlugin::set_state(const XMLNode& node) +LadspaPlugin::set_state (const XMLNode& node, int version) { + if (version < 3000) { + return set_state_2X (node, version); + } + XMLNodeList nodes; XMLProperty *prop; XMLNodeConstIterator iter; @@ -389,6 +393,9 @@ LadspaPlugin::set_state(const XMLNode& node) uint32_t port_id; LocaleGuard lg (X_("POSIX")); + cout << "LADSPA Plugin set state " << version << "\n"; + cout << "- node " << node.name() << "\n"; + if (node.name() != state_node_name()) { error << _("Bad node sent to LadspaPlugin::set_state") << endmsg; return -1; @@ -423,6 +430,54 @@ LadspaPlugin::set_state(const XMLNode& node) } int +LadspaPlugin::set_state_2X (const XMLNode& node, int version) +{ + XMLNodeList nodes; + XMLProperty *prop; + XMLNodeConstIterator iter; + XMLNode *child; + const char *port; + const char *data; + uint32_t port_id; + LocaleGuard lg (X_("POSIX")); + + cout << "LADSPA Plugin set state " << version << "\n"; + cout << "- node " << node.name() << "\n"; + + if (node.name() != state_node_name()) { + error << _("Bad node sent to LadspaPlugin::set_state") << endmsg; + return -1; + } + + nodes = node.children ("port"); + + for(iter = nodes.begin(); iter != nodes.end(); ++iter){ + + child = *iter; + + if ((prop = child->property("number")) != 0) { + port = prop->value().c_str(); + } else { + warning << _("LADSPA: no ladspa port number") << endmsg; + continue; + } + if ((prop = child->property("value")) != 0) { + data = prop->value().c_str(); + } else { + warning << _("LADSPA: no ladspa port data") << endmsg; + continue; + } + + sscanf (port, "%" PRIu32, &port_id); + set_parameter (port_id, atof(data)); + } + + latency_compute_run (); + + return 0; +} + +int LadspaPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc) const { LADSPA_PortRangeHint prh; diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc index 4db398e534..5fb0442eba 100644 --- a/libs/ardour/location.cc +++ b/libs/ardour/location.cc @@ -59,7 +59,7 @@ Location::Location (const Location& other) _locked = false; } -Location::Location (const XMLNode& node) +Location::Location (const XMLNode& node, int version) { if (set_state (node)) { throw failed_constructor (); @@ -347,7 +347,7 @@ Location::get_state (void) } int -Location::set_state (const XMLNode& node) +Location::set_state (const XMLNode& node, int version) { const XMLProperty *prop; @@ -674,7 +674,7 @@ Locations::get_state () } int -Locations::set_state (const XMLNode& node) +Locations::set_state (const XMLNode& node, int version) { XMLNodeList nlist; XMLNodeConstIterator niter; diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index dd221e103b..4cae900074 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -1381,7 +1381,7 @@ MidiDiskstream::get_state () } int -MidiDiskstream::set_state (const XMLNode& node) +MidiDiskstream::set_state (const XMLNode& node, int version) { const XMLProperty* prop; XMLNodeList nlist = node.children(); diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc index fb09cda60f..df34d13a24 100644 --- a/libs/ardour/midi_model.cc +++ b/libs/ardour/midi_model.cc @@ -260,7 +260,7 @@ MidiModel::DeltaCommand::unmarshal_note(XMLNode *xml_note) #define DELTA_COMMAND_ELEMENT "DeltaCommand" int -MidiModel::DeltaCommand::set_state(const XMLNode& delta_command) +MidiModel::DeltaCommand::set_state (const XMLNode& delta_command, int version) { if (delta_command.name() != string(DELTA_COMMAND_ELEMENT)) { return 1; @@ -646,7 +646,7 @@ MidiModel::DiffCommand::unmarshal_change(XMLNode *xml_change) } int -MidiModel::DiffCommand::set_state(const XMLNode& diff_command) +MidiModel::DiffCommand::set_state(const XMLNode& diff_command, int version) { if (diff_command.name() != string(DIFF_COMMAND_ELEMENT)) { return 1; diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc index cc72a630ba..b0fd5de24e 100644 --- a/libs/ardour/midi_playlist.cc +++ b/libs/ardour/midi_playlist.cc @@ -187,7 +187,7 @@ MidiPlaylist::check_dependents (boost::shared_ptr<Region> /*r*/, bool /*norefres int -MidiPlaylist::set_state (const XMLNode& node) +MidiPlaylist::set_state (const XMLNode& node, int version) { in_set_state++; freeze (); diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc index 87c7d656e7..f22a1994bf 100644 --- a/libs/ardour/midi_region.cc +++ b/libs/ardour/midi_region.cc @@ -285,7 +285,7 @@ MidiRegion::set_live_state (const XMLNode& node, Change& what_changed, bool send } int -MidiRegion::set_state (const XMLNode& node) +MidiRegion::set_state (const XMLNode& node, int version) { /* Region::set_state() calls the virtual set_live_state(), which will get us back to AudioRegion::set_live_state() diff --git a/libs/ardour/midi_source.cc b/libs/ardour/midi_source.cc index f92d6a2a4f..e90e90aa32 100644 --- a/libs/ardour/midi_source.cc +++ b/libs/ardour/midi_source.cc @@ -94,7 +94,7 @@ MidiSource::get_state () } int -MidiSource::set_state (const XMLNode& node) +MidiSource::set_state (const XMLNode& node, int version) { const XMLProperty* prop; diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index ce466343ea..6f036f803c 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -66,8 +66,8 @@ MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mo _mode = mode; } -MidiTrack::MidiTrack (Session& sess, const XMLNode& node) - : Track (sess, node, DataType::MIDI ) +MidiTrack::MidiTrack (Session& sess, const XMLNode& node, int version) + : Track (sess, node, version, DataType::MIDI) , _immediate_events(1024) // FIXME: size? , _step_edit_ring_buffer(64) // FIXME: size? , _note_mode(Sustained) @@ -75,7 +75,7 @@ MidiTrack::MidiTrack (Session& sess, const XMLNode& node) , _default_channel (0) , _midi_thru (true) { - _set_state(node, false); + _set_state (node, version, false); } MidiTrack::~MidiTrack () @@ -155,18 +155,18 @@ MidiTrack::midi_diskstream() const } int -MidiTrack::set_state (const XMLNode& node) +MidiTrack::set_state (const XMLNode& node, int version) { - return _set_state (node, true); + return _set_state (node, version, true); } int -MidiTrack::_set_state (const XMLNode& node, bool call_base) +MidiTrack::_set_state (const XMLNode& node, int version, bool call_base) { const XMLProperty *prop; XMLNodeConstIterator iter; - if (Route::_set_state (node, call_base)) { + if (Route::_set_state (node, version, call_base)) { return -1; } diff --git a/libs/ardour/mute_master.cc b/libs/ardour/mute_master.cc index 9aea8f981a..dd507aaceb 100644 --- a/libs/ardour/mute_master.cc +++ b/libs/ardour/mute_master.cc @@ -103,7 +103,7 @@ MuteMaster::get_value () const } int -MuteMaster::set_state (const XMLNode& node) +MuteMaster::set_state (const XMLNode& node, int version) { const XMLProperty* prop; diff --git a/libs/ardour/named_selection.cc b/libs/ardour/named_selection.cc index d2cf1c03a8..0c6b3699b6 100644 --- a/libs/ardour/named_selection.cc +++ b/libs/ardour/named_selection.cc @@ -106,7 +106,7 @@ NamedSelection::~NamedSelection () } int -NamedSelection::set_state (const XMLNode& /*node*/) +NamedSelection::set_state (const XMLNode& /*node*/, int /*version*/) { return 0; } diff --git a/libs/ardour/panner.cc b/libs/ardour/panner.cc index a8d30954cc..993cbe39f8 100644 --- a/libs/ardour/panner.cc +++ b/libs/ardour/panner.cc @@ -162,7 +162,7 @@ StreamPanner::set_position (float xpos, float ypos, float zpos, bool link_call) } int -StreamPanner::set_state (const XMLNode& node) +StreamPanner::set_state (const XMLNode& node, int version) { const XMLProperty* prop; XMLNodeConstIterator iter; @@ -485,7 +485,7 @@ EqualPowerStereoPanner::state (bool /*full_state*/) } int -EqualPowerStereoPanner::set_state (const XMLNode& node) +EqualPowerStereoPanner::set_state (const XMLNode& node, int version) { const XMLProperty* prop; float pos; @@ -673,7 +673,7 @@ Multi2dPanner::state (bool /*full_state*/) } int -Multi2dPanner::set_state (const XMLNode& node) +Multi2dPanner::set_state (const XMLNode& node, int version) { const XMLProperty* prop; float newx,newy; @@ -830,6 +830,8 @@ Panner::reset (uint32_t nouts, uint32_t npans) bool changed = false; bool do_not_and_did_not_need_panning = ((nouts < 2) && (outputs.size() < 2)); + cout << "Reset panner for " << nouts << " " << npans << "\n"; + /* if new and old config don't need panning, or if the config hasn't changed, we're done. */ @@ -1085,7 +1087,7 @@ Panner::state (bool full) } int -Panner::set_state (const XMLNode& node) +Panner::set_state (const XMLNode& node, int version) { XMLNodeList nlist; XMLNodeConstIterator niter; diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index ce9f0335b8..aebcb59f3d 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -1789,7 +1789,7 @@ Playlist::mark_session_dirty () } int -Playlist::set_state (const XMLNode& node) +Playlist::set_state (const XMLNode& node, int version) { XMLNode *child; XMLNodeList nlist; diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index 1fff176713..14ea464555 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -81,12 +81,12 @@ PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug) ProcessorCreated (this); /* EMIT SIGNAL */ } -PluginInsert::PluginInsert (Session& s, const XMLNode& node) +PluginInsert::PluginInsert (Session& s, const XMLNode& node, int version) : Processor (s, "unnamed plugin insert"), _signal_analysis_collected_nframes(0), _signal_analysis_collect_nframes_max(0) { - if (set_state (node)) { + if (set_state (node, version)) { throw failed_constructor(); } @@ -716,7 +716,7 @@ PluginInsert::state (bool full) } int -PluginInsert::set_state(const XMLNode& node) +PluginInsert::set_state(const XMLNode& node, int version) { XMLNodeList nlist = node.children(); XMLNodeIterator niter; @@ -730,6 +730,7 @@ PluginInsert::set_state(const XMLNode& node) } if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */ + cout << "- LADSPA\n"; type = ARDOUR::LADSPA; } else if (prop->value() == X_("lv2")) { type = ARDOUR::LV2; @@ -743,6 +744,7 @@ PluginInsert::set_state(const XMLNode& node) } prop = node.property ("unique-id"); + cout << "- ID " << prop->value() << "\n"; if (prop == 0) { error << _("Plugin has no unique ID field") << endmsg; return -1; @@ -777,7 +779,7 @@ PluginInsert::set_state(const XMLNode& node) for (niter = nlist.begin(); niter != nlist.end(); ++niter) { if ((*niter)->name() == plugin->state_node_name()) { for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { - (*i)->set_state (**niter); + (*i)->set_state (**niter, version); } break; } @@ -792,8 +794,8 @@ PluginInsert::set_state(const XMLNode& node) break; } } - - Processor::set_state (*insert_node); + + Processor::set_state (*insert_node, version); /* look for port automation node */ diff --git a/libs/ardour/port_insert.cc b/libs/ardour/port_insert.cc index 61ae4d37e8..04a145aa52 100644 --- a/libs/ardour/port_insert.cc +++ b/libs/ardour/port_insert.cc @@ -48,12 +48,12 @@ PortInsert::PortInsert (Session& s, boost::shared_ptr<MuteMaster> mm) ProcessorCreated (this); /* EMIT SIGNAL */ } -PortInsert::PortInsert (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLNode& node) +PortInsert::PortInsert (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLNode& node, int version) : IOProcessor (s, true, true, "unnamed port insert") , _out (new Delivery (s, _output, mm, _name, Delivery::Insert)) { - if (set_state (node)) { + if (set_state (node, version)) { throw failed_constructor(); } @@ -104,7 +104,7 @@ PortInsert::state (bool full) } int -PortInsert::set_state(const XMLNode& node) +PortInsert::set_state (const XMLNode& node, int version) { XMLNodeList nlist = node.children(); XMLNodeIterator niter; diff --git a/libs/ardour/processor.cc b/libs/ardour/processor.cc index c8f7a136bb..e1db982fe1 100644 --- a/libs/ardour/processor.cc +++ b/libs/ardour/processor.cc @@ -145,8 +145,43 @@ Processor::state (bool full_state) } int -Processor::set_state (const XMLNode& node) +Processor::set_state_2X (const XMLNode & node, int version) { + XMLProperty const * prop; + + XMLNodeList children = node.children (); + + for (XMLNodeIterator i = children.begin(); i != children.end(); ++i) { + + if ((*i)->name() == X_("IO")) { + + if ((prop = (*i)->property ("name")) != 0) { + set_name (prop->value ()); + } + + if ((prop = (*i)->property ("id")) != 0) { + _id = prop->value (); + } + + if ((prop = (*i)->property ("active")) != 0) { + if (_active != string_is_affirmative (prop->value())) { + _active = !_active; + ActiveChanged (); /* EMIT_SIGNAL */ + } + } + } + } + + return 0; +} + +int +Processor::set_state (const XMLNode& node, int version) +{ + if (version < 3000) { + return set_state_2X (node, version); + } + const XMLProperty *prop; const XMLProperty *legacy_active = 0; diff --git a/libs/ardour/rc_configuration.cc b/libs/ardour/rc_configuration.cc index ba9389eec8..afa9a2a4c3 100644 --- a/libs/ardour/rc_configuration.cc +++ b/libs/ardour/rc_configuration.cc @@ -240,7 +240,7 @@ RCConfiguration::get_variables () } int -RCConfiguration::set_state (const XMLNode& root) +RCConfiguration::set_state (const XMLNode& root, int version) { if (root.name() != "Ardour") { return -1; diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index e1bc5c0883..244312bc0a 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -1339,7 +1339,7 @@ Region::set_live_state (const XMLNode& node, Change& what_changed, bool send) } int -Region::set_state (const XMLNode& node) +Region::set_state (const XMLNode& node, int version) { const XMLProperty *prop; Change what_changed = Change (0); diff --git a/libs/ardour/return.cc b/libs/ardour/return.cc index 858d658c9c..69aa2f700e 100644 --- a/libs/ardour/return.cc +++ b/libs/ardour/return.cc @@ -89,7 +89,7 @@ Return::state(bool full) } int -Return::set_state(const XMLNode& node) +Return::set_state (const XMLNode& node, int version) { XMLNodeList nlist = node.children(); XMLNodeIterator niter; diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 95b651b6ca..7e453653dc 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -96,7 +96,7 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type) _meter_connection = Metering::connect (mem_fun (*this, &Route::meter)); } -Route::Route (Session& sess, const XMLNode& node, DataType default_type) +Route::Route (Session& sess, const XMLNode& node, int version, DataType default_type) : SessionObject (sess, "toBeReset") , AutomatableControls (sess) , _solo_control (new SoloControllable (X_("solo"), *this)) @@ -105,7 +105,7 @@ Route::Route (Session& sess, const XMLNode& node, DataType default_type) { init (); - _set_state (node, false); + _set_state (node, version, false); /* now that we have _meter, its safe to connect to this */ @@ -684,7 +684,6 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::ite // Set up processor list channels. This will set processor->[input|output]_streams(), // configure redirect ports properly, etc. - if (configure_processors_unlocked (err)) { ProcessorList::iterator ploc = loc; --ploc; @@ -831,6 +830,64 @@ Route::add_processor_from_xml (const XMLNode& node, ProcessorList::iterator iter } } + +bool +Route::add_processor_from_xml_2X (const XMLNode& node, int version, ProcessorList::iterator iter) +{ + const XMLProperty *prop; + + try { + boost::shared_ptr<Processor> processor; + + if (node.name() == "Insert") { + + if ((prop = node.property ("type")) != 0) { + + if (prop->value() == "ladspa" || prop->value() == "Ladspa" || + prop->value() == "lv2" || + prop->value() == "vst" || + prop->value() == "audiounit") { + + processor.reset (new PluginInsert (_session, node, version)); + + } else { + + processor.reset (new PortInsert (_session, _mute_master, node, version)); + } + + } + + } else if (node.name() == "Send") { + + processor.reset (new Send (_session, _mute_master, node, version)); + + } else { + + error << string_compose(_("unknown Processor type \"%1\"; ignored"), node.name()) << endmsg; + return false; + } + + if (iter == _processors.end() && processor->visible() && !_processors.empty()) { + /* check for invisible processors stacked at the end and leave them there */ + ProcessorList::iterator p; + p = _processors.end(); + --p; + while (!(*p)->visible() && p != _processors.begin()) { + --p; + } + ++p; + iter = p; + } + + return (add_processor (processor, iter) == 0); + } + + catch (failed_constructor &err) { + warning << _("processor could not be created. Ignored.") << endmsg; + return false; + } +} + int Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor> before, ProcessorStreams* err) { @@ -1326,6 +1383,7 @@ Route::configure_processors_unlocked (ProcessorStreams* err) uint32_t index = 0; for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++index) { + if ((*p)->can_support_io_configuration(in, out)) { configuration.push_back(make_pair(in, out)); in = out; @@ -1600,15 +1658,18 @@ Route::state(bool full_state) } int -Route::set_state (const XMLNode& node) +Route::set_state (const XMLNode& node, int version) { - return _set_state (node, true); + return _set_state (node, version, true); } int -Route::_set_state (const XMLNode& node, bool /*call_base*/) +Route::_set_state (const XMLNode& node, int version, bool /*call_base*/) { - + if (version < 3000) { + return _set_state_2X (node, version); + } + XMLNodeList nlist; XMLNodeConstIterator niter; XMLNode *child; @@ -1773,6 +1834,200 @@ Route::_set_state (const XMLNode& node, bool /*call_base*/) return 0; } +int +Route::_set_state_2X (const XMLNode& node, int version) +{ + XMLNodeList nlist; + XMLNodeConstIterator niter; + XMLNode *child; + XMLPropertyList plist; + const XMLProperty *prop; + + /* 2X things which still remain to be handled: + * default-type + * muted + * mute-affects-pre-fader + * mute-affects-post-fader + * mute-affects-control-outs + * mute-affects-main-outs + * automation + * controlouts + */ + + if (node.name() != "Route") { + error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg; + return -1; + } + + if ((prop = node.property (X_("flags"))) != 0) { + _flags = Flag (string_2_enum (prop->value(), _flags)); + } else { + _flags = Flag (0); + } + + /* add standard processors */ + + _meter.reset (new PeakMeter (_session)); + add_processor (_meter, PreFader); + + if (_flags & ControlOut) { + /* where we listen to tracks */ + _intreturn.reset (new InternalReturn (_session)); + add_processor (_intreturn, PreFader); + } + + _main_outs.reset (new Delivery (_session, _output, _mute_master, _name, Delivery::Main)); + add_processor (_main_outs, PostFader); + + /* IOs */ + + nlist = node.children (); + for (niter = nlist.begin(); niter != nlist.end(); ++niter) { + + child = *niter; + + if (child->name() == IO::state_node_name) { + _input->set_state_2X (*child, version, true); + _output->set_state_2X (*child, version, false); + + if ((prop = child->property (X_("name"))) != 0) { + set_name (prop->value ()); + } + + if ((prop = child->property (X_("id"))) != 0) { + _id = prop->value (); + } + + if ((prop = child->property (X_("active"))) != 0) { + bool yn = string_is_affirmative (prop->value()); + _active = !yn; // force switch + set_active (yn); + } + } + + /* XXX: panners? */ + } + + if ((prop = node.property (X_("phase-invert"))) != 0) { + set_phase_invert (string_is_affirmative (prop->value())); + } + + if ((prop = node.property (X_("denormal-protection"))) != 0) { + set_denormal_protection (string_is_affirmative (prop->value())); + } + + if ((prop = node.property (X_("soloed"))) != 0) { + bool yn = string_is_affirmative (prop->value()); + + /* XXX force reset of solo status */ + + set_solo (yn, this); + } + + if ((prop = node.property (X_("meter-point"))) != 0) { + _meter_point = MeterPoint (string_2_enum (prop->value (), _meter_point)); + } + + /* XXX: if the route was in both a mix group and an edit group, it'll end up + just in the edit group. */ + + if ((prop = node.property (X_("mix-group"))) != 0) { + RouteGroup* route_group = _session.route_group_by_name(prop->value()); + if (route_group == 0) { + error << string_compose(_("Route %1: unknown route group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg; + } else { + set_route_group (route_group, this); + } + } + + if ((prop = node.property (X_("edit-group"))) != 0) { + RouteGroup* route_group = _session.route_group_by_name(prop->value()); + if (route_group == 0) { + error << string_compose(_("Route %1: unknown route group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg; + } else { + set_route_group (route_group, this); + } + } + + if ((prop = node.property (X_("order-keys"))) != 0) { + + long n; + + string::size_type colon, equal; + string remaining = prop->value(); + + while (remaining.length()) { + + if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) { + error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining) + << endmsg; + } else { + if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) { + error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining) + << endmsg; + } else { + set_order_key (remaining.substr (0, equal), n); + } + } + + colon = remaining.find_first_of (':'); + + if (colon != string::npos) { + remaining = remaining.substr (colon+1); + } else { + break; + } + } + } + + XMLNodeList redirect_nodes; + + for (niter = nlist.begin(); niter != nlist.end(); ++niter){ + + child = *niter; + + if (child->name() == X_("Send") || child->name() == X_("Insert")) { + redirect_nodes.push_back(child); + } + + } + + set_processor_state_2X (redirect_nodes, version); + + for (niter = nlist.begin(); niter != nlist.end(); ++niter){ + child = *niter; + + if (child->name() == X_("Comment")) { + + /* XXX this is a terrible API design in libxml++ */ + + XMLNode *cmt = *(child->children().begin()); + _comment = cmt->content(); + + } else if (child->name() == X_("Extra")) { + + _extra_xml = new XMLNode (*child); + + } else if (child->name() == X_("Controllable") && (prop = child->property("name")) != 0) { + + if (prop->value() == "solo") { + _solo_control->set_state (*child); + _session.add_controllable (_solo_control); + } + + } else if (child->name() == X_("RemoteControl")) { + if ((prop = child->property (X_("id"))) != 0) { + int32_t x; + sscanf (prop->value().c_str(), "%d", &x); + set_remote_control_id (x); + } + + } + } + + return 0; +} + XMLNode& Route::get_processor_state () { @@ -1785,6 +2040,20 @@ Route::get_processor_state () } void +Route::set_processor_state_2X (XMLNodeList const & nList, int version) +{ + /* We don't bother removing existing processors not in nList, as this + method will only be called when creating a Route from scratch, not + for undo purposes. Just put processors in at the appropriate place + in the list. + */ + + for (XMLNodeConstIterator i = nList.begin(); i != nList.end(); ++i) { + add_processor_from_xml_2X (**i, version, _processors.begin ()); + } +} + +void Route::set_processor_state (const XMLNode& node) { const XMLNodeList &nlist = node.children(); diff --git a/libs/ardour/route_group.cc b/libs/ardour/route_group.cc index 5cfc1fb3d0..3d7ac3ef70 100644 --- a/libs/ardour/route_group.cc +++ b/libs/ardour/route_group.cc @@ -136,9 +136,13 @@ RouteGroup::get_state (void) return *node; } -int -RouteGroup::set_state (const XMLNode& node) +int +RouteGroup::set_state (const XMLNode& node, int version) { + if (version < 3000) { + return set_state_2X (node, version); + } + const XMLProperty *prop; if ((prop = node.property ("name")) != 0) { @@ -156,6 +160,28 @@ RouteGroup::set_state (const XMLNode& node) return 0; } +int +RouteGroup::set_state_2X (const XMLNode& node, int version) +{ + XMLProperty const * prop; + + if ((prop = node.property ("name")) != 0) { + _name = prop->value(); + } + + if ((prop = node.property ("flags")) != 0) { + _flags = Flag (string_2_enum (prop->value(), _flags)); + } + + if (node.name() == "MixGroup") { + _properties = Property (Gain | Mute | Solo | RecEnable); + } else if (node.name() == "EditGroup") { + _properties = Property (Select | Edit); + } + + return 0; +} + void RouteGroup::set_active (bool yn, void *src) { diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc index f01512332e..bd9eccaf54 100644 --- a/libs/ardour/send.cc +++ b/libs/ardour/send.cc @@ -46,14 +46,14 @@ Send::Send (Session& s, boost::shared_ptr<MuteMaster> mm, Role r) ProcessorCreated (this); /* EMIT SIGNAL */ } -Send::Send (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLNode& node, Role r) +Send::Send (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLNode& node, int version, Role r) : Delivery (s, mm, "send", r) , _metering (false) { _amp.reset (new Amp (_session, _mute_master)); _meter.reset (new PeakMeter (_session)); - if (set_state (node)) { + if (set_state (node, version)) { throw failed_constructor(); } @@ -150,7 +150,7 @@ Send::state(bool full) } int -Send::set_state(const XMLNode& node) +Send::set_state (const XMLNode& node, int version) { XMLNodeList nlist = node.children(); XMLNodeIterator niter; diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 96bd69eca3..79790b5673 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -2062,8 +2062,8 @@ Session::new_route_from_template (uint32_t how_many, const std::string& template Track::zero_diskstream_id_in_xml (node_copy); try { - shared_ptr<Route> route (XMLRouteFactory (node_copy)); - + shared_ptr<Route> route (XMLRouteFactory (node_copy, 3000)); + if (route == 0) { error << _("Session: cannot create track/bus from template description") << endmsg; goto out; diff --git a/libs/ardour/session_command.cc b/libs/ardour/session_command.cc index af1286e8f2..ffd68bb5a6 100644 --- a/libs/ardour/session_command.cc +++ b/libs/ardour/session_command.cc @@ -170,7 +170,7 @@ Session::GlobalRouteStateCommand::GlobalRouteStateCommand (Session& s, const XML } int -Session::GlobalRouteStateCommand::set_state (const XMLNode& node) +Session::GlobalRouteStateCommand::set_state (const XMLNode& node, int version) { GlobalRouteBooleanState states; XMLNodeList nlist; @@ -483,7 +483,7 @@ Session::GlobalMeteringStateCommand::get_state() } int -Session::GlobalMeteringStateCommand::set_state (const XMLNode& node) +Session::GlobalMeteringStateCommand::set_state (const XMLNode& node, int version) { GlobalRouteBooleanState states; XMLNodeList nlist; diff --git a/libs/ardour/session_configuration.cc b/libs/ardour/session_configuration.cc index 2cae7021e1..c35da62368 100644 --- a/libs/ardour/session_configuration.cc +++ b/libs/ardour/session_configuration.cc @@ -76,7 +76,7 @@ SessionConfiguration::get_variables () int -SessionConfiguration::set_state (XMLNode const& root) +SessionConfiguration::set_state (XMLNode const& root, int version) { if (root.name() != "Ardour") { return -1; diff --git a/libs/ardour/session_metadata.cc b/libs/ardour/session_metadata.cc index e792fd1585..446d944f8a 100644 --- a/libs/ardour/session_metadata.cc +++ b/libs/ardour/session_metadata.cc @@ -163,7 +163,7 @@ SessionMetadata::get_state () } int -SessionMetadata::set_state (const XMLNode & state) +SessionMetadata::set_state (const XMLNode & state, int version) { const XMLNodeList & children = state.children(); ustring name; diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index b85f2ac078..de99558c16 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -1123,7 +1123,7 @@ Session::get_control_protocol_state () } int -Session::set_state (const XMLNode& node) +Session::set_state (const XMLNode& node, int version) { XMLNodeList nlist; XMLNode* child; @@ -1137,6 +1137,10 @@ Session::set_state (const XMLNode& node) return -1; } + if ((prop = node.property ("version")) != 0) { + version = atoi (prop->value ()) * 1000; + } + if ((prop = node.property ("name")) != 0) { _name = prop->value (); } @@ -1205,10 +1209,12 @@ Session::set_state (const XMLNode& node) if (use_config_midi_ports ()) { } - if ((child = find_named_node (node, "Metadata")) == 0) { - warning << _("Session: XML state has no metadata section (2.0 session?)") << endmsg; - } else if (_metadata->set_state (*child)) { - goto out; + if (version >= 3000) { + if ((child = find_named_node (node, "Metadata")) == 0) { + warning << _("Session: XML state has no metadata section") << endmsg; + } else if (_metadata->set_state (*child)) { + goto out; + } } if ((child = find_named_node (node, "Locations")) == 0) { @@ -1270,7 +1276,7 @@ Session::set_state (const XMLNode& node) } else if (load_unused_playlists (*child)) { goto out; } - + if ((child = find_named_node (node, "NamedSelections")) != 0) { if (load_named_selections (*child)) { goto out; @@ -1284,21 +1290,42 @@ Session::set_state (const XMLNode& node) goto out; } - if ((child = find_named_node (node, "Bundles")) == 0) { - warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg; - //goto out; - } else { - /* We can't load Bundles yet as they need to be able - to convert from port names to Port objects, which can't happen until - later */ - _bundle_xml_node = new XMLNode (*child); + if (version >= 3000) { + if ((child = find_named_node (node, "Bundles")) == 0) { + warning << _("Session: XML state has no bundles section") << endmsg; + //goto out; + } else { + /* We can't load Bundles yet as they need to be able + to convert from port names to Port objects, which can't happen until + later */ + _bundle_xml_node = new XMLNode (*child); + } } + + if (version >= 3000) { + + if ((child = find_named_node (node, "RouteGroups")) == 0) { + error << _("Session: XML state has no route groups section") << endmsg; + goto out; + } else if (load_route_groups (*child, version)) { + goto out; + } + + } else if (version < 3000) { + + if ((child = find_named_node (node, "EditGroups")) == 0) { + error << _("Session: XML state has no edit groups section") << endmsg; + goto out; + } else if (load_route_groups (*child, version)) { + goto out; + } - if ((child = find_named_node (node, "RouteGroups")) == 0) { - error << _("Session: XML state has no route groups section") << endmsg; - goto out; - } else if (load_route_groups (*child)) { - goto out; + if ((child = find_named_node (node, "MixGroups")) == 0) { + error << _("Session: XML state has no mix groups section") << endmsg; + goto out; + } else if (load_route_groups (*child, version)) { + goto out; + } } if ((child = find_named_node (node, "TempoMap")) == 0) { @@ -1311,7 +1338,7 @@ Session::set_state (const XMLNode& node) if ((child = find_named_node (node, "Routes")) == 0) { error << _("Session: XML state has no routes section") << endmsg; goto out; - } else if (load_routes (*child)) { + } else if (load_routes (*child, version)) { goto out; } @@ -1336,7 +1363,7 @@ Session::set_state (const XMLNode& node) } int -Session::load_routes (const XMLNode& node) +Session::load_routes (const XMLNode& node, int version) { XMLNodeList nlist; XMLNodeConstIterator niter; @@ -1348,7 +1375,7 @@ Session::load_routes (const XMLNode& node) for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - boost::shared_ptr<Route> route (XMLRouteFactory (**niter)); + boost::shared_ptr<Route> route (XMLRouteFactory (**niter, version)); if (route == 0) { error << _("Session: cannot create Route from XML description.") << endmsg; @@ -1366,7 +1393,7 @@ Session::load_routes (const XMLNode& node) } boost::shared_ptr<Route> -Session::XMLRouteFactory (const XMLNode& node) +Session::XMLRouteFactory (const XMLNode& node, int version) { if (node.name() != "Route") { return boost::shared_ptr<Route> ((Route*) 0); @@ -1385,14 +1412,14 @@ Session::XMLRouteFactory (const XMLNode& node) if (has_diskstream) { if (type == DataType::AUDIO) { - boost::shared_ptr<Route> ret (new AudioTrack (*this, node)); + boost::shared_ptr<Route> ret (new AudioTrack (*this, node, version)); return ret; } else { - boost::shared_ptr<Route> ret (new MidiTrack (*this, node)); + boost::shared_ptr<Route> ret (new MidiTrack (*this, node, version)); return ret; } } else { - boost::shared_ptr<Route> ret (new Route (*this, node)); + boost::shared_ptr<Route> ret (new Route (*this, node, version)); return ret; } } @@ -2053,18 +2080,31 @@ Session::load_bundles (XMLNode const & node) } int -Session::load_route_groups (const XMLNode& node) +Session::load_route_groups (const XMLNode& node, int version) { XMLNodeList nlist = node.children(); XMLNodeConstIterator niter; set_dirty (); - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - if ((*niter)->name() == "RouteGroup") { - RouteGroup* rg = new RouteGroup (*this, ""); - add_route_group (rg); - rg->set_state (**niter); + if (version >= 3000) { + + for (niter = nlist.begin(); niter != nlist.end(); ++niter) { + if ((*niter)->name() == "RouteGroup") { + RouteGroup* rg = new RouteGroup (*this, ""); + add_route_group (rg); + rg->set_state (**niter, version); + } + } + + } else if (version < 3000) { + + for (niter = nlist.begin(); niter != nlist.end(); ++niter) { + if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") { + RouteGroup* rg = new RouteGroup (*this, ""); + add_route_group (rg); + rg->set_state (**niter, version); + } } } diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc index 679f244dbe..358cbb1257 100644 --- a/libs/ardour/smf_source.cc +++ b/libs/ardour/smf_source.cc @@ -329,7 +329,7 @@ SMFSource::get_state () } int -SMFSource::set_state (const XMLNode& node) +SMFSource::set_state (const XMLNode& node, int version) { if (Source::set_state (node)) { return -1; diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc index 45cd1fb904..7ed4e584ce 100644 --- a/libs/ardour/source.cc +++ b/libs/ardour/source.cc @@ -110,7 +110,7 @@ Source::get_state () } int -Source::set_state (const XMLNode& node) +Source::set_state (const XMLNode& node, int version) { const XMLProperty* prop; diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index 623dd21627..c66e0f6f24 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -1500,7 +1500,7 @@ TempoMap::get_state () } int -TempoMap::set_state (const XMLNode& node) +TempoMap::set_state (const XMLNode& node, int version) { { Glib::RWLock::WriterLock lm (lock); diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index ce208769f6..ecd8208282 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -51,8 +51,8 @@ Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, Data _mode = mode; } -Track::Track (Session& sess, const XMLNode& node, DataType default_type) - : Route (sess, node, default_type) +Track::Track (Session& sess, const XMLNode& node, int version, DataType default_type) + : Route (sess, node, version, default_type) , _rec_enable_control (new RecEnableControllable(*this)) { _freeze_record.state = NoFreeze; diff --git a/libs/ardour/user_bundle.cc b/libs/ardour/user_bundle.cc index e2d46ab6e0..73b5960e03 100644 --- a/libs/ardour/user_bundle.cc +++ b/libs/ardour/user_bundle.cc @@ -24,7 +24,7 @@ ARDOUR::UserBundle::UserBundle (XMLNode const & x, bool i) } int -ARDOUR::UserBundle::set_state (XMLNode const & node) +ARDOUR::UserBundle::set_state (XMLNode const & node, int version) { XMLProperty const * name; |