コード例 #1
0
ファイル: WaveTrack.cpp プロジェクト: Kirushanr/audacity
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;
}