21#include "../LabelTrack.h"
22#include "../SyncLock.h"
23#include "../WaveClip.h"
24#include "../WaveTrack.h"
56 std::unique_ptr<SBSMSInterface>
iface;
71 Slide *rateSlide, Slide *pitchSlide,
73 const SampleCountType
samples,
long preSamples,
74 SBSMSQuality *quality)
75 : SBSMSInterfaceSliding(rateSlide,pitchSlide,bReferenceInput,
samples,preSamples,quality)
116 for(
decltype(blockSize) i=0; i<blockSize; i++) {
121 data->buf = r->
buf.get();
122 data->size = blockSize;
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);
129 data->ratio0 = r->
ratio;
130 data->ratio1 = r->
ratio;
143 data->ratio0 = 1.0 / r->
ratio;
144 data->ratio1 = 1.0 / r->
ratio;
149 SlideType rateSlideTypeIn, SlideType pitchSlideTypeIn,
150 bool bLinkRatePitchIn,
bool bRateReferenceInputIn,
bool bPitchReferenceInputIn)
165 setParameters(tempoRatio, tempoRatio, pitchRatio, pitchRatio,
166 SlideConstant, SlideConstant,
false,
false,
false);
170 double rateStart,
double rateEnd, SlideType rateSlideType)
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);
204 return slide.getInverseStretchedTime(outputTime);
210 return slide.getRate(t);
215 bool bGoodResult =
true;
222 double maxDuration = 0.0;
234 return fallthrough();
240 return fallthrough();
258 WaveTrack *rightTrack = (channels.size() > 1)
259 ? * ++ channels.first
280 float srTrack = leftTrack->
GetRate();
289 rb.
rightTrack = rightTrack?rightTrack:leftTrack;
294 auto samplesIn =
end - start;
297 auto samplesToProcess = (
sampleCount) (samplesIn.as_float() * (srProcess/srTrack));
299 SlideType outSlideType;
300 SBSMSResampleCB outResampleCB;
310 sizeof(_sbsms_::SampleCountType),
311 "Type _sbsms_::SampleCountType is too narrow to hold a sampleCount");
312 rb.
iface = std::make_unique<SBSMSInterfaceSliding>
314 static_cast<_sbsms_::SampleCountType
>
315 ( samplesToProcess.as_long_long() ),
321 outSlideType = (srProcess==srTrack?SlideIdentity:SlideConstant);
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);
331 rb.
iface = std::make_unique<SBSMSEffectInterface>
332 (rb.
resampler.get(), &rateSlide, &pitchSlide,
334 static_cast<_sbsms_::SampleCountType
>( samplesToProcess.as_long_long() ),
339 Resampler resampler(outResampleCB,&rb,outSlideType);
354 if(duration > maxDuration)
355 maxDuration = duration;
364 long outputCount = -1;
367 while(pos<samplesOut && outputCount) {
371 outputCount = resampler.read(outBuf,frames);
372 for(
int i = 0; i < outputCount; i++) {
373 outBufLeft[i] = outBuf[i][0];
375 outBufRight[i] = outBuf[i][1];
382 double frac = (double)pos / samplesOut.as_double();
404 std::rethrow_exception(pException);
436 std::vector<std::pair<double, double>> gaps;
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();
446 if (
mCurT0 < st && clip == front) {
447 gaps.push_back(std::make_pair(
mCurT0, st));
449 else if (last < st &&
mCurT0 <= last ) {
450 gaps.push_back(std::make_pair(last, st));
453 if (et <
mCurT1 && clip == back) {
454 gaps.push_back(std::make_pair(et,
mCurT1));
464 for (
auto gap : gaps) {
std::unique_ptr< TimeWarper > createTimeWarper(double t0, double t1, double duration, double rateStart, double rateEnd, SlideType rateSlideType)
long postResampleCB(void *cb_data, SBSMSFrame *data)
long resampleCB(void *cb_data, SBSMSFrame *data)
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Contains declarations for TimeWarper, IdentityTimeWarper, ShiftTimeWarper, LinearTimeWarper,...
void reinit(Integral count, bool initialize=false)
std::shared_ptr< TrackList > mOutputTracks
void ReplaceProcessedTracks(const bool bGoodResult)
void CopyInputTracks(bool allSyncLockSelected=false)
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={}) const
Performs effect computation.
void setParameters(double rateStart, double rateEnd, double pitchStart, double pitchEnd, SlideType rateSlideType, SlideType pitchSlideType, bool bLinkRatePitch, bool bRateReferenceInput, bool bPitchReferenceInput)
bool ProcessLabelTrack(LabelTrack *track)
bool bPitchReferenceInput
static double getInvertedStretchedTime(double rateStart, double rateEnd, SlideType slideType, double outputTime)
void Finalize(WaveTrack *orig, WaveTrack *out, const TimeWarper *warper)
bool Process(EffectInstance &instance, EffectSettings &settings) override
static double getRate(double rateStart, double rateEnd, SlideType slideType, double t)
A LabelTrack is a Track that holds labels (LabelStruct).
void WarpLabels(const TimeWarper &warper)
No change before the specified region; during the region, warp according to the given warper; after t...
ArrayOf< audio > SBSMSBuf
std::shared_ptr< WaveTrack > outputRightTrack
std::unique_ptr< SBSMSInterface > iface
ArrayOf< float > leftBuffer
std::unique_ptr< SBSMSQuality > quality
std::shared_ptr< WaveTrack > outputLeftTrack
std::exception_ptr mpException
ArrayOf< float > rightBuffer
std::unique_ptr< SBSMS > sbsms
std::unique_ptr< Resampler > resampler
long samples(audio *buf, long n)
virtual ~SBSMSEffectInterface()
SBSMSEffectInterface(Resampler *resampler, Slide *rateSlide, Slide *pitchSlide, bool bReferenceInput, const SampleCountType samples, long preSamples, SBSMSQuality *quality)
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.
double LongSamplesToTime(sampleCount pos) const
Convert correctly between a number of samples and an (absolute) time in seconds.
sampleCount TimeToLongSamples(double t0) const
Convert correctly between an (absolute) time in seconds and a number of samples.
static bool IsSyncLockSelected(const Track *pTrack)
Transforms one point in time to another point. For example, a time stretching effect might use one to...
virtual double Warp(double originalTime) const =0
Abstract base class for an object holding data associated with points on a time axis.
Continuation<> Fallthrough
Type of arguments passed as optional second parameter to TypeSwitch<void>() cases.
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
A Track that contains audio waveform data.
void SplitDelete(double t0, double t1)
double GetStartTime() const override
Get the time at which the first clip in the track starts.
size_t GetMaxBlockSize() const override
This returns a nonnegative number of samples meant to size a memory buffer.
size_t GetBestBlockSize(sampleCount t) const override
This returns a nonnegative number of samples meant to size a memory buffer.
WaveClipPointers SortedClipArray()
double GetEndTime() const override
Get the time at which the last clip in the track ends, plus recorded stuff.
double GetRate() const override
void ClearAndPaste(double t0, double t1, const Track *src, bool preserve=true, bool merge=true, const TimeWarper *effectWarper=NULL)
Holder EmptyCopy(const SampleBlockFactoryPtr &pFactory={}, bool keepLink=true) const
Positions or offsets within audio files need a wide type.
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Externalized state of a plug-in.