1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-19 14:17:41 +02:00

Bug 1215 - Incorrect splits produced by Change Tempo with leading whitespace

This commit is contained in:
Leland Lucius 2021-01-29 23:23:54 -06:00
parent 6c44b4fdc0
commit 0576d8c945
2 changed files with 23 additions and 39 deletions

View File

@ -69,7 +69,7 @@ public:
SBSMSEffectInterface(Resampler *resampler,
Slide *rateSlide, Slide *pitchSlide,
bool bReferenceInput,
long samples, long preSamples,
const SampleCountType samples, long preSamples,
SBSMSQuality *quality)
: SBSMSInterfaceSliding(rateSlide,pitchSlide,bReferenceInput,samples,preSamples,quality)
{
@ -237,9 +237,9 @@ bool EffectSBSMS::Process()
if (!leftTrack->GetSelected())
return fallthrough();
//Get start and end times from track
mCurT0 = leftTrack->GetStartTime();
mCurT1 = leftTrack->GetEndTime();
//Get start and end times from selection
mCurT0 = mT0;
mCurT1 = mT1;
//Set the current bounds to whichever left marker is
//greater and whichever right marker is less
@ -273,10 +273,6 @@ bool EffectSBSMS::Process()
mCurTrackNum++; // Increment for rightTrack, too.
}
const auto trackStart =
leftTrack->TimeToLongSamples(leftTrack->GetStartTime());
const auto trackEnd =
leftTrack->TimeToLongSamples(leftTrack->GetEndTime());
// SBSMS has a fixed sample rate - we just convert to its sample rate and then convert back
float srTrack = leftTrack->GetRate();
@ -328,30 +324,13 @@ bool EffectSBSMS::Process()
rb.sbsms = std::make_unique<SBSMS>(rightTrack ? 2 : 1, rb.quality.get(), true);
rb.SBSMSBlockSize = rb.sbsms->getInputFrameSize();
rb.SBSMSBuf.reinit(static_cast<size_t>(rb.SBSMSBlockSize), true);
// Note: width of getMaxPresamples() is only long. Widen it
decltype(start) processPresamples = rb.quality->getMaxPresamples();
processPresamples =
std::min(processPresamples,
decltype(processPresamples)
(( start - trackStart ).as_float() *
(srProcess/srTrack)));
auto trackPresamples = start - trackStart;
trackPresamples =
std::min(trackPresamples,
decltype(trackPresamples)
(processPresamples.as_float() *
(srTrack/srProcess)));
rb.offset = start - trackPresamples;
rb.end = trackEnd;
rb.offset = start;
rb.end = end;
rb.iface = std::make_unique<SBSMSEffectInterface>
(rb.resampler.get(), &rateSlide, &pitchSlide,
bPitchReferenceInput,
// UNSAFE_SAMPLE_COUNT_TRUNCATION
// The argument type is only long!
static_cast<long> ( samplesToProcess.as_long_long() ),
// This argument type is also only long!
static_cast<long> ( processPresamples.as_long_long() ),
static_cast<_sbsms_::SampleCountType>( samplesToProcess.as_long_long() ),
0,
rb.quality.get());
}
@ -443,10 +422,6 @@ bool EffectSBSMS::Process()
if (bGoodResult) {
ReplaceProcessedTracks(bGoodResult);
// Update selection
mT0 = mCurT0;
mT1 = mCurT0 + maxDuration;
}
return bGoodResult;
@ -486,7 +461,10 @@ void EffectSBSMS::Finalize(WaveTrack* orig, WaveTrack* out, const TimeWarper *wa
for (auto gap : gaps) {
auto st = orig->LongSamplesToTime(orig->TimeToLongSamples(gap.first));
auto et = orig->LongSamplesToTime(orig->TimeToLongSamples(gap.second));
orig->SplitDelete(warper->Warp(st), warper->Warp(et));
if (st >= mCurT0 && et <= mCurT1 && st != et)
{
orig->SplitDelete(warper->Warp(st), warper->Warp(et));
}
}
}

View File

@ -115,6 +115,11 @@ bool EffectSoundTouch::ProcessWithTimeWarper(InitFunction initer,
mCurT0 = mT0;
mCurT1 = mT1;
//Set the current bounds to whichever left marker is
//greater and whichever right marker is less
mCurT0 = wxMax(mT0, mCurT0);
mCurT1 = wxMin(mT1, mCurT1);
// Process only if the right marker is to the right of the left marker
if (mCurT1 > mCurT0) {
mSoundTouch = std::make_unique<soundtouch::SoundTouch>();
@ -171,11 +176,9 @@ bool EffectSoundTouch::ProcessWithTimeWarper(InitFunction initer,
}
);
if (bGoodResult)
if (bGoodResult) {
ReplaceProcessedTracks(bGoodResult);
// mT0 = mCurT0;
// mT1 = mCurT0 + m_maxNewLength; // Update selection.
}
return bGoodResult;
}
@ -429,7 +432,10 @@ void EffectSoundTouch::Finalize(WaveTrack* orig, WaveTrack* out, const TimeWarpe
for (auto gap : gaps) {
auto st = orig->LongSamplesToTime(orig->TimeToLongSamples(gap.first));
auto et = orig->LongSamplesToTime(orig->TimeToLongSamples(gap.second));
orig->SplitDelete(warper.Warp(st), warper.Warp(et));
if (st >= mCurT0 && et <= mCurT1 && st != et)
{
orig->SplitDelete(warper.Warp(st), warper.Warp(et));
}
}
}