Audacity  3.0.3
SBSMSEffect.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3 Audacity: A Digital Audio Editor
4 
5 SBSMSEffect.cpp
6 
7 Clayton Otey
8 
9 This class contains all of the common code for an
10 effect that uses SBSMS to do its processing (TimeScale)
11 
12 **********************************************************************/
13 
14 
15 
16 #if USE_SBSMS
17 #include "SBSMSEffect.h"
18 
19 #include <math.h>
20 
21 #include "../LabelTrack.h"
22 #include "../WaveClip.h"
23 #include "../WaveTrack.h"
24 #include "TimeWarper.h"
25 
26 enum {
27  SBSMSOutBlockSize = 512
28 };
29 
31 {
32 public:
34  {
35  processed = 0;
36  }
37 
39  {
40  }
41 
42  bool bPitch;
44  double ratio;
46  size_t blockSize;
54  std::unique_ptr<SBSMS> sbsms;
55  std::unique_ptr<SBSMSInterface> iface;
57 
58  // Not required by callbacks, but makes for easier cleanup
59  std::unique_ptr<Resampler> resampler;
60  std::unique_ptr<SBSMSQuality> quality;
61  std::shared_ptr<WaveTrack> outputLeftTrack;
62  std::shared_ptr<WaveTrack> outputRightTrack;
63 
64  std::exception_ptr mpException {};
65 };
66 
67 class SBSMSEffectInterface final : public SBSMSInterfaceSliding {
68 public:
70  Slide *rateSlide, Slide *pitchSlide,
71  bool bReferenceInput,
72  const SampleCountType samples, long preSamples,
73  SBSMSQuality *quality)
74  : SBSMSInterfaceSliding(rateSlide,pitchSlide,bReferenceInput,samples,preSamples,quality)
75  {
76  this->resampler = resampler;
77  }
78  virtual ~SBSMSEffectInterface() {}
79 
80  long samples(audio *buf, long n) {
81  return resampler->read(buf, n);
82  }
83 
84 protected:
85  Resampler *resampler;
86 };
87 
88 long resampleCB(void *cb_data, SBSMSFrame *data)
89 {
90  ResampleBuf *r = (ResampleBuf*) cb_data;
91 
92  auto blockSize = limitSampleBufferSize(
94  r->end - r->offset
95  );
96 
97  // Get the samples from the tracks and put them in the buffers.
98  // I don't know if we can safely propagate errors through sbsms, and it
99  // does not seem to let us report error codes, so use this roundabout to
100  // stop the effect early.
101  try {
102  r->leftTrack->Get(
103  (samplePtr)(r->leftBuffer.get()), floatSample, r->offset, blockSize);
104  r->rightTrack->Get(
105  (samplePtr)(r->rightBuffer.get()), floatSample, r->offset, blockSize);
106  }
107  catch ( ... ) {
108  // Save the exception object for re-throw when out of the library
109  r->mpException = std::current_exception();
110  data->size = 0;
111  return 0;
112  }
113 
114  // convert to sbsms audio format
115  for(decltype(blockSize) i=0; i<blockSize; i++) {
116  r->buf[i][0] = r->leftBuffer[i];
117  r->buf[i][1] = r->rightBuffer[i];
118  }
119 
120  data->buf = r->buf.get();
121  data->size = blockSize;
122  if(r->bPitch) {
123  float t0 = r->processed.as_float() / r->iface->getSamplesToInput();
124  float t1 = (r->processed + blockSize).as_float() / r->iface->getSamplesToInput();
125  data->ratio0 = r->iface->getStretch(t0);
126  data->ratio1 = r->iface->getStretch(t1);
127  } else {
128  data->ratio0 = r->ratio;
129  data->ratio1 = r->ratio;
130  }
131  r->processed += blockSize;
132  r->offset += blockSize;
133  return blockSize;
134 }
135 
136 long postResampleCB(void *cb_data, SBSMSFrame *data)
137 {
138  ResampleBuf *r = (ResampleBuf*) cb_data;
139  auto count = r->sbsms->read(r->iface.get(), r->SBSMSBuf.get(), r->SBSMSBlockSize);
140  data->buf = r->SBSMSBuf.get();
141  data->size = count;
142  data->ratio0 = 1.0 / r->ratio;
143  data->ratio1 = 1.0 / r->ratio;
144  return count;
145 }
146 
147 void EffectSBSMS :: setParameters(double rateStartIn, double rateEndIn, double pitchStartIn, double pitchEndIn,
148  SlideType rateSlideTypeIn, SlideType pitchSlideTypeIn,
149  bool bLinkRatePitchIn, bool bRateReferenceInputIn, bool bPitchReferenceInputIn)
150 {
151  this->rateStart = rateStartIn;
152  this->rateEnd = rateEndIn;
153  this->pitchStart = pitchStartIn;
154  this->pitchEnd = pitchEndIn;
155  this->bLinkRatePitch = bLinkRatePitchIn;
156  this->rateSlideType = rateSlideTypeIn;
157  this->pitchSlideType = pitchSlideTypeIn;
158  this->bRateReferenceInput = bRateReferenceInputIn;
159  this->bPitchReferenceInput = bPitchReferenceInputIn;
160 }
161 
162 void EffectSBSMS::setParameters(double tempoRatio, double pitchRatio)
163 {
164  setParameters(tempoRatio, tempoRatio, pitchRatio, pitchRatio,
165  SlideConstant, SlideConstant, false, false, false);
166 }
167 
168 std::unique_ptr<TimeWarper> createTimeWarper(double t0, double t1, double duration,
169  double rateStart, double rateEnd, SlideType rateSlideType)
170 {
171  std::unique_ptr<TimeWarper> warper;
172  if (rateStart == rateEnd || rateSlideType == SlideConstant) {
173  warper = std::make_unique<LinearTimeWarper>(t0, t0, t1, t0+duration);
174  } else if(rateSlideType == SlideLinearInputRate) {
175  warper = std::make_unique<LinearInputRateTimeWarper>(t0, t1, rateStart, rateEnd);
176  } else if(rateSlideType == SlideLinearOutputRate) {
177  warper = std::make_unique<LinearOutputRateTimeWarper>(t0, t1, rateStart, rateEnd);
178  } else if(rateSlideType == SlideLinearInputStretch) {
179  warper = std::make_unique<LinearInputStretchTimeWarper>(t0, t1, rateStart, rateEnd);
180  } else if(rateSlideType == SlideLinearOutputStretch) {
181  warper = std::make_unique<LinearOutputStretchTimeWarper>(t0, t1, rateStart, rateEnd);
182  } else if(rateSlideType == SlideGeometricInput) {
183  warper = std::make_unique<GeometricInputTimeWarper>(t0, t1, rateStart, rateEnd);
184  } else if(rateSlideType == SlideGeometricOutput) {
185  warper = std::make_unique<GeometricOutputTimeWarper>(t0, t1, rateStart, rateEnd);
186  }
187  return warper;
188 }
189 
190 // Labels inside the affected region are moved to match the audio; labels after
191 // it are shifted along appropriately.
193 {
195  RegionTimeWarper warper{ mT0, mT1, std::move(warper1) };
196  lt->WarpLabels(warper);
197  return true;
198 }
199 
200 double EffectSBSMS::getInvertedStretchedTime(double rateStart, double rateEnd, SlideType slideType, double outputTime)
201 {
202  Slide slide(slideType,rateStart,rateEnd,0);
203  return slide.getInverseStretchedTime(outputTime);
204 }
205 
206 double EffectSBSMS::getRate(double rateStart, double rateEnd, SlideType slideType, double t)
207 {
208  Slide slide(slideType,rateStart,rateEnd,0);
209  return slide.getRate(t);
210 }
211 
213 {
214  bool bGoodResult = true;
215 
216  //Iterate over each track
217  //all needed because this effect needs to introduce silence in the group tracks to keep sync
218  this->CopyInputTracks(true); // Set up mOutputTracks.
219  mCurTrackNum = 0;
220 
221  double maxDuration = 0.0;
222 
223  // Must sync if selection length will change
224  bool mustSync = (rateStart != rateEnd);
225  Slide rateSlide(rateSlideType,rateStart,rateEnd);
226  Slide pitchSlide(pitchSlideType,pitchStart,pitchEnd);
227  mTotalStretch = rateSlide.getTotalStretch();
228 
229  mOutputTracks->Leaders().VisitWhile( bGoodResult,
230  [&](LabelTrack *lt, const Track::Fallthrough &fallthrough) {
231  if (!(lt->GetSelected() || (mustSync && lt->IsSyncLockSelected())))
232  return fallthrough();
233  if (!ProcessLabelTrack(lt))
234  bGoodResult = false;
235  },
236  [&](WaveTrack *leftTrack, const Track::Fallthrough &fallthrough) {
237  if (!leftTrack->GetSelected())
238  return fallthrough();
239 
240  //Get start and end times from selection
241  mCurT0 = mT0;
242  mCurT1 = mT1;
243 
244  //Set the current bounds to whichever left marker is
245  //greater and whichever right marker is less
246  mCurT0 = wxMax(mT0, mCurT0);
247  mCurT1 = wxMin(mT1, mCurT1);
248 
249  // Process only if the right marker is to the right of the left marker
250  if (mCurT1 > mCurT0) {
251  auto start = leftTrack->TimeToLongSamples(mCurT0);
252  auto end = leftTrack->TimeToLongSamples(mCurT1);
253 
254  // TODO: more-than-two-channels
255  auto channels = TrackList::Channels(leftTrack);
256  WaveTrack *rightTrack = (channels.size() > 1)
257  ? * ++ channels.first
258  : nullptr;
259  if (rightTrack) {
260  double t;
261 
262  //Adjust bounds by the right tracks markers
263  t = rightTrack->GetStartTime();
264  t = wxMax(mT0, t);
265  mCurT0 = wxMin(mCurT0, t);
266  t = rightTrack->GetEndTime();
267  t = wxMin(mT1, t);
268  mCurT1 = wxMax(mCurT1, t);
269 
270  //Transform the marker timepoints to samples
271  start = leftTrack->TimeToLongSamples(mCurT0);
272  end = leftTrack->TimeToLongSamples(mCurT1);
273 
274  mCurTrackNum++; // Increment for rightTrack, too.
275  }
276 
277  // SBSMS has a fixed sample rate - we just convert to its sample rate and then convert back
278  float srTrack = leftTrack->GetRate();
279  float srProcess = bLinkRatePitch ? srTrack : 44100.0;
280 
281  // the resampler needs a callback to supply its samples
282  ResampleBuf rb;
283  auto maxBlockSize = leftTrack->GetMaxBlockSize();
284  rb.blockSize = maxBlockSize;
285  rb.buf.reinit(rb.blockSize, true);
286  rb.leftTrack = leftTrack;
287  rb.rightTrack = rightTrack?rightTrack:leftTrack;
288  rb.leftBuffer.reinit(maxBlockSize, true);
289  rb.rightBuffer.reinit(maxBlockSize, true);
290 
291  // Samples in selection
292  auto samplesIn = end - start;
293 
294  // Samples for SBSMS to process after resampling
295  auto samplesToProcess = (sampleCount) (samplesIn.as_float() * (srProcess/srTrack));
296 
297  SlideType outSlideType;
298  SBSMSResampleCB outResampleCB;
299 
300  if(bLinkRatePitch) {
301  rb.bPitch = true;
302  outSlideType = rateSlideType;
303  outResampleCB = resampleCB;
304  rb.offset = start;
305  rb.end = end;
306  // Third party library has its own type alias, check it
307  static_assert(sizeof(sampleCount::type) <=
308  sizeof(_sbsms_::SampleCountType),
309  "Type _sbsms_::SampleCountType is too narrow to hold a sampleCount");
310  rb.iface = std::make_unique<SBSMSInterfaceSliding>
311  (&rateSlide, &pitchSlide, bPitchReferenceInput,
312  static_cast<_sbsms_::SampleCountType>
313  ( samplesToProcess.as_long_long() ),
314  0, nullptr);
315 
316  }
317  else {
318  rb.bPitch = false;
319  outSlideType = (srProcess==srTrack?SlideIdentity:SlideConstant);
320  outResampleCB = postResampleCB;
321  rb.ratio = srProcess/srTrack;
322  rb.quality = std::make_unique<SBSMSQuality>(&SBSMSQualityStandard);
323  rb.resampler = std::make_unique<Resampler>(resampleCB, &rb, srProcess==srTrack?SlideIdentity:SlideConstant);
324  rb.sbsms = std::make_unique<SBSMS>(rightTrack ? 2 : 1, rb.quality.get(), true);
325  rb.SBSMSBlockSize = rb.sbsms->getInputFrameSize();
326  rb.SBSMSBuf.reinit(static_cast<size_t>(rb.SBSMSBlockSize), true);
327  rb.offset = start;
328  rb.end = end;
329  rb.iface = std::make_unique<SBSMSEffectInterface>
330  (rb.resampler.get(), &rateSlide, &pitchSlide,
332  static_cast<_sbsms_::SampleCountType>( samplesToProcess.as_long_long() ),
333  0,
334  rb.quality.get());
335  }
336 
337  Resampler resampler(outResampleCB,&rb,outSlideType);
338 
339  audio outBuf[SBSMSOutBlockSize];
340  float outBufLeft[2*SBSMSOutBlockSize];
341  float outBufRight[2*SBSMSOutBlockSize];
342 
343  // Samples in output after SBSMS
344  sampleCount samplesToOutput = rb.iface->getSamplesToOutput();
345 
346  // Samples in output after resampling back
347  auto samplesOut = (sampleCount) (samplesToOutput.as_float() * (srTrack/srProcess));
348 
349  // Duration in track time
350  double duration = (mCurT1-mCurT0) * mTotalStretch;
351 
352  if(duration > maxDuration)
353  maxDuration = duration;
354 
355  auto warper = createTimeWarper(mCurT0,mCurT1,maxDuration,rateStart,rateEnd,rateSlideType);
356 
357  rb.outputLeftTrack = leftTrack->EmptyCopy();
358  if(rightTrack)
359  rb.outputRightTrack = rightTrack->EmptyCopy();
360 
361  long pos = 0;
362  long outputCount = -1;
363 
364  // process
365  while(pos<samplesOut && outputCount) {
366  const auto frames =
367  limitSampleBufferSize( SBSMSOutBlockSize, samplesOut - pos );
368 
369  outputCount = resampler.read(outBuf,frames);
370  for(int i = 0; i < outputCount; i++) {
371  outBufLeft[i] = outBuf[i][0];
372  if(rightTrack)
373  outBufRight[i] = outBuf[i][1];
374  }
375  pos += outputCount;
376  rb.outputLeftTrack->Append((samplePtr)outBufLeft, floatSample, outputCount);
377  if(rightTrack)
378  rb.outputRightTrack->Append((samplePtr)outBufRight, floatSample, outputCount);
379 
380  double frac = (double)pos / samplesOut.as_double();
381  int nWhichTrack = mCurTrackNum;
382  if(rightTrack) {
383  nWhichTrack = 2*(mCurTrackNum/2);
384  if (frac < 0.5)
385  frac *= 2.0; // Show twice as far for each track, because we're doing 2 at once.
386  else {
387  nWhichTrack++;
388  frac -= 0.5;
389  frac *= 2.0; // Show twice as far for each track, because we're doing 2 at once.
390  }
391  }
392  if (TrackProgress(nWhichTrack, frac)) {
393  bGoodResult = false;
394  return;
395  }
396  }
397 
398  {
399  auto pException = rb.mpException;
400  rb.mpException = {};
401  if (pException)
402  std::rethrow_exception(pException);
403  }
404 
405  rb.outputLeftTrack->Flush();
406  if(rightTrack)
407  rb.outputRightTrack->Flush();
408 
409  Finalize(leftTrack, rb.outputLeftTrack.get(), warper.get());
410  if(rightTrack)
411  Finalize(rightTrack, rb.outputRightTrack.get(), warper.get());
412  }
413  mCurTrackNum++;
414  },
415  [&](Track *t) {
416  if (mustSync && t->IsSyncLockSelected())
417  {
418  t->SyncLockAdjust(mCurT1, mCurT0 + (mCurT1 - mCurT0) * mTotalStretch);
419  }
420  }
421  );
422 
423  if (bGoodResult) {
424  ReplaceProcessedTracks(bGoodResult);
425  }
426 
427  return bGoodResult;
428 }
429 
430 void EffectSBSMS::Finalize(WaveTrack* orig, WaveTrack* out, const TimeWarper *warper)
431 {
432  // Silenced samples will be inserted in gaps between clips, so capture where these
433  // gaps are for later deletion
434  std::vector<std::pair<double, double>> gaps;
435  double last = 0.0;
436  auto clips = orig->SortedClipArray();
437  auto front = clips.front();
438  auto back = clips.back();
439  for (auto &clip : clips) {
440  auto st = clip->GetStartTime();
441  auto et = clip->GetEndTime();
442 
443  if (st >= mCurT0 || et < mCurT1) {
444  if (mCurT0 < st && clip == front) {
445  gaps.push_back(std::make_pair(mCurT0, st));
446  }
447  if (mCurT1 > et && clip == back) {
448  gaps.push_back(std::make_pair(et, mCurT1));
449  }
450  if (last >= mCurT0) {
451  gaps.push_back(std::make_pair(last, st));
452  }
453  }
454  last = et;
455  }
456 
457  // Take the output track and insert it in place of the original sample data
458  orig->ClearAndPaste(mCurT0, mCurT1, out, true, true, warper);
459 
460  // Finally, recreate the gaps
461  for (auto gap : gaps) {
462  auto st = orig->LongSamplesToTime(orig->TimeToLongSamples(gap.first));
463  auto et = orig->LongSamplesToTime(orig->TimeToLongSamples(gap.second));
464  if (st >= mCurT0 && et <= mCurT1 && st != et)
465  {
466  orig->SplitDelete(warper->Warp(st), warper->Warp(et));
467  }
468  }
469 }
470 
471 #endif
EffectSBSMS::rateEnd
double rateEnd
Definition: SBSMSEffect.h:51
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:68
EffectSBSMS::mTotalStretch
float mTotalStretch
Definition: SBSMSEffect.h:58
TimeWarper
Transforms one point in time to another point. For example, a time stretching effect might use one to...
Definition: TimeWarper.h:62
EffectSBSMS::bPitchReferenceInput
bool bPitchReferenceInput
Definition: SBSMSEffect.h:52
EffectSBSMS::pitchStart
double pitchStart
Definition: SBSMSEffect.h:51
ResampleBuf::leftBuffer
ArrayOf< float > leftBuffer
Definition: SBSMSEffect.cpp:50
WaveTrack::GetEndTime
double GetEndTime() const override
Get the time at which the last clip in the track ends, plus recorded stuff.
Definition: WaveTrack.cpp:1797
ResampleBuf::ResampleBuf
ResampleBuf()
Definition: SBSMSEffect.cpp:33
Effect::CopyInputTracks
void CopyInputTracks(bool allSyncLockSelected=false)
Definition: Effect.cpp:2070
EffectSBSMS::mCurT1
double mCurT1
Definition: SBSMSEffect.h:57
TimeWarper.h
Contains declarations for TimeWarper, IdentityTimeWarper, ShiftTimeWarper, LinearTimeWarper,...
TrackList::Channels
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1467
SBSMSEffect.h
Effect::mT1
double mT1
Definition: Effect.h:466
ArrayOf::reinit
void reinit(Integral count, bool initialize=false)
Definition: MemoryX.h:112
ResampleBuf::sbsms
std::unique_ptr< SBSMS > sbsms
Definition: SBSMSEffect.cpp:54
LabelTrack
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:88
ResampleBuf::mpException
std::exception_ptr mpException
Definition: SBSMSEffect.cpp:64
floatSample
@ floatSample
Definition: Types.h:714
WaveTrack::ClearAndPaste
void ClearAndPaste(double t0, double t1, const Track *src, bool preserve=true, bool merge=true, const TimeWarper *effectWarper=NULL)
Definition: WaveTrack.cpp:750
sampleCount::as_float
float as_float() const
Definition: Types.h:607
Track::IsSyncLockSelected
bool IsSyncLockSelected() const
Definition: Track.cpp:245
WaveTrack::EmptyCopy
Holder EmptyCopy(const SampleBlockFactoryPtr &pFactory={}) const
Definition: WaveTrack.cpp:574
ResampleBuf::~ResampleBuf
~ResampleBuf()
Definition: SBSMSEffect.cpp:38
WaveTrack::SplitDelete
void SplitDelete(double t0, double t1)
Definition: WaveTrack.cpp:926
WaveTrack::Get
bool Get(samplePtr buffer, sampleFormat format, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
Definition: WaveTrack.cpp:1895
WaveTrack::SortedClipArray
WaveClipPointers SortedClipArray()
Definition: WaveTrack.cpp:2502
limitSampleBufferSize
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: Types.h:698
ResampleBuf
Definition: SBSMSEffect.cpp:31
EffectSBSMS::mCurTrackNum
int mCurTrackNum
Definition: SBSMSEffect.h:55
ResampleBuf::rightBuffer
ArrayOf< float > rightBuffer
Definition: SBSMSEffect.cpp:51
ResampleBuf::offset
sampleCount offset
Definition: SBSMSEffect.cpp:48
SBSMSEffectInterface::resampler
Resampler * resampler
Definition: SBSMSEffect.cpp:85
ResampleBuf::blockSize
size_t blockSize
Definition: SBSMSEffect.cpp:46
samplePtr
char * samplePtr
Definition: Types.h:729
Effect::mT0
double mT0
Definition: Effect.h:465
postResampleCB
long postResampleCB(void *cb_data, SBSMSFrame *data)
Definition: SBSMSEffect.cpp:136
WaveTrack::LongSamplesToTime
double LongSamplesToTime(sampleCount pos) const
Convert correctly between a number of samples and an (absolute) time in seconds.
Definition: WaveTrack.cpp:1772
EffectSBSMS::bLinkRatePitch
bool bLinkRatePitch
Definition: SBSMSEffect.h:52
ResampleBuf::quality
std::unique_ptr< SBSMSQuality > quality
Definition: SBSMSEffect.cpp:60
EffectSBSMS::bRateReferenceInput
bool bRateReferenceInput
Definition: SBSMSEffect.h:52
RegionTimeWarper
No change before the specified region; during the region, warp according to the given warper; after t...
Definition: TimeWarper.h:192
LabelTrack::WarpLabels
void WarpLabels(const TimeWarper &warper)
Definition: LabelTrack.cpp:256
ResampleBuf::ratio
double ratio
Definition: SBSMSEffect.cpp:44
ResampleBuf::iface
std::unique_ptr< SBSMSInterface > iface
Definition: SBSMSEffect.cpp:55
Effect::ReplaceProcessedTracks
void ReplaceProcessedTracks(const bool bGoodResult)
Definition: Effect.cpp:2192
Track::Fallthrough
Continuation<> Fallthrough
Type of arguments passed as optional second parameter to TypeSwitch<void>() cases.
Definition: Track.h:487
gap
static const int gap
Definition: Meter.cpp:255
EffectSBSMS::ProcessLabelTrack
bool ProcessLabelTrack(LabelTrack *track)
Definition: SBSMSEffect.cpp:192
WaveTrack::GetStartTime
double GetStartTime() const override
Get the time at which the first clip in the track starts.
Definition: WaveTrack.cpp:1777
sampleCount::type
long long type
Definition: Types.h:583
SBSMSEffectInterface::SBSMSEffectInterface
SBSMSEffectInterface(Resampler *resampler, Slide *rateSlide, Slide *pitchSlide, bool bReferenceInput, const SampleCountType samples, long preSamples, SBSMSQuality *quality)
Definition: SBSMSEffect.cpp:69
TimeWarper::Warp
virtual double Warp(double originalTime) const =0
Effect::mOutputTracks
std::shared_ptr< TrackList > mOutputTracks
Definition: Effect.h:464
EffectSBSMS::rateStart
double rateStart
Definition: SBSMSEffect.h:51
Track::GetSelected
bool GetSelected() const
Definition: Track.h:414
WaveTrack::GetMaxBlockSize
size_t GetMaxBlockSize() const
Definition: WaveTrack.cpp:1578
EffectSBSMS::getRate
static double getRate(double rateStart, double rateEnd, SlideType slideType, double t)
Definition: SBSMSEffect.cpp:206
SBSMSEffectInterface::samples
long samples(audio *buf, long n)
Definition: SBSMSEffect.cpp:80
EffectSBSMS::getInvertedStretchedTime
static double getInvertedStretchedTime(double rateStart, double rateEnd, SlideType slideType, double outputTime)
Definition: SBSMSEffect.cpp:200
ResampleBuf::leftTrack
WaveTrack * leftTrack
Definition: SBSMSEffect.cpp:52
WaveTrack::TimeToLongSamples
sampleCount TimeToLongSamples(double t0) const
Convert correctly between an (absolute) time in seconds and a number of samples.
Definition: WaveTrack.cpp:1767
resampleCB
long resampleCB(void *cb_data, SBSMSFrame *data)
Definition: SBSMSEffect.cpp:88
ResampleBuf::outputLeftTrack
std::shared_ptr< WaveTrack > outputLeftTrack
Definition: SBSMSEffect.cpp:61
Track
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:238
ResampleBuf::outputRightTrack
std::shared_ptr< WaveTrack > outputRightTrack
Definition: SBSMSEffect.cpp:62
ResampleBuf::end
sampleCount end
Definition: SBSMSEffect.cpp:49
ResampleBuf::rightTrack
WaveTrack * rightTrack
Definition: SBSMSEffect.cpp:53
sampleCount
Definition: Types.h:581
EffectSBSMS::pitchSlideType
SlideType pitchSlideType
Definition: SBSMSEffect.h:54
EffectSBSMS::mCurT0
double mCurT0
Definition: SBSMSEffect.h:56
SBSMSEffectInterface
Definition: SBSMSEffect.cpp:67
WaveTrack::GetBestBlockSize
size_t GetBestBlockSize(sampleCount t) const
Definition: WaveTrack.cpp:1560
EffectSBSMS::Finalize
void Finalize(WaveTrack *orig, WaveTrack *out, const TimeWarper *warper)
Definition: SBSMSEffect.cpp:430
ResampleBuf::buf
ArrayOf< audio > buf
Definition: SBSMSEffect.cpp:43
ResampleBuf::bPitch
bool bPitch
Definition: SBSMSEffect.cpp:42
SBSMSOutBlockSize
@ SBSMSOutBlockSize
Definition: SBSMSEffect.cpp:27
EffectSBSMS::pitchEnd
double pitchEnd
Definition: SBSMSEffect.h:51
Effect::TrackProgress
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={})
Definition: Effect.cpp:2024
ArrayOf< audio >
ResampleBuf::SBSMSBlockSize
long SBSMSBlockSize
Definition: SBSMSEffect.cpp:47
ResampleBuf::SBSMSBuf
ArrayOf< audio > SBSMSBuf
Definition: SBSMSEffect.cpp:56
createTimeWarper
std::unique_ptr< TimeWarper > createTimeWarper(double t0, double t1, double duration, double rateStart, double rateEnd, SlideType rateSlideType)
Definition: SBSMSEffect.cpp:168
SBSMSEffectInterface::~SBSMSEffectInterface
virtual ~SBSMSEffectInterface()
Definition: SBSMSEffect.cpp:78
EffectSBSMS::rateSlideType
SlideType rateSlideType
Definition: SBSMSEffect.h:53
ResampleBuf::resampler
std::unique_ptr< Resampler > resampler
Definition: SBSMSEffect.cpp:59
EffectSBSMS::setParameters
void setParameters(double rateStart, double rateEnd, double pitchStart, double pitchEnd, SlideType rateSlideType, SlideType pitchSlideType, bool bLinkRatePitch, bool bRateReferenceInput, bool bPitchReferenceInput)
Definition: SBSMSEffect.cpp:147
ResampleBuf::processed
sampleCount processed
Definition: SBSMSEffect.cpp:45
WaveTrack::GetRate
double GetRate() const
Definition: WaveTrack.cpp:360
EffectSBSMS::Process
bool Process() override
Definition: SBSMSEffect.cpp:212