| 108 | |
| 109 | namespace { |
| 110 | std::pair<Track *, Track *> FindSyncLockGroup(Track &member) |
| 111 | { |
| 112 | // A non-trivial sync-locked group is a maximal sub-sequence of the tracks |
| 113 | // consisting of any positive number of audio tracks followed by zero or |
| 114 | // more label tracks. |
| 115 | |
| 116 | // Step back through any label tracks. |
| 117 | auto pList = member.GetOwner(); |
| 118 | auto ppMember = pList->Find(&member); |
| 119 | while (*ppMember && IsSeparatorTrack(**ppMember)) |
| 120 | --ppMember; |
| 121 | |
| 122 | // Step back through the wave and note tracks before the label tracks. |
| 123 | Track *first = nullptr; |
| 124 | while (*ppMember && IsSyncLockableNonSeparatorTrack(**ppMember)) { |
| 125 | first = *ppMember; |
| 126 | --ppMember; |
| 127 | } |
| 128 | |
| 129 | if (!first) |
| 130 | // Can't meet the criteria described above. In that case, |
| 131 | // consider the track to be the sole member of a group. |
| 132 | return { &member, &member }; |
| 133 | |
| 134 | auto last = pList->Find(first); |
| 135 | auto next = last; |
| 136 | bool inLabels = false; |
| 137 | |
| 138 | while (*++next) { |
| 139 | if (!IsGoodNextSyncLockTrack(**next, inLabels)) |
| 140 | break; |
| 141 | last = next; |
| 142 | inLabels = IsSeparatorTrack(**last); |
| 143 | } |
| 144 | |
| 145 | return { first, *last }; |
| 146 | } |
| 147 | |
| 148 | } |
| 149 |
no test coverage detected