~ubuntu-branches/ubuntu/gutsy/audacity/gutsy-backports

« back to all changes in this revision

Viewing changes to src/effects/Repeat.cpp

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2008-02-18 21:58:19 UTC
  • mfrom: (13.1.2 hardy)
  • Revision ID: james.westby@ubuntu.com-20080218215819-tmbcf1rx238r8gdv
Tags: 1.3.4-1.1ubuntu1~gutsy1
Automated backport upload; no source changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include "../Audacity.h"
24
24
 
25
25
#include "Repeat.h"
 
26
#include "../ShuttleGui.h"
26
27
#include "../WaveTrack.h"
27
28
 
28
29
#include <wx/button.h>
106
107
 
107
108
bool EffectRepeat::Process()
108
109
{
109
 
   TrackListIterator iter(mWaveTracks);
 
110
   this->CopyInputWaveTracks(); // Set up m_pOutputWaveTracks.
 
111
   bool bGoodResult = true;
 
112
 
 
113
   TrackListIterator iter(m_pOutputWaveTracks);
110
114
   WaveTrack *track = (WaveTrack *) iter.First();
111
 
   int count = 0;
112
 
        double maxDestLen = 0.0; // used to change selection to original plus generated
113
 
        double newDestLen = 0.0;
114
 
   while (track) {
 
115
   int nTrack = 0;
 
116
        double maxDestLen = 0.0; // used to change selection to generated bit
 
117
   while ((track != NULL) && bGoodResult) {
115
118
      double trackStart = track->GetStartTime();
116
119
      double trackEnd = track->GetEndTime();
117
120
      double t0 = mT0 < trackStart? trackStart: mT0;
123
126
      longSampleCount start = track->TimeToLongSamples(t0);
124
127
      longSampleCount end = track->TimeToLongSamples(t1);
125
128
      sampleCount len = (sampleCount)(end - start);
 
129
      double tLen = track->LongSamplesToTime(len);
 
130
      double tc = t0 + tLen;
126
131
 
127
132
      if (len <= 0)
128
133
         continue;
129
134
 
130
 
      //
131
 
      // Create a track that contains 1 or more copies of the
132
 
      // selection, cleverly arranged so that every BlockFile
133
 
      // is within the minimum and maxmimum lengths of a normal
134
 
      // BlockFile.  That allows us to repeat the same sequence
135
 
      // of identical BlockFiles, saving lots of disk space.
136
 
      //
137
 
 
138
 
      sampleFormat format = track->GetSampleFormat();
139
 
      WaveTrack *unitTrack = mFactory->NewWaveTrack(format, track->GetRate());
140
 
      WaveTrack *dest = mFactory->NewWaveTrack(format, track->GetRate());
141
 
      sampleCount maxBlockSize = unitTrack->GetMaxBlockSize();
142
 
      sampleCount minBlockSize = maxBlockSize / 2;
143
 
      samplePtr buffer = NewSamples(maxBlockSize, format);
144
 
 
145
 
      int numCopies = 1;
146
 
      int chunkSize = len;
147
 
      int j;
148
 
 
149
 
      while (chunkSize * numCopies < minBlockSize)
150
 
         numCopies++;
151
 
      
152
 
      if (chunkSize > maxBlockSize) {
153
 
         j=2;
154
 
 
155
 
         while(chunkSize/j >= maxBlockSize)
156
 
            j++;
157
 
 
158
 
         chunkSize = (chunkSize + (j-1)) / j;
159
 
      }
160
 
 
161
 
      sampleCount totalSamples = 0;
162
 
      while(totalSamples < len * numCopies) {
163
 
         sampleCount blockLen = chunkSize;
164
 
         sampleCount blockStart = (totalSamples % len);
165
 
 
166
 
         if (totalSamples + blockLen > len * numCopies)
167
 
            blockLen = len * numCopies - totalSamples;
168
 
 
169
 
         if (!track->Get(buffer, format, start+blockStart, blockLen)) {
170
 
            delete unitTrack;
171
 
            return false;
 
135
      Track *dest;
 
136
      track->Copy(t0, t1, &dest);
 
137
      for(int j=0; j<repeatCount; j++)
 
138
      {
 
139
         if (!track->Paste(tc, dest) || 
 
140
               TrackProgress(nTrack, j / repeatCount)) // TrackProgress returns true on Cancel.
 
141
         {
 
142
            bGoodResult = false;
 
143
            break;
172
144
         }
173
 
 
174
 
         unitTrack->Append(buffer, format, blockLen);
175
 
         if (numCopies == 1)
176
 
            unitTrack->Flush();
177
 
 
178
 
         totalSamples += blockLen;
 
145
         tc += tLen;
179
146
      }
180
 
      if (numCopies != 1)
181
 
         unitTrack->Flush();
182
 
 
183
 
      //
184
 
      // Repeat the unit track enough times, possible creating a few
185
 
      // more than desired
186
 
      //
187
 
 
188
 
      int desiredCopies = repeatCount+1;
189
 
      int desiredUnitTracks = (desiredCopies + (numCopies-1)) / numCopies;
190
 
      for(j=0; j<desiredUnitTracks; j++)
191
 
         dest->Paste(dest->GetEndTime(), unitTrack);
192
 
 
193
 
      //
194
 
      // If necessary, delete a few copies from the end
195
 
      //
196
 
 
197
 
      int actualCopies = desiredUnitTracks * numCopies;
198
 
      if (actualCopies > desiredCopies) {
199
 
         double oneLen = unitTrack->GetEndTime() / numCopies;
200
 
         double clearLen = oneLen * (actualCopies - desiredCopies);
201
 
                        double oldDestLen = dest->GetEndTime();
202
 
                        newDestLen = oldDestLen - clearLen;
203
 
         dest->Clear(newDestLen, oldDestLen);
204
 
      } else {
205
 
                        newDestLen = dest->GetEndTime();
206
 
                }
207
 
 
208
 
                if (newDestLen > maxDestLen)
209
 
                        maxDestLen = newDestLen;
210
 
 
211
 
      track->Clear(t0, t1);
212
 
      track->Paste(t0, dest);
213
 
 
214
 
      delete unitTrack;
 
147
      if (tc > maxDestLen)
 
148
         maxDestLen = tc;
215
149
      delete dest;
216
150
 
217
151
      track = (WaveTrack *) iter.Next();
218
 
      count++;
219
 
   }
220
 
 
221
 
        mT1 = mT0 + maxDestLen; // Change selection to original plus generated.
222
 
   return true;
 
152
      nTrack++;
 
153
   }
 
154
 
 
155
   if (bGoodResult)
 
156
   {
 
157
      // Change selection to just the generated bits.
 
158
      mT0 = mT1;
 
159
           mT1 = maxDestLen;
 
160
   }
 
161
 
 
162
   this->ReplaceProcessedWaveTracks(bGoodResult); 
 
163
   return bGoodResult;
223
164
}
224
165
 
225
166
//----------------------------------------------------------------------------
242
183
 
243
184
   wxStaticText *statText =
244
185
      new wxStaticText(this, -1,
 
186
                        /* i18n-hint: && in here is an escape character to get
 
187
                         * a single & on screen, so keep it as is */
245
188
                       _("Repeat by Dominic Mazzoni && Vaughan Johnson"));
246
189
   mainSizer->Add(statText, 0, wxALIGN_CENTRE | wxALL, 5);
247
190
 
266
209
   hSizer->Add(mTotalTime, 1, wxALL | wxEXPAND, 5);
267
210
   mainSizer->Add(hSizer, 0, wxALIGN_CENTRE | wxALL, 5);
268
211
 
269
 
   hSizer = new wxBoxSizer(wxHORIZONTAL);
270
 
 
271
 
   wxButton *cancel = new wxButton(this, wxID_CANCEL, _("&Cancel"));
272
 
   hSizer->Add(cancel, 0, wxALIGN_CENTRE|wxALL, 5);
273
 
 
274
 
   wxButton *ok = new wxButton(this, wxID_OK, _("&OK"));
275
 
   ok->SetDefault();
276
 
   hSizer->Add(ok, 0, wxALIGN_CENTRE|wxALL, 5);
277
 
 
278
 
   mainSizer->Add(hSizer, 0, wxALIGN_CENTRE|wxALIGN_CENTER_VERTICAL|wxALL, 5);
 
212
   // OK & Cancel buttons
 
213
   mainSizer->Add(CreateStdButtonSizer(this, eCancelButton|eOkButton), 0, wxEXPAND);
279
214
 
280
215
   SetAutoLayout(true);
281
216
   SetSizer(mainSizer);