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