1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-11 17:41:15 +02:00

View types reduced to 2; choose scale in new Waveforms page instead...

... also, view type choices in track drop-down are radio buttons
This commit is contained in:
Paul Licameli 2015-07-28 08:09:31 -04:00
commit 806b4dab7d
16 changed files with 708 additions and 167 deletions

View File

@ -94,6 +94,7 @@ It handles initialization and termination by subclassing wxApp.
#include "widgets/ErrorDialog.h" #include "widgets/ErrorDialog.h"
#include "prefs/DirectoriesPrefs.h" #include "prefs/DirectoriesPrefs.h"
#include "prefs/SpectrogramSettings.h" #include "prefs/SpectrogramSettings.h"
#include "prefs/WaveformSettings.h"
//temporarilly commented out till it is added to all projects //temporarilly commented out till it is added to all projects
//#include "Profiler.h" //#include "Profiler.h"
@ -1017,6 +1018,7 @@ void AudacityApp::InitLang( const wxString & lang )
// Some static arrays unconnected with any project want to be informed of language changes. // Some static arrays unconnected with any project want to be informed of language changes.
SpectrogramSettings::InvalidateNames(); SpectrogramSettings::InvalidateNames();
WaveformSettings::InvalidateNames();
} }
void AudacityApp::OnFatalException() void AudacityApp::OnFatalException()

View File

@ -488,6 +488,10 @@ audacity_SOURCES = \
prefs/TracksPrefs.h \ prefs/TracksPrefs.h \
prefs/WarningsPrefs.cpp \ prefs/WarningsPrefs.cpp \
prefs/WarningsPrefs.h \ prefs/WarningsPrefs.h \
prefs/WaveformPrefs.cpp \
prefs/WaveformPrefs.h \
prefs/WaveformSettings.cpp \
prefs/WaveformSettings.h \
toolbars/ControlToolBar.cpp \ toolbars/ControlToolBar.cpp \
toolbars/ControlToolBar.h \ toolbars/ControlToolBar.h \
toolbars/DeviceToolBar.cpp \ toolbars/DeviceToolBar.cpp \

View File

