Replaced Audio Spectrum Window and Audio Spectrum Overlaps with a single Audio Spectrum Quality option.

Originally committed to SVN as r1304.
This commit is contained in:
Niels Martin Hansen 2007-06-24 20:46:52 +00:00
parent e2858d07c9
commit 0a1069407e
5 changed files with 33 additions and 16 deletions

View File

@ -577,7 +577,7 @@ void AudioDisplay::DrawSpectrum(wxDC &finaldc,bool weak) {
unsigned char *img = (unsigned char *)malloc(h*w*3); // wxImage requires using malloc unsigned char *img = (unsigned char *)malloc(h*w*3); // wxImage requires using malloc
if (!spectrumRenderer) if (!spectrumRenderer)
spectrumRenderer = new AudioSpectrum(provider, 1<<Options.AsInt(_T("Audio Spectrum Window"))); spectrumRenderer = new AudioSpectrum(provider);
spectrumRenderer->SetScaling(scale); spectrumRenderer->SetScaling(scale);

View File

@ -63,7 +63,7 @@ private:
unsigned int overlaps; unsigned int overlaps;
public: public:
CacheLine& GetLine(unsigned long i, unsigned int overlap) CacheLine& GetLine(unsigned long i, unsigned int overlap, bool &created)
{ {
// This check ought to be redundant // This check ought to be redundant
if (i >= start && i-start < length) if (i >= start && i-start < length)
@ -149,7 +149,7 @@ private:
AudioProvider *provider; AudioProvider *provider;
public: public:
CacheLine &GetLine(unsigned long i, unsigned int overlap) CacheLine &GetLine(unsigned long i, unsigned int overlap, bool &created)
{ {
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
@ -157,6 +157,7 @@ public:
assert(subcache < sub_caches.size()); assert(subcache < sub_caches.size());
if (!sub_caches[subcache]) { if (!sub_caches[subcache]) {
created = true;
if (subcaches_are_final) { if (subcaches_are_final) {
sub_caches[subcache] = new FinalSpectrumCache(provider, start+subcache*subcache_length, subcache_length, overlaps); sub_caches[subcache] = new FinalSpectrumCache(provider, start+subcache*subcache_length, subcache_length, overlaps);
} else { } else {
@ -164,7 +165,7 @@ public:
} }
} }
return sub_caches[subcache]->GetLine(i, overlap); return sub_caches[subcache]->GetLine(i, overlap, created);
} else { } else {
return null_line; return null_line;
} }
@ -204,17 +205,26 @@ public:
// AudioSpectrum // AudioSpectrum
AudioSpectrum::AudioSpectrum(AudioProvider *_provider, unsigned long _line_length) AudioSpectrum::AudioSpectrum(AudioProvider *_provider)
{ {
provider = _provider; provider = _provider;
line_length = _line_length;
int quality_index = Options.AsInt(_T("Audio Spectrum Quality"));
if (quality_index < 0) quality_index = 0;
if (quality_index > 5) quality_index = 5; // no need to go freaking insane
if (quality_index > 1)
line_length = 1 << (8 + quality_index - 1);
else
line_length = 1 << 8;
if (quality_index > 0)
fft_overlaps = 1 << (quality_index*2);
else
fft_overlaps = 1;
__int64 _num_lines = provider->GetNumSamples() / line_length / 2; __int64 _num_lines = provider->GetNumSamples() / line_length / 2;
//assert (_num_lines < (1<<31)); // hope it fits into 32 bits... //assert (_num_lines < (1<<31)); // hope it fits into 32 bits...
num_lines = (unsigned long)_num_lines; num_lines = (unsigned long)_num_lines;
fft_overlaps = Options.AsInt(_T("Audio Spectrum Overlaps"));
fft_overlaps = MAX(1, fft_overlaps);
AudioSpectrumCache::SetLineLength(line_length); AudioSpectrumCache::SetLineLength(line_length);
cache = new IntermediateSpectrumCache(provider, 0, num_lines, fft_overlaps, 0); cache = new IntermediateSpectrumCache(provider, 0, num_lines, fft_overlaps, 0);
@ -249,6 +259,9 @@ void AudioSpectrum::RenderRange(__int64 range_start, __int64 range_end, bool sel
unsigned long first_line = (unsigned long)(fft_overlaps * range_start / line_length / 2); unsigned long first_line = (unsigned long)(fft_overlaps * range_start / line_length / 2);
unsigned long last_line = (unsigned long)(fft_overlaps * range_end / line_length / 2); unsigned long last_line = (unsigned long)(fft_overlaps * range_end / line_length / 2);
unsigned int cache_hits=0, cache_misses=0;
bool was_cache_miss;
float *power = new float[line_length]; float *power = new float[line_length];
int last_imgcol_rendered = -1; int last_imgcol_rendered = -1;
@ -275,12 +288,15 @@ 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(baseline, overlap); was_cache_miss = false;
AudioSpectrumCache::CacheLine &line = cache->GetLine(baseline, overlap, was_cache_miss);
++overlap; ++overlap;
if (overlap >= fft_overlaps) { if (overlap >= fft_overlaps) {
overlap = 0; overlap = 0;
++baseline; ++baseline;
} }
if (was_cache_miss) cache_misses++;
else cache_hits++;
// Apply a "compressed" scaling to the signal power // Apply a "compressed" scaling to the signal power
for (unsigned int j = 0; j < line_length; j++) { for (unsigned int j = 0; j < line_length; j++) {
@ -346,6 +362,8 @@ void AudioSpectrum::RenderRange(__int64 range_start, __int64 range_end, bool sel
} }
delete[] power; delete[] power;
wxLogDebug(_T("Rendered spectrum: %u cache hits, %u misses"), cache_hits, cache_misses);
} }

View File

@ -49,7 +49,7 @@ public:
typedef std::vector<float> CacheLine; typedef std::vector<float> CacheLine;
// Get the overlap'th overlapping FFT in FFT group i, generating it if needed // Get the overlap'th overlapping FFT in FFT group i, generating it if needed
virtual CacheLine& GetLine(unsigned long i, unsigned int overlap) = 0; virtual CacheLine& GetLine(unsigned long i, unsigned int overlap, bool &created) = 0;
// Set the FFT size used // Set the FFT size used
static void SetLineLength(unsigned long new_length); static void SetLineLength(unsigned long new_length);
@ -83,7 +83,7 @@ private:
int maxband; // largest frequency band displayed int maxband; // largest frequency band displayed
public: public:
AudioSpectrum(AudioProvider *_provider, unsigned long _line_length); AudioSpectrum(AudioProvider *_provider);
~AudioSpectrum(); ~AudioSpectrum();
void RenderRange(__int64 range_start, __int64 range_end, bool selected, unsigned char *img, int imgleft, int imgwidth, int imgpitch, int imgheight); void RenderRange(__int64 range_start, __int64 range_end, bool selected, unsigned char *img, int imgleft, int imgwidth, int imgpitch, int imgheight);

View File

@ -528,8 +528,8 @@ DialogOptions::DialogOptions(wxWindow *parent)
AddTextControl(audioAdvPage,audioAdvSizer1,_("HD cache path"),_T("Audio HD Cache Location"),TEXT_TYPE_FOLDER); AddTextControl(audioAdvPage,audioAdvSizer1,_("HD cache path"),_T("Audio HD Cache Location"),TEXT_TYPE_FOLDER);
AddTextControl(audioAdvPage,audioAdvSizer1,_("HD cache name"),_T("Audio HD CAche Name")); AddTextControl(audioAdvPage,audioAdvSizer1,_("HD cache name"),_T("Audio HD CAche Name"));
AddTextControl(audioAdvPage,audioAdvSizer1,_("Spectrum cutoff"),_T("Audio spectrum cutoff"),TEXT_TYPE_NUMBER); AddTextControl(audioAdvPage,audioAdvSizer1,_("Spectrum cutoff"),_T("Audio spectrum cutoff"),TEXT_TYPE_NUMBER);
AddTextControl(audioAdvPage,audioAdvSizer1,_("Spectrum FFT window exponent"),_T("Audio spectrum window"),TEXT_TYPE_NUMBER); wxString spectrum_quality_choices[] = { _("0 - Regular quality"), _("1 - Better quality"), _("2 - High quality"), _("3 - Insane quality") };
AddTextControl(audioAdvPage,audioAdvSizer1,_("Spectrum FFT window overlaps"),_T("Audio spectrum overlaps"),TEXT_TYPE_NUMBER); AddComboControl(audioAdvPage,audioAdvSizer1,_("Spectrum quality"),_T("Audio spectrum quality"),wxArrayString(4,spectrum_quality_choices));
audioAdvSizer1->AddGrowableCol(0,1); audioAdvSizer1->AddGrowableCol(0,1);
// Main sizer // Main sizer

View File

@ -189,10 +189,9 @@ void OptionsManager::LoadDefaults(bool onlyDefaults) {
SetText(_T("Audio Alsa Device"), _T("plughw:0,0")); SetText(_T("Audio Alsa Device"), _T("plughw:0,0"));
SetText(_T("Audio HD Cache Location"),_T("default")); SetText(_T("Audio HD Cache Location"),_T("default"));
SetText(_T("Audio HD Cache Name"),_T("audio%02i.tmp")); SetText(_T("Audio HD Cache Name"),_T("audio%02i.tmp"));
// Technically these can do with just the spectrum class being re-created // Technically these can do with just the spectrum object being re-created
SetInt(_T("Audio Spectrum Cutoff"),0); SetInt(_T("Audio Spectrum Cutoff"),0);
SetInt(_T("Audio Spectrum Window"),8); SetInt(_T("Audio Spectrum Quality"),0);
SetInt(_T("Audio Spectrum Overlaps"),1);
// Automation // Automation
// The path changes only take effect when a script is (re)loaded but Automatic should be good enough, it certainly doesn't warrart a restart // The path changes only take effect when a script is (re)loaded but Automatic should be good enough, it certainly doesn't warrart a restart