mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-02 08:39:46 +02:00
Use WaveTrackCache for spectrograms
Zooming-in of spectrograms (or other view changes that invalidate the whole pixel cache of the WaveClip) used to do at least one opening and closing of a block file for each column of pixels. With this change, open each block file not more than once for each repopulation of the cache. Improved speed may be more noticeable on less powerful computers, or when the audio file is in a slower storage device.
This commit is contained in:
parent
bdc2839112
commit
e6ccd51326
@ -143,8 +143,8 @@ audio tracks.
|
||||
*//*******************************************************************/
|
||||
|
||||
#include "Audacity.h"
|
||||
#include "AudacityApp.h"
|
||||
#include "TrackArtist.h"
|
||||
#include "AudacityApp.h"
|
||||
#include "float_cast.h"
|
||||
|
||||
#include <math.h>
|
||||
@ -1749,8 +1749,9 @@ void TrackArtist::DrawSpectrum(WaveTrack *track,
|
||||
return;
|
||||
}
|
||||
|
||||
WaveTrackCache cache(track);
|
||||
for (WaveClipList::compatibility_iterator it = track->GetClipIterator(); it; it = it->GetNext()) {
|
||||
DrawClipSpectrum(track, it->GetData(), dc, r, viewInfo, autocorrelation, logF);
|
||||
DrawClipSpectrum(cache, it->GetData(), dc, r, viewInfo, autocorrelation, logF);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1822,7 +1823,7 @@ AColor::ColorGradientChoice ChooseColorSet( float bin0, float bin1, float selBin
|
||||
|
||||
|
||||
|
||||
void TrackArtist::DrawClipSpectrum(WaveTrack *track,
|
||||
void TrackArtist::DrawClipSpectrum(WaveTrackCache &cache,
|
||||
WaveClip *clip,
|
||||
wxDC & dc,
|
||||
const wxRect & r,
|
||||
@ -1830,6 +1831,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrack *track,
|
||||
bool autocorrelation,
|
||||
bool logF)
|
||||
{
|
||||
const WaveTrack *const track = cache.GetTrack();
|
||||
|
||||
enum { MONOCHROME_LINE = 230, COLORED_LINE = 0 };
|
||||
enum { DASH_LENGTH = 10 /* pixels */ };
|
||||
|
||||
@ -1962,7 +1965,7 @@ void TrackArtist::DrawClipSpectrum(WaveTrack *track,
|
||||
float *freq = new float[mid.width * half];
|
||||
sampleCount *where = new sampleCount[mid.width+1];
|
||||
|
||||
bool updated = clip->GetSpectrogram(freq, where, mid.width,
|
||||
bool updated = clip->GetSpectrogram(cache, freq, where, mid.width,
|
||||
t0, pps, autocorrelation);
|
||||
int ifreq = lrint(rate/2);
|
||||
|
||||
|
@ -29,6 +29,7 @@ class wxHashTable;
|
||||
|
||||
class Track;
|
||||
class WaveTrack;
|
||||
class WaveTrackCache;
|
||||
class WaveClip;
|
||||
class NoteTrack;
|
||||
class LabelTrack;
|
||||
@ -141,7 +142,7 @@ class AUDACITY_DLL_API TrackArtist {
|
||||
bool drawEnvelope, bool drawSamples, bool drawSliders,
|
||||
bool dB, bool muted);
|
||||
|
||||
void DrawClipSpectrum(WaveTrack *track, WaveClip *clip,
|
||||
void DrawClipSpectrum(WaveTrackCache &cache, WaveClip *clip,
|
||||
wxDC & dc, const wxRect & r, const ViewInfo *viewInfo,
|
||||
bool autocorrelation, bool logF);
|
||||
|
||||
|
@ -25,6 +25,8 @@ drawing). Cache's the Spectrogram frequency samples.
|
||||
|
||||
*//*******************************************************************/
|
||||
|
||||
#include "WaveClip.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
@ -32,7 +34,6 @@ drawing). Cache's the Spectrogram frequency samples.
|
||||
|
||||
#include "Spectrum.h"
|
||||
#include "Prefs.h"
|
||||
#include "WaveClip.h"
|
||||
#include "Envelope.h"
|
||||
#include "Resample.h"
|
||||
#include "Project.h"
|
||||
@ -753,10 +754,11 @@ bool WaveClip::GetWaveDisplay(float *min, float *max, float *rms,int* bl,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WaveClip::GetSpectrogram(float *freq, sampleCount *where,
|
||||
int numPixels,
|
||||
double t0, double pixelsPerSecond,
|
||||
bool autocorrelation)
|
||||
bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache,
|
||||
float *freq, sampleCount *where,
|
||||
int numPixels,
|
||||
double t0, double pixelsPerSecond,
|
||||
bool autocorrelation)
|
||||
{
|
||||
int minFreq = gPrefs->Read(wxT("/Spectrum/MinFreq"), 0L);
|
||||
int maxFreq = gPrefs->Read(wxT("/Spectrum/MaxFreq"), 8000L);
|
||||
@ -912,6 +914,7 @@ bool WaveClip::GetSpectrogram(float *freq, sampleCount *where,
|
||||
}
|
||||
}
|
||||
|
||||
float *useBuffer;
|
||||
#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
|
||||
float *buffer = new float[windowSize*fftSkipPoints1];
|
||||
mSpecCache->fftSkipPointsOld = fftSkipPoints;
|
||||
@ -952,6 +955,7 @@ bool WaveClip::GetSpectrogram(float *freq, sampleCount *where,
|
||||
}
|
||||
else
|
||||
{
|
||||
bool copy = !autocorrelation;
|
||||
float *adj = buffer;
|
||||
start -= windowSize >> 1;
|
||||
|
||||
@ -960,42 +964,58 @@ bool WaveClip::GetSpectrogram(float *freq, sampleCount *where,
|
||||
*adj++ = 0;
|
||||
len += start;
|
||||
start = 0;
|
||||
copy = true;
|
||||
}
|
||||
#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
|
||||
copy = true;
|
||||
if (start + len*fftSkipPoints1 > mSequence->GetNumSamples()) {
|
||||
int newlen = (mSequence->GetNumSamples() - start)/fftSkipPoints1;
|
||||
for (i = newlen*fftSkipPoints1; i < (sampleCount)len*fftSkipPoints1; i++)
|
||||
adj[i] = 0;
|
||||
len = newlen;
|
||||
}
|
||||
#else //!EXPERIMENTAL_FFT_SKIP_POINTS
|
||||
if (start + len > mSequence->GetNumSamples()) {
|
||||
int newlen = mSequence->GetNumSamples() - start;
|
||||
for (i = newlen; i < (sampleCount)len; i++)
|
||||
#endif //EXPERIMENTAL_FFT_SKIP_POINTS
|
||||
adj[i] = 0;
|
||||
len = newlen;
|
||||
copy = true;
|
||||
}
|
||||
#endif //EXPERIMENTAL_FFT_SKIP_POINTS
|
||||
|
||||
if (len > 0) {
|
||||
#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
|
||||
useBuffer = (float*)(waveTrackCache.Get(floatSample,
|
||||
floor(0.5 + start + mOffset * mRate),
|
||||
len * fftSkipPoints1));
|
||||
memmove(adj, useBuffer, len * fftSkipPoints1 * sizeof(float));
|
||||
if (fftSkipPoints) {
|
||||
// TODO: (maybe) alternatively change Get to include skipping of points
|
||||
int j=0;
|
||||
for (int i=0; i < len; i++) {
|
||||
adj[i]=adj[j];
|
||||
j+=fftSkipPoints1;
|
||||
}
|
||||
}
|
||||
#else //!EXPERIMENTAL_FFT_SKIP_POINTS
|
||||
useBuffer = (float*)(waveTrackCache.Get(floatSample,
|
||||
floor(0.5 + start + mOffset * mRate), len));
|
||||
if (copy)
|
||||
memmove(adj, useBuffer, len * sizeof(float));
|
||||
#endif //EXPERIMENTAL_FFT_SKIP_POINTS
|
||||
}
|
||||
|
||||
if (len > 0)
|
||||
#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
|
||||
mSequence->Get((samplePtr)adj, floatSample, start, len*fftSkipPoints1);
|
||||
if (fftSkipPoints) {
|
||||
// TODO: (maybe) alternatively change Get to include skipping of points
|
||||
int j=0;
|
||||
for (int i=0; i < len; i++) {
|
||||
adj[i]=adj[j];
|
||||
j+=fftSkipPoints1;
|
||||
}
|
||||
}
|
||||
#else //!EXPERIMENTAL_FFT_SKIP_POINTS
|
||||
mSequence->Get((samplePtr)adj, floatSample, start, len);
|
||||
#endif //EXPERIMENTAL_FFT_SKIP_POINTS
|
||||
if (copy)
|
||||
useBuffer = buffer;
|
||||
|
||||
#ifdef EXPERIMENTAL_USE_REALFFTF
|
||||
if(autocorrelation) {
|
||||
ComputeSpectrum(buffer, windowSize, windowSize,
|
||||
ComputeSpectrum(useBuffer, windowSize, windowSize,
|
||||
mRate, &mSpecCache->freq[half * x],
|
||||
autocorrelation, windowType);
|
||||
} else {
|
||||
ComputeSpectrumUsingRealFFTf(buffer, hFFT, mWindow, mWindowSize, &mSpecCache->freq[half * x]);
|
||||
ComputeSpectrumUsingRealFFTf(useBuffer, hFFT, mWindow, mWindowSize, &mSpecCache->freq[half * x]);
|
||||
}
|
||||
#else // EXPERIMENTAL_USE_REALFFTF
|
||||
ComputeSpectrum(buffer, windowSize, windowSize,
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
class Envelope;
|
||||
class WaveCache;
|
||||
class WaveTrackCache;
|
||||
class SpecCache;
|
||||
|
||||
class SpecPxCache {
|
||||
@ -140,7 +141,8 @@ public:
|
||||
* calculations and Contrast */
|
||||
bool GetWaveDisplay(float *min, float *max, float *rms,int* bl, sampleCount *where,
|
||||
int numPixels, double t0, double pixelsPerSecond, bool &isLoadingOD);
|
||||
bool GetSpectrogram(float *buffer, sampleCount *where,
|
||||
bool GetSpectrogram(WaveTrackCache &cache,
|
||||
float *buffer, sampleCount *where,
|
||||
int numPixels,
|
||||
double t0, double pixelsPerSecond,
|
||||
bool autocorrelation);
|
||||
|
Loading…
x
Reference in New Issue
Block a user