bool WaveTrack::Get(samplePtr buffer, sampleFormat format, longSampleCount start, sampleCount len) { // Simple optimization: When this buffer is completely contained within one clip, // don't clear anything (because we never won't have to). Otherwise, just clear // everything to be on the safe side. WaveClipList::Node* it; bool doClear = true; for (it=GetClipIterator(); it; it=it->GetNext()) { WaveClip *clip = it->GetData(); if (start >= clip->GetStartSample() && start+len <= clip->GetEndSample()) { doClear = false; break; } } if (doClear) ClearSamples(buffer, format, 0, len); for (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->GetSamples((samplePtr)(((char*)buffer)+startDelta*SAMPLE_SIZE(format)), format, inclipDelta, samplesToCopy)) { wxASSERT(false); // should always work return false; } } } return true; }