mirror of https://github.com/odrling/Aegisub
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:
parent
b28eeabc47
commit
7779ad6dde
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
|
|
Loading…
Reference in New Issue