@ -175,6 +175,7 @@ audio tracks.
#include "TimeTrack.h" #include "TimeTrack.h"
#include "Prefs.h" #include "Prefs.h"
#include "prefs/SpectrogramSettings.h" #include "prefs/SpectrogramSettings.h"
#include "prefs/WaveformSettings.h"
#include "Sequence.h" #include "Sequence.h"
#include "Spectrum.h" #include "Spectrum.h"
#include "ViewInfo.h" #include "ViewInfo.h"
@ -457,13 +458,9 @@ void TrackArtist::DrawTrack(const Track * t,
bool muted = (hasSolo || t->GetMute()) && !t->GetSolo(); bool muted = (hasSolo || t->GetMute()) && !t->GetSolo();
switch (wt->GetDisplay()) { switch (wt->GetDisplay()) {
case WaveTrack::WaveformDisplay: case WaveTrack::Waveform:
DrawWaveform(wt, dc, rect, selectedRegion, zoomInfo, DrawWaveform(wt, dc, rect, selectedRegion, zoomInfo,
drawEnvelope, bigPoints, drawSliders, false, muted); drawEnvelope, bigPoints, drawSliders, muted);
break;
case WaveTrack::WaveformDBDisplay:
DrawWaveform(wt, dc, rect, selectedRegion, zoomInfo,
drawEnvelope, bigPoints, drawSliders, true, muted);
break; break;
case WaveTrack::Spectrum: case WaveTrack::Spectrum:
DrawSpectrum(wt, dc, rect, selectedRegion, zoomInfo); DrawSpectrum(wt, dc, rect, selectedRegion, zoomInfo);
@ -685,107 +682,115 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect)
// The ruler needs a bevelled surround. // The ruler needs a bevelled surround.
if (t->GetKind() == Track::Wave) { if (t->GetKind() == Track::Wave) {
WaveTrack *wt = static_cast<WaveTrack*>(t); WaveTrack *wt = static_cast<WaveTrack*>(t);
int display = wt->GetDisplay();
if (display == WaveTrack::WaveformDisplay) { const int display = wt->GetDisplay();
// Waveform
float min, max; if (display == WaveTrack::Waveform) {
wt->GetDisplayBounds(&min, &max); WaveformSettings::ScaleType scaleType =
if(wt->GetLastDisplay()==WaveTrack::WaveformDBDisplay) wt->GetWaveformSettings().scaleType;
{
// do a translation into the WaveTrack::WaveformDisplay space
wt->SetDisplay(WaveTrack::WaveformDisplay); // this makes the last display not WaveformDBDisplay
float sign = (min >= 0 ? 1 : -1);
if (min != 0.) {
min = DB_TO_LINEAR(fabs(min)*mdBrange - mdBrange);
if (min < 0.0)
min = 0.0;
min *= sign;
}
sign = (max >= 0 ? 1 : -1);
if (max != 0.) { if (scaleType == WaveformSettings::stLinear) {
max = DB_TO_LINEAR(fabs(max)*mdBrange - mdBrange); // Waveform
if (max < 0.0)
max = 0.0;
max *= sign;
}
wt->SetDisplayBounds(min, max);
}
vruler->SetBounds(rect.x, rect.y+1, rect.x + rect.width, rect.y + rect.height-1); float min, max;
vruler->SetOrientation(wxVERTICAL); wt->GetDisplayBounds(&min, &max);
vruler->SetRange(max, min); if (wt->GetLastScaleType() != scaleType)
vruler->SetFormat(Ruler::RealFormat); {
vruler->SetUnits(wxT("")); // do a translation into the linear space
vruler->SetLabelEdges(false); wt->SetLastScaleType(scaleType);
vruler->SetLog(false); float sign = (min >= 0 ? 1 : -1);
} if (min != 0.) {
else if (display == WaveTrack::WaveformDBDisplay) { min = DB_TO_LINEAR(fabs(min)*mdBrange - mdBrange);
// Waveform (db) if (min < 0.0)
min = 0.0;
min *= sign;
}
sign = (max >= 0 ? 1 : -1);
vruler->SetUnits(wxT("")); if (max != 0.) {
max = DB_TO_LINEAR(fabs(max)*mdBrange - mdBrange);
float min, max; if (max < 0.0)
wt->GetDisplayBounds(&min, &max); max = 0.0;
max *= sign;
if(wt->GetLastDisplay()==WaveTrack::WaveformDisplay) }
{ wt->SetDisplayBounds(min, max);
// do a translation into the WaveTrack::WaveformDBDisplay space
wt->SetDisplay(WaveTrack::WaveformDBDisplay); // this makes the last display not WaveformDisplay
float sign = (min >= 0 ? 1 : -1);
if (min != 0.) {
min = (LINEAR_TO_DB(fabs(min)) + mdBrange) / mdBrange;
if (min < 0.0)
min = 0.0;
min *= sign;
}
sign = (max >= 0 ? 1 : -1);
if (max != 0.) {
max = (LINEAR_TO_DB(fabs(max)) + mdBrange) / mdBrange;
if (max < 0.0)
max = 0.0;
max *= sign;
}
wt->SetDisplayBounds(min, max);
}
if (max > 0) {
int top = 0;
float topval = 0;
int bot = rect.height;
float botval = -mdBrange;
if (min < 0) {
bot = top + (int)((max / (max-min))*(bot-top));
min = 0;
} }
if (max > 1) { vruler->SetBounds(rect.x, rect.y + 1, rect.x + rect.width, rect.y + rect.height - 1);
top += (int)((max-1)/(max-min) * (bot-top));
max = 1;
}
if (max < 1 && max > 0)
topval = -((1-max)*mdBrange);
if (min > 0) {
botval = -((1-min)*mdBrange);
}
vruler->SetBounds(rect.x, rect.y+top+1, rect.x + rect.width, rect.y + bot-1);
vruler->SetOrientation(wxVERTICAL); vruler->SetOrientation(wxVERTICAL);
vruler->SetRange(topval, botval); vruler->SetRange(max, min);
} vruler->SetFormat(Ruler::RealFormat);
else vruler->SetUnits(wxT(""));
vruler->SetBounds(0.0, 0.0, 0.0, 0.0); // A.C.H I couldn't find a way to just disable it? vruler->SetLabelEdges(false);
vruler->SetFormat(Ruler::RealLogFormat); vruler->SetLog(false);
vruler->SetLabelEdges(true); }
vruler->SetLog(false); else {
wxASSERT(scaleType == WaveformSettings::stLogarithmic);
scaleType = WaveformSettings::stLogarithmic;
vruler->SetUnits(wxT(""));
float min, max;
wt->GetDisplayBounds(&min, &max);
if (wt->GetLastScaleType() != scaleType)
{
// do a translation into the dB space
wt->SetLastScaleType(scaleType);
float sign = (min >= 0 ? 1 : -1);
if (min != 0.) {
min = (LINEAR_TO_DB(fabs(min)) + mdBrange) / mdBrange;
if (min < 0.0)
min = 0.0;
min *= sign;
}
sign = (max >= 0 ? 1 : -1);
if (max != 0.) {
max = (LINEAR_TO_DB(fabs(max)) + mdBrange) / mdBrange;
if (max < 0.0)
max = 0.0;
max *= sign;
}
wt->SetDisplayBounds(min, max);
}
if (max > 0) {
int top = 0;
float topval = 0;
int bot = rect.height;
float botval = -mdBrange;
if (min < 0) {
bot = top + (int)((max / (max - min))*(bot - top));
min = 0;
}
if (max > 1) {
top += (int)((max - 1) / (max - min) * (bot - top));
max = 1;
}
if (max < 1 && max > 0)
topval = -((1 - max)*mdBrange);
if (min > 0) {
botval = -((1 - min)*mdBrange);
}
vruler->SetBounds(rect.x, rect.y + top + 1, rect.x + rect.width, rect.y + bot - 1);
vruler->SetOrientation(wxVERTICAL);
vruler->SetRange(topval, botval);
}
else
vruler->SetBounds(0.0, 0.0, 0.0, 0.0); // A.C.H I couldn't find a way to just disable it?
vruler->SetFormat(Ruler::RealLogFormat);
vruler->SetLabelEdges(true);
vruler->SetLog(false);
}
} }
else if (display == WaveTrack::Spectrum) { else {
wxASSERT(display == WaveTrack::Spectrum);
switch (wt->GetSpectrogramSettings().scaleType) { switch (wt->GetSpectrogramSettings().scaleType) {
default: default:
wxASSERT(false); wxASSERT(false);
@ -1416,9 +1421,10 @@ void TrackArtist::DrawWaveform(WaveTrack *track,
bool drawEnvelope, bool drawEnvelope,
bool bigPoints, bool bigPoints,
bool drawSliders, bool drawSliders,
bool dB,
bool muted) bool muted)
{ {
const bool dB = !track->GetWaveformSettings().isLinear();
DrawBackgroundWithSelection(&dc, rect, track, blankSelectedBrush, blankBrush, DrawBackgroundWithSelection(&dc, rect, track, blankSelectedBrush, blankBrush,
selectedRegion, zoomInfo); selectedRegion, zoomInfo);

View File

@ -97,7 +97,7 @@ class AUDACITY_DLL_API TrackArtist {
wxDC & dc, const wxRect & rect, wxDC & dc, const wxRect & rect,
const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo, const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo,
bool drawEnvelope, bool bigPoints, bool drawSliders, bool drawEnvelope, bool bigPoints, bool drawSliders,
bool dB, bool muted); bool muted);
void DrawSpectrum(WaveTrack *track, void DrawSpectrum(WaveTrack *track,
wxDC & dc, const wxRect & rect, wxDC & dc, const wxRect & rect,

View File

@ -220,6 +220,7 @@ is time to refresh some aspect of the screen.
#include "prefs/PrefsDialog.h" #include "prefs/PrefsDialog.h"
#include "prefs/SpectrumPrefs.h" #include "prefs/SpectrumPrefs.h"
#include "prefs/WaveformPrefs.h"
#include "toolbars/ControlToolBar.h" #include "toolbars/ControlToolBar.h"
#include "toolbars/ToolManager.h" #include "toolbars/ToolManager.h"
@ -326,7 +327,6 @@ enum {
OnFloatID, // <--- OnFloatID, // <---
OnWaveformID, OnWaveformID,
OnWaveformDBID,
OnSpectrumID, OnSpectrumID,
OnViewSettingsID, OnViewSettingsID,
@ -722,10 +722,9 @@ void TrackPanel::BuildMenus(void)
/* build the pop-down menu used on wave (sampled audio) tracks */ /* build the pop-down menu used on wave (sampled audio) tracks */
mWaveTrackMenu = new wxMenu(); mWaveTrackMenu = new wxMenu();
BuildCommonDropMenuItems(mWaveTrackMenu); // does name, up/down etc BuildCommonDropMenuItems(mWaveTrackMenu); // does name, up/down etc
mWaveTrackMenu->Append(OnWaveformID, _("Wa&veform")); mWaveTrackMenu->AppendRadioItem(OnWaveformID, _("&Waveform"));
mWaveTrackMenu->Append(OnWaveformDBID, _("&Waveform (dB)")); mWaveTrackMenu->AppendRadioItem(OnSpectrumID, _("&Spectrum"));
mWaveTrackMenu->Append(OnSpectrumID, _("&Spectrum")); mWaveTrackMenu->Append(OnViewSettingsID, _("&View Settings..."));
mWaveTrackMenu->Append(OnViewSettingsID, _("View& Settings...")); // PRL: all the other letters already taken for accelerators!
mWaveTrackMenu->AppendSeparator(); mWaveTrackMenu->AppendSeparator();
mWaveTrackMenu->AppendRadioItem(OnChannelMonoID, _("&Mono")); mWaveTrackMenu->AppendRadioItem(OnChannelMonoID, _("&Mono"));
@ -3775,10 +3774,8 @@ void TrackPanel::ForwardEventToWaveTrackEnvelope(wxMouseEvent & event)
// This asks which one is in use. (ie, Wave, Spectrum, etc) // This asks which one is in use. (ie, Wave, Spectrum, etc)
int display = pwavetrack->GetDisplay(); int display = pwavetrack->GetDisplay();
// AS: If we're using the right type of display for envelope operations if (display == WaveTrack::Waveform) {
// ie one of the Wave displays const bool dB = !pwavetrack->GetWaveformSettings().isLinear();
const bool dB = (display == WaveTrack::WaveformDBDisplay);
if (dB || (display == WaveTrack::WaveformDisplay)) {
bool needUpdate; bool needUpdate;
// AS: Then forward our mouse event to the envelope. // AS: Then forward our mouse event to the envelope.
@ -4849,20 +4846,12 @@ bool TrackPanel::IsSampleEditingPossible( wxMouseEvent &event, Track * t )
//If we aren't displaying the waveform, Display a message dialog //If we aren't displaying the waveform, Display a message dialog
WaveTrack *const wt = static_cast<WaveTrack*>(t); WaveTrack *const wt = static_cast<WaveTrack*>(t);
const int display = wt->GetDisplay(); const int display = wt->GetDisplay();
#if 1
if (!(WaveTrack::WaveformDisplay == display || if (WaveTrack::Waveform != display)
WaveTrack::WaveformDBDisplay == display))
{
wxMessageBox(_("To use Draw, choose 'Waveform' or 'Waveform dB' in the Track Drop-down Menu."), wxT("Draw Tool"));
return false;
}
#else
if(WaveTrack::WaveformDisplay != display)
{ {
wxMessageBox(_("To use Draw, choose 'Waveform' in the Track Drop-down Menu."), wxT("Draw Tool")); wxMessageBox(_("To use Draw, choose 'Waveform' in the Track Drop-down Menu."), wxT("Draw Tool"));
return false; return false;
} }
#endif
bool showPoints; bool showPoints;
{ {
@ -4900,7 +4889,7 @@ float TrackPanel::FindSampleEditingLevel(wxMouseEvent &event, double t0)
const int y = event.m_y - mDrawingTrackTop; const int y = event.m_y - mDrawingTrackTop;
const int height = mDrawingTrack->GetHeight(); const int height = mDrawingTrack->GetHeight();
const bool dB = (WaveTrack::WaveformDBDisplay == mDrawingTrack->GetDisplay()); const bool dB = !mDrawingTrack->GetWaveformSettings().isLinear();
float newLevel = ::ValueOfPixel(y, height, false, dB, mdBr, zoomMin, zoomMax); float newLevel = ::ValueOfPixel(y, height, false, dB, mdBr, zoomMin, zoomMax);
//Take the envelope into account //Take the envelope into account
@ -6908,16 +6897,14 @@ bool TrackPanel::HitTestEnvelope(Track *track, wxRect &r, wxMouseEvent & event)
if (!envelope) if (!envelope)
return false; return false;
int displayType = wavetrack->GetDisplay(); const int displayType = wavetrack->GetDisplay();
// Not an envelope hit, unless we're using a type of wavetrack display // Not an envelope hit, unless we're using a type of wavetrack display
// suitable for envelopes operations, ie one of the Wave displays. // suitable for envelopes operations, ie one of the Wave displays.
const bool dB = (displayType == WaveTrack::WaveformDBDisplay); if ( displayType != WaveTrack::Waveform)
if (!
(dB || (displayType == WaveTrack::WaveformDisplay))
)
return false; // No envelope, not a hit, so return. return false; // No envelope, not a hit, so return.
// Get envelope point, range 0.0 to 1.0 // Get envelope point, range 0.0 to 1.0
const bool dB = !wavetrack->GetWaveformSettings().isLinear();
// Convert x to time. // Convert x to time.
const double envValue = envelope->GetValue(mViewInfo->PositionToTime(event.m_x, r.x)); const double envValue = envelope->GetValue(mViewInfo->PositionToTime(event.m_x, r.x));
@ -6975,10 +6962,10 @@ bool TrackPanel::HitTestSamples(Track *track, wxRect &r, wxMouseEvent & event)
//Get rate in order to calculate the critical zoom threshold //Get rate in order to calculate the critical zoom threshold
double rate = wavetrack->GetRate(); double rate = wavetrack->GetRate();
int displayType = wavetrack->GetDisplay(); const int displayType = wavetrack->GetDisplay();
bool dB = (WaveTrack::WaveformDBDisplay == displayType); if (WaveTrack::Waveform != displayType)
if (!(WaveTrack::WaveformDisplay == displayType || dB))
return false; // Not a wave, so return. return false; // Not a wave, so return.
const bool dB = !wavetrack->GetWaveformSettings().isLinear();
const double tt = mViewInfo->PositionToTime(event.m_x, r.x); const double tt = mViewInfo->PositionToTime(event.m_x, r.x);
if (!SampleResolutionTest(*mViewInfo, wavetrack, tt, rate)) if (!SampleResolutionTest(*mViewInfo, wavetrack, tt, rate))
@ -8448,13 +8435,11 @@ void TrackPanel::OnTrackMenu(Track *t)
theMenu->Enable(OnChannelLeftID, !t->GetLinked()); theMenu->Enable(OnChannelLeftID, !t->GetLinked());
theMenu->Enable(OnChannelRightID, !t->GetLinked()); theMenu->Enable(OnChannelRightID, !t->GetLinked());
int display = ((WaveTrack *) t)->GetDisplay(); const int display = static_cast<WaveTrack *>(t)->GetDisplay();
theMenu->Check(
theMenu->Enable(OnWaveformID, display != WaveTrack::WaveformDisplay); (display == WaveTrack::Waveform) ? OnWaveformID : OnSpectrumID,
theMenu->Enable(OnWaveformDBID, true
display != WaveTrack::WaveformDBDisplay); );
theMenu->Enable(OnSpectrumID, display != WaveTrack::Spectrum);
theMenu->Enable(OnViewSettingsID, true);
WaveTrack * track = (WaveTrack *)t; WaveTrack * track = (WaveTrack *)t;
SetMenuCheck(*mRateMenu, IdOfRate((int) track->GetRate())); SetMenuCheck(*mRateMenu, IdOfRate((int) track->GetRate()));
@ -8920,30 +8905,42 @@ class ViewSettingsDialog : public PrefsDialog
{ {
public: public:
ViewSettingsDialog ViewSettingsDialog
(wxWindow *parent, const wxString &title, PrefsDialog::Factories &factories) (wxWindow *parent, const wxString &title, PrefsDialog::Factories &factories,
int page)
: PrefsDialog(parent, title, factories) : PrefsDialog(parent, title, factories)
, mPage(page)
{ {
} }
virtual long GetPreferredPage() virtual long GetPreferredPage()
{ {
// Future: choose Spectrum or Waveform page return mPage;
return 0;
} }
virtual void SavePreferredPage() virtual void SavePreferredPage()
{ {
} }
private:
const int mPage;
}; };
void TrackPanel::OnViewSettings(wxCommandEvent &) void TrackPanel::OnViewSettings(wxCommandEvent &)
{ {
WaveTrack *const wt = static_cast<WaveTrack*>(mPopupMenuTarget); WaveTrack *const wt = static_cast<WaveTrack*>(mPopupMenuTarget);
WaveformPrefsFactory waveformFactory(wt);
SpectrumPrefsFactory spectrumFactory(wt); SpectrumPrefsFactory spectrumFactory(wt);
// Put Waveform page first
PrefsDialog::Factories factories; PrefsDialog::Factories factories;
factories.push_back(&waveformFactory);
factories.push_back(&spectrumFactory); factories.push_back(&spectrumFactory);
const int page = (wt->GetDisplay() == WaveTrack::Spectrum)
? 1 : 0;
wxString title(wt->GetName() + wxT(": ")); wxString title(wt->GetName() + wxT(": "));
ViewSettingsDialog dialog(this, title, factories); ViewSettingsDialog dialog(this, title, factories, page);
if (0 != dialog.ShowModal()) if (0 != dialog.ShowModal())
// Redraw // Redraw
Refresh(false); Refresh(false);
@ -8964,9 +8961,7 @@ void TrackPanel::OnSetDisplay(wxCommandEvent & event)
switch (idInt) { switch (idInt) {
default: default:
case OnWaveformID: case OnWaveformID:
id = WaveTrack::WaveformDisplay; break; id = WaveTrack::Waveform; break;
case OnWaveformDBID:
id = WaveTrack::WaveformDBDisplay; break;
case OnSpectrumID: case OnSpectrumID:
id = WaveTrack::Spectrum; break; id = WaveTrack::Spectrum; break;
} }
@ -8985,9 +8980,10 @@ void TrackPanel::OnSetDisplay(wxCommandEvent & event)
} }
#endif #endif
UpdateVRuler(wt); UpdateVRuler(wt);
MakeParentModifyState(true);
Refresh(false);
} }
MakeParentModifyState(true);
Refresh(false);
} }
/// Sets the sample rate for a track, and if it is linked to /// Sets the sample rate for a track, and if it is linked to

View File

@ -55,6 +55,7 @@ Track classes.
#include "effects/TimeWarper.h" #include "effects/TimeWarper.h"
#include "prefs/SpectrumPrefs.h" #include "prefs/SpectrumPrefs.h"
#include "prefs/WaveformPrefs.h"
using std::max; using std::max;
@ -73,9 +74,10 @@ WaveTrack *TrackFactory::NewWaveTrack(sampleFormat format, double rate)
return new WaveTrack(mDirManager, format, rate); return new WaveTrack(mDirManager, format, rate);
} }
WaveTrack::WaveTrack(DirManager *projDirManager, sampleFormat format, double rate): WaveTrack::WaveTrack(DirManager *projDirManager, sampleFormat format, double rate) :
Track(projDirManager) Track(projDirManager)
, mpSpectrumSettings(0) , mpSpectrumSettings(0)
, mpWaveformSettings(0)
{ {
if (format == (sampleFormat)0) if (format == (sampleFormat)0)
{ {
@ -101,7 +103,7 @@ WaveTrack::WaveTrack(DirManager *projDirManager, sampleFormat format, double rat
mDisplayNumLocations = 0; mDisplayNumLocations = 0;
mDisplayLocations = NULL; mDisplayLocations = NULL;
mDisplayNumLocationsAllocated = 0; mDisplayNumLocationsAllocated = 0;
mLastDisplay = -1; mLastScaleType = -1;
mAutoSaveIdent = 0; mAutoSaveIdent = 0;
} }
@ -110,9 +112,11 @@ WaveTrack::WaveTrack(WaveTrack &orig):
, mpSpectrumSettings(orig.mpSpectrumSettings , mpSpectrumSettings(orig.mpSpectrumSettings
? new SpectrogramSettings(*orig.mpSpectrumSettings) : 0 ? new SpectrogramSettings(*orig.mpSpectrumSettings) : 0
) )
, mpWaveformSettings(orig.mpWaveformSettings
? new WaveformSettings(*orig.mpWaveformSettings) : 0)
{ {
mDisplay = FindDefaultViewMode(); mDisplay = FindDefaultViewMode();
mLastDisplay = -1; mLastScaleType = -1;
mLegacyProjectFileOffset = 0; mLegacyProjectFileOffset = 0;
@ -150,6 +154,8 @@ void WaveTrack::Merge(const Track &orig)
mPan = wt.mPan; mPan = wt.mPan;
SetSpectrogramSettings(wt.mpSpectrumSettings SetSpectrogramSettings(wt.mpSpectrumSettings
? new SpectrogramSettings(*wt.mpSpectrumSettings) : 0); ? new SpectrogramSettings(*wt.mpSpectrumSettings) : 0);
SetWaveformSettings
(wt.mpWaveformSettings ? new WaveformSettings(*wt.mpWaveformSettings) : 0);
} }
Track::Merge(orig); Track::Merge(orig);
} }
@ -168,6 +174,7 @@ WaveTrack::~WaveTrack()
delete [] mDisplayLocations; delete [] mDisplayLocations;
delete mpSpectrumSettings; delete mpSpectrumSettings;
delete mpWaveformSettings;
} }
double WaveTrack::GetOffset() const double WaveTrack::GetOffset() const
@ -204,7 +211,7 @@ WaveTrack::WaveTrackDisplay WaveTrack::FindDefaultViewMode()
if (viewMode < 0) { if (viewMode < 0) {
int oldMode; int oldMode;
gPrefs->Read(wxT("/GUI/DefaultViewMode"), &oldMode, gPrefs->Read(wxT("/GUI/DefaultViewMode"), &oldMode,
int(WaveTrack::WaveformDisplay)); int(WaveTrack::Waveform));
viewMode = WaveTrack::ConvertLegacyDisplayValue(oldMode); viewMode = WaveTrack::ConvertLegacyDisplayValue(oldMode);
} }
@ -231,9 +238,12 @@ WaveTrack::ConvertLegacyDisplayValue(int oldValue)
switch (oldValue) { switch (oldValue) {
default: default:
case Waveform: case Waveform:
newValue = WaveTrack::WaveformDisplay; break; case WaveformDB:
newValue = WaveTrack::Waveform; break;
/*
case WaveformDB: case WaveformDB:
newValue = WaveTrack::WaveformDBDisplay; break; newValue = WaveTrack::WaveformDBDisplay; break;
*/
case Spectrogram: case Spectrogram:
case SpectrogramLogF: case SpectrogramLogF:
case Pitch: case Pitch:
@ -254,8 +264,7 @@ WaveTrack::ValidateWaveTrackDisplay(WaveTrackDisplay display)
{ {
switch (display) { switch (display) {
// non-obsolete codes // non-obsolete codes
case WaveformDisplay: case Waveform:
case WaveformDBDisplay:
case Spectrum: case Spectrum:
return display; return display;
@ -266,6 +275,9 @@ WaveTrack::ValidateWaveTrackDisplay(WaveTrackDisplay display)
case obsolete4: // was PitchDisplay case obsolete4: // was PitchDisplay
return Spectrum; return Spectrum;
case obsolete5: // was WaveformDBDisplay
return Waveform;
// codes out of bounds (from future prefs files?) // codes out of bounds (from future prefs files?)
default: default:
return MinDisplay; return MinDisplay;
@ -682,6 +694,37 @@ void WaveTrack::SetSpectrogramSettings(SpectrogramSettings *pSettings)
} }
} }
const WaveformSettings &WaveTrack::GetWaveformSettings() const
{
if (mpWaveformSettings)
return *mpWaveformSettings;
else
return WaveformSettings::defaults();
}
WaveformSettings &WaveTrack::GetWaveformSettings()
{
if (mpWaveformSettings)
return *mpWaveformSettings;
else
return WaveformSettings::defaults();
}
WaveformSettings &WaveTrack::GetIndependentWaveformSettings()
{
if (!mpWaveformSettings)
mpWaveformSettings = new WaveformSettings(WaveformSettings::defaults());
return *mpWaveformSettings;
}
void WaveTrack::SetWaveformSettings(WaveformSettings *pSettings)
{
if (mpWaveformSettings != pSettings) {
delete mpWaveformSettings;
mpWaveformSettings = 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

@ -23,6 +23,7 @@
#include <wx/thread.h> #include <wx/thread.h>
class SpectrogramSettings; class SpectrogramSettings;
class WaveformSettings;
class TimeWarper; class TimeWarper;
// //
@ -151,6 +152,11 @@ class AUDACITY_DLL_API WaveTrack: public Track {
SpectrogramSettings &GetIndependentSpectrogramSettings(); SpectrogramSettings &GetIndependentSpectrogramSettings();
void SetSpectrogramSettings(SpectrogramSettings *pSettings); void SetSpectrogramSettings(SpectrogramSettings *pSettings);
const WaveformSettings &GetWaveformSettings() const;
WaveformSettings &GetWaveformSettings();
WaveformSettings &GetIndependentWaveformSettings();
void SetWaveformSettings(WaveformSettings *pSettings);
// //
// High-level editing // High-level editing
// //
@ -414,10 +420,11 @@ class AUDACITY_DLL_API WaveTrack: public Track {
// DO NOT REORDER OLD VALUES! Replace obsoletes with placeholders. // DO NOT REORDER OLD VALUES! Replace obsoletes with placeholders.
WaveformDisplay = 0, Waveform = 0,
MinDisplay = WaveformDisplay, MinDisplay = Waveform,
obsolete5, // was WaveformDBDisplay
WaveformDBDisplay,
Spectrum, Spectrum,
obsolete1, // was SpectrumLogDisplay obsolete1, // was SpectrumLogDisplay
@ -441,14 +448,15 @@ class AUDACITY_DLL_API WaveTrack: public Track {
// Handle restriction of range of values of the enum from future versions // Handle restriction of range of values of the enum from future versions
static WaveTrackDisplay ValidateWaveTrackDisplay(WaveTrackDisplay display); static WaveTrackDisplay ValidateWaveTrackDisplay(WaveTrackDisplay display);
void SetDisplay(WaveTrackDisplay display) { int GetLastScaleType() { return mLastScaleType; }
if (mDisplay < Spectrum) void SetLastScaleType(int scaleType)
// remember last display mode for wave and wavedb so they can remap the vertical ruler {
mLastDisplay = mDisplay; // remember last display mode for wave and wavedb so vertical ruler can remap
mDisplay = display; mLastScaleType = scaleType;
} }
WaveTrackDisplay GetDisplay() const { return mDisplay; } WaveTrackDisplay GetDisplay() const { return mDisplay; }
int GetLastDisplay() {return mLastDisplay;} void SetDisplay(WaveTrackDisplay display) { mDisplay = display; }
void GetDisplayBounds(float *min, float *max); void GetDisplayBounds(float *min, float *max);
void SetDisplayBounds(float min, float max); void SetDisplayBounds(float min, float max);
@ -474,7 +482,7 @@ class AUDACITY_DLL_API WaveTrack: public Track {
float mDisplayMin; float mDisplayMin;
float mDisplayMax; float mDisplayMax;
WaveTrackDisplay mDisplay; WaveTrackDisplay mDisplay;
int mLastDisplay; // last display mode int mLastScaleType; // last scale type choice
int mDisplayNumLocations; int mDisplayNumLocations;
int mDisplayNumLocationsAllocated; int mDisplayNumLocationsAllocated;
Location* mDisplayLocations; Location* mDisplayLocations;
@ -495,6 +503,7 @@ class AUDACITY_DLL_API WaveTrack: public Track {
int mAutoSaveIdent; int mAutoSaveIdent;
SpectrogramSettings *mpSpectrumSettings; SpectrogramSettings *mpSpectrumSettings;
WaveformSettings *mpWaveformSettings;
}; };
// 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

@ -789,8 +789,7 @@ bool NyquistEffect::ProcessOne()
type = wxT("wave"); type = wxT("wave");
switch (((WaveTrack *) mCurTrack[0])->GetDisplay()) switch (((WaveTrack *) mCurTrack[0])->GetDisplay())
{ {
case WaveTrack::WaveformDisplay: view = wxT("\"Waveform\""); break; case WaveTrack::Waveform: view = wxT("\"Waveform\""); break;
case WaveTrack::WaveformDBDisplay: view = wxT("\"Waveform (dB)\""); break;
case WaveTrack::Spectrum: view = wxT("\"Spectrum\""); break; case WaveTrack::Spectrum: view = wxT("\"Spectrum\""); break;
default: view = wxT("NIL"); break; default: view = wxT("NIL"); break;
} }

View File

@ -64,6 +64,7 @@
#include "ThemePrefs.h" #include "ThemePrefs.h"
#include "TracksPrefs.h" #include "TracksPrefs.h"
#include "WarningsPrefs.h" #include "WarningsPrefs.h"
#include "WaveformPrefs.h"
#include "ExtImportPrefs.h" #include "ExtImportPrefs.h"
#ifdef EXPERIMENTAL_MIDI_OUT #ifdef EXPERIMENTAL_MIDI_OUT
@ -131,6 +132,7 @@ PrefsDialog::Factories
#if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || !defined(DISABLE_DYNAMIC_LOADING_LAME) #if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || !defined(DISABLE_DYNAMIC_LOADING_LAME)
static LibraryPrefsFactory libraryPrefsFactory; static LibraryPrefsFactory libraryPrefsFactory;
#endif #endif
static WaveformPrefsFactory waveformPrefsFactory;
static SpectrumPrefsFactory spectrumPrefsFactory; static SpectrumPrefsFactory spectrumPrefsFactory;
static DirectoriesPrefsFactory directoriesPrefsFactory; static DirectoriesPrefsFactory directoriesPrefsFactory;
static WarningsPrefsFactory warningsPrefsFactory; static WarningsPrefsFactory warningsPrefsFactory;
@ -161,6 +163,7 @@ PrefsDialog::Factories
#if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || !defined(DISABLE_DYNAMIC_LOADING_LAME) #if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || !defined(DISABLE_DYNAMIC_LOADING_LAME)
&libraryPrefsFactory, &libraryPrefsFactory,
#endif #endif
&waveformPrefsFactory,
&spectrumPrefsFactory, &spectrumPrefsFactory,
&directoriesPrefsFactory, &directoriesPrefsFactory,
&warningsPrefsFactory, &warningsPrefsFactory,

View File

@ -60,10 +60,7 @@ void TracksPrefs::Populate()
// we don't display them by increasing integer values. // we don't display them by increasing integer values.
mViewChoices.Add(_("Waveform")); mViewChoices.Add(_("Waveform"));
mViewCodes.Add(int(WaveTrack::WaveformDisplay)); mViewCodes.Add(int(WaveTrack::Waveform));
mViewChoices.Add(_("Waveform (dB)"));
mViewCodes.Add(int(WaveTrack::WaveformDBDisplay));
mViewChoices.Add(_("Spectrum")); mViewChoices.Add(_("Spectrum"));
mViewCodes.Add(WaveTrack::Spectrum); mViewCodes.Add(WaveTrack::Spectrum);

214
src/prefs/WaveformPrefs.cpp Normal file
View File

@ -0,0 +1,214 @@
/**********************************************************************
Audacity: A Digital Audio Editor
WaveformPrefs.cpp
Paul Licameli
*******************************************************************//**
\class WaveformPrefs
\brief A PrefsPanel for spectrum settings.
*//*******************************************************************/
#include "../Audacity.h"
#include "WaveformPrefs.h"
#include <wx/checkbox.h>
#include "../Project.h"
#include "../TrackPanel.h"
#include "../ShuttleGUI.h"
WaveformPrefs::WaveformPrefs(wxWindow * parent, WaveTrack *wt)
: PrefsPanel(parent, _("Waveforms"))
, mWt(wt)
, mPopulating(false)
{
if (mWt) {
WaveformSettings &settings = wt->GetWaveformSettings();
mDefaulted = (&WaveformSettings::defaults() == &settings);
mTempSettings = settings;
}
else {
mTempSettings = WaveformSettings::defaults();
mDefaulted = false;
}
Populate();
}
WaveformPrefs::~WaveformPrefs()
{
}
enum {
ID_DEFAULTS = 10001,
ID_APPLY,
ID_SCALE,
};
void WaveformPrefs::Populate()
{
mScaleChoices = WaveformSettings::GetScaleNames();
//------------------------- Main section --------------------
// Now construct the GUI itself.
ShuttleGui S(this, eIsCreating);
PopulateOrExchange(S);
// ----------------------- End of main section --------------
}
void WaveformPrefs::PopulateOrExchange(ShuttleGui & S)
{
mPopulating = true;
S.SetBorder(2);
// S.StartStatic(_("Track Settings"));
{
mDefaultsCheckbox = 0;
if (mWt) {
mDefaultsCheckbox = S.Id(ID_DEFAULTS).TieCheckBox(_("Defaults"), mDefaulted);
}
S.StartStatic(_("Display"));
{
S.StartTwoColumn();
{
S.Id(ID_SCALE).TieChoice(_("S&cale") + wxString(wxT(":")),
*(int*)&mTempSettings.scaleType,
&mScaleChoices);
}
S.EndTwoColumn();
}
S.EndStatic();
}
// S.EndStatic();
/*
S.StartStatic(_("Global settings"));
{
}
S.EndStatic();
*/
S.StartMultiColumn(2, wxALIGN_RIGHT);
{
S.Id(ID_APPLY).AddButton(_("Appl&y"));
}
S.EndMultiColumn();
mPopulating = false;
}
bool WaveformPrefs::Validate()
{
// Do checking for whole numbers
// ToDo: use wxIntegerValidator<unsigned> when available
ShuttleGui S(this, eIsGettingFromDialog);
PopulateOrExchange(S);
// Delegate range checking to WaveformSettings class
const bool result = mTempSettings.Validate(false);
return result;
}
bool WaveformPrefs::Apply()
{
const bool isOpenPage = this->IsShown();
WaveTrack *const partner =
mWt ? static_cast<WaveTrack*>(mWt->GetLink()) : 0;
ShuttleGui S(this, eIsGettingFromDialog);
PopulateOrExchange(S);
WaveformSettings::Globals::Get().SavePrefs();
if (mWt) {
if (mDefaulted) {
mWt->SetWaveformSettings(NULL);
if (partner)
partner->SetWaveformSettings(NULL);
}
else {
WaveformSettings *pSettings =
&mWt->GetIndependentWaveformSettings();
*pSettings = mTempSettings;
if (partner) {
pSettings = &partner->GetIndependentWaveformSettings();
*pSettings = mTempSettings;
}
}
}
if (!mWt || mDefaulted) {
WaveformSettings *const pSettings =
&WaveformSettings::defaults();
*pSettings = mTempSettings;
pSettings->SavePrefs();
}
if (mWt && isOpenPage) {
mWt->SetDisplay(WaveTrack::Waveform);
if (partner)
partner->SetDisplay(WaveTrack::Waveform);
}
return true;
}
void WaveformPrefs::OnControl(wxCommandEvent&)
{
// Common routine for most controls
// If any per-track setting is changed, break the association with defaults
// Skip this, and View Settings... will be able to change defaults instead
// when the checkbox is on, as in the original design.
if (mDefaultsCheckbox && !mPopulating) {
mDefaulted = false;
mDefaultsCheckbox->SetValue(false);
}
}
void WaveformPrefs::OnDefaults(wxCommandEvent &)
{
if (mDefaultsCheckbox->IsChecked()) {
mTempSettings = WaveformSettings::defaults();
mDefaulted = true;
ShuttleGui S(this, eIsSettingToDialog);
PopulateOrExchange(S);
}
}
void WaveformPrefs::OnApply(wxCommandEvent &)
{
if (Validate()) {
Apply();
::GetActiveProject()->GetTrackPanel()->Refresh(false);
}
}
BEGIN_EVENT_TABLE(WaveformPrefs, PrefsPanel)
EVT_CHOICE(ID_SCALE, WaveformPrefs::OnControl)
EVT_CHECKBOX(ID_DEFAULTS, WaveformPrefs::OnDefaults)
EVT_BUTTON(ID_APPLY, WaveformPrefs::OnApply)
END_EVENT_TABLE()
WaveformPrefsFactory::WaveformPrefsFactory(WaveTrack *wt)
: mWt(wt)
{
}
PrefsPanel *WaveformPrefsFactory::Create(wxWindow *parent)
{
return new WaveformPrefs(parent, mWt);
}

60
src/prefs/WaveformPrefs.h Normal file
View File

@ -0,0 +1,60 @@
/**********************************************************************
Audacity: A Digital Audio Editor
WaveformPrefs.h
Paul Licameli
**********************************************************************/
#ifndef __AUDACITY_WAVEFORM_PREFS__
#define __AUDACITY_WAVEFORM_PREFS__
#include "PrefsPanel.h"
#include "WaveformSettings.h"
class ShuttleGui;
class WaveTrack;
class wxCheckBox;
class WaveformPrefs :public PrefsPanel
{
public:
WaveformPrefs(wxWindow * parent, WaveTrack *wt);
virtual ~WaveformPrefs();
virtual bool Apply();
virtual bool Validate();
private:
void Populate();
void PopulateOrExchange(ShuttleGui & S);
void OnControl(wxCommandEvent&);
void OnDefaults(wxCommandEvent&);
void OnApply(wxCommandEvent &);
DECLARE_EVENT_TABLE()
WaveTrack *const mWt;
bool mDefaulted;
wxCheckBox *mDefaultsCheckbox;
wxArrayString mScaleChoices;
WaveformSettings mTempSettings;
bool mPopulating;
};
class WaveformPrefsFactory : public PrefsPanelFactory
{
public:
explicit WaveformPrefsFactory(WaveTrack *wt = 0);
virtual PrefsPanel *Create(wxWindow *parent);
private:
WaveTrack *const mWt;
};
#endif

View File

@ -0,0 +1,129 @@
/**********************************************************************
Audacity: A Digital Audio Editor
WaveformSettings.cpp
Paul Licameli
*******************************************************************//**
\class WaveformSettings
\brief Waveform settings, either for one track or as defaults.
*//*******************************************************************/
#include "../Audacity.h"
#include "WaveformSettings.h"
#include <algorithm>
#include <wx/intl.h>
#include "../Prefs.h"
WaveformSettings::Globals::Globals()
{
LoadPrefs();
}
void WaveformSettings::Globals::SavePrefs()
{
}
void WaveformSettings::Globals::LoadPrefs()
{
}
WaveformSettings::Globals
&WaveformSettings::Globals::Get()
{
static Globals instance;
return instance;
}
WaveformSettings::WaveformSettings()
{
LoadPrefs();
}
WaveformSettings::WaveformSettings(const WaveformSettings &other)
: scaleType(other.scaleType)
{
}
WaveformSettings &WaveformSettings::operator= (const WaveformSettings &other)
{
if (this != &other) {
scaleType = other.scaleType;
}
return *this;
}
WaveformSettings& WaveformSettings::defaults()
{
static WaveformSettings instance;
return instance;
}
bool WaveformSettings::Validate(bool quiet)
{
quiet;
scaleType = ScaleType(
std::max(0, std::min(int(stNumScaleTypes) - 1, int(scaleType)))
);
return true;
}
void WaveformSettings::LoadPrefs()
{
scaleType = ScaleType(gPrefs->Read(wxT("/Waveform/ScaleType"), 0L));
// Enforce legal values
Validate(true);
Update();
}
void WaveformSettings::SavePrefs()
{
gPrefs->Write(wxT("/Waveform/ScaleType"), long(scaleType));
}
void WaveformSettings::Update()
{
}
namespace
{
wxArrayString &scaleNamesArray()
{
static wxArrayString theArray;
return theArray;
}
}
//static
void WaveformSettings::InvalidateNames()
{
scaleNamesArray().Clear();
}
//static
const wxArrayString &WaveformSettings::GetScaleNames()
{
wxArrayString &theArray = scaleNamesArray();
if (theArray.IsEmpty()) {
// Keep in correspondence with enum WaveTrack::WaveTrackDisplay:
theArray.Add(_("Linear"));
theArray.Add(_("Logarithmic"));
}
return theArray;
}
WaveformSettings::~WaveformSettings()
{
}

View File

@ -0,0 +1,63 @@
/**********************************************************************
Audacity: A Digital Audio Editor
WaveformSettings.h
Paul Licameli
**********************************************************************/
#ifndef __AUDACITY_WAVEFORM_SETTINGS__
#define __AUDACITY_WAVEFORM_SETTINGS__
class wxArrayString;
class WaveformSettings
{
public:
// Singleton for settings that are not per-track
class Globals
{
public:
static Globals &Get();
void SavePrefs();
private:
Globals();
void LoadPrefs();
};
static WaveformSettings &defaults();
WaveformSettings();
WaveformSettings(const WaveformSettings &other);
WaveformSettings& operator= (const WaveformSettings &other);
~WaveformSettings();
bool IsDefault() const
{
return this == &defaults();
}
bool Validate(bool quiet);
void LoadPrefs();
void SavePrefs();
void Update();
enum ScaleType {
stLinear,
stLogarithmic,
stNumScaleTypes,
};
static void InvalidateNames(); // in case of language change
static const wxArrayString &GetScaleNames();
ScaleType scaleType;
// Convenience
bool isLinear() const { return stLinear == scaleType; }
};
#endif

View File

@ -287,6 +287,8 @@
<ClCompile Include="..\..\..\src\PluginManager.cpp" /> <ClCompile Include="..\..\..\src\PluginManager.cpp" />
<ClCompile Include="..\..\..\src\Prefs.cpp" /> <ClCompile Include="..\..\..\src\Prefs.cpp" />
<ClCompile Include="..\..\..\src\prefs\SpectrogramSettings.cpp" /> <ClCompile Include="..\..\..\src\prefs\SpectrogramSettings.cpp" />
<ClCompile Include="..\..\..\src\prefs\WaveformPrefs.cpp" />
<ClCompile Include="..\..\..\src\prefs\WaveformSettings.cpp" />
<ClCompile Include="..\..\..\src\Printing.cpp" /> <ClCompile Include="..\..\..\src\Printing.cpp" />
<ClCompile Include="..\..\..\src\Profiler.cpp" /> <ClCompile Include="..\..\..\src\Profiler.cpp" />
<ClCompile Include="..\..\..\src\Project.cpp" /> <ClCompile Include="..\..\..\src\Project.cpp" />
@ -535,6 +537,8 @@
<ClInclude Include="..\..\..\src\ModuleManager.h" /> <ClInclude Include="..\..\..\src\ModuleManager.h" />
<ClInclude Include="..\..\..\src\NumberScale.h" /> <ClInclude Include="..\..\..\src\NumberScale.h" />
<ClInclude Include="..\..\..\src\prefs\SpectrogramSettings.h" /> <ClInclude Include="..\..\..\src\prefs\SpectrogramSettings.h" />
<ClInclude Include="..\..\..\src\prefs\WaveformPrefs.h" />
<ClInclude Include="..\..\..\src\prefs\WaveformSettings.h" />
<ClInclude Include="..\..\..\src\RevisionIdent.h" /> <ClInclude Include="..\..\..\src\RevisionIdent.h" />
<ClInclude Include="..\..\..\src\SelectedRegion.h" /> <ClInclude Include="..\..\..\src\SelectedRegion.h" />
<ClInclude Include="..\..\..\src\SseMathFuncs.h" /> <ClInclude Include="..\..\..\src\SseMathFuncs.h" />

View File

@ -843,6 +843,12 @@
<ClCompile Include="..\..\..\src\prefs\SpectrogramSettings.cpp"> <ClCompile Include="..\..\..\src\prefs\SpectrogramSettings.cpp">
<Filter>src/prefs</Filter> <Filter>src/prefs</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\prefs\WaveformPrefs.cpp">
<Filter>src/prefs</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\prefs\WaveformSettings.cpp">
<Filter>src/prefs</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\..\src\AboutDialog.h"> <ClInclude Include="..\..\..\src\AboutDialog.h">
@ -1688,6 +1694,12 @@
<ClInclude Include="..\..\..\src\NumberScale.h"> <ClInclude Include="..\..\..\src\NumberScale.h">
<Filter>src</Filter> <Filter>src</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\src\prefs\WaveformPrefs.h">
<Filter>src/prefs</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\prefs\WaveformSettings.h">
<Filter>src/prefs</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Image Include="..\..\audacity.ico"> <Image Include="..\..\audacity.ico">