diff --git a/src/Envelope.cpp b/src/Envelope.cpp index 537bad9ff..520f9e525 100644 --- a/src/Envelope.cpp +++ b/src/Envelope.cpp @@ -701,7 +701,7 @@ void Envelope::Paste(double t0, const Envelope *e) unsigned int len = mEnv.size(); // get values to perform framing of the insertion - double splitval = GetValue(t0 + mOffset); + const double splitval = GetValueRelative( t0 ); /* Old analysis of cases: @@ -852,8 +852,8 @@ Old analysis of cases: // Add end points in case they are not not in e. // If they are in e, no harm, because the repeated Insert // calls for the start and end times will have no effect. - const double leftval = e->GetValue(0 + e->mOffset); - const double rightval = e->GetValue(e->mTrackLen + e->mOffset); + const double leftval = e->GetValueRelative( 0 ); + const double rightval = e->GetValueRelative( e->mTrackLen ); InsertOrReplaceRelative(t0, leftval); InsertOrReplaceRelative(t0 + e->mTrackLen, rightval); } @@ -983,6 +983,13 @@ void Envelope::GetPoints(double *bufferWhen, } } +void Envelope::Cap( double sampleTime ) +{ + auto range = EqualRange( mTrackLen, sampleTime ); + if ( range.first == range.second ) + InsertOrReplaceRelative( mTrackLen, GetValueRelative( mTrackLen ) ); +} + // Private methods // We no longer tolerate multiple envelope control points at the exact @@ -1083,17 +1090,21 @@ void Envelope::SetOffset(double newOffset) mOffset = newOffset; } -void Envelope::SetTrackLen(double trackLen) +void Envelope::SetTrackLen( double trackLen, double sampleTime ) // NOFAIL-GUARANTEE { - // Preserve the right-side limit at trackLen. - bool needPoint = ( trackLen < mTrackLen ); + // Preserve the left-side limit at trackLen. + auto range = EqualRange( trackLen, sampleTime ); + bool needPoint = ( range.first == range.second && trackLen < mTrackLen ); double value; if ( needPoint ) value = GetValueRelative( trackLen ); mTrackLen = trackLen; - int newLen = EqualRange( trackLen, 0 ).second; + + // Shrink the array. + // If more than one point already at the end, keep only the first of them. + int newLen = std::min( 1 + range.first, range.second ); mEnv.resize( newLen ); if ( needPoint ) diff --git a/src/Envelope.h b/src/Envelope.h index 9db7f1dfc..44bc72790 100644 --- a/src/Envelope.h +++ b/src/Envelope.h @@ -128,7 +128,7 @@ public: // Control void SetOffset(double newOffset); - void SetTrackLen(double trackLen); + void SetTrackLen( double trackLen, double sampleTime = 0.0 ); void RescaleValues(double minValue, double maxValue); void RescaleTimes( double newLength ); @@ -147,6 +147,9 @@ public: void GetValues (double *buffer, int bufferLen, int leftOffset, const ZoomInfo &zoomInfo) const; + // Guarantee an envelope point at the end of the domain. + void Cap( double sampleTime ); + private: double GetValueRelative(double t) const; void GetValuesRelative diff --git a/src/WaveClip.cpp b/src/WaveClip.cpp index 71ce8d494..238e3798a 100644 --- a/src/WaveClip.cpp +++ b/src/WaveClip.cpp @@ -1345,7 +1345,8 @@ void WaveClip::ConvertToSampleFormat(sampleFormat format) void WaveClip::UpdateEnvelopeTrackLen() // NOFAIL-GUARANTEE { - mEnvelope->SetTrackLen((mSequence->GetNumSamples().as_double()) / mRate); + mEnvelope->SetTrackLen + ((mSequence->GetNumSamples().as_double()) / mRate, 1.0 / GetRate()); } void WaveClip::TimeToSamplesClip(double t0, sampleCount *s0) const @@ -1626,12 +1627,11 @@ void WaveClip::InsertSilence( double t, double len, double *pEnvelopeValue ) // Preserve limit value at the end auto oldLen = pEnvelope->GetTrackLen(); - auto oldT = pEnvelope->GetOffset() + oldLen; auto newLen = oldLen + len; - pEnvelope->InsertOrReplace( oldT, pEnvelope->GetValue( oldT ) ); + pEnvelope->Cap( sampleTime ); // Ramp across the silence to the given value - pEnvelope->SetTrackLen( newLen ); + pEnvelope->SetTrackLen( newLen, sampleTime ); pEnvelope->InsertOrReplace ( pEnvelope->GetOffset() + newLen, *pEnvelopeValue ); }