bool WaveTrack::Silence(double t0, double t1) { if (t1 < t0) return false; longSampleCount start = (longSampleCount)floor(t0 * mRate + 0.5); longSampleCount len = (longSampleCount)floor(t1 * mRate + 0.5) - start; bool result = true; for (WaveClipList::Node* it=GetClipIterator(); it; it=it->GetNext()) { WaveClip *clip = it->GetData(); longSampleCount clipStart = clip->GetStartSample(); longSampleCount clipEnd = clip->GetEndSample(); if (clipEnd > start && clipStart < start+len) { // Clip sample region and Get/Put sample region overlap sampleCount samplesToCopy = start+len - clipStart; if (samplesToCopy > clip->GetNumSamples()) samplesToCopy = clip->GetNumSamples(); longSampleCount inclipDelta = 0; longSampleCount startDelta = clipStart - start; if (startDelta < 0) { inclipDelta = -startDelta; // make positive value samplesToCopy -= inclipDelta; startDelta = 0; } if (!clip->GetSequence()->SetSilence(inclipDelta, samplesToCopy)) { wxASSERT(false); // should always work return false; } clip->MarkChanged(); } } return result; }
bool WaveTrack::Set(samplePtr buffer, sampleFormat format, longSampleCount start, sampleCount len) { bool result = true; for (WaveClipList::Node* it=GetClipIterator(); it; it=it->GetNext()) { WaveClip *clip = it->GetData(); longSampleCount clipStart = clip->GetStartSample(); longSampleCount clipEnd = clip->GetEndSample(); if (clipEnd > start && clipStart < start+len) { // Clip sample region and Get/Put sample region overlap sampleCount samplesToCopy = start+len - clipStart; if (samplesToCopy > clip->GetNumSamples()) samplesToCopy = clip->GetNumSamples(); longSampleCount inclipDelta = 0; longSampleCount startDelta = clipStart - start; if (startDelta < 0) { inclipDelta = -startDelta; // make positive value samplesToCopy -= inclipDelta; startDelta = 0; } if (!clip->SetSamples((samplePtr)(((char*)buffer)+startDelta*SAMPLE_SIZE(format)), format, inclipDelta, samplesToCopy)) { wxASSERT(false); // should always work return false; } clip->MarkChanged(); } } return result; }
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; }