Lets say I have 2 midi clips, one that has a loop length of 2 bars, and another that has a loop length of 8 bars. what I’m essentially trying to do is overdubbing, and trying to merge these two clips togther into one. but since the overdub clip (8bars) is longer than the 2 bar clip, what i want is to essentially duplicate the 2 bar clip so that it becomes an 8 bar clip as if it had looped for 8 bars, and then merge the midi notes in both bars sequences. Now i have code (which i think is working as far as i can tell) which is essentially just setting the 2 bar clips end value to 8 bars out instead of 2, and then looping through the overdub clip’s sequence and using addNote to essentially add the notes from the overdub clip into the 2 bar clip. but I still have to implement the logic for duplicating the notes from the 2 bar clip to 8 bars out.
I hope this is making sense. If not let me know and I can attempt to explain it more clearly. Essentially i want the original 2 bar midi sequence to keep looping while i add the new notes from the 8 bar overdub, and save that all as a consolidated clip. Not sure if this makes a difference, but the first midi clip (the original 2 bar) is in a clipslot, whereas the overdub clip (8 bars) is just created as a midiclip on the track itself. My goal is to somehow merge the overdub clip into the original clip in the clipslot, while preserving looping. Now I’m sure it’s possible with the way I’m attempting to do this, but I’m starting to wonder if theres an easier way which isn’t as convoluted as my approach. I essentially have the 2 clips ready to do the processing for combining them in the manner I just explained, I just need to figure out the most straightforward way to do so.
I have looked at stuff like mergeInMidiSequence, mergeMidiClips, and getSequenceLooped/createSequenceLooped, but I’m not sure if thats what I’m supposed to use, or even what exactly those functions do… I’m quite a newbie with tracktion engine and I’ve been making a lot of slow progress, so any sort of guidance would be helpful, especially if I’m going about this completely wrong.
Edit:
I figured a snippet of my code would help:
// Merging overdub clip into existing clip in slot
if (existingClipInSlot && existingClipInSlot != pendingClip)
{
auto &edit = existingClipInSlot->edit;
auto &tempoSequence = edit.tempoSequence;
// Step 1: Extend existing clip's loop range if overdub is longer
auto existingLoopRange = existingClipInSlot->getLoopRangeBeats();
auto existingLoopLength = existingLoopRange.getLength();
auto existingLoopEnd = existingLoopRange.getStart() + existingLoopLength;
// Calculate new loop end based on overdub clip (e.g., 8 bars)
auto newLoopEndBeats = calculateLoopEnd(*existingClipInSlot, true); // true = isOverdub
if (newLoopEndBeats > existingLoopEnd)
{
// Extend clip's time range to accommodate new loop length
auto clipCurrentStartBeat = tracktion::toBeats(
existingClipInSlot->getPosition().getStart(), tempoSequence);
auto newClipEndBeat = clipCurrentStartBeat +
tracktion::BeatDuration::fromBeats(newLoopEndBeats.inBeats());
auto newClipEndTime = tracktion::toTime(newClipEndBeat, tempoSequence);
existingClipInSlot->setEnd(newClipEndTime, false);
// Update loop range
auto newLoopLength = tracktion::BeatDuration::fromBeats(
newLoopEndBeats.inBeats() - existingLoopRange.getStart().inBeats());
auto newLoopRange = tracktion::BeatRange(
existingLoopRange.getStart(), newLoopLength);
existingClipInSlot->setLoopRangeBeats(newLoopRange);
}
// Step 2: Duplicate original clip's notes to fill extended loop length
// TODO: Implement logic to duplicate 2-bar clip's notes to 8 bars
// (e.g., if original is 2 bars and new loop is 8 bars, duplicate 3 more times)
// Step 3: Merge overdub clip's notes into existing clip
auto &existingSequence = existingClipInSlot->getSequence();
auto &overdubSequence = pendingClip->getSequence();
for (int i = 0; i < overdubSequence.getNumNotes(); ++i)
{
if (auto note = overdubSequence.getNote(i))
{
existingSequence.addNote(
note->getNoteNumber(),
note->getStartBeat(),
note->getLengthBeats(),
note->getVelocity(),
0, // channel
&edit.getUndoManager());
}
}
// Clean up overdub clip
pendingClip->removeFromParent();
}
