1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-07 23:51:14 +02:00

Some preliminary changes to SpectrogramSettings, for View Settings project

This commit is contained in:
Paul Licameli 2015-07-26 21:12:04 -04:00
commit ca767c0f7a
16 changed files with 584 additions and 449 deletions

View File

@ -39,13 +39,13 @@
* 9: Gaussian(a=4.5)
*/
#include "FFT.h"
#include <wx/intl.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "FFT.h"
static int **gFFTBitTable = NULL;
static const int MaxFastBits = 16;

View File

@ -32,6 +32,8 @@
#ifndef __AUDACITY_FFT_H__
#define __AUDACITY_FFT_H__
#include <wx/defs.h>
/*
Salvo Ventura - November 2006
Added more window functions:

View File

@ -477,6 +477,8 @@ audacity_SOURCES = \
prefs/QualityPrefs.h \
prefs/RecordingPrefs.cpp \
prefs/RecordingPrefs.h \
prefs/SpectrogramSettings.cpp \
prefs/SpectrogramSettings.h \
prefs/SpectrumPrefs.cpp \
prefs/SpectrumPrefs.h \
prefs/ThemePrefs.cpp \

View File

@ -173,7 +173,7 @@ audio tracks.
#include "LabelTrack.h"
#include "TimeTrack.h"
#include "Prefs.h"
#include "prefs/SpectrumPrefs.h"
#include "prefs/SpectrogramSettings.h"
#include "Sequence.h"
#include "Spectrum.h"
#include "ViewInfo.h"
@ -692,7 +692,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect)
// All waves have a ruler in the info panel
// The ruler needs a bevelled surround.
if (t->GetKind() == Track::Wave) {
WaveTrack *wt = (WaveTrack *)t;
WaveTrack *wt = static_cast<WaveTrack*>(t);
int display = wt->GetDisplay();
if (display == WaveTrack::WaveformDisplay) {
@ -802,16 +802,10 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect)
if (rect.height < 60)
return;
double rate = wt->GetRate();
int freq = lrint(rate/2.);
int maxFreq = GetSpectrumMaxFreq(freq);
if(maxFreq > freq)
maxFreq = freq;
int minFreq = GetSpectrumMinFreq(0);
if(minFreq < 0)
minFreq = 0;
const SpectrogramSettings &settings = wt->GetSpectrogramSettings();
const double rate = wt->GetRate();
const int maxFreq = settings.GetMaxFreq(rate);
const int minFreq = settings.GetMinFreq(rate);
/*
draw the ruler
@ -842,16 +836,10 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect)
if (rect.height < 10)
return;
double rate = wt->GetRate();
int freq = lrint(rate/2.);
int maxFreq = GetSpectrumLogMaxFreq(freq);
if(maxFreq > freq)
maxFreq = freq;
int minFreq = GetSpectrumLogMinFreq(freq/1000.0);
if(minFreq < 1)
minFreq = 1;
const SpectrogramSettings &settings = wt->GetSpectrogramSettings();
const double rate = wt->GetRate();
const int maxFreq = settings.GetLogMaxFreq(rate);
const int minFreq = settings.GetLogMinFreq(rate);
/*
draw the ruler
@ -2042,6 +2030,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
#endif
const WaveTrack *const track = waveTrackCache.GetTrack();
const SpectrogramSettings &settings = track->GetSpectrogramSettings();
const int display = track->GetDisplay();
const bool autocorrelation = (WaveTrack::PitchDisplay == display);
const bool logF = (WaveTrack::SpectrumLogDisplay == display
@ -2079,7 +2069,6 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
}
#endif
const SpectrogramSettings &settings = SpectrogramSettings::defaults();
const bool &isGrayscale = settings.isGrayscale;
const int &range = settings.range;
const int &gain = settings.gain;
@ -2104,7 +2093,7 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
return;
unsigned char *data = image->GetData();
const int half = GetSpectrumWindowSize(!autocorrelation) / 2;
const int half = settings.GetFFTLength(autocorrelation) / 2;
const double binUnit = rate / (2 * half);
const float *freq = 0;
const sampleCount *where = 0;
@ -2115,28 +2104,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
t0, pps, autocorrelation);
}
int ifreq = lrint(rate / 2);
int maxFreq;
if (!logF)
maxFreq = GetSpectrumMaxFreq(ifreq);
else
maxFreq = GetSpectrumLogMaxFreq(ifreq);
if(maxFreq > ifreq)
maxFreq = ifreq;
int minFreq;
if (!logF) {
minFreq = GetSpectrumMinFreq(0);
if(minFreq < 0)
minFreq = 0;
}
else {
minFreq = GetSpectrumLogMinFreq(ifreq/1000.0);
if(minFreq < 1)
// Paul L: I suspect this line is now unreachable
minFreq = 1.0;
}
const int minFreq = logF ? settings.GetLogMinFreq(rate) : settings.GetMinFreq(rate);
const int maxFreq = logF ? settings.GetLogMaxFreq(rate) : settings.GetMaxFreq(rate);
float minBin = ((double)minFreq / binUnit);
float maxBin = ((double)maxFreq / binUnit);
@ -3217,66 +3186,6 @@ void TrackArtist::UpdatePrefs()
gPrefs->Flush();
}
// Get various preference values
int TrackArtist::GetSpectrumMinFreq(int deffreq)
{
const int &minFreq = SpectrogramSettings::defaults().minFreq;
return minFreq < 0 ? deffreq : minFreq;
}
int TrackArtist::GetSpectrumMaxFreq(int deffreq)
{
const int &maxFreq = SpectrogramSettings::defaults().maxFreq;
return maxFreq < 0 ? deffreq : maxFreq;
}
int TrackArtist::GetSpectrumLogMinFreq(int deffreq)
{
const int &logMinFreq = SpectrogramSettings::defaults().logMinFreq;
return logMinFreq < 0 ? deffreq : logMinFreq;
}
int TrackArtist::GetSpectrumLogMaxFreq(int deffreq)
{
const int &logMaxFreq = SpectrogramSettings::defaults().logMaxFreq;
return logMaxFreq < 0 ? deffreq : logMaxFreq;
}
int TrackArtist::GetSpectrumWindowSize(bool includeZeroPadding)
{
includeZeroPadding;
const int &windowSize = SpectrogramSettings::defaults().windowSize;
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
if (includeZeroPadding) {
const int &zeroPaddingFactor = SpectrogramSettings::defaults().zeroPaddingFactor;
return windowSize * zeroPaddingFactor;
}
else
#endif
return windowSize;
}
// Set various preference values
void TrackArtist::SetSpectrumMinFreq(int freq)
{
SpectrogramSettings::defaults().minFreq = freq;
}
void TrackArtist::SetSpectrumMaxFreq(int freq)
{
SpectrogramSettings::defaults().maxFreq = freq;
}
void TrackArtist::SetSpectrumLogMinFreq(int freq)
{
SpectrogramSettings::defaults().logMinFreq = freq;
}
void TrackArtist::SetSpectrumLogMaxFreq(int freq)
{
SpectrogramSettings::defaults().logMaxFreq = freq;
}
// Draws the sync-lock bitmap, tiled; always draws stationary relative to the DC
//
// AWD: now that the tiles don't link together, we're drawing a tilted grid, at

View File

@ -73,16 +73,6 @@ class AUDACITY_DLL_API TrackArtist {
void InvalidateSpectrumCache(TrackList *tracks);
void InvalidateSpectrumCache(WaveTrack *track);
int GetSpectrumMinFreq(int deffreq);
int GetSpectrumMaxFreq(int deffreq);
int GetSpectrumLogMinFreq(int deffreq);
int GetSpectrumLogMaxFreq(int deffreq);
int GetSpectrumWindowSize(bool includeZeroPadding);
void SetSpectrumMinFreq(int freq);
void SetSpectrumMaxFreq(int freq);
void SetSpectrumLogMinFreq(int freq);
void SetSpectrumLogMaxFreq(int freq);
void SetBackgroundBrushes(wxBrush unselectedBrush, wxBrush selectedBrush,
wxPen unselectedPen, wxPen selectedPen) {

View File

@ -217,7 +217,7 @@ is time to refresh some aspect of the screen.
#include "ondemand/ODManager.h"
#include "prefs/SpectrumPrefs.h"
#include "prefs/SpectrogramSettings.h"
#include "toolbars/ControlToolBar.h"
#include "toolbars/ToolManager.h"
@ -230,7 +230,7 @@ is time to refresh some aspect of the screen.
#include <wx/arrimpl.cpp>
#define ZOOMLIMIT 0.001
#define ZOOMLIMIT 0.001f
WX_DEFINE_OBJARRAY(TrackClipArray);
@ -2992,10 +2992,10 @@ inline double findMaxRatio(double center, double rate)
}
void TrackPanel::SnapCenterOnce(WaveTrack *pTrack, bool up)
void TrackPanel::SnapCenterOnce(const WaveTrack *pTrack, bool up)
{
// Always spectrogram, never pitch view, pass true
const int windowSize = mTrackArtist->GetSpectrumWindowSize(true);
const SpectrogramSettings &settings = pTrack->GetSpectrogramSettings();
const int windowSize = settings.GetFFTLength(false);
const double rate = pTrack->GetRate();
const double nyq = rate / 2.0;
const double binFrequency = rate / windowSize;
@ -3032,7 +3032,7 @@ void TrackPanel::SnapCenterOnce(WaveTrack *pTrack, bool up)
(snappedFrequency / ratio, snappedFrequency * ratio);
}
void TrackPanel::StartSnappingFreqSelection (WaveTrack *pTrack)
void TrackPanel::StartSnappingFreqSelection (const WaveTrack *pTrack)
{
static const sampleCount minLength = 8;
@ -3057,12 +3057,13 @@ void TrackPanel::StartSnappingFreqSelection (WaveTrack *pTrack)
// Use same settings as are now used for spectrogram display,
// except, shrink the window as needed so we get some answers
// Always spectrogram, never pitch view, pass true
int windowSize = mTrackArtist->GetSpectrumWindowSize(true);
const SpectrogramSettings &settings = pTrack->GetSpectrogramSettings();
int windowSize = settings.GetFFTLength(false);
while(windowSize > effectiveLength)
windowSize >>= 1;
const int windowType = SpectrogramSettings::defaults().windowType;
const int windowType = settings.windowType;
mFrequencySnapper->Calculate(
SpectrumAnalyst::Spectrum, windowType, windowSize, rate,
&frequencySnappingData[0], length);
@ -3087,8 +3088,8 @@ void TrackPanel::MoveSnappingFreqSelection (int mouseYCoordinate,
// I am not worrying about that odd case.
const double rate = wt->GetRate();
const double frequency =
PositionToFrequency(false, mouseYCoordinate,
trackTopEdge, trackHeight, rate, logF);
PositionToFrequency(wt, false, mouseYCoordinate,
trackTopEdge, trackHeight, logF);
const double snappedFrequency =
mFrequencySnapper->FindPeak(frequency, NULL);
const double maxRatio = findMaxRatio(snappedFrequency, rate);
@ -3124,10 +3125,9 @@ void TrackPanel::StartFreqSelection (int mouseYCoordinate, int trackTopEdge,
if (isSpectrogramTrack(pTrack, &logF)) {
mFreqSelTrack = static_cast<WaveTrack*>(pTrack);
mFreqSelMode = FREQ_SEL_FREE;
const double rate = mFreqSelTrack->GetRate();
mFreqSelPin =
PositionToFrequency(false, mouseYCoordinate,
trackTopEdge, trackHeight, rate, logF);
PositionToFrequency(mFreqSelTrack, false, mouseYCoordinate,
trackTopEdge, trackHeight, logF);
mViewInfo->selectedRegion.setFrequencies(mFreqSelPin, mFreqSelPin);
}
}
@ -3152,8 +3152,8 @@ void TrackPanel::ExtendFreqSelection(int mouseYCoordinate, int trackTopEdge,
;
const double rate = wt->GetRate();
const double frequency =
PositionToFrequency(true, mouseYCoordinate,
trackTopEdge, trackHeight, rate, logF);
PositionToFrequency(wt, true, mouseYCoordinate,
trackTopEdge, trackHeight, logF);
// Dragging center?
if (mFreqSelMode == FREQ_SEL_DRAG_CENTER) {
@ -3528,13 +3528,15 @@ enum { FREQ_SNAP_DISTANCE = 10 };
/// Converts a position (mouse Y coordinate) to
/// frequency, in Hz.
double TrackPanel::PositionToFrequency(bool maySnap,
double TrackPanel::PositionToFrequency(const WaveTrack *wt,
bool maySnap,
wxInt64 mouseYCoordinate,
wxInt64 trackTopEdge,
int trackHeight,
double rate,
bool logF) const
{
const double rate = wt->GetRate();
// Handle snapping
if (maySnap &&
mouseYCoordinate - trackTopEdge < FREQ_SNAP_DISTANCE)
@ -3544,42 +3546,38 @@ double TrackPanel::PositionToFrequency(bool maySnap,
return -1;
const double p = double(mouseYCoordinate - trackTopEdge) / trackHeight;
const int freq = lrint(rate/2.);
if (logF)
{
const double maxFreq =
std::min(freq, mTrackArtist->GetSpectrumLogMaxFreq(freq));
const double minFreq =
std::max(1, mTrackArtist->GetSpectrumLogMinFreq(1));
const SpectrogramSettings &settings = wt->GetSpectrogramSettings();
const double maxFreq = settings.GetLogMaxFreq(rate);
const double minFreq = settings.GetLogMinFreq(rate);
return exp(p * log(minFreq) + (1.0 - p) * log(maxFreq));
}
else
{
const double maxFreq =
std::min(freq, mTrackArtist->GetSpectrumMaxFreq(freq));
const double minFreq =
std::max(0, mTrackArtist->GetSpectrumMinFreq(0));
const SpectrogramSettings &settings = wt->GetSpectrogramSettings();
const double maxFreq = settings.GetMaxFreq(rate);
const double minFreq = settings.GetMinFreq(rate);
return p * minFreq + (1.0 - p) * maxFreq;
}
}
/// Converts a frequency to screen y position.
wxInt64 TrackPanel::FrequencyToPosition(double frequency,
wxInt64 TrackPanel::FrequencyToPosition(const WaveTrack *wt,
double frequency,
wxInt64 trackTopEdge,
int trackHeight,
double rate,
bool logF) const
{
const int freq = lrint(rate/2.);
const double rate = wt->GetRate();
double p = 0;
if (logF)
{
const double maxFreq =
std::min(freq, mTrackArtist->GetSpectrumLogMaxFreq(freq));
const double minFreq =
std::max(1, mTrackArtist->GetSpectrumLogMinFreq(1));
const SpectrogramSettings &settings = wt->GetSpectrogramSettings();
const double maxFreq = settings.GetLogMaxFreq(rate);
const double minFreq = settings.GetLogMinFreq(rate);
if (maxFreq > minFreq)
{
const double
@ -3591,10 +3589,9 @@ wxInt64 TrackPanel::FrequencyToPosition(double frequency,
}
else
{
const double maxFreq =
std::min(freq, mTrackArtist->GetSpectrumMaxFreq(freq));
const double minFreq =
std::max(0, mTrackArtist->GetSpectrumMinFreq(0));
const SpectrogramSettings &settings = wt->GetSpectrogramSettings();
const double maxFreq = settings.GetMaxFreq(rate);
const double minFreq = settings.GetMinFreq(rate);
if (maxFreq > minFreq)
p = (frequency - minFreq) / (maxFreq - minFreq);
}
@ -3687,12 +3684,10 @@ bool mayDragWidth, bool onlyWithinSnapDistance,
isSpectrogramTrack(pTrack, &logF)) {
const WaveTrack *const wt = static_cast<const WaveTrack*>(pTrack);
const wxInt64 bottomSel = (f0 >= 0)
? FrequencyToPosition(f0, rect.y, rect.height,
wt->GetRate(), logF)
? FrequencyToPosition(wt, f0, rect.y, rect.height, logF)
: rect.y + rect.height;
const wxInt64 topSel = (f1 >= 0)
? FrequencyToPosition(f1, rect.y, rect.height,
wt->GetRate(), logF)
? FrequencyToPosition(wt, f1, rect.y, rect.height, logF)
: rect.y;
wxInt64 signedBottomDist = int(event.m_y - bottomSel);
wxInt64 verticalDist = abs(signedBottomDist);
@ -3710,8 +3705,7 @@ bool mayDragWidth, bool onlyWithinSnapDistance,
#endif
) {
const wxInt64 centerSel =
FrequencyToPosition(fc, rect.y, rect.height,
wt->GetRate(), logF);
FrequencyToPosition(wt, fc, rect.y, rect.height, logF);
const wxInt64 centerDist = abs(int(event.m_y - centerSel));
if (centerDist < verticalDist)
chooseCenter = true, verticalDist = centerDist,
@ -4682,8 +4676,8 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
// don't do anything if track is not wave
if (mCapturedTrack->GetKind() != Track::Wave)
return;
WaveTrack *track = (WaveTrack *)mCapturedTrack;
WaveTrack *partner = (WaveTrack *)mTracks->GetLink(track);
WaveTrack *track = static_cast<WaveTrack*>(mCapturedTrack);
WaveTrack *partner = static_cast<WaveTrack *>(mTracks->GetLink(track));
int height = track->GetHeight();
int ypos = mCapturedRect.y;
@ -4695,40 +4689,27 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
}
float min, max, c, l, binSize = 0.0;
bool spectrum, spectrumLog;
int windowSize;
double rate = ((WaveTrack *)track)->GetRate();
spectrum = (((WaveTrack *) track)->GetDisplay() == WaveTrack::SpectrumDisplay) ||
(((WaveTrack *) track)->GetDisplay() == WaveTrack::SpectralSelectionDisplay) ;
spectrumLog=(((WaveTrack *) track)->GetDisplay() == WaveTrack::SpectrumLogDisplay) ||
(((WaveTrack *) track)->GetDisplay() == WaveTrack::SpectralSelectionLogDisplay)
;
const double rate = track->GetRate();
const bool spectrum = (track->GetDisplay() == WaveTrack::SpectrumDisplay) ||
(track->GetDisplay() == WaveTrack::SpectralSelectionDisplay);
const bool spectrumLog = (track->GetDisplay() == WaveTrack::SpectrumLogDisplay) ||
(track->GetDisplay() == WaveTrack::SpectralSelectionLogDisplay);
if(spectrum) {
min = mTrackArtist->GetSpectrumMinFreq(0);
if(min < 0)
min = 0;
max = mTrackArtist->GetSpectrumMaxFreq(8000);
if(max > rate/2.)
max = rate/2.;
// Always spectrogram, never pitch view, pass true
windowSize = mTrackArtist->GetSpectrumWindowSize(true);
binSize = rate / windowSize;
minBins = wxMin(10, windowSize/2); //minimum 10 freq bins, unless there are less
const SpectrogramSettings &settings = track->GetSpectrogramSettings();
min = settings.GetMinFreq(rate);
max = settings.GetMaxFreq(rate);
const int fftLength = settings.GetFFTLength(false);
binSize = rate / fftLength;
minBins = std::min(10, fftLength / 2); //minimum 10 freq bins, unless there are less
}
else
if(spectrumLog) {
min = mTrackArtist->GetSpectrumLogMinFreq(lrint(rate/1000.0));
if(min < 1)
min = 1;
max = mTrackArtist->GetSpectrumLogMaxFreq(lrint(rate/2.));
if(max > rate/2.)
max = rate/2.;
// Always spectrogram, never pitch view, pass true
windowSize = mTrackArtist->GetSpectrumWindowSize(true);
binSize = rate / windowSize;
minBins = wxMin(10, windowSize/2); //minimum 10 freq bins, unless there are less
const SpectrogramSettings &settings = track->GetSpectrogramSettings();
min = settings.GetLogMinFreq(rate);
max = settings.GetLogMaxFreq(rate);
const int fftLength = settings.GetFFTLength(false);
binSize = rate / fftLength;
minBins = std::min(10, fftLength / 2); //minimum 10 freq bins, unless there are less
}
else
track->GetDisplayBounds(&min, &max);
@ -4743,8 +4724,8 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
double xmax = 1-(mZoomStart - ypos) / (float)height;
double lmin=log10(tmin), lmax=log10(tmax);
double d=lmax-lmin;
min=wxMax(1.0, pow(10, xmin*d+lmin));
max=wxMin(rate/2.0, pow(10, xmax*d+lmin));
min=std::max(1.0, pow(10, xmin*d+lmin));
max=std::min(rate/2.0, pow(10, xmax*d+lmin));
// Enforce vertical zoom limits
// done in the linear freq domain for now, but not too far out
if(max < min + minBins * binSize)
@ -4798,11 +4779,11 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
l = (c - min);
if(c - 2*l <= 0) {
min = 0.0;
max = wxMin( rate/2., 2. * max);
max = std::min( rate/2., 2. * max);
}
else {
min = wxMax( 0.0, c - 2*l);
max = wxMin( rate/2., c + 2*l);
min = std::max( 0.0f, c - 2*l);
max = std::min( float(rate)/2, c + 2*l);
}
}
}
@ -4822,8 +4803,8 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
double xmax = c + 1.;
double lmin = log10(min), lmax = log10(max);
double d = lmax-lmin;
min = wxMax(1,pow(10, xmin*d+lmin));
max = wxMin(rate/2., pow(10, xmax*d+lmin));
min = std::max(1.0f,float(pow(10, xmin*d+lmin)));
max = std::min(rate/2., pow(10, xmax*d+lmin));
}
}
else {
@ -4845,8 +4826,8 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
float minRange = (min < -1) ? -2.0 : -1.0;
float maxRange = (max > 1) ? 2.0 : 1.0;
// and enforce vertical zoom limits.
min = wxMin(maxRange - ZOOMLIMIT, wxMax(minRange, c - 2*l));
max = wxMax(minRange + ZOOMLIMIT, wxMin(maxRange, c + 2*l));
min = std::min(maxRange - ZOOMLIMIT, std::max(minRange, c - 2*l));
max = std::max(minRange + ZOOMLIMIT, std::min(maxRange, c + 2*l));
}
}
}
@ -4858,12 +4839,12 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
if(spectrum) {
c = 0.5*(min+max);
// Enforce maximum vertical zoom
l = wxMax( minBins * binSize, (c - min));
l = std::max( minBins * binSize, (c - min));
p1 = (mZoomStart - ypos) / (float)height;
c = (max * (1.0-p1) + min * p1);
min = wxMax( 0.0, c - 0.5*l);
max = wxMin( rate/2., min + l);
min = std::max( 0.0, c - 0.5*l);
max = std::min( float(rate)/2, min + l);
}
else {
if(spectrumLog) {
@ -4873,8 +4854,8 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
double xmax = c + 0.25;
double lmin = log10(min), lmax = log10(max);
double d = lmax-lmin;
min = wxMax(1,pow(10, xmin*d+lmin));
max = wxMin(rate/2., pow(10, xmax*d+lmin));
min = std::max(1.0f, float(pow(10, xmin*d+lmin)));
max = std::min(rate/2., pow(10, xmax*d+lmin));
// Enforce vertical zoom limits
// done in the linear freq domain for now, but not too far out
if(max < min + minBins * binSize)
@ -4893,7 +4874,7 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
else {
c = 0.5*(min+max);
// Enforce maximum vertical zoom
l = wxMax( ZOOMLIMIT, (c - min));
l = std::max( ZOOMLIMIT, (c - min));
p1 = (mZoomStart - ypos) / (float)height;
c = (max * (1.0-p1) + min * p1);
@ -4905,13 +4886,27 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
}
if(spectrum) {
mTrackArtist->SetSpectrumMaxFreq(max);
mTrackArtist->SetSpectrumMinFreq(min);
SpectrogramSettings &settings = track->GetSpectrogramSettings();
settings.SetMinFreq(min);
settings.SetMaxFreq(max);
if (partner) {
// To do: share memory with reference counting?
SpectrogramSettings &settings = partner->GetSpectrogramSettings();
settings.SetMinFreq(min);
settings.SetMaxFreq(max);
}
mTrackArtist->InvalidateSpectrumCache(mTracks);
}
else if(spectrumLog) {
mTrackArtist->SetSpectrumLogMaxFreq(max);
mTrackArtist->SetSpectrumLogMinFreq(min);
SpectrogramSettings &settings = track->GetSpectrogramSettings();
settings.SetLogMinFreq(min);
settings.SetLogMaxFreq(max);
if (partner) {
// To do: share memory with reference counting?
SpectrogramSettings &settings = partner->GetSpectrogramSettings();
settings.SetLogMinFreq(min);
settings.SetLogMaxFreq(max);
}
mTrackArtist->InvalidateSpectrumCache(mTracks);
}
else {

View File

@ -337,9 +337,9 @@ protected:
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
public:
void SnapCenterOnce (WaveTrack *pTrack, bool up);
void SnapCenterOnce (const WaveTrack *pTrack, bool up);
protected:
void StartSnappingFreqSelection (WaveTrack *pTrack);
void StartSnappingFreqSelection (const WaveTrack *pTrack);
void MoveSnappingFreqSelection (int mouseYCoordinate,
int trackTopEdge,
int trackHeight, Track *pTrack);
@ -494,9 +494,9 @@ protected:
virtual wxRect FindTrackRect(Track * target, bool label);
virtual int GetVRulerWidth() const;
virtual int GetVRulerOffset() const { return mTrackInfo.GetTrackInfoWidth(); };
virtual int GetVRulerOffset() const { return mTrackInfo.GetTrackInfoWidth(); }
virtual int GetLabelWidth() const { return mTrackInfo.GetTrackInfoWidth() + GetVRulerWidth(); };
virtual int GetLabelWidth() const { return mTrackInfo.GetTrackInfoWidth() + GetVRulerWidth(); }
// JKC Nov-2011: These four functions only used from within a dll such as mod-track-panel
// They work around some messy problems with constructors.
@ -693,16 +693,16 @@ protected:
void HandleCenterFrequencyClick
(bool shiftDown, Track *pTrack, double value);
double PositionToFrequency(bool maySnap,
double PositionToFrequency(const WaveTrack *wt,
bool maySnap,
wxInt64 mouseYCoordinate,
wxInt64 trackTopEdge,
int trackHeight,
double rate,
bool logF) const;
wxInt64 FrequencyToPosition(double frequency,
wxInt64 FrequencyToPosition(const WaveTrack *wt,
double frequency,
wxInt64 trackTopEdge,
int trackHeight,
double rate,
bool logF) const;
#endif

View File

@ -33,7 +33,7 @@
#include "Resample.h"
#include "Project.h"
#include "prefs/SpectrumPrefs.h"
#include "prefs/SpectrogramSettings.h"
#include <wx/listimpl.cpp>
WX_DEFINE_LIST(WaveClipList);
@ -902,8 +902,8 @@ bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache,
double t0, double pixelsPerSecond,
bool autocorrelation)
{
const SpectrogramSettings &settings = SpectrogramSettings::defaults();
const WaveTrack *const track = waveTrackCache.GetTrack();
const SpectrogramSettings &settings = track->GetSpectrogramSettings();
const int &frequencyGain = settings.frequencyGain;
const int &windowSize = settings.windowSize;
const int &windowType = settings.windowType;

View File

@ -54,6 +54,7 @@ Track classes.
#include "ondemand/ODManager.h"
#include "effects/TimeWarper.h"
#include "prefs/SpectrumPrefs.h"
using std::max;
@ -74,6 +75,7 @@ WaveTrack *TrackFactory::NewWaveTrack(sampleFormat format, double rate)
WaveTrack::WaveTrack(DirManager *projDirManager, sampleFormat format, double rate):
Track(projDirManager)
, mpSpectrumSettings(0)
{
if (format == (sampleFormat)0)
{
@ -105,6 +107,9 @@ WaveTrack::WaveTrack(DirManager *projDirManager, sampleFormat format, double rat
WaveTrack::WaveTrack(WaveTrack &orig):
Track(orig)
, mpSpectrumSettings(orig.mpSpectrumSettings
? new SpectrogramSettings(*orig.mpSpectrumSettings) : 0
)
{
mDisplay = FindDefaultViewMode();
mLastDisplay = -1;
@ -139,9 +144,12 @@ void WaveTrack::Merge(const Track &orig)
{
if (orig.GetKind() == Wave)
{
mDisplay = ((WaveTrack &)orig).mDisplay;
mGain = ((WaveTrack &)orig).mGain;
mPan = ((WaveTrack &)orig).mPan;
const WaveTrack &wt = static_cast<const WaveTrack&>(orig);
mDisplay = wt.mDisplay;
mGain = wt.mGain;
mPan = wt.mPan;
SetSpectrogramSettings(wt.mpSpectrumSettings
? new SpectrogramSettings(*wt.mpSpectrumSettings) : 0);
}
Track::Merge(orig);
}
@ -159,6 +167,7 @@ WaveTrack::~WaveTrack()
if (mDisplayLocations)
delete [] mDisplayLocations;
delete mpSpectrumSettings;
}
double WaveTrack::GetOffset() const
@ -624,6 +633,38 @@ bool WaveTrack::ClearAndAddCutLine(double t0, double t1)
return HandleClear(t0, t1, true, false);
}
const SpectrogramSettings &WaveTrack::GetSpectrogramSettings() const
{
if (mpSpectrumSettings)
return *mpSpectrumSettings;
else
return SpectrogramSettings::defaults();
}
SpectrogramSettings &WaveTrack::GetSpectrogramSettings()
{
if (mpSpectrumSettings)
return *mpSpectrumSettings;
else
return SpectrogramSettings::defaults();
}
SpectrogramSettings &WaveTrack::GetIndependentSpectrogramSettings()
{
if (!mpSpectrumSettings)
mpSpectrumSettings =
new SpectrogramSettings(SpectrogramSettings::defaults());
return *mpSpectrumSettings;
}
void WaveTrack::SetSpectrogramSettings(SpectrogramSettings *pSettings)
{
if (mpSpectrumSettings != pSettings) {
delete mpSpectrumSettings;
mpSpectrumSettings = pSettings;
}
}
//
// ClearAndPaste() is a specialized version of HandleClear()
// followed by Paste() and is used mostly by effects that

View File

@ -22,6 +22,7 @@
#include <wx/longlong.h>
#include <wx/thread.h>
class SpectrogramSettings;
class TimeWarper;
//
@ -145,6 +146,11 @@ class AUDACITY_DLL_API WaveTrack: public Track {
sampleFormat GetSampleFormat() { return mFormat; }
bool ConvertToSampleFormat(sampleFormat format);
const SpectrogramSettings &GetSpectrogramSettings() const;
SpectrogramSettings &GetSpectrogramSettings();
SpectrogramSettings &GetIndependentSpectrogramSettings();
void SetSpectrogramSettings(SpectrogramSettings *pSettings);
//
// High-level editing
//
@ -490,6 +496,8 @@ class AUDACITY_DLL_API WaveTrack: public Track {
wxCriticalSection mAppendCriticalSection;
double mLegacyProjectFileOffset;
int mAutoSaveIdent;
SpectrogramSettings *mpSpectrumSettings;
};
// This is meant to be a short-lived object, during whose lifetime,

View File

@ -0,0 +1,320 @@
/**********************************************************************
Audacity: A Digital Audio Editor
SpectrogramSettings.cpp
Paul Licameli
*******************************************************************//**
\class SpectrogramSettings
\brief Spectrogram settings, either for one track or as defaults.
*//*******************************************************************/
#include "../Audacity.h"
#include "SpectrogramSettings.h"
#include "../FFT.h"
#include "../Prefs.h"
#include "../RealFFTf.h"
#include <algorithm>
#include <cmath>
SpectrogramSettings::SpectrogramSettings()
: hFFT(0)
, window(0)
{
UpdatePrefs();
}
SpectrogramSettings::SpectrogramSettings(const SpectrogramSettings &other)
: minFreq(other.minFreq)
, maxFreq(other.maxFreq)
, logMinFreq(other.logMinFreq)
, logMaxFreq(other.logMaxFreq)
, range(other.range)
, gain(other.gain)
, frequencyGain(other.frequencyGain)
, windowType(other.windowType)
, windowSize(other.windowSize)
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
, zeroPaddingFactor(other.zeroPaddingFactor)
#endif
, isGrayscale(other.isGrayscale)
#ifdef EXPERIMENTAL_FFT_Y_GRID
, fftYGrid(other.fftYGrid)
#endif
#ifdef EXPERIMENTAL_FIND_NOTES
, fftFindNotes(other.fftFindNotes)
, findNotesMinA(other.findNotesMinA)
, numberOfMaxima(other.numberOfMaxima)
, findNotesQuantize(other.findNotesQuantize)
#endif
// Do not copy these!
, hFFT(0)
, window(0)
{
}
SpectrogramSettings &SpectrogramSettings::operator= (const SpectrogramSettings &other)
{
if (this != &other) {
minFreq = other.minFreq;
maxFreq = other.maxFreq;
logMinFreq = other.logMinFreq;
logMaxFreq = other.logMaxFreq;
range = other.range;
gain = other.gain;
frequencyGain = other.frequencyGain;
windowType = other.windowType;
windowSize = other.windowSize;
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
zeroPaddingFactor = other.zeroPaddingFactor;
#endif
isGrayscale = other.isGrayscale;
#ifdef EXPERIMENTAL_FFT_Y_GRID
fftYGrid = other.fftYGrid;
#endif
#ifdef EXPERIMENTAL_FIND_NOTES
fftFindNotes = other.fftFindNotes;
findNotesMinA = other.findNotesMinA;
numberOfMaxima = other.numberOfMaxima;
findNotesQuantize = other.findNotesQuantize;
#endif
// Do not copy these!
hFFT = 0;
window = 0;
}
return *this;
}
SpectrogramSettings& SpectrogramSettings::defaults()
{
static SpectrogramSettings instance;
return instance;
}
void SpectrogramSettings::UpdatePrefs()
{
bool destroy = false;
minFreq = gPrefs->Read(wxT("/Spectrum/MinFreq"), -1L);
maxFreq = gPrefs->Read(wxT("/Spectrum/MaxFreq"), 8000L);
// These preferences are not written anywhere in the program as of now,
// but I keep this legacy here. Who knows, someone might edit prefs files
// directly. PRL
logMaxFreq = gPrefs->Read(wxT("/SpectrumLog/MaxFreq"), -1);
if (logMaxFreq < 0)
logMaxFreq = maxFreq;
logMinFreq = gPrefs->Read(wxT("/SpectrumLog/MinFreq"), -1);
if (logMinFreq < 0)
logMinFreq = minFreq;
if (logMinFreq < 1)
logMinFreq = 1;
range = gPrefs->Read(wxT("/Spectrum/Range"), 80L);
gain = gPrefs->Read(wxT("/Spectrum/Gain"), 20L);
frequencyGain = gPrefs->Read(wxT("/Spectrum/FrequencyGain"), 0L);
const int newWindowSize = gPrefs->Read(wxT("/Spectrum/FFTSize"), 256);
if (newWindowSize != windowSize) {
destroy = true;
windowSize = newWindowSize;
}
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
const int newZeroPaddingFactor = gPrefs->Read(wxT("/Spectrum/ZeroPaddingFactor"), 1);
if (newZeroPaddingFactor != zeroPaddingFactor) {
destroy = true;
zeroPaddingFactor = newZeroPaddingFactor;
}
#endif
int newWindowType;
gPrefs->Read(wxT("/Spectrum/WindowType"), &newWindowType, 3);
if (newWindowType != windowType) {
destroy = true;
windowType = newWindowType;
}
isGrayscale = (gPrefs->Read(wxT("/Spectrum/Grayscale"), 0L) != 0);
#ifdef EXPERIMENTAL_FFT_Y_GRID
fftYGrid = (gPrefs->Read(wxT("/Spectrum/FFTYGrid"), 0L) != 0);
#endif //EXPERIMENTAL_FFT_Y_GRID
#ifdef EXPERIMENTAL_FIND_NOTES
fftFindNotes = (gPrefs->Read(wxT("/Spectrum/FFTFindNotes"), 0L) != 0);
findNotesMinA = gPrefs->Read(wxT("/Spectrum/FindNotesMinA"), -30.0);
numberOfMaxima = gPrefs->Read(wxT("/Spectrum/FindNotesN"), 5L);
findNotesQuantize = (gPrefs->Read(wxT("/Spectrum/FindNotesQuantize"), 0L) != 0);
#endif //EXPERIMENTAL_FIND_NOTES
if (destroy)
DestroyWindows();
}
SpectrogramSettings::~SpectrogramSettings()
{
DestroyWindows();
}
void SpectrogramSettings::DestroyWindows()
{
#ifdef EXPERIMENTAL_USE_REALFFTF
if (hFFT != NULL) {
EndFFT(hFFT);
hFFT = NULL;
}
if (window != NULL) {
delete[] window;
window = NULL;
}
#endif
}
namespace
{
enum { WINDOW, TWINDOW, DWINDOW };
void RecreateWindow(
float *&window, int which, int fftLen,
int padding, int windowType, int windowSize, double &scale)
{
if (window != NULL)
delete[] window;
// Create the requested window function
window = new float[fftLen];
int ii;
wxASSERT(windowSize % 2 == 0);
const int endOfWindow = padding + windowSize;
// Left and right padding
for (ii = 0; ii < padding; ++ii) {
window[ii] = 0.0;
window[fftLen - ii - 1] = 0.0;
}
// Default rectangular window in the middle
for (; ii < endOfWindow; ++ii)
window[ii] = 1.0;
// Overwrite middle as needed
switch (which) {
case WINDOW:
WindowFunc(windowType, windowSize, window + padding);
// NewWindowFunc(windowType, windowSize, extra, window + padding);
break;
case TWINDOW:
wxASSERT(false);
#if 0
// Future, reassignment
NewWindowFunc(windowType, windowSize, extra, window + padding);
for (int ii = padding, multiplier = -windowSize / 2; ii < endOfWindow; ++ii, ++multiplier)
window[ii] *= multiplier;
break;
#endif
case DWINDOW:
wxASSERT(false);
#if 0
// Future, reassignment
DerivativeOfWindowFunc(windowType, windowSize, extra, window + padding);
break;
#endif
default:
wxASSERT(false);
}
// Scale the window function to give 0dB spectrum for 0dB sine tone
if (which == WINDOW) {
scale = 0.0;
for (ii = padding; ii < endOfWindow; ++ii)
scale += window[ii];
if (scale > 0)
scale = 2.0 / scale;
}
for (ii = padding; ii < endOfWindow; ++ii)
window[ii] *= scale;
}
}
void SpectrogramSettings::CacheWindows() const
{
#ifdef EXPERIMENTAL_USE_REALFFTF
if (hFFT == NULL || window == NULL) {
double scale;
const int fftLen = windowSize * zeroPaddingFactor;
const int padding = (windowSize * (zeroPaddingFactor - 1)) / 2;
if (hFFT != NULL)
EndFFT(hFFT);
hFFT = InitializeFFT(fftLen);
RecreateWindow(window, WINDOW, fftLen, padding, windowType, windowSize, scale);
}
#endif // EXPERIMENTAL_USE_REALFFTF
}
int SpectrogramSettings::GetMinFreq(double rate) const
{
const int top = lrint(rate / 2.);
return std::max(0, std::min(top, minFreq));
}
int SpectrogramSettings::GetMaxFreq(double rate) const
{
const int top = lrint(rate / 2.);
if (maxFreq < 0)
return top;
else
return std::max(0, std::min(top, maxFreq));
}
int SpectrogramSettings::GetLogMinFreq(double rate) const
{
const int top = lrint(rate / 2.);
if (logMinFreq < 0)
return top / 1000.0;
else
return std::max(1, std::min(top, logMinFreq));
}
int SpectrogramSettings::GetLogMaxFreq(double rate) const
{
const int top = lrint(rate / 2.);
if (logMaxFreq < 0)
return top;
else
return std::max(1, std::min(top, logMaxFreq));
}
void SpectrogramSettings::SetMinFreq(int freq)
{
minFreq = freq;
}
void SpectrogramSettings::SetMaxFreq(int freq)
{
maxFreq = freq;
}
void SpectrogramSettings::SetLogMinFreq(int freq)
{
logMinFreq = freq;
}
void SpectrogramSettings::SetLogMaxFreq(int freq)
{
logMaxFreq = freq;
}
int SpectrogramSettings::GetFFTLength(bool autocorrelation) const
{
return windowSize
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
* (!autocorrelation ? zeroPaddingFactor : 1);
#endif
;
}

