mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-16 16:10:06 +02:00
Fix Bug 183: Zero crossing detection previously could/would select samples that were in the spaces between audio. This led to selection of audio before time zero. It also led to poor behaviour where clips did not end at zero. Now spaces between audio are strongly discouraged (treated as samples of value 2.0) for zero detection.
This commit is contained in:
parent
b7406f91e3
commit
2f0323c8fd
@ -2574,6 +2574,7 @@ void AudacityProject::OnPlaySpeedDec()
|
||||
|
||||
double AudacityProject::NearestZeroCrossing(double t0)
|
||||
{
|
||||
// Window is 1/100th of a second.
|
||||
int windowSize = (int)(GetRate() / 100);
|
||||
float *dist = new float[windowSize];
|
||||
int i, j;
|
||||
@ -2592,8 +2593,10 @@ double AudacityProject::NearestZeroCrossing(double t0)
|
||||
int oneWindowSize = (int)(one->GetRate() / 100);
|
||||
float *oneDist = new float[oneWindowSize];
|
||||
sampleCount s = one->TimeToLongSamples(t0);
|
||||
// fillTwo to ensure that missing values are treated as 2, and hence do not
|
||||
// get used as zero crossings.
|
||||
one->Get((samplePtr)oneDist, floatSample,
|
||||
s - oneWindowSize/2, oneWindowSize);
|
||||
s - oneWindowSize/2, oneWindowSize, fillTwo);
|
||||
|
||||
// Start by penalizing downward motion. We prefer upward
|
||||
// zero crossings.
|
||||
@ -2615,6 +2618,9 @@ double AudacityProject::NearestZeroCrossing(double t0)
|
||||
oneDist[oneWindowSize-1] = fabs(.25 * oldVal +
|
||||
.75 * oneDist[oneWindowSize-1]);
|
||||
|
||||
// TODO: The mixed rate zero crossing code is broken,
|
||||
// if oneWindowSize > windowSize we'll miss out some
|
||||
// samples - so they will still be zero, so we'll use them.
|
||||
for(i=0; i<windowSize; i++) {
|
||||
if (windowSize != oneWindowSize)
|
||||
j = i * (oneWindowSize-1) / (windowSize-1);
|
||||
|
@ -84,6 +84,7 @@ AUDACITY_DLL_API void DeleteSamples(samplePtr p)
|
||||
free(p);
|
||||
}
|
||||
|
||||
// TODO: Risky? Assumes 0.0f is represented by 0x00000000;
|
||||
void ClearSamples(samplePtr src, sampleFormat format,
|
||||
int start, int len)
|
||||
{
|
||||
|
@ -24,6 +24,12 @@ typedef enum {
|
||||
floatSample = 0x0004000F
|
||||
} sampleFormat;
|
||||
|
||||
// Used to determine how to fill in empty areas of audio.
|
||||
typedef enum {
|
||||
fillZero = 0,
|
||||
fillTwo = 2
|
||||
}fillFormat;
|
||||
|
||||
/** \brief Return the size (in memory) of one sample (bytes) */
|
||||
#define SAMPLE_SIZE(SampleFormat) (SampleFormat >> 16)
|
||||
/** \brief Return the size on disk of one uncompressed sample (bytes) */
|
||||
|
@ -1607,10 +1607,10 @@ bool WaveTrack::GetRMS(float *rms, double t0, double t1)
|
||||
}
|
||||
|
||||
bool WaveTrack::Get(samplePtr buffer, sampleFormat format,
|
||||
sampleCount start, sampleCount len)
|
||||
sampleCount start, sampleCount len, fillFormat fill )
|
||||
{
|
||||
// Simple optimization: When this buffer is completely contained within one clip,
|
||||
// don't clear anything (because we never won't have to). Otherwise, just clear
|
||||
// don't clear anything (because we won't have to). Otherwise, just clear
|
||||
// everything to be on the safe side.
|
||||
WaveClipList::compatibility_iterator it;
|
||||
|
||||
@ -1625,7 +1625,23 @@ bool WaveTrack::Get(samplePtr buffer, sampleFormat format,
|
||||
}
|
||||
}
|
||||
if (doClear)
|
||||
ClearSamples(buffer, format, 0, len);
|
||||
{
|
||||
// Usually we fill in empty sapce with zero
|
||||
if( fill == fillZero )
|
||||
ClearSamples(buffer, format, 0, len);
|
||||
// but we don't have to.
|
||||
else if( fill==fillTwo )
|
||||
{
|
||||
wxASSERT( format==floatSample );
|
||||
float * pBuffer = (float*)buffer;
|
||||
for(int i=0;i<len;i++)
|
||||
pBuffer[i]=2.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxFAIL_MSG(wxT("Invalid fill format"));
|
||||
}
|
||||
}
|
||||
|
||||
for (it=GetClipIterator(); it; it=it->GetNext())
|
||||
{
|
||||
|
@ -214,7 +214,7 @@ class AUDACITY_DLL_API WaveTrack: public Track {
|
||||
/// guaranteed that the same samples are affected.
|
||||
///
|
||||
bool Get(samplePtr buffer, sampleFormat format,
|
||||
sampleCount start, sampleCount len);
|
||||
sampleCount start, sampleCount len, fillFormat fill=fillZero);
|
||||
bool Set(samplePtr buffer, sampleFormat format,
|
||||
sampleCount start, sampleCount len);
|
||||
void GetEnvelopeValues(double *buffer, int bufferLen,
|
||||
|
Loading…
x
Reference in New Issue
Block a user