mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-24 00:18:07 +02:00
Change the drawing of wave track envelope at high zoom...
... The function defined by the envelope is evaluated exactly at the times of samples, but not between samples -- instead there is a simple interpolation. Therefore the curve might not go through the control points when they are not at sample times. The exact value of the function defined by the envelope has no influence on rendering of the sound in between samples. So this can make it clear that the middle point has no influence at all in case three points are very close. Drawing of other envelopes (Time track, Equalization curves) is not changed.
This commit is contained in:
parent
537ccfbc4f
commit
e428425c7d
@ -1306,10 +1306,45 @@ void Envelope::GetValuesRelative(double *buffer, int bufferLen,
|
||||
}
|
||||
|
||||
void Envelope::GetValues
|
||||
(double *buffer, int bufferLen, int leftOffset, const ZoomInfo &zoomInfo) const
|
||||
( double alignedTime, double sampleDur,
|
||||
double *buffer, int bufferLen, int leftOffset,
|
||||
const ZoomInfo &zoomInfo )
|
||||
const
|
||||
{
|
||||
for (int xx = 0; xx < bufferLen; ++xx)
|
||||
buffer[xx] = GetValue(zoomInfo.PositionToTime(xx, -leftOffset));
|
||||
// Getting many envelope values, corresponding to pixel columns, which may
|
||||
// not be uniformly spaced in time when there is a fisheye.
|
||||
|
||||
double prevDiscreteTime, prevSampleVal, nextSampleVal;
|
||||
for ( int xx = 0; xx < bufferLen; ++xx ) {
|
||||
auto time = zoomInfo.PositionToTime( xx, -leftOffset );
|
||||
if ( sampleDur <= 0 )
|
||||
// Sample interval not defined (as for time track)
|
||||
buffer[xx] = GetValue( time );
|
||||
else {
|
||||
// The level of zoom-in may resolve individual samples.
|
||||
// If so, then instead of evaluating the envelope directly,
|
||||
// we draw a piecewise curve with knees at each sample time.
|
||||
// This actually makes clearer what happens as you drag envelope
|
||||
// points and make discontinuities.
|
||||
auto leftDiscreteTime = alignedTime +
|
||||
sampleDur * floor( ( time - alignedTime ) / sampleDur );
|
||||
if ( xx == 0 || leftDiscreteTime != prevDiscreteTime ) {
|
||||
prevDiscreteTime = leftDiscreteTime;
|
||||
prevSampleVal =
|
||||
GetValue( prevDiscreteTime, sampleDur );
|
||||
nextSampleVal =
|
||||
GetValue( prevDiscreteTime + sampleDur, sampleDur );
|
||||
}
|
||||
auto ratio = ( time - leftDiscreteTime ) / sampleDur;
|
||||
if ( GetExponential() )
|
||||
buffer[ xx ] = exp(
|
||||
( 1.0 - ratio ) * log( prevSampleVal )
|
||||
+ ratio * log( nextSampleVal ) );
|
||||
else
|
||||
buffer[ xx ] =
|
||||
( 1.0 - ratio ) * prevSampleVal + ratio * nextSampleVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// relative time
|
||||
|
@ -142,10 +142,13 @@ public:
|
||||
* more than one value in a row. */
|
||||
void GetValues(double *buffer, int len, double t0, double tstep) const;
|
||||
|
||||
/** \brief Get many envelope points at once, but don't assume uniform time step.
|
||||
/** \brief Get many envelope points for pixel columns at once,
|
||||
* but don't assume uniform time per pixel.
|
||||
*/
|
||||
void GetValues
|
||||
(double *buffer, int bufferLen, int leftOffset, const ZoomInfo &zoomInfo) const;
|
||||
( double aligned_time, double sampleDur,
|
||||
double *buffer, int bufferLen, int leftOffset,
|
||||
const ZoomInfo &zoomInfo) const;
|
||||
|
||||
// Guarantee an envelope point at the end of the domain.
|
||||
void Cap( double sampleDur );
|
||||
|
@ -281,7 +281,8 @@ void TimeTrack::Draw(wxDC & dc, const wxRect & r, const ZoomInfo &zoomInfo) cons
|
||||
mRuler->Draw(dc, this);
|
||||
|
||||
Doubles envValues{ size_t(mid.width) };
|
||||
GetEnvelope()->GetValues(envValues.get(), mid.width, 0, zoomInfo);
|
||||
GetEnvelope()->GetValues
|
||||
( 0, 0, envValues.get(), mid.width, 0, zoomInfo );
|
||||
|
||||
dc.SetPen(AColor::envelopePen);
|
||||
|
||||
|
@ -1781,7 +1781,8 @@ void TrackArtist::DrawClipWaveform(const WaveTrack *track,
|
||||
|
||||
std::vector<double> vEnv(mid.width);
|
||||
double *const env = &vEnv[0];
|
||||
clip->GetEnvelope()->GetValues(env, mid.width, leftOffset, zoomInfo);
|
||||
clip->GetEnvelope()->GetValues
|
||||
( tOffset, 1.0 / rate, env, mid.width, leftOffset, zoomInfo );
|
||||
|
||||
// Draw the background of the track, outlining the shape of
|
||||
// the envelope and using a colored pen for the selected
|
||||
@ -1912,7 +1913,8 @@ void TrackArtist::DrawClipWaveform(const WaveTrack *track,
|
||||
if (!showIndividualSamples) {
|
||||
std::vector<double> vEnv2(rect.width);
|
||||
double *const env2 = &vEnv2[0];
|
||||
clip->GetEnvelope()->GetValues(env2, rect.width, leftOffset, zoomInfo);
|
||||
clip->GetEnvelope()->GetValues
|
||||
( tOffset, 1.0 / rate, env2, rect.width, leftOffset, zoomInfo );
|
||||
DrawMinMaxRMS(dc, rect, env2,
|
||||
zoomMin, zoomMax,
|
||||
dB, dBRange,
|
||||
|
Loading…
x
Reference in New Issue
Block a user