Example #1
0
bool SetClipCommand::ApplyInner( const CommandContext & context, Track * t )
{
   static_cast<void>(context);
   // if no 'At' is specified, then any clip in any selected track will be set.
   t->TypeSwitch([&](WaveTrack *waveTrack) {
      WaveClipPointers ptrs( waveTrack->SortedClipArray());
      for(auto it = ptrs.begin(); (it != ptrs.end()); it++ ){
         WaveClip * pClip = *it;
         bool bFound =
            !bHasContainsTime || (
               ( pClip->GetStartTime() <= mContainsTime ) &&
               ( pClip->GetEndTime() >= mContainsTime )
            );
         if( bFound )
         {
            // Inside this IF is where we actually apply the command

            if( bHasColour )
               pClip->SetColourIndex(mColour);
            // No validation of overlap yet.  We assume the user is sensible!
            if( bHasT0 )
               pClip->SetOffset(mT0);
            // \todo Use SetClip to move a clip between tracks too.

         }
      }
   } );
   return true;
}
Example #2
0
WaveClip* WaveTrack::GetLastOrCreateClip()
{
   if (mClips.IsEmpty()) {
      WaveClip *clip = CreateClip();
      clip->SetOffset(mOffset);
      return clip;
   }
   else
      return mClips.GetLast()->GetData();
}
Example #3
0
//Trim trims within a clip, rather than trimming everything.
//If a bound is outside a clip, it trims everything.
bool WaveTrack::Trim (double t0, double t1)
{
   bool inside0 = false;
   bool inside1 = false;
   //Keeps track of the offset of the first clip greater than
   // the left selection t0.
   double firstGreaterOffset = -1;

   WaveClipList::Node * it;
   for(it = GetClipIterator(); it; it = it->GetNext())
      {
            
         WaveClip * clip = it->GetData();

         //Find the first clip greater than the offset.
         //If we end up clipping the entire track, this is useful.
         if(firstGreaterOffset < 0 && 
            clip->GetStartTime() >= t0)
            firstGreaterOffset = clip->GetStartTime();

         if(t1 > clip->GetStartTime() && t1 < clip->GetEndTime())
            {
               if (!clip->Clear(t1,clip->GetEndTime()))
                  return false;
               inside1 = true;
            }

         if(t0 > clip->GetStartTime() && t0 < clip->GetEndTime())
            {
               if (!clip->Clear(clip->GetStartTime(),t0))
                  return false;
               clip->SetOffset(t0);
               inside0 = true;
            }
      }

   //if inside0 is false, then the left selector was between
   //clips, so delete everything to its left.
   if(false == inside1)
      {
         if (!Clear(t1,GetEndTime()))
            return false;
      }

   if(false == inside0)
      {
         if (!Clear(0,t0))
            return false;
         //Reset the track offset to be at the point of the first remaining clip. 
         SetOffset(firstGreaterOffset );
      }
   
   return true;
}
Example #4
0
void WaveTrack::SetOffset(double o)
{
   double delta = o - GetOffset();

   for (WaveClipList::Node* it=GetClipIterator(); it; it=it->GetNext())
   {
      WaveClip* clip = it->GetData();
      clip->SetOffset(clip->GetOffset() + delta);
   }

   mOffset = o;
}
Example #5
0
bool WaveTrack::Join(double t0, double t1)
{
   // Merge all WaveClips overlapping selection into one

   WaveClipList::Node* it;
   WaveClipList clipsToDelete;
   WaveClip *newClip;

   for (it=GetClipIterator(); it; it=it->GetNext())
   {
      WaveClip *clip = it->GetData();   

      if (clip->GetStartTime() < t1-(1.0/mRate) &&
          clip->GetEndTime()-(1.0/mRate) > t0) {

         // Put in sorted order
         int i;
         for(i=0; i<clipsToDelete.GetCount(); i++)
            if (clipsToDelete[i]->GetStartTime() > clip->GetStartTime())
               break;
         //printf("Insert clip %.6f at position %d\n", clip->GetStartTime(), i);
         clipsToDelete.Insert(i, clip);
      }
   }

   newClip = CreateClip();
   double t = clipsToDelete[0]->GetOffset();
   newClip->SetOffset(t);
   for(it=clipsToDelete.GetFirst(); it; it=it->GetNext()) 
   {
      WaveClip *clip = it->GetData();

      //printf("t=%.6f adding clip (offset %.6f, %.6f ... %.6f)\n",
      //       t, clip->GetOffset(), clip->GetStartTime(), clip->GetEndTime());

      if (clip->GetOffset() - t > (1.0 / mRate)) {
         double addedSilence = (clip->GetOffset() - t);
         //printf("Adding %.6f seconds of silence\n");
         newClip->InsertSilence(t, addedSilence);
         t += addedSilence;
      }

      //printf("Pasting at %.6f\n", t);
      newClip->Paste(t, clip);
      t = newClip->GetEndTime();      

      mClips.DeleteObject(clip);
      delete clip;
   }

   return true;
}
Example #6
0
bool WaveClip::ClearAndAddCutLine(double t0, double t1)
{
   if (t0 > GetEndTime() || t1 < GetStartTime())
      return true; // time out of bounds
      
   WaveClip *newClip = new WaveClip(mSequence->GetDirManager(),
                                    mSequence->GetSampleFormat(),
                                    mRate);
   double clip_t0 = t0;
   double clip_t1 = t1;
   if (clip_t0 < GetStartTime())
      clip_t0 = GetStartTime();
   if (clip_t1 > GetEndTime())
      clip_t1 = GetEndTime();

   if (!newClip->CreateFromCopy(clip_t0, clip_t1, this))
      return false;
   newClip->SetOffset(clip_t0-mOffset);

   // Sort out cutlines that belong to the new cutline
   WaveClipList::compatibility_iterator nextIt;

   for (WaveClipList::compatibility_iterator it = mCutLines.GetFirst(); it; it=nextIt)
   {
      nextIt = it->GetNext();
      WaveClip* clip = it->GetData();
      double cutlinePosition = mOffset + clip->GetOffset();
      if (cutlinePosition >= t0 && cutlinePosition <= t1)
      {
         clip->SetOffset(cutlinePosition - newClip->GetOffset() - mOffset);
         newClip->mCutLines.Append(clip);
         mCutLines.DeleteNode(it);
      } else
      if (cutlinePosition >= t1)
      {
         clip->Offset(clip_t0-clip_t1);
      }
   }
   
   // Clear actual audio data
   sampleCount s0, s1;

   TimeToSamplesClip(t0, &s0);
   TimeToSamplesClip(t1, &s1);
   
   if (GetSequence()->Delete(s0, s1-s0))
   {
      // Collapse envelope
      GetEnvelope()->CollapseRegion(t0, t1);
      if (t0 < GetStartTime())
         Offset(-(GetStartTime() - t0));

      MarkChanged();

      mCutLines.Append(newClip);
      return true;
   } else
   {
      delete newClip;
      return false;
   }
}
Example #7
0
bool WaveTrack::Copy(double t0, double t1, Track **dest)
{
   *dest = NULL;

   if (t1 <= t0)
      return false;

   WaveTrack *newTrack = new WaveTrack(mDirManager);

   newTrack->Init(*this);

   WaveClipList::Node* it;
   
   for (it=GetClipIterator(); it; it=it->GetNext())
   {
      WaveClip *clip = it->GetData();

      if (t0 <= clip->GetStartTime() && t1 >= clip->GetEndTime())
      {
         // Whole clip is in copy region
         //printf("copy: clip %i is in copy region\n", (int)clip);
         
         WaveClip *newClip = new WaveClip(*clip, mDirManager);
         newClip->RemoveAllCutLines();
         newClip->Offset(-t0);
         newTrack->mClips.Append(newClip);
      } else
      if (t1 > clip->GetStartTime() && t0 < clip->GetEndTime())
      {
         // Clip is affected by command
         //printf("copy: clip %i is affected by command\n", (int)clip);
         
         WaveClip *newClip = new WaveClip(*clip, mDirManager);
         newClip->RemoveAllCutLines();
         double clip_t0 = t0;
         double clip_t1 = t1;
         if (clip_t0 < clip->GetStartTime())
            clip_t0 = clip->GetStartTime();
         if (clip_t1 > clip->GetEndTime())
            clip_t1 = clip->GetEndTime();

         //printf("copy: clip_t0=%f, clip_t1=%f\n", clip_t0, clip_t1);

         newClip->Offset(-t0);
         if (newClip->GetOffset() < 0)
            newClip->SetOffset(0);

         //printf("copy: clip offset is now %f\n", newClip->GetOffset());
            
         if (!newClip->CreateFromCopy(clip_t0, clip_t1, clip))
         {
            //printf("paste: CreateFromCopy(%f, %f, %i) returns false, quitting\n",
            //   clip_t0, clip_t1, (int)clip);

            return false;
         }

         newTrack->mClips.Append(newClip);
      }
   }

   *dest = newTrack;

   return true;
}
Example #8
0
bool EffectReverse::ProcessOneWave(int count, WaveTrack * track, sampleCount start, sampleCount len)
{
   bool rValue = true; // return value

   sampleCount end = (sampleCount) start + len; // start, end, len refer to the selected reverse region

   // STEP 1:
   // If a reverse selection begins and/or ends at the inside of a clip
   // perform a split at the start and/or end of the reverse selection
   WaveClipList::compatibility_iterator node = track->GetClipIterator();
   while (node) {
      WaveClip *clip = node->GetData();
      sampleCount clipStart = clip->GetStartSample();
      sampleCount clipEnd = clip->GetEndSample();
      if (clipStart < start && clipEnd > start && clipEnd <= end) { // the reverse selection begins at the inside of a clip
         double splitTime = track->LongSamplesToTime(start);
         track->SplitAt(splitTime);
      }
      else if (clipStart >= start && clipStart < end && clipEnd > end) { // the reverse selection ends at the inside of a clip
         double splitTime = track->LongSamplesToTime(end);
         track->SplitAt(splitTime);
      }
      else if (clipStart < start && clipEnd > end) { // the selection begins AND ends at the inside of a clip
         double splitTime = track->LongSamplesToTime(start);
         track->SplitAt(splitTime);
         splitTime = track->LongSamplesToTime(end);
         track->SplitAt(splitTime);
      }
      node = node->GetNext();
   }

   //STEP 2:
   // Individually reverse each clip inside the selected region
   // and apply the appropriate offset after detaching them from the track

   bool checkedFirstClip = false;
   
   // used in calculating the offset of clips to rearrange
   // holds the new end position of the current clip
   sampleCount currentEnd = (sampleCount)end;
   
   WaveClipList revClips; // holds the reversed clips
   WaveClipList otherClips; // holds the clips that appear after the reverse selection region
   WaveClipArray clipArray;
   track->FillSortedClipArray(clipArray);
   size_t i;
   for (i=0; i < clipArray.Count(); i++) {
      
      WaveClip *clip = clipArray.Item(i);
      sampleCount clipStart = clip->GetStartSample();
      sampleCount clipEnd = clip->GetEndSample();
            
      if (clipStart >= start && clipEnd <= end) { // if the clip is inside the selected region
         
         // this is used to check if the selected region begins with a whitespace.
         // if yes then clipStart (of the first clip) and start are not the same.
         // adjust currentEnd accordingly and set endMerge to false
         if(checkedFirstClip == false && clipStart > start) { 
            checkedFirstClip = true;
            if(i > 0) {
               if (clipArray.Item(i-1)->GetEndSample() <= start) {
                  currentEnd -= (clipStart - start);
               }
            }
            else {
               currentEnd -= (clipStart - start);
            }
         }
         
         sampleCount revStart = (clipStart >= start)? clipStart: start;
         sampleCount revEnd = (clipEnd >= end)? end: clipEnd;
         sampleCount revLen = (sampleCount)revEnd-revStart;
         if (revEnd >= revStart) {
            if(!ProcessOneClip(count, track, revStart, revLen, start, end)) // reverse the clip
            {
               rValue = false;
               break;
            }

            sampleCount clipOffsetStart = (sampleCount)(currentEnd - (clipEnd-clipStart)); // calculate the offset required
            double offsetStartTime = track->LongSamplesToTime(clipOffsetStart);
            if(i+1 < clipArray.Count()) // update currentEnd if there is a clip to process next
            {
               sampleCount nextClipStart = clipArray.Item(i+1)->GetStartSample();
               currentEnd = (sampleCount)(currentEnd - (clipEnd - clipStart) - (nextClipStart - clipEnd));
            }

            clip = track->RemoveAndReturnClip(clip); // detach the clip from track
            clip->SetOffset(track->LongSamplesToTime(track->TimeToLongSamples(offsetStartTime))); // align time to a sample and set offset
            revClips.Append(clip);
            
         }
      }
      else if (clipStart >= end) { // clip is after the selection region
         clip = track->RemoveAndReturnClip(clip); // simply remove and append to otherClips
         otherClips.Append(clip);
      }
   }
   
   // STEP 3: Append the clips from
   // revClips and otherClips back to the track
   size_t revClipsCount = revClips.GetCount();
   for (i = 0; i < revClipsCount; i++) {
      WaveClipList::compatibility_iterator node = revClips.Item(revClipsCount - 1 - i); // the last clip of revClips is appended to the track first
      WaveClip *clip = node->GetData();
      track->AddClip(clip);
   }

   for (i = 0; i < otherClips.GetCount(); i++) {
      WaveClipList::compatibility_iterator node = otherClips.Item(i);
      track->AddClip(node->GetData());
   }

   return rValue;
}