1
0
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:
unknown 2015-06-01 18:51:39 -04:00
parent ecb97e9c58
commit 34b09053b4
2 changed files with 75 additions and 70 deletions

View File

@ -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;
} }

View File

@ -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__