View File

@ -0,0 +1,81 @@
/**********************************************************************
Audacity: A Digital Audio Editor
SpectrogramSettings.h
Paul Licameli
**********************************************************************/
#ifndef __AUDACITY_SPECTROGRAM_SETTINGS__
#define __AUDACITY_SPECTROGRAM_SETTINGS__
#include "../Experimental.h"
struct FFTParam;
class SpectrogramSettings
{
public:
static SpectrogramSettings &defaults();
SpectrogramSettings();
SpectrogramSettings(const SpectrogramSettings &other);
SpectrogramSettings& operator= (const SpectrogramSettings &other);
~SpectrogramSettings();
void UpdatePrefs();
void DestroyWindows();
void CacheWindows() const;
private:
int minFreq;
int maxFreq;
int logMinFreq;
int logMaxFreq;
public:
int GetMinFreq(double rate) const;
int GetMaxFreq(double rate) const;
int GetLogMinFreq(double rate) const;
int GetLogMaxFreq(double rate) const;
void SetMinFreq(int freq);
void SetMaxFreq(int freq);
void SetLogMinFreq(int freq);
void SetLogMaxFreq(int freq);
public:
int range;
int gain;
int frequencyGain;
int windowType;
int windowSize;
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
int zeroPaddingFactor;
#endif
int GetFFTLength(bool autocorrelation) const; // window size (times zero padding, if STFT)
bool isGrayscale;
#ifdef EXPERIMENTAL_FFT_Y_GRID
bool fftYGrid;
#endif //EXPERIMENTAL_FFT_Y_GRID
#ifdef EXPERIMENTAL_FIND_NOTES
bool fftFindNotes;
bool findNotesMinA;
bool numberOfMaxima;
bool findNotesQuantize;
#endif //EXPERIMENTAL_FIND_NOTES
// Following fields are derived from preferences.
#ifdef EXPERIMENTAL_USE_REALFFTF
// Variables used for computing the spectrum
mutable FFTParam *hFFT;
mutable float *window;
#endif
};
#endif

