From 0a1069407ec5858a6aab92dac8c3bfc0365d8018 Mon Sep 17 00:00:00 2001 From: Niels Martin Hansen Date: Sun, 24 Jun 2007 20:46:52 +0000 Subject: [PATCH] Replaced Audio Spectrum Window and Audio Spectrum Overlaps with a single Audio Spectrum Quality option. Originally committed to SVN as r1304. --- aegisub/audio_display.cpp | 2 +- aegisub/audio_spectrum.cpp | 34 ++++++++++++++++++++++++++-------- aegisub/audio_spectrum.h | 4 ++-- aegisub/dialog_options.cpp | 4 ++-- aegisub/options.cpp | 5 ++--- 5 files changed, 33 insertions(+), 16 deletions(-) diff --git a/aegisub/audio_display.cpp b/aegisub/audio_display.cpp index 425e235d8..f505bcd01 100644 --- a/aegisub/audio_display.cpp +++ b/aegisub/audio_display.cpp @@ -577,7 +577,7 @@ void AudioDisplay::DrawSpectrum(wxDC &finaldc,bool weak) { unsigned char *img = (unsigned char *)malloc(h*w*3); // wxImage requires using malloc if (!spectrumRenderer) - spectrumRenderer = new AudioSpectrum(provider, 1<SetScaling(scale); diff --git a/aegisub/audio_spectrum.cpp b/aegisub/audio_spectrum.cpp index 64c7f9ed7..4bf0dffec 100644 --- a/aegisub/audio_spectrum.cpp +++ b/aegisub/audio_spectrum.cpp @@ -63,7 +63,7 @@ private: unsigned int overlaps; 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 if (i >= start && i-start < length) @@ -149,7 +149,7 @@ private: AudioProvider *provider; 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) { // Determine which sub-cache this line resides in @@ -157,6 +157,7 @@ public: assert(subcache < sub_caches.size()); if (!sub_caches[subcache]) { + created = true; if (subcaches_are_final) { sub_caches[subcache] = new FinalSpectrumCache(provider, start+subcache*subcache_length, subcache_length, overlaps); } else { @@ -164,7 +165,7 @@ public: } } - return sub_caches[subcache]->GetLine(i, overlap); + return sub_caches[subcache]->GetLine(i, overlap, created); } else { return null_line; } @@ -204,17 +205,26 @@ public: // AudioSpectrum -AudioSpectrum::AudioSpectrum(AudioProvider *_provider, unsigned long _line_length) +AudioSpectrum::AudioSpectrum(AudioProvider *_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; //assert (_num_lines < (1<<31)); // hope it fits into 32 bits... num_lines = (unsigned long)_num_lines; - fft_overlaps = Options.AsInt(_T("Audio Spectrum Overlaps")); - fft_overlaps = MAX(1, fft_overlaps); AudioSpectrumCache::SetLineLength(line_length); 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 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]; 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) continue; - AudioSpectrumCache::CacheLine &line = cache->GetLine(baseline, overlap); + was_cache_miss = false; + AudioSpectrumCache::CacheLine &line = cache->GetLine(baseline, overlap, was_cache_miss); ++overlap; if (overlap >= fft_overlaps) { overlap = 0; ++baseline; } + if (was_cache_miss) cache_misses++; + else cache_hits++; // Apply a "compressed" scaling to the signal power 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; + + wxLogDebug(_T("Rendered spectrum: %u cache hits, %u misses"), cache_hits, cache_misses); } diff --git a/aegisub/audio_spectrum.h b/aegisub/audio_spectrum.h index feee3726c..be13176c3 100644 --- a/aegisub/audio_spectrum.h +++ b/aegisub/audio_spectrum.h @@ -49,7 +49,7 @@ public: typedef std::vector CacheLine; // 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 static void SetLineLength(unsigned long new_length); @@ -83,7 +83,7 @@ private: int maxband; // largest frequency band displayed public: - AudioSpectrum(AudioProvider *_provider, unsigned long _line_length); + AudioSpectrum(AudioProvider *_provider); ~AudioSpectrum(); void RenderRange(__int64 range_start, __int64 range_end, bool selected, unsigned char *img, int imgleft, int imgwidth, int imgpitch, int imgheight); diff --git a/aegisub/dialog_options.cpp b/aegisub/dialog_options.cpp index 8050a8a88..82e6f98f7 100644 --- a/aegisub/dialog_options.cpp +++ b/aegisub/dialog_options.cpp @@ -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 name"),_T("Audio HD CAche Name")); 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); - AddTextControl(audioAdvPage,audioAdvSizer1,_("Spectrum FFT window overlaps"),_T("Audio spectrum overlaps"),TEXT_TYPE_NUMBER); + wxString spectrum_quality_choices[] = { _("0 - Regular quality"), _("1 - Better quality"), _("2 - High quality"), _("3 - Insane quality") }; + AddComboControl(audioAdvPage,audioAdvSizer1,_("Spectrum quality"),_T("Audio spectrum quality"),wxArrayString(4,spectrum_quality_choices)); audioAdvSizer1->AddGrowableCol(0,1); // Main sizer diff --git a/aegisub/options.cpp b/aegisub/options.cpp index 9141a1c07..b818a5421 100644 --- a/aegisub/options.cpp +++ b/aegisub/options.cpp @@ -189,10 +189,9 @@ void OptionsManager::LoadDefaults(bool onlyDefaults) { SetText(_T("Audio Alsa Device"), _T("plughw:0,0")); SetText(_T("Audio HD Cache Location"),_T("default")); 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 Window"),8); - SetInt(_T("Audio Spectrum Overlaps"),1); + SetInt(_T("Audio Spectrum Quality"),0); // 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