mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-16 08:34:10 +02:00
Simplified some management of WaveClip caches
This commit is contained in:
parent
ecb97e9c58
commit
34b09053b4
124
src/WaveClip.cpp
124
src/WaveClip.cpp
@ -29,6 +29,7 @@ drawing). Cache's the Spectrogram frequency samples.
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <wx/log.h>
|
#include <wx/log.h>
|
||||||
|
|
||||||
@ -41,14 +42,23 @@ drawing). Cache's the Spectrogram frequency samples.
|
|||||||
#include <wx/listimpl.cpp>
|
#include <wx/listimpl.cpp>
|
||||||
WX_DEFINE_LIST(WaveClipList);
|
WX_DEFINE_LIST(WaveClipList);
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
inline int CountODPixels(int *bl, int start, int end)
|
||||||
|
{
|
||||||
|
using namespace std;
|
||||||
|
return count_if(bl + start, bl + end, bind2nd(less<int>(), 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class WaveCache {
|
class WaveCache {
|
||||||
public:
|
public:
|
||||||
WaveCache(int cacheLen)
|
WaveCache(int cacheLen)
|
||||||
|
: len(cacheLen)
|
||||||
{
|
{
|
||||||
dirty = -1;
|
dirty = -1;
|
||||||
start = -1.0;
|
start = -1.0;
|
||||||
pps = 0.0;
|
pps = 0.0;
|
||||||
len = cacheLen;
|
|
||||||
min = len ? new float[len] : 0;
|
min = len ? new float[len] : 0;
|
||||||
max = len ? new float[len] : 0;
|
max = len ? new float[len] : 0;
|
||||||
rms = len ? new float[len] : 0;
|
rms = len ? new float[len] : 0;
|
||||||
@ -70,7 +80,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int dirty;
|
int dirty;
|
||||||
sampleCount len;
|
const sampleCount len;
|
||||||
double start;
|
double start;
|
||||||
double pps;
|
double pps;
|
||||||
int rate;
|
int rate;
|
||||||
@ -121,7 +131,7 @@ public:
|
|||||||
invalEnd = len;
|
invalEnd = len;
|
||||||
|
|
||||||
|
|
||||||
mRegionsMutex.Lock();
|
ODLocker locker(mRegionsMutex);
|
||||||
|
|
||||||
//look thru the region array for a place to insert. We could make this more spiffy than a linear search
|
//look thru the region array for a place to insert. We could make this more spiffy than a linear search
|
||||||
//but right now it is not needed since there will usually only be one region (which grows) for OD loading.
|
//but right now it is not needed since there will usually only be one region (which grows) for OD loading.
|
||||||
@ -187,18 +197,12 @@ public:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mRegionsMutex.Unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//lock before calling these in a section. unlock after finished.
|
//lock before calling these in a section. unlock after finished.
|
||||||
int GetNumInvalidRegions(){return mRegions.size();}
|
int GetNumInvalidRegions() const {return mRegions.size();}
|
||||||
int GetInvalidRegionStart(int i){return mRegions[i]->start;}
|
int GetInvalidRegionStart(int i) const {return mRegions[i]->start;}
|
||||||
int GetInvalidRegionEnd(int i){return mRegions[i]->end;}
|
int GetInvalidRegionEnd(int i) const {return mRegions[i]->end;}
|
||||||
|
|
||||||
void LockInvalidRegions(){mRegionsMutex.Lock();}
|
|
||||||
void UnlockInvalidRegions(){mRegionsMutex.Unlock();}
|
|
||||||
|
|
||||||
void ClearInvalidRegions()
|
void ClearInvalidRegions()
|
||||||
{
|
{
|
||||||
@ -209,6 +213,38 @@ public:
|
|||||||
mRegions.clear();
|
mRegions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LoadInvalidRegion(int ii, Sequence *sequence, bool updateODCount)
|
||||||
|
{
|
||||||
|
const int invStart = GetInvalidRegionStart(ii);
|
||||||
|
const int invEnd = GetInvalidRegionEnd(ii);
|
||||||
|
|
||||||
|
//before check number of ODPixels
|
||||||
|
int regionODPixels = 0;
|
||||||
|
if (updateODCount)
|
||||||
|
regionODPixels = CountODPixels(bl, invStart, invEnd);
|
||||||
|
|
||||||
|
sequence->GetWaveDisplay(&min[invStart],
|
||||||
|
&max[invStart],
|
||||||
|
&rms[invStart],
|
||||||
|
&bl[invStart],
|
||||||
|
invEnd - invStart,
|
||||||
|
&where[invStart]);
|
||||||
|
|
||||||
|
//after check number of ODPixels
|
||||||
|
if (updateODCount)
|
||||||
|
{
|
||||||
|
const int regionODPixelsAfter = CountODPixels(bl, invStart, invEnd);
|
||||||
|
numODPixels -= (regionODPixels - regionODPixelsAfter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadInvalidRegions(Sequence *sequence, bool updateODCount)
|
||||||
|
{
|
||||||
|
//invalid regions are kept in a sorted array.
|
||||||
|
for (int i = 0; i < GetNumInvalidRegions(); i++)
|
||||||
|
LoadInvalidRegion(i, sequence, updateODCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<InvalidRegion*> mRegions;
|
std::vector<InvalidRegion*> mRegions;
|
||||||
@ -444,20 +480,18 @@ bool WaveClip::AfterClip(double t) const
|
|||||||
///Delete the wave cache - force redraw. Thread-safe
|
///Delete the wave cache - force redraw. Thread-safe
|
||||||
void WaveClip::DeleteWaveCache()
|
void WaveClip::DeleteWaveCache()
|
||||||
{
|
{
|
||||||
mWaveCacheMutex.Lock();
|
ODLocker locker(mWaveCacheMutex);
|
||||||
if(mWaveCache!=NULL)
|
if(mWaveCache!=NULL)
|
||||||
delete mWaveCache;
|
delete mWaveCache;
|
||||||
mWaveCache = new WaveCache(0);
|
mWaveCache = new WaveCache(0);
|
||||||
mWaveCacheMutex.Unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///Adds an invalid region to the wavecache so it redraws that portion only.
|
///Adds an invalid region to the wavecache so it redraws that portion only.
|
||||||
void WaveClip::AddInvalidRegion(long startSample, long endSample)
|
void WaveClip::AddInvalidRegion(long startSample, long endSample)
|
||||||
{
|
{
|
||||||
mWaveCacheMutex.Lock();
|
ODLocker locker(mWaveCacheMutex);
|
||||||
if(mWaveCache!=NULL)
|
if(mWaveCache!=NULL)
|
||||||
mWaveCache->AddInvalidRegion(startSample,endSample);
|
mWaveCache->AddInvalidRegion(startSample,endSample);
|
||||||
mWaveCacheMutex.Unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -524,7 +558,7 @@ bool WaveClip::GetWaveDisplay(float *min, float *max, float *rms,int* bl,
|
|||||||
int numPixels, double t0,
|
int numPixels, double t0,
|
||||||
double pixelsPerSecond, bool &isLoadingOD)
|
double pixelsPerSecond, bool &isLoadingOD)
|
||||||
{
|
{
|
||||||
mWaveCacheMutex.Lock();
|
ODLocker locker(mWaveCacheMutex);
|
||||||
|
|
||||||
|
|
||||||
const bool match =
|
const bool match =
|
||||||
@ -536,40 +570,7 @@ bool WaveClip::GetWaveDisplay(float *min, float *max, float *rms,int* bl,
|
|||||||
mWaveCache->start == t0 &&
|
mWaveCache->start == t0 &&
|
||||||
mWaveCache->len >= numPixels) {
|
mWaveCache->len >= numPixels) {
|
||||||
|
|
||||||
//check for invalid regions, and make the bottom if an else if.
|
mWaveCache->LoadInvalidRegions(mSequence, true);
|
||||||
//invalid regions are kept in a sorted array.
|
|
||||||
for(int i=0;i<mWaveCache->GetNumInvalidRegions();i++)
|
|
||||||
{
|
|
||||||
int invStart;
|
|
||||||
invStart = mWaveCache->GetInvalidRegionStart(i);
|
|
||||||
int invEnd;
|
|
||||||
invEnd = mWaveCache->GetInvalidRegionEnd(i);
|
|
||||||
|
|
||||||
int regionODPixels;
|
|
||||||
regionODPixels =0;
|
|
||||||
int regionODPixelsAfter;
|
|
||||||
regionODPixelsAfter =0;
|
|
||||||
//before check number of ODPixels
|
|
||||||
for(int j=invStart;j<invEnd;j++)
|
|
||||||
{
|
|
||||||
if(mWaveCache->bl[j]<0)
|
|
||||||
regionODPixels++;
|
|
||||||
}
|
|
||||||
mSequence->GetWaveDisplay(&mWaveCache->min[invStart],
|
|
||||||
&mWaveCache->max[invStart],
|
|
||||||
&mWaveCache->rms[invStart],
|
|
||||||
&mWaveCache->bl[invStart],
|
|
||||||
invEnd-invStart,
|
|
||||||
&mWaveCache->where[invStart]);
|
|
||||||
//after check number of ODPixels
|
|
||||||
for(int j=invStart;j<invEnd;j++)
|
|
||||||
{
|
|
||||||
if(mWaveCache->bl[j]<0)
|
|
||||||
regionODPixelsAfter++;
|
|
||||||
}
|
|
||||||
//decrement the number of od pixels.
|
|
||||||
mWaveCache->numODPixels -= (regionODPixels - regionODPixelsAfter);
|
|
||||||
}
|
|
||||||
mWaveCache->ClearInvalidRegions();
|
mWaveCache->ClearInvalidRegions();
|
||||||
|
|
||||||
|
|
||||||
@ -579,7 +580,6 @@ bool WaveClip::GetWaveDisplay(float *min, float *max, float *rms,int* bl,
|
|||||||
memcpy(bl, mWaveCache->bl, numPixels*sizeof(int));
|
memcpy(bl, mWaveCache->bl, numPixels*sizeof(int));
|
||||||
memcpy(where, mWaveCache->where, (numPixels+1)*sizeof(sampleCount));
|
memcpy(where, mWaveCache->where, (numPixels+1)*sizeof(sampleCount));
|
||||||
isLoadingOD = mWaveCache->numODPixels>0;
|
isLoadingOD = mWaveCache->numODPixels>0;
|
||||||
mWaveCacheMutex.Unlock();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,24 +626,10 @@ bool WaveClip::GetWaveDisplay(float *min, float *max, float *rms,int* bl,
|
|||||||
p0 = mWaveCache->len;
|
p0 = mWaveCache->len;
|
||||||
p1 = 0;
|
p1 = 0;
|
||||||
|
|
||||||
//check for invalid regions, and make the bottom if an else if.
|
//TODO: only load inval regions if
|
||||||
//invalid regions are keep in a sorted array.
|
|
||||||
//TODO:integrate into below for loop so that we only load inval regions if
|
|
||||||
//necessary. (usually is the case, so no rush.)
|
//necessary. (usually is the case, so no rush.)
|
||||||
//also, we should be updating the NEW cache, but here we are patching the old one up.
|
//also, we should be updating the NEW cache, but here we are patching the old one up.
|
||||||
for(int i=0;i<oldCache->GetNumInvalidRegions();i++)
|
oldCache->LoadInvalidRegions(mSequence, false);
|
||||||
{
|
|
||||||
int invStart;
|
|
||||||
invStart = oldCache->GetInvalidRegionStart(i);
|
|
||||||
int invEnd;
|
|
||||||
invEnd = oldCache->GetInvalidRegionEnd(i);
|
|
||||||
mSequence->GetWaveDisplay(&oldCache->min[invStart],
|
|
||||||
&oldCache->max[invStart],
|
|
||||||
&oldCache->rms[invStart],
|
|
||||||
&oldCache->bl[invStart],
|
|
||||||
invEnd-invStart,
|
|
||||||
&oldCache->where[invStart]);
|
|
||||||
}
|
|
||||||
oldCache->ClearInvalidRegions();
|
oldCache->ClearInvalidRegions();
|
||||||
|
|
||||||
for (sampleCount x = 0; x < mWaveCache->len; x++)
|
for (sampleCount x = 0; x < mWaveCache->len; x++)
|
||||||
@ -756,7 +742,6 @@ bool WaveClip::GetWaveDisplay(float *min, float *max, float *rms,int* bl,
|
|||||||
&mWaveCache->where[p0]))
|
&mWaveCache->where[p0]))
|
||||||
{
|
{
|
||||||
isLoadingOD=false;
|
isLoadingOD=false;
|
||||||
mWaveCacheMutex.Unlock();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -778,7 +763,6 @@ bool WaveClip::GetWaveDisplay(float *min, float *max, float *rms,int* bl,
|
|||||||
mWaveCache->numODPixels++;
|
mWaveCache->numODPixels++;
|
||||||
|
|
||||||
isLoadingOD = mWaveCache->numODPixels>0;
|
isLoadingOD = mWaveCache->numODPixels>0;
|
||||||
mWaveCacheMutex.Unlock();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,5 +166,26 @@ protected:
|
|||||||
|
|
||||||
#endif // __WXMAC__
|
#endif // __WXMAC__
|
||||||
|
|
||||||
|
// Like wxMutexLocker
|
||||||
|
// So you can use the RAII idiom with ODLock, on whatever platform
|
||||||
|
class ODLocker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ODLocker(ODLock &lock)
|
||||||
|
: mLock(lock)
|
||||||
|
{
|
||||||
|
mLock.Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
~ODLocker()
|
||||||
|
{
|
||||||
|
mLock.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ODLock &mLock;
|
||||||
|
};
|
||||||
|
|
||||||
#endif //__AUDACITY_ODTASKTHREAD__
|
#endif //__AUDACITY_ODTASKTHREAD__
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user