Fix copy/paste transition causes bad audio - #1880
Open
bmatherly wants to merge 1 commit into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates multi-clip paste operations in TimelineDock to better preserve transitions when copying/pasting a track/tractor, addressing a reported issue where pasted transitions could cause incorrect audio.
Changes:
- Detect transition “mix” clips in pasted MLT playlists and skip inserting them as normal clips.
- Recreate skipped transitions via
AddTransitionByTrimOutCommandafter inserting adjacent clips. - Adjust inserted clip in/out points and insertion positions to account for skipped transition entries.
Comments suppressed due to low confidence (3)
src/docks/timelinedock.cpp:4538
- A transition is added whenever pendingTransitionDuration > 0, even if the transition tractor's right-side clip could not be resolved (pendingTransitionRightIn < 0 / pendingTransitionRightClip invalid) or does not match the current clip. In those cases this can add a transition between the wrong pair of clips. Gate the transition creation on successfully matching the current clip to the transition's right clip, but still reset the pending-transition state either way.
if (pendingTransitionDuration > 0) {
const int rightClipIndex = clipIndexAtPosition(trackIndex,
overwritePosition);
const int leftClipIndex = rightClipIndex - 1;
if (leftClipIndex >= 0 && rightClipIndex >= 0
src/docks/timelinedock.cpp:4532
- This code now overwrites clips at overwritePosition (= position + info.start - skippedTransitionDuration), but the group-restore pass later in this function still looks up overwritten clips using position + clipInfo.start. When transitions are skipped (skippedTransitionDuration > 0), those lookups can resolve to the wrong clip (or blank), causing copied group membership to be restored incorrectly for pastes that include transitions.
const int overwritePosition = position + info.start
- skippedTransitionDuration;
MAIN.undoStack()->push(new Timeline::OverwriteCommand(m_model,
trackIndex,
overwritePosition,
MLT.XML(&clip),
false));
src/docks/timelinedock.cpp:4303
- A transition is added whenever pendingTransitionDuration > 0, even if the transition tractor's right-side clip could not be resolved (pendingTransitionRightIn < 0 / pendingTransitionRightClip invalid) or does not match the current clip. In those cases this can add a transition between the wrong pair of clips. Gate the transition creation on successfully matching the current clip to the transition's right clip, but still reset the pending-transition state either way.
if (pendingTransitionDuration > 0) {
const int rightClipIndex = clipIndexAtPosition(trackIndex,
insertPosition);
const int leftClipIndex = rightClipIndex - 1;
if (leftClipIndex >= 0 && rightClipIndex >= 0
Comment on lines
+2703
to
+2724
| if (pendingTransitionDuration > 0) { | ||
| const int rightClipIndex = clipCount(trackIndex) - 1; | ||
| const int leftClipIndex = rightClipIndex - 1; | ||
| if (leftClipIndex >= 0 && rightClipIndex >= 0 | ||
| && !isBlank(trackIndex, leftClipIndex) | ||
| && !isBlank(trackIndex, rightClipIndex) | ||
| && !isTransition(trackIndex, leftClipIndex) | ||
| && !isTransition(trackIndex, rightClipIndex) | ||
| && m_model.addTransitionByTrimOutValid( | ||
| trackIndex, leftClipIndex, -pendingTransitionDuration)) { | ||
| MAIN.undoStack()->push( | ||
| new Timeline::AddTransitionByTrimOutCommand( | ||
| m_model, | ||
| trackIndex, | ||
| leftClipIndex, | ||
| -pendingTransitionDuration, | ||
| 0)); | ||
| } | ||
| pendingTransitionDuration = 0; | ||
| pendingTransitionRightIn = -1; | ||
| pendingTransitionRightClip = Mlt::Producer(); | ||
| } |
Comment on lines
+4288
to
4296
| const int insertPosition = position + info.start | ||
| - skippedTransitionDuration; | ||
| bool lastClip = mltTrackIndex == tractor.count() - 1 | ||
| && mltClipIndex == playlist.count() - 1; | ||
| MAIN.undoStack()->push(new Timeline::InsertCommand(m_model, | ||
| m_markersModel, | ||
| trackIndex, | ||
| position + info.start, | ||
| insertPosition, | ||
| MLT.XML(&clip), |
Member
|
sheez, these methods are huge. Is there an opportunity to make a reusable method in the added code? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
As reported here:
https://forum.shotcut.org/t/bug-with-dissolve-on-copied-track/51766/