107
108
bool EffectRepeat::Process()
109
TrackListIterator iter(mWaveTracks);
110
this->CopyInputWaveTracks(); // Set up m_pOutputWaveTracks.
111
bool bGoodResult = true;
113
TrackListIterator iter(m_pOutputWaveTracks);
110
114
WaveTrack *track = (WaveTrack *) iter.First();
112
double maxDestLen = 0.0; // used to change selection to original plus generated
113
double newDestLen = 0.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;
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.
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);
149
while (chunkSize * numCopies < minBlockSize)
152
if (chunkSize > maxBlockSize) {
155
while(chunkSize/j >= maxBlockSize)
158
chunkSize = (chunkSize + (j-1)) / j;
161
sampleCount totalSamples = 0;
162
while(totalSamples < len * numCopies) {
163
sampleCount blockLen = chunkSize;
164
sampleCount blockStart = (totalSamples % len);
166
if (totalSamples + blockLen > len * numCopies)
167
blockLen = len * numCopies - totalSamples;
169
if (!track->Get(buffer, format, start+blockStart, blockLen)) {
136
track->Copy(t0, t1, &dest);
137
for(int j=0; j<repeatCount; j++)
139
if (!track->Paste(tc, dest) ||
140
TrackProgress(nTrack, j / repeatCount)) // TrackProgress returns true on Cancel.
174
unitTrack->Append(buffer, format, blockLen);
178
totalSamples += blockLen;
184
// Repeat the unit track enough times, possible creating a few
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);
194
// If necessary, delete a few copies from the end
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);
205
newDestLen = dest->GetEndTime();
208
if (newDestLen > maxDestLen)
209
maxDestLen = newDestLen;
211
track->Clear(t0, t1);
212
track->Paste(t0, dest);
217
151
track = (WaveTrack *) iter.Next();
221
mT1 = mT0 + maxDestLen; // Change selection to original plus generated.
157
// Change selection to just the generated bits.
162
this->ReplaceProcessedWaveTracks(bGoodResult);
225
166
//----------------------------------------------------------------------------
266
209
hSizer->Add(mTotalTime, 1, wxALL | wxEXPAND, 5);
267
210
mainSizer->Add(hSizer, 0, wxALIGN_CENTRE | wxALL, 5);
269
hSizer = new wxBoxSizer(wxHORIZONTAL);
271
wxButton *cancel = new wxButton(this, wxID_CANCEL, _("&Cancel"));
272
hSizer->Add(cancel, 0, wxALIGN_CENTRE|wxALL, 5);
274
wxButton *ok = new wxButton(this, wxID_OK, _("&OK"));
276
hSizer->Add(ok, 0, wxALIGN_CENTRE|wxALL, 5);
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);
280
215
SetAutoLayout(true);
281
216
SetSizer(mainSizer);