bool WaveTrack::Paste(double t0, Track *src) { //printf("paste: entering WaveTrack::Paste\n"); if (src->GetKind() != Track::Wave) return false; //printf("paste: we have a wave track\n"); WaveTrack* other = (WaveTrack*)src; // // Pasting is a bit complicated, because with the existence of multiclip mode, // we must guess the behaviour the user wants. // // Currently, two modes are implemented: // // - If a single clip should be pasted, and it should be pasted inside another // clip, no new clips are generated. The audio is simply inserted. // This resembles the old (pre-multiclip support) behaviour. However, if // the clip is pasted outside of any clip, a new clip is generated. This is // the only behaviour which is different to what was done before, but it // shouldn't confuse users too much. // // - If multiple clips should be pasted, these are always pasted as single // clips, and the current clip is splitted, when necessary. This may seem // strange at first, but it probably is better than trying to auto-merge // anything. The user can still merge the clips by hand (which should be // a simple command reachable by a hotkey or single mouse click). // if (other->GetNumClips() == 0) return false; //printf("paste: we have at least one clip\n"); double insertDuration = other->GetEndTime(); WaveClipList::Node* it; //printf("Check if we need to make room for the pasted data\n"); // Make room for the pasted data, unless the space being pasted in is empty of // any clips if (!IsEmpty(t0, t0+insertDuration-1.0/mRate)) { for (it=GetClipIterator(); it; it=it->GetNext()) { WaveClip* clip = it->GetData(); //printf("paste: offsetting already existing clip %i by %f seconds\n", //(int)clip, insertDuration); if (clip->GetStartTime() > t0-(1.0/mRate)) clip->Offset(insertDuration); } } if (other->GetNumClips() == 1) { // Single clip mode // printf("paste: checking for single clip mode!\n"); WaveClip *insideClip = NULL; for (it=GetClipIterator(); it; it=it->GetNext()) { WaveClip *clip = it->GetData(); // The 1.0/mRate is the time for one sample - kind of a fudge factor, // because an overlap of less than a sample should not trigger // traditional behaviour. if (t0+src->GetEndTime()-1.0/mRate > clip->GetStartTime() && t0 < clip->GetEndTime() - 1.0/mRate) { //printf("t0=%.6f: inside clip is %.6f ... %.6f\n", // t0, clip->GetStartTime(), clip->GetEndTime()); insideClip = clip; break; } } if (insideClip) { // Exhibit traditional behaviour //printf("paste: traditional behaviour\n"); return insideClip->Paste(t0, other->GetClipByIndex(0)); } // Just fall through and exhibit new behaviour } // Insert new clips //printf("paste: multi clip mode!\n"); for (it=other->GetClipIterator(); it; it=it->GetNext()) { WaveClip* clip = it->GetData(); WaveClip* newClip = new WaveClip(*clip, mDirManager); newClip->Offset(t0); newClip->MarkChanged(); mClips.Append(newClip); } return true; }