1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-08 08:01:19 +02:00

Access SpectrogramSettings via WaveTrack, which may be nondefault (no UI yet)...

... and add accessors to SpectrogramSettings, and remove TrackArtist functions
for getting and setting the globals.
This commit is contained in:
Paul Licameli 2015-06-13 12:13:55 -04:00
parent a1621f7d1b
commit 1dffeace93
9 changed files with 232 additions and 223 deletions

View File

@ -692,7 +692,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect)
// All waves have a ruler in the info panel // All waves have a ruler in the info panel
// The ruler needs a bevelled surround. // The ruler needs a bevelled surround.
if (t->GetKind() == Track::Wave) { if (t->GetKind() == Track::Wave) {
WaveTrack *wt = (WaveTrack *)t; WaveTrack *wt = static_cast<WaveTrack*>(t);
int display = wt->GetDisplay(); int display = wt->GetDisplay();
if (display == WaveTrack::WaveformDisplay) { if (display == WaveTrack::WaveformDisplay) {
@ -802,16 +802,10 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect)
if (rect.height < 60) if (rect.height < 60)
return; return;
double rate = wt->GetRate(); const SpectrogramSettings &settings = wt->GetSpectrogramSettings();
int freq = lrint(rate/2.); const double rate = wt->GetRate();
const int maxFreq = settings.GetMaxFreq(rate);
int maxFreq = GetSpectrumMaxFreq(freq); const int minFreq = settings.GetMinFreq(rate);
if(maxFreq > freq)
maxFreq = freq;
int minFreq = GetSpectrumMinFreq(0);
if(minFreq < 0)
minFreq = 0;
/* /*
draw the ruler draw the ruler
@ -842,16 +836,10 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect)
if (rect.height < 10) if (rect.height < 10)
return; return;
double rate = wt->GetRate(); const SpectrogramSettings &settings = wt->GetSpectrogramSettings();
int freq = lrint(rate/2.); const double rate = wt->GetRate();
const int maxFreq = settings.GetLogMaxFreq(rate);
int maxFreq = GetSpectrumLogMaxFreq(freq); const int minFreq = settings.GetLogMinFreq(rate);
if(maxFreq > freq)
maxFreq = freq;
int minFreq = GetSpectrumLogMinFreq(freq/1000.0);
if(minFreq < 1)
minFreq = 1;
/* /*
draw the ruler draw the ruler
@ -2042,6 +2030,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
#endif #endif
const WaveTrack *const track = waveTrackCache.GetTrack(); const WaveTrack *const track = waveTrackCache.GetTrack();
const SpectrogramSettings &settings = track->GetSpectrogramSettings();
const int display = track->GetDisplay(); const int display = track->GetDisplay();
const bool autocorrelation = (WaveTrack::PitchDisplay == display); const bool autocorrelation = (WaveTrack::PitchDisplay == display);
const bool logF = (WaveTrack::SpectrumLogDisplay == display const bool logF = (WaveTrack::SpectrumLogDisplay == display
@ -2079,7 +2069,6 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
} }
#endif #endif
const SpectrogramSettings &settings = SpectrogramSettings::defaults();
const bool &isGrayscale = settings.isGrayscale; const bool &isGrayscale = settings.isGrayscale;
const int &range = settings.range; const int &range = settings.range;
const int &gain = settings.gain; const int &gain = settings.gain;
@ -2115,28 +2104,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
t0, pps, autocorrelation); t0, pps, autocorrelation);
} }
int ifreq = lrint(rate / 2); const int minFreq = logF ? settings.GetLogMinFreq(rate) : settings.GetMinFreq(rate);
const int maxFreq = logF ? settings.GetLogMaxFreq(rate) : settings.GetMaxFreq(rate);
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;
}
float minBin = ((double)minFreq / binUnit); float minBin = ((double)minFreq / binUnit);
float maxBin = ((double)maxFreq / binUnit); float maxBin = ((double)maxFreq / binUnit);
@ -3217,66 +3186,6 @@ void TrackArtist::UpdatePrefs()
gPrefs->Flush(); 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 // 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 // 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(TrackList *tracks);
void InvalidateSpectrumCache(WaveTrack *track); 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, void SetBackgroundBrushes(wxBrush unselectedBrush, wxBrush selectedBrush,
wxPen unselectedPen, wxPen selectedPen) { wxPen unselectedPen, wxPen selectedPen) {

View File

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

View File

@ -337,9 +337,9 @@ protected:
#ifdef EXPERIMENTAL_SPECTRAL_EDITING #ifdef EXPERIMENTAL_SPECTRAL_EDITING
public: public:
void SnapCenterOnce (WaveTrack *pTrack, bool up); void SnapCenterOnce (const WaveTrack *pTrack, bool up);
protected: protected:
void StartSnappingFreqSelection (WaveTrack *pTrack); void StartSnappingFreqSelection (const WaveTrack *pTrack);
void MoveSnappingFreqSelection (int mouseYCoordinate, void MoveSnappingFreqSelection (int mouseYCoordinate,
int trackTopEdge, int trackTopEdge,
int trackHeight, Track *pTrack); int trackHeight, Track *pTrack);
@ -494,9 +494,9 @@ protected:
virtual wxRect FindTrackRect(Track * target, bool label); virtual wxRect FindTrackRect(Track * target, bool label);
virtual int GetVRulerWidth() const; 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 // 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. // They work around some messy problems with constructors.
@ -693,16 +693,16 @@ protected:
void HandleCenterFrequencyClick void HandleCenterFrequencyClick
(bool shiftDown, Track *pTrack, double value); (bool shiftDown, Track *pTrack, double value);
double PositionToFrequency(bool maySnap, double PositionToFrequency(const WaveTrack *wt,
bool maySnap,
wxInt64 mouseYCoordinate, wxInt64 mouseYCoordinate,
wxInt64 trackTopEdge, wxInt64 trackTopEdge,
int trackHeight, int trackHeight,
double rate,
bool logF) const; bool logF) const;
wxInt64 FrequencyToPosition(double frequency, wxInt64 FrequencyToPosition(const WaveTrack *wt,
double frequency,
wxInt64 trackTopEdge, wxInt64 trackTopEdge,
int trackHeight, int trackHeight,
double rate,
bool logF) const; bool logF) const;
#endif #endif

View File

@ -902,8 +902,8 @@ bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache,
double t0, double pixelsPerSecond, double t0, double pixelsPerSecond,
bool autocorrelation) 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 &frequencyGain = settings.frequencyGain;
const int &windowSize = settings.windowSize; const int &windowSize = settings.windowSize;
const int &windowType = settings.windowType; const int &windowType = settings.windowType;

View File

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

View File

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

View File

@ -19,6 +19,9 @@ Paul Licameli
#include "../Prefs.h" #include "../Prefs.h"
#include "../RealFFTf.h" #include "../RealFFTf.h"
#include <algorithm>
#include <cmath>
SpectrogramSettings::SpectrogramSettings() SpectrogramSettings::SpectrogramSettings()
: hFFT(0) : hFFT(0)
, window(0) , window(0)
@ -254,6 +257,59 @@ void SpectrogramSettings::CacheWindows() const
#endif // EXPERIMENTAL_USE_REALFFTF #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 int SpectrogramSettings::GetFFTLength(bool autocorrelation) const
{ {
return windowSize return windowSize

View File

@ -28,12 +28,23 @@ public:
void DestroyWindows(); void DestroyWindows();
void CacheWindows() const; void CacheWindows() const;
private:
int minFreq; int minFreq;
int maxFreq; int maxFreq;
int logMinFreq; int logMinFreq;
int logMaxFreq; 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 range;
int gain; int gain;
int frequencyGain; int frequencyGain;
@ -67,5 +78,4 @@ public:
mutable float *window; mutable float *window;
#endif #endif
}; };
#endif #endif