mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-19 17:40:15 +02:00
Performance improvements for track spectrum display and PCM
import submitted by Sami Liedes.
This commit is contained in:
parent
1d6e1593ee
commit
c0b5fb01da
@ -568,14 +568,23 @@ void AColor::DarkMIDIChannel(wxDC * dc, int channel /* 1 - 16 */ )
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetColorGradient(float value,
|
bool AColor::gradient_inited = 0;
|
||||||
bool selected,
|
|
||||||
bool grayscale,
|
unsigned char AColor::gradient_pre[2][2][gradientSteps][3];
|
||||||
unsigned char *red,
|
|
||||||
unsigned char *green, unsigned char *blue)
|
void AColor::PreComputeGradient() {
|
||||||
{
|
{
|
||||||
|
if (!gradient_inited) {
|
||||||
|
gradient_inited = 1;
|
||||||
|
|
||||||
|
for (int selected = 0; selected <= 1; selected++)
|
||||||
|
for (int grayscale = 0; grayscale <= 1; grayscale++) {
|
||||||
float r, g, b;
|
float r, g, b;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i=0; i<gradientSteps; i++) {
|
||||||
|
float value = float(i)/gradientSteps;
|
||||||
|
|
||||||
if (grayscale) {
|
if (grayscale) {
|
||||||
r = g = b = 0.84 - 0.84 * value;
|
r = g = b = 0.84 - 0.84 * value;
|
||||||
} else {
|
} else {
|
||||||
@ -604,10 +613,13 @@ void GetColorGradient(float value,
|
|||||||
g *= 0.77f;
|
g *= 0.77f;
|
||||||
b *= 0.885f;
|
b *= 0.885f;
|
||||||
}
|
}
|
||||||
|
gradient_pre[selected][grayscale][i][0] = (unsigned char) (255 * r);
|
||||||
*red = (unsigned char) (255 * r);
|
gradient_pre[selected][grayscale][i][1] = (unsigned char) (255 * g);
|
||||||
*green = (unsigned char) (255 * g);
|
gradient_pre[selected][grayscale][i][2] = (unsigned char) (255 * b);
|
||||||
*blue = (unsigned char) (255 * b);
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
|
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
|
||||||
|
19
src/AColor.h
19
src/AColor.h
@ -54,6 +54,8 @@ class AColor {
|
|||||||
static void TrackFocusPen(wxDC * dc, int level /* 0 - 2 */);
|
static void TrackFocusPen(wxDC * dc, int level /* 0 - 2 */);
|
||||||
static void SnapGuidePen(wxDC * dc);
|
static void SnapGuidePen(wxDC * dc);
|
||||||
|
|
||||||
|
static void PreComputeGradient();
|
||||||
|
|
||||||
// Member variables
|
// Member variables
|
||||||
|
|
||||||
static wxBrush lightBrush[2];
|
static wxBrush lightBrush[2];
|
||||||
@ -93,6 +95,10 @@ class AColor {
|
|||||||
|
|
||||||
static wxBrush tooltipBrush;
|
static wxBrush tooltipBrush;
|
||||||
|
|
||||||
|
static bool gradient_inited;
|
||||||
|
static const int gradientSteps = 512;
|
||||||
|
static unsigned char gradient_pre[2][2][gradientSteps][3];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static wxPen sparePen;
|
static wxPen sparePen;
|
||||||
static wxBrush spareBrush;
|
static wxBrush spareBrush;
|
||||||
@ -100,11 +106,20 @@ class AColor {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void GetColorGradient(float value,
|
inline void GetColorGradient(float value,
|
||||||
bool selected,
|
bool selected,
|
||||||
bool grayscale,
|
bool grayscale,
|
||||||
unsigned char *red,
|
unsigned char *red,
|
||||||
unsigned char *green, unsigned char *blue);
|
unsigned char *green, unsigned char *blue) {
|
||||||
|
if (!AColor::gradient_inited)
|
||||||
|
AColor::PreComputeGradient();
|
||||||
|
|
||||||
|
int idx = value * (AColor::gradientSteps - 1);
|
||||||
|
|
||||||
|
*red = AColor::gradient_pre[selected][grayscale][idx][0];
|
||||||
|
*green = AColor::gradient_pre[selected][grayscale][idx][1];
|
||||||
|
*blue = AColor::gradient_pre[selected][grayscale][idx][2];
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ static inline float todB_a(const float *x){
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
static inline float todB_a(const float *x){
|
static inline float todB_a(const float *x){
|
||||||
return (*(x)==0?-400.f:log(*(x)**(x))*4.34294480f);
|
return (*(x)==0?-400.f:logf(*(x)**(x))*4.34294480f);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -78,7 +78,7 @@ bool ComputeSpectrum(float * data, int width,
|
|||||||
// of the power, instead of the square root
|
// of the power, instead of the square root
|
||||||
|
|
||||||
for (i = 0; i < windowSize; i++)
|
for (i = 0; i < windowSize; i++)
|
||||||
in[i] = pow(in[i], 1.0f / 3.0f);
|
in[i] = powf(in[i], 1.0f / 3.0f);
|
||||||
|
|
||||||
// Take FFT
|
// Take FFT
|
||||||
#ifdef EXPERIMENTAL_USE_REALFFTF
|
#ifdef EXPERIMENTAL_USE_REALFFTF
|
||||||
|
@ -1656,13 +1656,13 @@ void TrackArtist::DrawClipSpectrum(WaveTrack *track,
|
|||||||
const float
|
const float
|
||||||
// e=exp(1.0f),
|
// e=exp(1.0f),
|
||||||
f=rate/2.0f/half,
|
f=rate/2.0f/half,
|
||||||
lmin=log(float(minFreq)),
|
lmin=logf(float(minFreq)),
|
||||||
lmax=log(float(maxFreq)),
|
lmax=logf(float(maxFreq)),
|
||||||
#ifdef EXPERIMENTAL_FIND_NOTES
|
#ifdef EXPERIMENTAL_FIND_NOTES
|
||||||
log2=log(2.0f),
|
log2=logf(2.0f),
|
||||||
#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
|
#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
|
||||||
lmins=log(float(minFreq)/(mFftSkipPoints+1)),
|
lmins=logf(float(minFreq)/(mFftSkipPoints+1)),
|
||||||
lmaxs=log(float(maxFreq)/(mFftSkipPoints+1)),
|
lmaxs=logf(float(maxFreq)/(mFftSkipPoints+1)),
|
||||||
#else //!EXPERIMENTAL_FFT_SKIP_POINTS
|
#else //!EXPERIMENTAL_FFT_SKIP_POINTS
|
||||||
lmins=lmin,
|
lmins=lmin,
|
||||||
lmaxs=lmax,
|
lmaxs=lmax,
|
||||||
@ -1681,10 +1681,10 @@ void TrackArtist::DrawClipSpectrum(WaveTrack *track,
|
|||||||
for (int y = 0; y < mid.height; y++) {
|
for (int y = 0; y < mid.height; y++) {
|
||||||
float n =(float(y )/mid.height*scale2-lmin2)*12;
|
float n =(float(y )/mid.height*scale2-lmin2)*12;
|
||||||
float n2=(float(y+1)/mid.height*scale2-lmin2)*12;
|
float n2=(float(y+1)/mid.height*scale2-lmin2)*12;
|
||||||
float f =float(minFreq)/(mFftSkipPoints+1)*pow(2.0f, n /12.0f+lmin2);
|
float f =float(minFreq)/(mFftSkipPoints+1)*powf(2.0f, n /12.0f+lmin2);
|
||||||
float f2=float(minFreq)/(mFftSkipPoints+1)*pow(2.0f, n2/12.0f+lmin2);
|
float f2=float(minFreq)/(mFftSkipPoints+1)*powf(2.0f, n2/12.0f+lmin2);
|
||||||
n =log(f /440)/log2*12;
|
n =logf(f /440)/log2*12;
|
||||||
n2=log(f2/440)/log2*12;
|
n2=logf(f2/440)/log2*12;
|
||||||
if (floor(n) < floor(n2))
|
if (floor(n) < floor(n2))
|
||||||
yGrid[y]=true;
|
yGrid[y]=true;
|
||||||
else
|
else
|
||||||
@ -1702,9 +1702,9 @@ void TrackArtist::DrawClipSpectrum(WaveTrack *track,
|
|||||||
f2bin = half/(rate/2.0f),
|
f2bin = half/(rate/2.0f),
|
||||||
#endif //EXPERIMENTAL_FFT_SKIP_POINTS
|
#endif //EXPERIMENTAL_FFT_SKIP_POINTS
|
||||||
bin2f = 1.0f/f2bin,
|
bin2f = 1.0f/f2bin,
|
||||||
minDistance = pow(2.0f, 2.0f/12.0f),
|
minDistance = powf(2.0f, 2.0f/12.0f),
|
||||||
i0=exp(lmin)/f,
|
i0=expf(lmin)/f,
|
||||||
i1=exp(scale+lmin)/f,
|
i1=expf(scale+lmin)/f,
|
||||||
minColor=0.0f;
|
minColor=0.0f;
|
||||||
const int maxTableSize=1024;
|
const int maxTableSize=1024;
|
||||||
int *indexes=new int[maxTableSize];
|
int *indexes=new int[maxTableSize];
|
||||||
@ -1819,19 +1819,19 @@ void TrackArtist::DrawClipSpectrum(WaveTrack *track,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The f2pix helper macro converts a frequency into a pixel coordinate.
|
// The f2pix helper macro converts a frequency into a pixel coordinate.
|
||||||
#define f2pix(f) (log(f)-lmins)/(lmaxs-lmins)*mid.height
|
#define f2pix(f) (logf(f)-lmins)/(lmaxs-lmins)*mid.height
|
||||||
|
|
||||||
// Possibly quantize the maxima frequencies and create the pixel block limits.
|
// Possibly quantize the maxima frequencies and create the pixel block limits.
|
||||||
for (int i=0; i < maximas; i++) {
|
for (int i=0; i < maximas; i++) {
|
||||||
int index=maxima[i];
|
int index=maxima[i];
|
||||||
float f = float(index)*bin2f;
|
float f = float(index)*bin2f;
|
||||||
if (mFindNotesQuantize)
|
if (mFindNotesQuantize)
|
||||||
{ f = exp(int(log(f/440)/log2*12-0.5)/12.0f*log2)*440;
|
{ f = expf(int(log(f/440)/log2*12-0.5)/12.0f*log2)*440;
|
||||||
maxima[i] = f*f2bin;
|
maxima[i] = f*f2bin;
|
||||||
}
|
}
|
||||||
float f0 = exp((log(f/440)/log2*24-1)/24.0f*log2)*440;
|
float f0 = expf((log(f/440)/log2*24-1)/24.0f*log2)*440;
|
||||||
maxima0[i] = f2pix(f0);
|
maxima0[i] = f2pix(f0);
|
||||||
float f1 = exp((log(f/440)/log2*24+1)/24.0f*log2)*440;
|
float f1 = expf((log(f/440)/log2*24+1)/24.0f*log2)*440;
|
||||||
maxima1[i] = f2pix(f1);
|
maxima1[i] = f2pix(f1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1840,17 +1840,18 @@ void TrackArtist::DrawClipSpectrum(WaveTrack *track,
|
|||||||
bool inMaximum = false;
|
bool inMaximum = false;
|
||||||
#endif //EXPERIMENTAL_FIND_NOTES
|
#endif //EXPERIMENTAL_FIND_NOTES
|
||||||
|
|
||||||
|
double yy2_base=exp(lmin)/f;
|
||||||
|
float yy2 = yy2_base;
|
||||||
|
double exp_scale_per_height = exp(scale/mid.height);
|
||||||
for (int yy = 0; yy < mid.height; yy++) {
|
for (int yy = 0; yy < mid.height; yy++) {
|
||||||
if(!usePxCache) {
|
if(!usePxCache) {
|
||||||
float h=float(yy)/mid.height;
|
|
||||||
float yy2=exp(h*scale+lmin)/f;
|
|
||||||
if (int(yy2)>=half)
|
if (int(yy2)>=half)
|
||||||
yy2=half-1;
|
yy2=half-1;
|
||||||
if (yy2<0)
|
if (yy2<0)
|
||||||
yy2=0;
|
yy2=0;
|
||||||
float bin0 = float(yy2);
|
float bin0 = float(yy2);
|
||||||
float h1=float(yy+1)/mid.height;
|
yy2_base *= exp_scale_per_height;
|
||||||
float yy3=exp(h1*scale+lmin)/f;
|
float yy3 = yy2_base;
|
||||||
if (int(yy3)>=half)
|
if (int(yy3)>=half)
|
||||||
yy3=half-1;
|
yy3=half-1;
|
||||||
if (yy3<0)
|
if (yy3<0)
|
||||||
@ -1896,6 +1897,7 @@ void TrackArtist::DrawClipSpectrum(WaveTrack *track,
|
|||||||
if (value < 0.0)
|
if (value < 0.0)
|
||||||
value = float(0.0);
|
value = float(0.0);
|
||||||
clip->mSpecPxCache->values[x * mid.height + yy] = value;
|
clip->mSpecPxCache->values[x * mid.height + yy] = value;
|
||||||
|
yy2 = yy2_base;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
value = clip->mSpecPxCache->values[x * mid.height + yy];
|
value = clip->mSpecPxCache->values[x * mid.height + yy];
|
||||||
|
@ -285,7 +285,7 @@ void ComputeSpectrumUsingRealFFTf(float *buffer, HFFT hFFT, float *window, int l
|
|||||||
if(power <= 0)
|
if(power <= 0)
|
||||||
out[i] = -160.0;
|
out[i] = -160.0;
|
||||||
else
|
else
|
||||||
out[i] = 10.0*log10(power);
|
out[i] = 10.0*log10f(power);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // EXPERIMENTAL_USE_REALFFTF
|
#endif // EXPERIMENTAL_USE_REALFFTF
|
||||||
|
@ -253,6 +253,7 @@ int PCMImportFileHandle::Import(TrackFactory *trackFactory,
|
|||||||
// lets use OD only if the file is longer than 30 seconds. Otherwise, why wake up extra threads.
|
// lets use OD only if the file is longer than 30 seconds. Otherwise, why wake up extra threads.
|
||||||
//todo: make this a user pref.
|
//todo: make this a user pref.
|
||||||
bool useOD =fileTotalFrames>kMinimumODFileSampleSize;
|
bool useOD =fileTotalFrames>kMinimumODFileSampleSize;
|
||||||
|
int updateCounter = 0;
|
||||||
|
|
||||||
for (sampleCount i = 0; i < fileTotalFrames; i += maxBlockSize) {
|
for (sampleCount i = 0; i < fileTotalFrames; i += maxBlockSize) {
|
||||||
|
|
||||||
@ -263,10 +264,14 @@ int PCMImportFileHandle::Import(TrackFactory *trackFactory,
|
|||||||
for (c = 0; c < mInfo.channels; c++)
|
for (c = 0; c < mInfo.channels; c++)
|
||||||
channels[c]->AppendAlias(mFilename, i, blockLen, c,useOD);
|
channels[c]->AppendAlias(mFilename, i, blockLen, c,useOD);
|
||||||
|
|
||||||
|
if (++updateCounter == 50) {
|
||||||
updateResult = mProgress->Update(i, fileTotalFrames);
|
updateResult = mProgress->Update(i, fileTotalFrames);
|
||||||
|
updateCounter = 0;
|
||||||
if (updateResult != eProgressSuccess)
|
if (updateResult != eProgressSuccess)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
updateResult = mProgress->Update(fileTotalFrames, fileTotalFrames);
|
||||||
|
|
||||||
//now go over the wavetrack/waveclip/sequence and load all the blockfiles into a ComputeSummaryTask.
|
//now go over the wavetrack/waveclip/sequence and load all the blockfiles into a ComputeSummaryTask.
|
||||||
//Add this task to the ODManager and the Track itself.
|
//Add this task to the ODManager and the Track itself.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user