Add some preliminary FFT cache aging... while it "works" it doesn't do so in a very useful fashion, since unused cache segments are killed off much faster when you scroll the view in short segments than when doing large scrolls. It should, however, limit memory usage to cache_line_age_limit*line_length*sizeof(float) bytes, which is 64 MB with the current Audio Spectrum Window size.

Originally committed to SVN as r1298.
This commit is contained in:
Niels Martin Hansen 2007-06-24 02:58:33 +00:00
parent b28eeabc47
commit 7779ad6dde
2 changed files with 52 additions and 5 deletions

View File

@ -44,6 +44,7 @@
// Audio spectrum FFT data cache // Audio spectrum FFT data cache
AudioSpectrumCache::LineAge AudioSpectrumCache::cache_line_age_limit = 0x10000; // TODO: make this less arbitrary
AudioSpectrumCache::CacheLine AudioSpectrumCache::null_line; AudioSpectrumCache::CacheLine AudioSpectrumCache::null_line;
unsigned long AudioSpectrumCache::line_length; unsigned long AudioSpectrumCache::line_length;
@ -60,10 +61,13 @@ class FinalSpectrumCache : public AudioSpectrumCache {
private: private:
std::vector<CacheLine> data; std::vector<CacheLine> data;
unsigned long start, length; // start and end of range unsigned long start, length; // start and end of range
unsigned long last_access; // aging parameter
public: public:
CacheLine& GetLine(unsigned long i) CacheLine& GetLine(unsigned long i, LineAge aging_time)
{ {
last_access = aging_time;
// This check ought to be redundant // This check ought to be redundant
if (i >= start && i-start < length) if (i >= start && i-start < length)
return data[i - start]; return data[i - start];
@ -71,10 +75,18 @@ public:
return null_line; return null_line;
} }
bool Age(LineAge aging_time)
{
assert(aging_time >= last_access);
return aging_time - last_access <= cache_line_age_limit;
}
FinalSpectrumCache(AudioProvider *provider, unsigned long _start, unsigned long _length) FinalSpectrumCache(AudioProvider *provider, unsigned long _start, unsigned long _length)
{ {
start = _start; start = _start;
length = _length; length = _length;
last_access = 0;
assert(length > 2); assert(length > 2);
@ -138,7 +150,7 @@ private:
AudioProvider *provider; AudioProvider *provider;
public: public:
CacheLine &GetLine(unsigned long i) CacheLine &GetLine(unsigned long i, LineAge aging_time)
{ {
if (i >= start && i-start <= length) { if (i >= start && i-start <= length) {
// Determine which sub-cache this line resides in // Determine which sub-cache this line resides in
@ -153,12 +165,33 @@ public:
} }
} }
return sub_caches[subcache]->GetLine(i); return sub_caches[subcache]->GetLine(i, aging_time);
} else { } else {
return null_line; return null_line;
} }
} }
bool Age(LineAge aging_time)
{
bool living_caches = false;
// Age every active sub-cache
for (size_t i = 0; i < sub_caches.size(); ++i) {
if (sub_caches[i]) {
if (sub_caches[i]->Age(aging_time)) {
// The sub-cache is still fresh, so we are too
living_caches = true;
} else {
// Sub-cache is too old, remove it
delete sub_caches[i];
sub_caches[i] = 0;
}
}
}
return living_caches;
}
IntermediateSpectrumCache(AudioProvider *_provider, unsigned long _start, unsigned long _length, int _depth) IntermediateSpectrumCache(AudioProvider *_provider, unsigned long _start, unsigned long _length, int _depth)
{ {
provider = _provider; provider = _provider;
@ -203,12 +236,14 @@ AudioSpectrum::AudioSpectrum(AudioProvider *_provider, unsigned long _line_lengt
AudioSpectrumCache::SetLineLength(line_length); AudioSpectrumCache::SetLineLength(line_length);
cache = new IntermediateSpectrumCache(provider, 0, num_lines, 0); cache = new IntermediateSpectrumCache(provider, 0, num_lines, 0);
cache_age = 0;
power_scale = 1; power_scale = 1;
minband = Options.AsInt(_T("Audio Spectrum Cutoff")); minband = Options.AsInt(_T("Audio Spectrum Cutoff"));
maxband = line_length - minband * 2/3; // TODO: make this customisable? maxband = line_length - minband * 2/3; // TODO: make this customisable?
// Generate colour maps // Generate colour maps
// TODO? allow selecting between several colour maps
unsigned char *palptr = colours_normal; unsigned char *palptr = colours_normal;
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; i++) {
//hsl_to_rgb(170 + i * 2/3, 128 + i/2, i, palptr+0, palptr+1, palptr+2); // Previous //hsl_to_rgb(170 + i * 2/3, 128 + i/2, i, palptr+0, palptr+1, palptr+2); // Previous
@ -258,7 +293,8 @@ void AudioSpectrum::RenderRange(__int64 range_start, __int64 range_end, bool sel
if (imgcol <= last_imgcol_rendered) if (imgcol <= last_imgcol_rendered)
continue; continue;
AudioSpectrumCache::CacheLine &line = cache->GetLine(i); AudioSpectrumCache::CacheLine &line = cache->GetLine(i, cache_age);
cache_age++;
// Calculate the signal power over frequency // Calculate the signal power over frequency
// "Compressed" scale // "Compressed" scale
@ -325,6 +361,8 @@ void AudioSpectrum::RenderRange(__int64 range_start, __int64 range_end, bool sel
} }
delete[] power; delete[] power;
cache->Age(cache_age);
} }

View File

@ -46,14 +46,22 @@
class AudioSpectrumCache { class AudioSpectrumCache {
public: public:
typedef std::vector<float> CacheLine; typedef std::vector<float> CacheLine;
typedef unsigned long LineAge;
virtual CacheLine& GetLine(unsigned long i) = 0; // Get the i'th cache line from the tree and propagate down the current "age time"
virtual CacheLine& GetLine(unsigned long i, LineAge aging_time) = 0;
// Set the desired length of cache lines
static void SetLineLength(unsigned long new_length); static void SetLineLength(unsigned long new_length);
// Perform cache aging process
// Return true if the object Age was called on is still fresh, false if it's old and should be purged
virtual bool Age(LineAge aging_time) = 0;
virtual ~AudioSpectrumCache() {}; virtual ~AudioSpectrumCache() {};
protected: protected:
static LineAge cache_line_age_limit;
static CacheLine null_line; static CacheLine null_line;
static unsigned long line_length; static unsigned long line_length;
}; };
@ -63,6 +71,7 @@ class AudioSpectrum {
private: private:
// Data provider // Data provider
AudioSpectrumCache *cache; AudioSpectrumCache *cache;
AudioSpectrumCache::LineAge cache_age;
// Colour pallettes // Colour pallettes
unsigned char colours_normal[256*3]; unsigned char colours_normal[256*3];