Audacity  3.0.3
SpectrumVZoomHandle.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3 Audacity: A Digital Audio Editor
4 
5 SpectrumVZoomHandle.cpp
6 
7 Paul Licameli split from WaveTrackVZoomHandle.cpp
8 
9 **********************************************************************/
10 
11 
12 #include "SpectrumVZoomHandle.h"
13 
14 #include "WaveTrackVZoomHandle.h"
15 
16 #include "../../../../HitTestResult.h"
17 #include "NumberScale.h"
18 #include "Prefs.h"
19 #include "../../../../ProjectHistory.h"
20 #include "../../../../RefreshCode.h"
21 #include "../../../../TrackPanelMouseEvent.h"
22 #include "../../../../WaveTrack.h"
23 #include "../../../../prefs/SpectrogramSettings.h"
24 
26 (const std::shared_ptr<WaveTrack> &pTrack, const wxRect &rect, int y)
27  : mpTrack{ pTrack } , mZoomStart(y), mZoomEnd(y), mRect(rect)
28 {
29 }
30 
32 
34 {
35 #ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
37 #endif
38 }
39 
41 {
42  return true;
43 }
44 
47 {
49 }
50 
52 (const TrackPanelMouseEvent &evt, AudacityProject *pProject)
53 {
54  using namespace RefreshCode;
55  auto pTrack = TrackList::Get( *pProject ).Lock(mpTrack);
56  if (!pTrack)
57  return Cancelled;
58  return WaveTrackVZoomHandle::DoDrag( evt, pProject, mZoomStart, mZoomEnd );
59 }
60 
63 {
65 }
66 
68 (const TrackPanelMouseEvent &evt, AudacityProject *pProject,
69  wxWindow *pParent)
70 {
71  auto pTrack = TrackList::Get( *pProject ).Lock(mpTrack);
73  evt, pProject, pParent, pTrack.get(), mRect,
76 }
77 
79 {
80  // Cancel is implemented! And there is no initial state to restore,
81  // so just return a code.
83 }
84 
86  TrackPanelDrawingContext &context,
87  const wxRect &rect, unsigned iPass )
88 {
89  if (!mpTrack.lock()) //? TrackList::Lock()
90  return;
92  context, rect, iPass, mZoomStart, mZoomEnd );
93 }
94 
97  const wxRect &rect, const wxRect &panelRect, unsigned iPass )
98 {
99  return WaveTrackVZoomHandle::DoDrawingArea( rect, panelRect, iPass );
100 }
101 
102 // ZoomKind says how to zoom.
103 // If ZoomStart and ZoomEnd are not equal, this may override
104 // the zoomKind and cause a drag-zoom-in.
106  AudacityProject *pProject,
107  WaveTrack *pTrack,
109  const wxRect &rect, int zoomStart, int zoomEnd,
110  bool fixedMousePoint)
111 {
112  using namespace WaveTrackViewConstants;
113  static const float ZOOMLIMIT = 0.001f;
114 
115  int height = rect.height;
116  int ypos = rect.y;
117 
118  // Ensure start and end are in order (swap if not).
119  if (zoomEnd < zoomStart)
120  std::swap( zoomStart, zoomEnd );
121 
122  float min, max, minBand = 0;
123  const double rate = pTrack->GetRate();
124  const float halfrate = rate / 2;
125  float maxFreq = 8000.0;
126  const SpectrogramSettings &specSettings = pTrack->GetSpectrogramSettings();
127  NumberScale scale;
128  const bool spectrumLinear =
130 
131 
132  bool bDragZoom = WaveTrackVZoomHandle::IsDragZooming(zoomStart, zoomEnd);
133  // Add 100 if spectral to separate the kinds of zoom.
134  const int kSpectral = 100;
135 
136  // Possibly override the zoom kind.
137  if( bDragZoom )
138  ZoomKind = kZoomInByDrag;
139 
140  float top=2.0;
141  float half=0.5;
142 
143  {
144  pTrack->GetSpectrumBounds(&min, &max);
145  scale = (specSettings.GetScale(min, max));
146  const auto fftLength = specSettings.GetFFTLength();
147  const float binSize = rate / fftLength;
148  maxFreq = SpectrumMaxFreq.Read();
149  // JKC: Following discussions of Bug 1208 I'm allowing zooming in
150  // down to one bin.
151  // const int minBins =
152  // std::min(10, fftLength / 2); //minimum 10 freq bins, unless there are less
153  const int minBins = 1;
154  minBand = minBins * binSize;
155  }
156 
157  // Compute min and max.
158  switch(ZoomKind)
159  {
160  default:
161  // If we have covered all the cases, this won't happen.
162  // In release builds Audacity will ignore the zoom.
163  wxFAIL_MSG("Zooming Case not implemented by Audacity");
164  break;
165 
166  // VZooming on spectral we don't implement the other zoom presets.
167  // They are also not in the menu.
168  case kZoomReset:
169  {
170  // Zoom out to normal level.
171  min = spectrumLinear ? 0.0f : 1.0f;
172  max = maxFreq;
173  }
174  break;
175  case kZoom1to1:
176  case kZoomDiv2:
177  case kZoomTimes2:
178  case kZoomHalfWave:
179  {
180  // Zoom out full
181  min = spectrumLinear ? 0.0f : 1.0f;
182  max = halfrate;
183  }
184  break;
185  case kZoomInByDrag:
186  {
187  double xmin = 1 - (zoomEnd - ypos) / (float)height;
188  double xmax = 1 - (zoomStart - ypos) / (float)height;
189  const float middle = (xmin + xmax) / 2;
190  const float middleValue = scale.PositionToValue(middle);
191 
192  min = std::max(spectrumLinear ? 0.0f : 1.0f,
193  std::min(middleValue - minBand / 2,
194  scale.PositionToValue(xmin)
195  ));
196  max = std::min(halfrate,
197  std::max(middleValue + minBand / 2,
198  scale.PositionToValue(xmax)
199  ));
200  }
201  break;
202  case kZoomIn:
203  {
204  // Center the zoom-in at the click
205  const float p1 = (zoomStart - ypos) / (float)height;
206  const float middle = 1.0f - p1;
207  const float middleValue = scale.PositionToValue(middle);
208 
209  if (fixedMousePoint) {
210  min = std::max(spectrumLinear ? 0.0f : 1.0f,
211  std::min(middleValue - minBand * middle,
212  scale.PositionToValue(0.5f * middle)
213  ));
214  max = std::min(halfrate,
215  std::max(middleValue + minBand * p1,
216  scale.PositionToValue(middle + 0.5f * p1)
217  ));
218  }
219  else {
220  min = std::max(spectrumLinear ? 0.0f : 1.0f,
221  std::min(middleValue - minBand / 2,
222  scale.PositionToValue(middle - 0.25f)
223  ));
224  max = std::min(halfrate,
225  std::max(middleValue + minBand / 2,
226  scale.PositionToValue(middle + 0.25f)
227  ));
228  }
229  }
230  break;
231  case kZoomOut:
232  {
233  // Zoom out
234  const float p1 = (zoomStart - ypos) / (float)height;
235  // (Used to zoom out centered at midline, ignoring the click, if linear view.
236  // I think it is better to be consistent. PRL)
237  // Center zoom-out at the midline
238  const float middle = // spectrumLinear ? 0.5f :
239  1.0f - p1;
240 
241  if (fixedMousePoint) {
242  min = std::max(spectrumLinear ? 0.0f : 1.0f, scale.PositionToValue(-middle));
243  max = std::min(halfrate, scale.PositionToValue(1.0f + p1));
244  }
245  else {
246  min = std::max(spectrumLinear ? 0.0f : 1.0f, scale.PositionToValue(middle - 1.0f));
247  max = std::min(halfrate, scale.PositionToValue(middle + 1.0f));
248  }
249  }
250  break;
251  }
252 
253  // Now actually apply the zoom.
254  for (auto channel : TrackList::Channels(pTrack))
255  channel->SetSpectrumBounds(min, max);
256 
257  zoomEnd = zoomStart = 0;
258  if( pProject )
259  ProjectHistory::Get( *pProject ).ModifyState(true);
260 }
261 
263 // Table class
264 
266 {
267  static SpectrumVRulerMenuTable instance;
268  return instance;
269 }
270 
272 
273 BeginSection( "Scales" );
274  {
275  const auto & names = SpectrogramSettings::GetScaleNames();
276  for (int ii = 0, nn = names.size(); ii < nn; ++ii) {
278  OnFirstSpectrumScaleID + ii, names[ii].Msgid(),
279  POPUP_MENU_FN( OnSpectrumScaleType ),
280  []( PopupMenuHandler &handler, wxMenu &menu, int id ){
281  WaveTrack *const wt =
282  static_cast<SpectrumVRulerMenuTable&>( handler )
283  .mpData->pTrack;
284  if ( id ==
286  (int)(wt->GetSpectrogramSettings().scaleType ) )
287  menu.Check(id, true);
288  }
289  );
290  }
291  }
293 
294 
295 BeginSection( "Zoom" );
296  // Accelerators only if zooming enabled.
297  bool bVZoom;
298  gPrefs->Read(wxT("/GUI/VerticalZooming"), &bVZoom, false);
299 
300  AppendItem( "Reset", OnZoomResetID, XXO("Zoom Reset"),
301  POPUP_MENU_FN( OnZoomReset ) );
303  MakeLabel( XXO("Zoom to Fit"), bVZoom, XXO("Shift-Right-Click") ),
304  POPUP_MENU_FN( OnZoomFitVertical ) );
306  MakeLabel( XXO("Zoom In"), bVZoom, XXO("Left-Click/Left-Drag") ),
307  POPUP_MENU_FN( OnZoomInVertical ) );
309  MakeLabel( XXO("Zoom Out"), bVZoom, XXO("Shift-Left-Click") ),
310  POPUP_MENU_FN( OnZoomOutVertical ) );
311 EndSection();
312 
314 
315 void SpectrumVRulerMenuTable::OnSpectrumScaleType(wxCommandEvent &evt)
316 {
317  WaveTrack *const wt = mpData->pTrack;
318 
319  const SpectrogramSettings::ScaleType newScaleType =
321  std::max(0,
323  evt.GetId() - OnFirstSpectrumScaleID
324  )));
325  if (wt->GetSpectrogramSettings().scaleType != newScaleType) {
326  for (auto channel : TrackList::Channels(wt))
327  channel->GetIndependentSpectrogramSettings().scaleType = newScaleType;
328 
329  ProjectHistory::Get( mpData->project ).ModifyState(true);
330 
331  using namespace RefreshCode;
332  mpData->result = UpdateVRuler | RefreshAll;
333  }
334 }
ProjectHistory::ModifyState
void ModifyState(bool bWantsAutoSave)
Definition: ProjectHistory.cpp:124
BeginSection
BeginSection("Scales")
SpectrogramSettings
Spectrogram settings, either for one track or as defaults.
Definition: SpectrogramSettings.h:27
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:69
SpectrumMaxFreq
IntSetting SpectrumMaxFreq
Definition: SpectrogramSettings.cpp:31
RefreshCode::RefreshAll
@ RefreshAll
Definition: RefreshCode.h:26
SpectrumVZoomHandle::Enter
void Enter(bool forward, AudacityProject *) override
Definition: SpectrumVZoomHandle.cpp:33
AppendRadioItem
AppendRadioItem("Instrument1", OnInstrument1ID, GetWaveColorStr(0), POPUP_MENU_FN(OnWaveColorChange), fn)
NumberScale.h
RefreshCode::RefreshNone
@ RefreshNone
Definition: RefreshCode.h:21
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:70
WaveTrackViewConstants::kZoomTimes2
@ kZoomTimes2
Definition: WaveTrackViewConstants.h:73
TrackList::Lock
std::shared_ptr< Subclass > Lock(const std::weak_ptr< Subclass > &wTrack)
Definition: Track.h:1542
PopupMenuTable
Definition: PopupMenuTable.h:115
SpectrogramSettings::stNumScaleTypes
@ stNumScaleTypes
Definition: SpectrogramSettings.h:66
WaveTrackVZoomHandle::DoRelease
AUDACITY_DLL_API Result DoRelease(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent, WaveTrack *pTrack, const wxRect &mRect, DoZoomFunction doZoom, PopupMenuTable &table, int zoomStart, int zoomEnd)
Definition: WaveTrackVZoomHandle.cpp:97
WaveTrackViewConstants
Definition: WaveTrackView.h:17
TrackPanelDrawingContext
Definition: TrackPanelDrawingContext.h:22
TrackList::Channels
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1484
SpectrumVZoomHandle::Click
Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
Definition: SpectrumVZoomHandle.cpp:46
WaveTrackVZoomHandle::DoDrawingArea
AUDACITY_DLL_API wxRect DoDrawingArea(const wxRect &rect, const wxRect &panelRect, unsigned iPass)
Definition: WaveTrackVZoomHandle.cpp:161
WaveTrackViewConstants::kZoom1to1
@ kZoom1to1
Definition: WaveTrackViewConstants.h:72
RefreshCode::Cancelled
@ Cancelled
Definition: RefreshCode.h:23
WaveTrackVZoomHandle::DoDrag
AUDACITY_DLL_API Result DoDrag(const TrackPanelMouseEvent &event, AudacityProject *pProject, int zoomStart, int &zoomEnd)
Definition: WaveTrackVZoomHandle.cpp:82
OnZoomResetID
@ OnZoomResetID
Definition: NoteTrackVZoomHandle.cpp:148
SpectrumVZoomHandle::Drag
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
Definition: SpectrumVZoomHandle.cpp:52
WaveTrackViewConstants::ZoomActions
ZoomActions
Definition: WaveTrackViewConstants.h:69
SpectrogramSettings::GetScaleNames
static const EnumValueSymbols & GetScaleNames()
Definition: SpectrogramSettings.cpp:184
WaveTrackVZoomHandle::DoDraw
AUDACITY_DLL_API void DoDraw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass, int zoomStart, int zoomEnd)
Definition: WaveTrackVZoomHandle.cpp:150
SpectrumVZoomHandle::mZoomEnd
int mZoomEnd
Definition: SpectrumVZoomHandle.h:72
WaveTrack::GetSpectrogramSettings
const SpectrogramSettings & GetSpectrogramSettings() const
Definition: WaveTrack.cpp:763
SpectrumVZoomHandle::~SpectrumVZoomHandle
~SpectrumVZoomHandle() override
SpectrumVRulerMenuTable::Instance
static PopupMenuTable & Instance()
Definition: SpectrumVZoomHandle.cpp:265
WaveTrackViewConstants::kZoomDiv2
@ kZoomDiv2
Definition: WaveTrackViewConstants.h:74
WaveTrackVZoomHandle::HitPreview
AUDACITY_DLL_API HitTestPreview HitPreview(const wxMouseState &state)
Definition: WaveTrackVZoomHandle.cpp:61
OnZoomFitVerticalID
@ OnZoomFitVerticalID
Definition: NoteTrackVZoomHandle.cpp:147
AppendItem
AppendItem("Reset", OnZoomResetID, XXO("Zoom Reset"), POPUP_MENU_FN(OnZoomReset))
Setting::Read
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:128
WaveTrackVZoomHandle::IsDragZooming
AUDACITY_DLL_API bool IsDragZooming(int zoomStart, int zoomEnd)
Definition: WaveTrackVZoomHandle.cpp:24
SpectrogramSettings::GetScale
NumberScale GetScale(float minFreq, float maxFreq) const
Definition: SpectrogramSettings.cpp:622
XXO
#define XXO(s)
Definition: Internat.h:44
UIHandle::mChangeHighlight
Result mChangeHighlight
Definition: UIHandle.h:139
EndSection
EndSection()
WaveTrack::GetSpectrumBounds
void GetSpectrumBounds(float *min, float *max) const
Definition: WaveTrack.cpp:332
SpectrumVZoomHandle::Draw
void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass) override
Definition: SpectrumVZoomHandle.cpp:85
UIHandle::Result
unsigned Result
Definition: UIHandle.h:38
HitTestPreview
Definition: HitTestResult.h:20
SpectrumVZoomHandle::Release
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
Definition: SpectrumVZoomHandle.cpp:68
SpectrogramSettings::GetFFTLength
size_t GetFFTLength() const
Definition: SpectrogramSettings.cpp:607
RefreshCode::UpdateVRuler
@ UpdateVRuler
Definition: RefreshCode.h:30
WaveTrackViewConstants::kZoomIn
@ kZoomIn
Definition: WaveTrackViewConstants.h:77
anonymous_namespace{NoteTrack.cpp}::swap
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:735
SpectrogramSettings::ScaleType
int ScaleType
Definition: SpectrogramSettings.h:57
RefreshCode::RefreshCell
@ RefreshCell
Definition: RefreshCode.h:24
SpectrogramSettings::scaleType
ScaleType scaleType
Definition: SpectrogramSettings.h:147
WaveTrackViewConstants::kZoomInByDrag
@ kZoomInByDrag
Definition: WaveTrackViewConstants.h:76
SpectrogramSettings::stLinear
@ stLinear
Definition: SpectrogramSettings.h:59
POPUP_MENU_FN
#define POPUP_MENU_FN(memFn)
Definition: PopupMenuTable.h:324
WaveTrackViewConstants::kZoomReset
@ kZoomReset
Definition: WaveTrackViewConstants.h:79
SpectrumVZoomHandle::DoZoom
static void DoZoom(AudacityProject *pProject, WaveTrack *pTrack, WaveTrackViewConstants::ZoomActions ZoomKind, const wxRect &rect, int zoomStart, int zoomEnd, bool fixedMousePoint)
Definition: SpectrumVZoomHandle.cpp:105
BEGIN_POPUP_MENU
#define BEGIN_POPUP_MENU(HandlerClass)
Definition: PopupMenuTable.h:316
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
SpectrumVZoomHandle::SpectrumVZoomHandle
SpectrumVZoomHandle(const SpectrumVZoomHandle &)
NumberScale::PositionToValue
float PositionToValue(float pp) const
Definition: NumberScale.h:154
TrackList::Get
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:506
PopupMenuHandler
Definition: PopupMenuTable.h:85
OnZoomOutVerticalID
@ OnZoomOutVerticalID
Definition: NoteTrackVZoomHandle.cpp:153
names
static TranslatableStrings names
Definition: Tags.cpp:744
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:92
TrackPanelMouseEvent
Definition: TrackPanelMouseEvent.h:46
TrackPanelMouseState
Definition: TrackPanelMouseEvent.h:28
SpectrumVZoomHandle::Cancel
Result Cancel(AudacityProject *pProject) override
Definition: SpectrumVZoomHandle.cpp:78
WaveTrackViewConstants::kZoomOut
@ kZoomOut
Definition: WaveTrackViewConstants.h:78
ExceptionType::Internal
@ Internal
Indicates internal failure from Audacity.
NumberScale
Definition: NumberScale.h:31
Prefs.h
SpectrumVZoomHandle.h
SpectrumVRulerMenuTable
Definition: SpectrumVZoomHandle.h:79
SpectrumVZoomHandle::mRect
wxRect mRect
Definition: SpectrumVZoomHandle.h:73
RefreshCode
Namespace containing an enum 'what to do on a refresh?'.
Definition: RefreshCode.h:16
SpectrumVZoomHandle::mZoomStart
int mZoomStart
Definition: SpectrumVZoomHandle.h:72
SpectrumVZoomHandle::DrawingArea
wxRect DrawingArea(TrackPanelDrawingContext &, const wxRect &rect, const wxRect &panelRect, unsigned iPass) override
Definition: SpectrumVZoomHandle.cpp:95
WaveTrackViewConstants::kZoomHalfWave
@ kZoomHalfWave
Definition: WaveTrackViewConstants.h:75
SpectrumVZoomHandle::Preview
HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject) override
Definition: SpectrumVZoomHandle.cpp:62
SpectrumVZoomHandle::mpTrack
std::weak_ptr< WaveTrack > mpTrack
Definition: SpectrumVZoomHandle.h:70
SpectrumVZoomHandle::HandlesRightClick
bool HandlesRightClick() override
Whether the handle has any special right-button handling.
Definition: SpectrumVZoomHandle.cpp:40
OnZoomInVerticalID
@ OnZoomInVerticalID
Definition: NoteTrackVZoomHandle.cpp:152
TrackPanelMouseState::state
wxMouseState & state
Definition: TrackPanelMouseEvent.h:38
ProjectHistory::Get
static ProjectHistory & Get(AudacityProject &project)
Definition: ProjectHistory.cpp:26
OnFirstSpectrumScaleID
@ OnFirstSpectrumScaleID
Definition: WaveTrackVZoomHandle.h:121
bVZoom
bool bVZoom
Definition: SpectrumVZoomHandle.cpp:297
END_POPUP_MENU
#define END_POPUP_MENU()
Definition: PopupMenuTable.h:331
WaveTrackVZoomHandle.h
WaveTrack::GetRate
double GetRate() const
Definition: WaveTrack.cpp:457