Update of /cvsroot/audacity/audacity-src/src/effects
In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv2309/effects

Modified Files:
        Reverse.cpp Reverse.h 
Log Message:
Vidyashankar Vellal's work on making Reverse do sensible things with multiple 
clips and labels.

Index: Reverse.cpp
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/effects/Reverse.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- Reverse.cpp 8 Jul 2009 15:39:44 -0000       1.19
+++ Reverse.cpp 20 Oct 2009 23:29:17 -0000      1.20
@@ -45,10 +45,11 @@
    while (t) {
       if (t->GetKind() == Track::Wave) {
          WaveTrack *track = (WaveTrack*)t;
-         double trackStart = track->GetStartTime();
-         double trackEnd = track->GetEndTime();
-         double t0 = mT0 < trackStart? trackStart: mT0;
-         double t1 = mT1 > trackEnd? trackEnd: mT1;
+         
+         // Since leading and trailing whitespaces should also be considered 
for reversal
+         // t0 and t1 must always be equal to mT0 and mT1
+         double t0 = mT0;
+         double t1 = mT1;
 
          if (track->GetSelected()) {
             if (t1 > t0) {
@@ -56,7 +57,7 @@
                sampleCount end = track->TimeToLongSamples(t1);
                sampleCount len = (sampleCount)(end - start);
 
-               if (!ProcessOne(count, track, start, len))
+               if (!ProcessOneWave(count, track, start, len))
                {
                   bGoodResult = false;
                   break;
@@ -104,8 +105,126 @@
    return bGoodResult;
 }
 
-bool EffectReverse::ProcessOne(int count, WaveTrack *track,
-                               sampleCount start, sampleCount len)
+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 clipIterator = 
track->GetClipIterator();
+   wxWaveClipListNode *node = (wxWaveClipListNode*)clipIterator;
+   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++) {
+      wxWaveClipListNode *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++) {
+      wxWaveClipListNode *node = otherClips.Item(i);
+      track->AddClip(node->GetData());
+   }
+
+   return rValue;
+}
+
+bool EffectReverse::ProcessOneClip(int count, WaveTrack *track,
+                               sampleCount start, sampleCount len,
+                               sampleCount originalStart, sampleCount 
originalEnd)
 {
    bool rc = true;
    // keep track of two blocks whose data we will swap
@@ -117,7 +236,7 @@
    float *buffer1 = new float[blockSize];
    float *buffer2 = new float[blockSize];
    
-   sampleCount originalLen = len;
+   sampleCount originalLen = (sampleCount)originalEnd-originalStart;
 
    while (len > 1) {
       sampleCount block = track->GetBestBlockSize(first);
@@ -138,7 +257,7 @@
       len -= 2 * block;
       first += block;
       
-      if( TrackProgress(count, 2*(first-start) / (double) originalLen) ) {
+      if( TrackProgress(count, 2*(first-originalStart) / (double) originalLen) 
) {
          rc = false;
          break;
       }

Index: Reverse.h
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/effects/Reverse.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- Reverse.h   12 Jul 2008 15:25:47 -0000      1.9
+++ Reverse.h   20 Oct 2009 23:29:17 -0000      1.10
@@ -47,9 +47,9 @@
    virtual bool Process();
 
  private:
-   bool ProcessOne(int count, WaveTrack * track,
-                   sampleCount start, sampleCount len);
-
+   bool ProcessOneClip(int count, WaveTrack* track,
+                   sampleCount start, sampleCount len, sampleCount 
originalStart, sampleCount originalEnd);
+   bool ProcessOneWave(int count, WaveTrack* track, sampleCount start, 
sampleCount len);
  };
 
 #endif


------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Audacity-cvs mailing list
Audacity-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/audacity-cvs

Reply via email to