Fix loading playlists of old sessions
Previously when loading Ardour v2, v3-5 sessions, tracks were created with a dummy name "toBeResetFroXML". In v6, Track::init() creates a playlist when the track name is not empty. Later Track::set_state() calls set_name(). When a playlist exists, the playlist's name is set to match the track's name. When loading v6 sessions none of this happens. A previously loaded playlist will be assigned by ID. Older versions identified Playlists by name and by the time the playlist is assigned, there may be ambiguities. With the default (track-name = playlist-name) two playlists with the same name exist: (1) the playlist loaded from the session file (2) the playlist created by Track::init() Playlists are stored in an ordered std::set<shared_ptr<Playlist>>, and name-lookup iterates over the set. When loading an old session after starting Ardour, it is very likely to always lookup the playlist (1), because new, later allocations from (2) are on top of the heap and ordered last. The session seemingly loads correctly, except for lingering, unused empty playlists "toBeResetFroXML" renamed to "Track name" that were never deleted. However when loading an old session from a running instance, ordering is mostly random, and many tracks end up with using the empty playlist (2) instead of the correct playlist (1).
This commit is contained in:
parent
213b3cd593
commit
7f862298cf
@ -1924,9 +1924,9 @@ Session::XMLRouteFactory_3X (const XMLNode& node, int version)
|
||||
boost::shared_ptr<Track> track;
|
||||
|
||||
if (type == DataType::AUDIO) {
|
||||
track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
|
||||
track.reset (new AudioTrack (*this, string())); // name will be reset from XML in ::set_state() below
|
||||
} else {
|
||||
track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
|
||||
track.reset (new MidiTrack (*this, string())); // name will be reset from XML in ::set_state() below
|
||||
}
|
||||
|
||||
if (track->init()) {
|
||||
@ -1986,9 +1986,9 @@ Session::XMLRouteFactory_2X (const XMLNode& node, int version)
|
||||
boost::shared_ptr<Track> track;
|
||||
|
||||
if (type == DataType::AUDIO) {
|
||||
track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
|
||||
track.reset (new AudioTrack (*this, string())); // name will be reset from XML in ::set_state() below
|
||||
} else {
|
||||
track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
|
||||
track.reset (new MidiTrack (*this, string())); // name will be reset from XML in ::set_state() below
|
||||
}
|
||||
|
||||
if (track->init()) {
|
||||
|
@ -110,8 +110,8 @@ Track::init ()
|
||||
|
||||
if (!name().empty()) {
|
||||
/* an empty name means that we are being constructed via
|
||||
serialized state (XML). Don't create a playlist, because one
|
||||
will be created or discovered during ::set_state().
|
||||
* serialized state (XML). Don't create a playlist, because one
|
||||
* will be created or discovered during ::set_state().
|
||||
*/
|
||||
use_new_playlist (data_type());
|
||||
}
|
||||
@ -419,6 +419,18 @@ Track::set_name (const string& str)
|
||||
}
|
||||
}
|
||||
|
||||
/* When creating a track during session-load,
|
||||
* do not change playlist's name, nor try to save the session.
|
||||
*
|
||||
* Changing the playlist name from 'toBeResetFroXML' breaks loading
|
||||
* Ardour v2..5 sessions. Older versions of Arodur identified playlist
|
||||
* by name, and this causes duplicate names and name conflicts.
|
||||
* (new track name -> new playlist name != old playlist)
|
||||
*/
|
||||
if (_session.loading ()) {
|
||||
return Route::set_name (str);
|
||||
}
|
||||
|
||||
for (uint32_t n = 0; n < DataType::num_types; ++n) {
|
||||
if (_playlists[n]) {
|
||||
_playlists[n]->set_name (str);
|
||||
|
Loading…
Reference in New Issue
Block a user