View File

@ -346,175 +346,3 @@ PrefsPanel *SpectrumPrefsFactory::Create(wxWindow *parent)
{
return new SpectrumPrefs(parent);
}
SpectrogramSettings::SpectrogramSettings()
: hFFT(0)
, window(0)
{
UpdatePrefs();
}
SpectrogramSettings& SpectrogramSettings::defaults()
{
static SpectrogramSettings instance;
return instance;
}
void SpectrogramSettings::UpdatePrefs()
{
bool destroy = false;
minFreq = gPrefs->Read(wxT("/Spectrum/MinFreq"), -1L);
maxFreq = gPrefs->Read(wxT("/Spectrum/MaxFreq"), 8000L);
// These preferences are not written anywhere in the program as of now,
// but I keep this legacy here. Who knows, someone might edit prefs files
// directly. PRL
logMaxFreq = gPrefs->Read(wxT("/SpectrumLog/MaxFreq"), -1);
if (logMaxFreq < 0)
logMaxFreq = maxFreq;
logMinFreq = gPrefs->Read(wxT("/SpectrumLog/MinFreq"), -1);
if (logMinFreq < 0)
logMinFreq = minFreq;
if (logMinFreq < 1)
logMinFreq = 1;
range = gPrefs->Read(wxT("/Spectrum/Range"), 80L);
gain = gPrefs->Read(wxT("/Spectrum/Gain"), 20L);
frequencyGain = gPrefs->Read(wxT("/Spectrum/FrequencyGain"), 0L);
const int newWindowSize = gPrefs->Read(wxT("/Spectrum/FFTSize"), 256);
if (newWindowSize != windowSize) {
destroy = true;
windowSize = newWindowSize;
}
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
const int newZeroPaddingFactor = gPrefs->Read(wxT("/Spectrum/ZeroPaddingFactor"), 1);
if (newZeroPaddingFactor != zeroPaddingFactor) {
destroy = true;
zeroPaddingFactor = newZeroPaddingFactor;
}
#endif
int newWindowType;
gPrefs->Read(wxT("/Spectrum/WindowType"), &newWindowType, 3);
if (newWindowType != windowType) {
destroy = true;
windowType = newWindowType;
}
isGrayscale = (gPrefs->Read(wxT("/Spectrum/Grayscale"), 0L) != 0);
#ifdef EXPERIMENTAL_FFT_Y_GRID
fftYGrid = (gPrefs->Read(wxT("/Spectrum/FFTYGrid"), 0L) != 0);
#endif //EXPERIMENTAL_FFT_Y_GRID
#ifdef EXPERIMENTAL_FIND_NOTES
fftFindNotes = (gPrefs->Read(wxT("/Spectrum/FFTFindNotes"), 0L) != 0);
findNotesMinA = gPrefs->Read(wxT("/Spectrum/FindNotesMinA"), -30.0);
numberOfMaxima = gPrefs->Read(wxT("/Spectrum/FindNotesN"), 5L);
findNotesQuantize = (gPrefs->Read(wxT("/Spectrum/FindNotesQuantize"), 0L) != 0);
#endif //EXPERIMENTAL_FIND_NOTES
if (destroy)
DestroyWindows();
}
SpectrogramSettings::~SpectrogramSettings()
{
DestroyWindows();
}
void SpectrogramSettings::DestroyWindows()
{
#ifdef EXPERIMENTAL_USE_REALFFTF
if (hFFT != NULL) {
EndFFT(hFFT);
hFFT = NULL;
}
if (window != NULL) {
delete[] window;
window = NULL;
}
#endif
}
namespace
{
enum { WINDOW, TWINDOW, DWINDOW };
void RecreateWindow(
float *&window, int which, int fftLen,
int padding, int windowType, int windowSize, double &scale)
{
if (window != NULL)
delete[] window;
// Create the requested window function
window = new float[fftLen];
int ii;
wxASSERT(windowSize % 2 == 0);
const int endOfWindow = padding + windowSize;
// Left and right padding
for (ii = 0; ii < padding; ++ii) {
window[ii] = 0.0;
window[fftLen - ii - 1] = 0.0;
}
// Default rectangular window in the middle
for (; ii < endOfWindow; ++ii)
window[ii] = 1.0;
// Overwrite middle as needed
switch (which) {
case WINDOW:
WindowFunc(windowType, windowSize, window + padding);
// NewWindowFunc(windowType, windowSize, extra, window + padding);
break;
case TWINDOW:
wxASSERT(false);
#if 0
// Future, reassignment
NewWindowFunc(windowType, windowSize, extra, window + padding);
for (int ii = padding, multiplier = -windowSize / 2; ii < endOfWindow; ++ii, ++multiplier)
window[ii] *= multiplier;
break;
#endif
case DWINDOW:
wxASSERT(false);
#if 0
// Future, reassignment
DerivativeOfWindowFunc(windowType, windowSize, extra, window + padding);
break;
#endif
default:
wxASSERT(false);
}
// Scale the window function to give 0dB spectrum for 0dB sine tone
if (which == WINDOW) {
scale = 0.0;
for (ii = padding; ii < endOfWindow; ++ii)
scale += window[ii];
if (scale > 0)
scale = 2.0 / scale;
}
for (ii = padding; ii < endOfWindow; ++ii)
window[ii] *= scale;
}
}
void SpectrogramSettings::CacheWindows() const
{
#ifdef EXPERIMENTAL_USE_REALFFTF
if (hFFT == NULL || window == NULL) {
double scale;
const int fftLen = windowSize * zeroPaddingFactor;
const int padding = (windowSize * (zeroPaddingFactor - 1)) / 2;
if (hFFT != NULL)
EndFFT(hFFT);
hFFT = InitializeFFT(fftLen);
RecreateWindow(window, WINDOW, fftLen, padding, windowType, windowSize, scale);
}
#endif // EXPERIMENTAL_USE_REALFFTF
}

