| 1034 | } |
| 1035 | |
| 1036 | void ProjectFileManager::FixTracks(TrackList& tracks, |
| 1037 | const std::function<void(const TranslatableString&)>& onError, |
| 1038 | const std::function<void(const TranslatableString&)>& onUnlink) |
| 1039 | { |
| 1040 | // This is successively assigned the left member of each pair that |
| 1041 | // becomes unlinked |
| 1042 | Track::Holder unlinkedTrack; |
| 1043 | // Beware iterator invalidation, because stereo channels get zipped, |
| 1044 | // replacing WaveTracks |
| 1045 | for (auto iter = tracks.begin(); iter != tracks.end();) { |
| 1046 | auto t = (*iter++)->SharedPointer(); |
| 1047 | const auto linkType = t->GetLinkType(); |
| 1048 | // Note, the next function may have an important upgrading side effect, |
| 1049 | // and return no error; or it may find a real error and repair it, but |
| 1050 | // that repaired track won't be used because opening will fail. |
| 1051 | if (!t->LinkConsistencyFix()) { |
| 1052 | onError(XO("A channel of a stereo track was missing.")); |
| 1053 | unlinkedTrack = nullptr; |
| 1054 | } |
| 1055 | if (!unlinkedTrack) { |
| 1056 | if (linkType != ChannelGroup::LinkType::None && |
| 1057 | t->NChannels() == 1) { |
| 1058 | // The track became unlinked. |
| 1059 | // It should NOT have been replaced with a "zip" |
| 1060 | assert(t->GetOwner().get() == &tracks); |
| 1061 | // Wait until LinkConsistencyFix is called on the second track |
| 1062 | unlinkedTrack = t; |
| 1063 | // Fix the iterator, which skipped the right channel before the |
| 1064 | // unlinking |
| 1065 | iter = tracks.Find(t.get()); |
| 1066 | ++iter; |
| 1067 | } |
| 1068 | } |
| 1069 | else { |
| 1070 | //Not an elegant way to deal with stereo wave track linking |
| 1071 | //compatibility between versions |
| 1072 | if (const auto left = dynamic_cast<WaveTrack*>(unlinkedTrack.get())) { |
| 1073 | if (const auto right = dynamic_cast<WaveTrack*>(t.get())) { |
| 1074 | // As with the left, it should not have vanished from the list |
| 1075 | assert(right->GetOwner().get() == &tracks); |
| 1076 | left->SetPan(-1.0f); |
| 1077 | right->SetPan(1.0f); |
| 1078 | RealtimeEffectList::Get(*left).Clear(); |
| 1079 | RealtimeEffectList::Get(*right).Clear(); |
| 1080 | |
| 1081 | if(left->GetRate() != right->GetRate()) |
| 1082 | //i18n-hint: explains why opened project was auto-modified |
| 1083 | onUnlink(XO("This project contained stereo tracks with different sample rates per channel.")); |
| 1084 | if(left->GetSampleFormat() != right->GetSampleFormat()) |
| 1085 | //i18n-hint: explains why opened project was auto-modified |
| 1086 | onUnlink(XO("This project contained stereo tracks with different sample formats in channels.")); |
| 1087 | //i18n-hint: explains why opened project was auto-modified |
| 1088 | onUnlink(XO("This project contained stereo tracks with non-aligned content.")); |
| 1089 | } |
| 1090 | } |
| 1091 | unlinkedTrack = nullptr; |
| 1092 | } |
| 1093 |
nothing calls this directly
no test coverage detected