From 55a367837a5770091fa6a46175a30a71d848e98c Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 5 Mar 2009 17:27:05 +0000 Subject: make track templates work, including a fix for the MidiTrack XML constructor git-svn-id: svn://localhost/ardour2/branches/3.0@4735 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/audio_track.h | 1 + libs/ardour/ardour/midi_track.h | 1 + libs/ardour/ardour/track.h | 1 + libs/ardour/audio_track.cc | 49 ++++++++++++++++++++++++++----------- libs/ardour/midi_track.cc | 53 +++++++++++++++++++++++++++------------- libs/ardour/route.cc | 1 - libs/ardour/session.cc | 13 +++++++++- libs/ardour/session_state.cc | 4 ++- libs/ardour/track.cc | 9 ++++++- 9 files changed, 97 insertions(+), 35 deletions(-) diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h index 04dd5f4798..2654b40142 100644 --- a/libs/ardour/ardour/audio_track.h +++ b/libs/ardour/ardour/audio_track.h @@ -71,6 +71,7 @@ class AudioTrack : public Track private: int set_diskstream (boost::shared_ptr, void *); int deprecated_use_diskstream_connections (); + void use_new_diskstream (); void set_state_part_two (); void set_state_part_three (); }; diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h index 9ffa4dcebd..d9cf7989cf 100644 --- a/libs/ardour/ardour/midi_track.h +++ b/libs/ardour/ardour/midi_track.h @@ -99,6 +99,7 @@ private: nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset); int set_diskstream (boost::shared_ptr ds); + void use_new_diskstream (); void set_state_part_two (); void set_state_part_three (); diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h index b11073a99f..581e5fbcac 100644 --- a/libs/ardour/ardour/track.h +++ b/libs/ardour/ardour/track.h @@ -83,6 +83,7 @@ class Track : public Route XMLNode& get_state(); XMLNode& get_template(); virtual int set_state(const XMLNode& node) = 0; + static void zero_diskstream_id_in_xml (XMLNode&); boost::shared_ptr rec_enable_control() { return _rec_enable_control; } diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index bd3402bd0e..330e2ba1b7 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -50,6 +50,22 @@ using namespace PBD; AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode mode) : Track (sess, name, flag, mode) +{ + use_new_diskstream (); +} + +AudioTrack::AudioTrack (Session& sess, const XMLNode& node) + : Track (sess, node) +{ + _set_state (node, false); +} + +AudioTrack::~AudioTrack () +{ +} + +void +AudioTrack::use_new_diskstream () { AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0); @@ -59,27 +75,17 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Recordable); } - if (mode == Destructive) { + if (_mode == Destructive) { dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Destructive); } - boost::shared_ptr ds (new AudioDiskstream (_session, name, dflags)); + boost::shared_ptr ds (new AudioDiskstream (_session, name(), dflags)); _session.add_diskstream (ds); set_diskstream (boost::dynamic_pointer_cast (ds), this); } -AudioTrack::AudioTrack (Session& sess, const XMLNode& node) - : Track (sess, node) -{ - _set_state (node, false); -} - -AudioTrack::~AudioTrack () -{ -} - int AudioTrack::set_mode (TrackMode m) { @@ -265,8 +271,19 @@ AudioTrack::_set_state (const XMLNode& node, bool call_base) } else { PBD::ID id (prop->value()); + PBD::ID zero ("0"); - if (use_diskstream (id)) { + /* this wierd hack is used when creating tracks from a template. there isn't + a particularly good time to interpose between setting the first part of + the track state (notably Route::set_state() and the track mode), and the + second part (diskstream stuff). So, we have a special ID for the diskstream + that means "you should create a new diskstream here, not look for + an old one. + */ + + if (id == zero) { + use_new_diskstream (); + } else if (use_diskstream (id)) { return -1; } } @@ -288,7 +305,11 @@ AudioTrack::_set_state (const XMLNode& node, bool call_base) pending_state = const_cast (&node); - _session.StateReady.connect (mem_fun (*this, &AudioTrack::set_state_part_two)); + if (_session.state_of_the_state() & Session::Loading) { + _session.StateReady.connect (mem_fun (*this, &AudioTrack::set_state_part_two)); + } else { + set_state_part_two (); + } return 0; } diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index ad8281c1bc..281bce658f 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -51,21 +51,8 @@ MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mo , _immediate_events(1024) // FIXME: size? , _note_mode(Sustained) { - MidiDiskstream::Flag dflags = MidiDiskstream::Flag (0); - - if (_flags & Hidden) { - dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Hidden); - } else { - dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Recordable); - } - - assert(mode != Destructive); + use_new_diskstream (); - boost::shared_ptr ds (new MidiDiskstream (_session, name, dflags)); - _session.add_diskstream (ds); - - set_diskstream (boost::dynamic_pointer_cast (ds)); - _declickable = true; _freeze_record.state = NoFreeze; _saved_meter_point = _meter_point; @@ -98,6 +85,24 @@ MidiTrack::~MidiTrack () { } +void +MidiTrack::use_new_diskstream () +{ + MidiDiskstream::Flag dflags = MidiDiskstream::Flag (0); + + if (_flags & Hidden) { + dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Hidden); + } else { + dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Recordable); + } + + assert(_mode != Destructive); + + boost::shared_ptr ds (new MidiDiskstream (_session, name(), dflags)); + _session.add_diskstream (ds); + + set_diskstream (boost::dynamic_pointer_cast (ds)); +} int MidiTrack::set_diskstream (boost::shared_ptr ds) @@ -191,13 +196,23 @@ MidiTrack::_set_state (const XMLNode& node, bool call_base) } else { PBD::ID id (prop->value()); + PBD::ID zero ("0"); + + /* this wierd hack is used when creating tracks from a template. there isn't + a particularly good time to interpose between setting the first part of + the track state (notably Route::set_state() and the track mode), and the + second part (diskstream stuff). So, we have a special ID for the diskstream + that means "you should create a new diskstream here, not look for + an old one. + */ - if (use_diskstream (id)) { + if (id == zero) { + use_new_diskstream (); + } else if (use_diskstream (id)) { return -1; } } - XMLNodeList nlist; XMLNodeConstIterator niter; XMLNode *child; @@ -214,7 +229,11 @@ MidiTrack::_set_state (const XMLNode& node, bool call_base) pending_state = const_cast (&node); - _session.StateReady.connect (mem_fun (*this, &MidiTrack::set_state_part_two)); + if (_session.state_of_the_state() & Session::Loading) { + _session.StateReady.connect (mem_fun (*this, &MidiTrack::set_state_part_two)); + } else { + set_state_part_two (); + } return 0; } diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index c1f7d97d5c..107603c176 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -2224,7 +2224,6 @@ Route::_set_state (const XMLNode& node, bool call_base) child = *niter; if (child->name() == IO::state_node_name && call_base) { - IO::set_state (*child); break; } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index d2938f666f..97672976ce 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -2024,9 +2024,11 @@ Session::new_route_from_template (uint32_t how_many, const std::string& template /*NOTREACHED*/ } - IO::set_name_in_state (node_copy, name); + IO::set_name_in_state (*node_copy.children().front(), name); } + Track::zero_diskstream_id_in_xml (node_copy); + try { shared_ptr route (XMLRouteFactory (node_copy)); @@ -2035,6 +2037,15 @@ Session::new_route_from_template (uint32_t how_many, const std::string& template goto out; } + if (boost::dynamic_pointer_cast(route)) { + /* force input/output change signals so that the new diskstream + picks up the configuration of the route. During session + loading this normally happens in a different way. + */ + route->input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this); + route->output_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this); + } + route->set_remote_control_id (control_id); ++control_id; diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 1439d0ef1c..88259e944f 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -1408,8 +1408,10 @@ Session::XMLRouteFactory (const XMLNode& node) DataType type = DataType::AUDIO; const XMLProperty* prop = node.property("default-type"); - if (prop) + + if (prop) { type = DataType(prop->value()); + } assert(type != DataType::NIL); diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index 8ec3a68a21..2ce73ce727 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -50,7 +50,7 @@ Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, Data } Track::Track (Session& sess, const XMLNode& node, DataType default_type) - : Route (sess, node) + : Route (sess, node, default_type) , _rec_enable_control (new RecEnableControllable(*this)) { _freeze_record.state = NoFreeze; @@ -228,3 +228,10 @@ Track::set_latency_delay (nframes_t longest_session_latency) _diskstream->set_roll_delay (_roll_delay); } +void +Track::zero_diskstream_id_in_xml (XMLNode& node) +{ + if (node.property ("diskstream-id")) { + node.add_property ("diskstream-id", "0"); + } +} -- cgit v1.2.3