View File

@ -28,6 +28,7 @@
#include "../Experimental.h"
#include "PrefsPanel.h"
#include "SpectrogramSettings.h"
class wxTextCtrl;
struct FFTParam;
@ -74,56 +75,6 @@ class SpectrumPrefs:public PrefsPanel
#endif
};
class SpectrogramSettings
{
public:
static SpectrogramSettings &defaults();
SpectrogramSettings();
~SpectrogramSettings();
void UpdatePrefs();
void DestroyWindows();
void CacheWindows() const;
int minFreq;
int maxFreq;
int logMinFreq;
int logMaxFreq;
int range;
int gain;
int frequencyGain;
int windowType;
int windowSize;
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
int zeroPaddingFactor;
#endif
bool isGrayscale;
#ifdef EXPERIMENTAL_FFT_Y_GRID
bool fftYGrid;
#endif //EXPERIMENTAL_FFT_Y_GRID
#ifdef EXPERIMENTAL_FIND_NOTES
bool fftFindNotes;
bool findNotesMinA;
bool numberOfMaxima;
bool findNotesQuantize;
#endif //EXPERIMENTAL_FIND_NOTES
// Following fields are derived from preferences.
#ifdef EXPERIMENTAL_USE_REALFFTF
// Variables used for computing the spectrum
mutable FFTParam *hFFT;
mutable float *window;
#endif
};
class SpectrumPrefsFactory : public PrefsPanelFactory
{
public:

View File

@ -286,6 +286,7 @@
<ClCompile Include="..\..\..\src\PlatformCompatibility.cpp" />
<ClCompile Include="..\..\..\src\PluginManager.cpp" />
<ClCompile Include="..\..\..\src\Prefs.cpp" />
<ClCompile Include="..\..\..\src\prefs\SpectrogramSettings.cpp" />
<ClCompile Include="..\..\..\src\Printing.cpp" />
<ClCompile Include="..\..\..\src\Profiler.cpp" />
<ClCompile Include="..\..\..\src\Project.cpp" />
@ -532,6 +533,7 @@
<ClInclude Include="..\..\..\src\import\MultiFormatReader.h" />
<ClInclude Include="..\..\..\src\import\SpecPowerMeter.h" />
<ClInclude Include="..\..\..\src\ModuleManager.h" />
<ClInclude Include="..\..\..\src\prefs\SpectrogramSettings.h" />
<ClInclude Include="..\..\..\src\RevisionIdent.h" />
<ClInclude Include="..\..\..\src\SelectedRegion.h" />
<ClInclude Include="..\..\..\src\SseMathFuncs.h" />

View File

@ -840,6 +840,9 @@
<ClCompile Include="..\..\..\src\ViewInfo.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\prefs\SpectrogramSettings.cpp">
<Filter>src/prefs</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\src\AboutDialog.h">
@ -1679,6 +1682,9 @@
<ClInclude Include="..\..\..\src\AudacityHeaders.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\prefs\SpectrogramSettings.h">
<Filter>src/prefs</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="..\..\audacity.ico">