Audacity  2.3.1
Contrast.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  Contrast.cpp
6 
7 \class ContrastDialog
8 \brief Dialog used for Contrast menu item
9 
10 *//*******************************************************************/
11 
12 #include "../Audacity.h"
13 #include "Contrast.h"
14 
15 #include "../WaveTrack.h"
16 #include "../Prefs.h"
17 #include "../Project.h"
18 #include "../ShuttleGui.h"
19 #include "../FileNames.h"
20 #include "../widgets/LinkingHtmlWindow.h"
21 #include "../widgets/HelpSystem.h"
22 #include "../widgets/NumericTextCtrl.h"
23 #include "../widgets/ErrorDialog.h"
24 
25 #include <cmath>
26 #include <limits>
27 
28 #if defined(__WXMSW__) && !defined(__CYGWIN__)
29 #include <float.h>
30 #define finite(x) _finite(x)
31 #endif
32 
33 #include <wx/filedlg.h>
34 #include <wx/valtext.h>
35 #include <wx/log.h>
36 
37 #include "../PlatformCompatibility.h"
38 
39 #define DB_MAX_LIMIT 0.0 // Audio is massively distorted.
40 #define WCAG2_PASS 20.0 // dB difference required to pass WCAG2 test.
41 
42 
43 bool ContrastDialog::GetDB(float &dB)
44 {
45  float rms = float(0.0);
46 
47  // For stereo tracks: sqrt((mean(L)+mean(R))/2)
48  double meanSq = 0.0;
49 
51  auto range =
52  p->GetTracks()->SelectedLeaders< const WaveTrack >();
53  auto numberSelectedTracks = range.size();
54  if (numberSelectedTracks > 1) {
55  AudacityMessageDialog m(NULL, _("You can only measure one track at a time."), _("Error"), wxOK);
56  m.ShowModal();
57  return false;
58  }
59  if(numberSelectedTracks == 0) {
60  wxMessageDialog m(NULL, _("Please select an audio track."), _("Error"), wxOK);
61  m.ShowModal();
62  return false;
63  }
64 
65  const auto channels = TrackList::Channels( *range.begin() );
66  for ( auto t : channels ) {
67  wxASSERT(mT0 <= mT1);
68 
69  // Ignore whitespace beyond ends of track.
70  if(mT0 < t->GetStartTime())
71  mT0 = t->GetStartTime();
72  if(mT1 > t->GetEndTime())
73  mT1 = t->GetEndTime();
74 
75  auto SelT0 = t->TimeToLongSamples(mT0);
76  auto SelT1 = t->TimeToLongSamples(mT1);
77 
78  if(SelT0 > SelT1)
79  {
80  AudacityMessageDialog m(NULL, _("Invalid audio selection.\nPlease ensure that audio is selected."), _("Error"), wxOK);
81  m.ShowModal();
82  return false;
83  }
84 
85  if(SelT0 == SelT1)
86  {
87  AudacityMessageDialog m(NULL, _("Nothing to measure.\nPlease select a section of a track."), _("Error"), wxOK);
88  m.ShowModal();
89  return false;
90  }
91 
92  // Don't throw in this analysis dialog
93  rms = t->GetRMS(mT0, mT1, false);
94  meanSq += rms * rms;
95  }
96  // TODO: This works for stereo, provided the audio clips are in both channels.
97  // We should really count gaps between clips as silence.
98  rms = (meanSq > 0.0)
99  ? sqrt( meanSq/static_cast<double>( channels.size() ) )
100  : 0.0;
101 
102  // Gives warning C4056, Overflow in floating-point constant arithmetic
103  // -INFINITY is intentional here.
104  // Looks like we are stuck with this warning, as
105  // #pragma warning( disable : 4056)
106  // even around the whole function does not disable it successfully.
107 
108  dB = (rms == 0.0)? -INFINITY : LINEAR_TO_DB(rms);
109  return true;
110 }
111 
113 {
117 }
118 
119 
120 // WDR: class implementations
121 
122 //----------------------------------------------------------------------------
123 // ContrastDialog
124 //----------------------------------------------------------------------------
125 
126 // WDR: event table for ContrastDialog
127 
128 enum {
131  //ID_BUTTON_GETURL,
134  //ID_BUTTON_CLOSE,
143 };
144 
145 BEGIN_EVENT_TABLE(ContrastDialog,wxDialogWrapper)
148  EVT_BUTTON(wxID_HELP, ContrastDialog::OnGetURL)
151  EVT_BUTTON(wxID_CANCEL, ContrastDialog::OnClose)
153 
154 static void OnChar(wxKeyEvent & event)
155 {
156  // Is this still required?
157  if (event.GetKeyCode() == WXK_TAB) {
158  // pass to next handler
159  event.Skip();
160  return;
161  }
162 
163  // ignore any other key
164  event.Skip(false);
165  return;
166 }
167 
168 /* i18n-hint: WCAG2 is the 'Web Content Accessibility Guidelines (WCAG) 2.0', see http://www.w3.org/TR/WCAG20/ */
169 ContrastDialog::ContrastDialog(wxWindow * parent, wxWindowID id,
170  const wxString & title,
171  const wxPoint & pos):
172  wxDialogWrapper(parent, id, title, pos, wxDefaultSize,
173  wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX )
174 {
175  SetName(GetTitle());
176 
177  mT0 = 0.0;
178  mT1 = 0.0;
179  foregrounddB = 0.0;
180  backgrounddB = 0.0;
181  mForegroundIsDefined = false;
182  mBackgroundIsDefined = false;
183 
184  // NULL out the control members until the controls are created.
185  mForegroundStartT = NULL;
186  mForegroundEndT = NULL;
187  mBackgroundStartT = NULL;
188  mBackgroundEndT = NULL;
189  wxTextValidator vld(wxFILTER_NUMERIC);
190  wxString number;
191 
193  mProjectRate = p->GetRate();
194 
195  ShuttleGui S(this, eIsCreating);
196 
197  S.SetBorder(5);
198  S.StartHorizontalLay(wxCENTER, false);
199  {
200  /* i18n-hint: RMS abbreviates root mean square, a certain averaging method */
201  S.AddTitle(_("Contrast Analyzer, for measuring RMS volume differences between two selections of audio."));
202  }
203  S.EndHorizontalLay();
204  S.StartStatic( _("Parameters") );
205  {
206  S.StartMultiColumn(5, wxEXPAND);
207  {
208 
209  // Headings
210  S.AddFixedText( {} ); // spacer
211  S.AddFixedText(_("Start"));
212  S.AddFixedText(_("End"));
213  S.AddFixedText( {} ); // spacer
214  S.AddFixedText(_("Volume "));
215 
216  const auto options = NumericTextCtrl::Options{}
217  .AutoPos(true)
218  .MenuEnabled(false)
219  .ReadOnly(true);
220 
221  //Foreground
222  S.AddFixedText(_("&Foreground:"), false);
223  if (S.GetMode() == eIsCreating)
224  {
229  0.0,
230  mProjectRate,
231  options);
232  mForegroundStartT->SetName(_("Foreground start time"));
233  }
235 
236  if (S.GetMode() == eIsCreating)
237  {
242  0.0,
243  mProjectRate,
244  options);
245  mForegroundEndT->SetName(_("Foreground end time"));
246  }
248 
249  m_pButton_UseCurrentF = S.Id(ID_BUTTON_USECURRENTF).AddButton(_("&Measure selection"));
251  mForegroundRMSText->Bind(wxEVT_KEY_DOWN, OnChar);
252 
253  //Background
254  S.AddFixedText(_("&Background:"));
255  if (S.GetMode() == eIsCreating)
256  {
261  0.0,
262  mProjectRate,
263  options);
264  mBackgroundStartT->SetName(_("Background start time"));
265  }
267 
268  if (S.GetMode() == eIsCreating)
269  {
274  0.0,
275  mProjectRate,
276  options);
277  mBackgroundEndT->SetName(_("Background end time"));
278  }
280 
281  m_pButton_UseCurrentB = S.Id(ID_BUTTON_USECURRENTB).AddButton(_("Mea&sure selection"));
282  mBackgroundRMSText = S.Id(ID_BACKGROUNDDB_TEXT).AddTextBox( {}, wxT(""), 17);
283  mBackgroundRMSText->Bind(wxEVT_KEY_DOWN, OnChar);
284  }
285  S.EndMultiColumn();
286  }
287  S.EndStatic();
288 
289  //Result
290  S.StartStatic( _("Result") );
291  {
292  S.StartMultiColumn(3, wxCENTER);
293  {
294  wxString label = _("Co&ntrast Result:");
295  S.AddFixedText(label);
296  mPassFailText = S.Id(ID_RESULTS_TEXT).AddTextBox( {}, wxT(""), 50);
297  mPassFailText->SetName(wxStripMenuCodes(label));
298  mPassFailText->Bind(wxEVT_KEY_DOWN, OnChar);
299  m_pButton_Reset = S.Id(ID_BUTTON_RESET).AddButton(_("R&eset"));
300 
301  label = _("&Difference:");
302  S.AddFixedText(label);
303  mDiffText = S.Id(ID_RESULTSDB_TEXT).AddTextBox( {}, wxT(""), 50);
304  mDiffText->SetName(wxStripMenuCodes(label));
305  mDiffText->Bind(wxEVT_KEY_DOWN, OnChar);
306  m_pButton_Export = S.Id(ID_BUTTON_EXPORT).AddButton(_("E&xport..."));
307  }
308  S.EndMultiColumn();
309  }
310  S.EndStatic();
312 #if 0
313  S.StartMultiColumn(3, wxEXPAND);
314  {
315  S.SetStretchyCol(1);
316  m_pButton_GetURL = S.Id(ID_BUTTON_GETURL).AddButton(_("&Help"));
317  S.AddFixedText(wxT(" ")); // spacer
318  m_pButton_Close = S.Id(ID_BUTTON_CLOSE).AddButton(_("&Close"));
319  }
320  S.EndMultiColumn();
321 #endif
322  Layout();
323  Fit();
324  SetMinSize(GetSize());
325  Center();
326 }
327 
328 void ContrastDialog::OnGetURL(wxCommandEvent & WXUNUSED(event))
329 {
330  // Original help page is back on-line (March 2016), but the manual should be more reliable.
331  // http://www.eramp.com/WCAG_2_audio_contrast_tool_help.htm
332  HelpSystem::ShowHelp(this, wxT("Contrast"));
333 }
334 
335 void ContrastDialog::OnClose(wxCommandEvent & WXUNUSED(event))
336 {
337  wxCommandEvent dummyEvent;
338  OnReset(dummyEvent);
339 
340  Show(false);
341 }
342 
343 void ContrastDialog::OnGetForeground(wxCommandEvent & /*event*/)
344 {
346 
347  if( p->GetTracks()->Selected< const WaveTrack >() ) {
350  }
351 
354  m_pButton_UseCurrentF->SetFocus();
355  results();
356 }
357 
358 void ContrastDialog::OnGetBackground(wxCommandEvent & /*event*/)
359 {
361 
362  if( p->GetTracks()->Selected< const WaveTrack >() ) {
365  }
366 
369  m_pButton_UseCurrentB->SetFocus();
370  results();
371 }
372 
373 namespace {
374  // PRL: I gathered formatting into these functions, and eliminated some
375  // repetitions, and removed the redundant word "Average" as applied to RMS.
376  // Should these variations in formats be collapsed further?
377 
378  // Pass nullptr when value is not yet defined
379  wxString FormatRMSMessage( float *pValue )
380  {
381 
382  /* i18n-hint: RMS abbreviates root mean square, a certain averaging method */
383  wxString format0{ _("RMS = %s.") };
384 
385  /* i18n-hint: dB abbreviates decibels */
386  wxString format1{ _("%s dB") };
387 
388  wxString value;
389 
390  if ( pValue )
391  if( fabs( *pValue ) != std::numeric_limits<float>::infinity() ) {
392  auto number = wxString::Format( _("%.2f"), *pValue );
393  value = wxString::Format( format1, number );
394  }
395  else
396  value = _("zero");
397  else
398  value = wxString::Format( format1, "" );
399 
400  return wxString::Format( format0, value );
401  }
402 
403  wxString FormatDifference( float diffdB )
404  {
405  if( diffdB != diffdB ) // test for NaN, reliant on IEEE implementation
406  return _("indeterminate");
407  else {
408  if( diffdB != std::numeric_limits<float>::infinity() )
409  /* i18n-hint: dB abbreviates decibels */
410  /* i18n-hint: RMS abbreviates root mean square, a certain averaging method */
411  return wxString::Format(_("%.2f dB RMS"), diffdB);
412  else
413  /* i18n-hint: dB abbreviates decibels */
414  return _("Infinite dB difference");
415  }
416  }
417 
418  wxString FormatDifferenceForExport( float diffdB )
419  {
420  if( diffdB != diffdB ) //test for NaN, reliant on IEEE implementation
421  return _("Difference is indeterminate.");
422  else
423  if( fabs(diffdB) != std::numeric_limits<float>::infinity() )
424  /* i18n-hint: dB abbreviates decibels */
425  /* i18n-hint: RMS abbreviates root mean square, a certain averaging method */
426  return wxString::Format(_("Difference = %.2f RMS dB."), diffdB );
427  else
428  /* i18n-hint: dB abbreviates decibels */
429  /* i18n-hint: RMS abbreviates root mean square, a certain averaging method */
430  return _("Difference = infinite RMS dB.");
431  }
432 }
433 
435 {
436  mPassFailText->SetName(wxT(""));
437  mPassFailText->ChangeValue(wxT(""));
438  mDiffText->ChangeValue(wxT(""));
439 
440  // foreground and background defined.
442  float diffdB = std::fabs(foregrounddB - backgrounddB);
443  if(foregrounddB > DB_MAX_LIMIT) {
444  mPassFailText->ChangeValue(_("Foreground level too high"));
445  }
446  else if (backgrounddB > DB_MAX_LIMIT) {
447  mPassFailText->ChangeValue(_("Background level too high"));
448  }
449  else if (backgrounddB > foregrounddB) {
450  mPassFailText->ChangeValue(_("Background higher than foreground"));
451  }
452  else if(diffdB > WCAG2_PASS) {
453  /* i18n-hint: WCAG abbreviates Web Content Accessibility Guidelines */
454  mPassFailText->ChangeValue(_("WCAG2 Pass"));
455  }
456  else {
457  /* i18n-hint: WCAG abbreviates Web Content Accessibility Guidelines */
458  mPassFailText->ChangeValue(_("WCAG2 Fail"));
459  }
460 
461  /* i18n-hint: i.e. difference in loudness at the moment. */
462  mDiffText->SetName(_("Current difference"));
463  mDiffText->ChangeValue( FormatDifference( diffdB ) );
464  }
465 
466  if (mForegroundIsDefined) {
467  mForegroundRMSText->SetName(_("Measured foreground level")); // Read by screen-readers
468  if(std::isinf(- foregrounddB))
469  mForegroundRMSText->ChangeValue(_("zero"));
470  else
471  mForegroundRMSText->ChangeValue(wxString::Format(_("%.2f dB"), foregrounddB)); // i18n-hint: short form of 'decibels'
472  }
473  else {
474  mForegroundRMSText->SetName(_("No foreground measured")); // Read by screen-readers
475  mForegroundRMSText->ChangeValue(wxT(""));
476  mPassFailText->ChangeValue(_("Foreground not yet measured"));
477  }
478 
479  if (mBackgroundIsDefined) {
480  mBackgroundRMSText->SetName(_("Measured background level"));
481  if(std::isinf(- backgrounddB))
482  mBackgroundRMSText->ChangeValue(_("zero"));
483  else
484  mBackgroundRMSText->ChangeValue(wxString::Format(_("%.2f dB"), backgrounddB));
485  }
486  else {
487  mBackgroundRMSText->SetName(_("No background measured"));
488  mBackgroundRMSText->ChangeValue(wxT(""));
489  mPassFailText->ChangeValue(_("Background not yet measured"));
490  }
491 }
492 
493 void ContrastDialog::OnExport(wxCommandEvent & WXUNUSED(event))
494 {
495  // TODO: Handle silence checks better (-infinity dB)
496  AudacityProject * project = GetActiveProject();
497  wxString fName = wxT("contrast.txt");
498 
500  _("Export Contrast Result As:"),
501  wxEmptyString,
502  fName,
503  wxT("txt"),
504  wxT("*.txt"),
505  wxFD_SAVE | wxRESIZE_BORDER,
506  this);
507 
508  if (fName == wxT(""))
509  return;
510 
511  wxTextFile f(fName);
512 #ifdef __WXMAC__
513  wxFile{}.Create(fName);
514 #else
515  f.Create();
516 #endif
517  f.Open();
518  if (!f.IsOpened()) {
520  wxString::Format( _("Couldn't write to file: %s"), fName) );
521  return;
522  }
523 
524  f.AddLine(wxT("==================================="));
525  /* i18n-hint: WCAG abbreviates Web Content Accessibility Guidelines */
526  f.AddLine(_("WCAG 2.0 Success Criteria 1.4.7 Contrast Results"));
527  f.AddLine(wxT(""));
528  f.AddLine(wxString::Format(_("Filename = %s."), project->GetFileName() ));
529  f.AddLine(wxT(""));
530  f.AddLine(_("Foreground"));
531  float t = (float)mForegroundStartT->GetValue();
532  int h = (int)(t/3600); // there must be a standard function for this!
533  int m = (int)((t - h*3600)/60);
534  float s = t - h*3600.0 - m*60.0;
535  f.AddLine(wxString::Format(_("Time started = %2d hour(s), %2d minute(s), %.2f seconds."), h, m, s ));
536  t = (float)mForegroundEndT->GetValue();
537  h = (int)(t/3600);
538  m = (int)((t - h*3600)/60);
539  s = t - h*3600.0 - m*60.0;
540  f.AddLine(wxString::Format(_("Time ended = %2d hour(s), %2d minute(s), %.2f seconds."), h, m, s ));
541  f.AddLine( FormatRMSMessage( mForegroundIsDefined ? &foregrounddB : nullptr ) );
542  f.AddLine(wxT(""));
543  f.AddLine(_("Background"));
544  t = (float)mBackgroundStartT->GetValue();
545  h = (int)(t/3600);
546  m = (int)((t - h*3600)/60);
547  s = t - h*3600.0 - m*60.0;
548  f.AddLine(wxString::Format(_("Time started = %2d hour(s), %2d minute(s), %.2f seconds."), h, m, s ));
549  t = (float)mBackgroundEndT->GetValue();
550  h = (int)(t/3600);
551  m = (int)((t - h*3600)/60);
552  s = t - h*3600.0 - m*60.0;
553  f.AddLine(wxString::Format(_("Time ended = %2d hour(s), %2d minute(s), %.2f seconds."), h, m, s ));
554  f.AddLine( FormatRMSMessage( mBackgroundIsDefined ? &backgrounddB : nullptr ) );
555  f.AddLine(wxT(""));
556  f.AddLine(_("Results"));
557  float diffdB = foregrounddB - backgrounddB;
558 
559  f.AddLine( FormatDifferenceForExport( diffdB ) );
560  if( diffdB > 20. )
561  f.AddLine(_("Success Criteria 1.4.7 of WCAG 2.0: Pass"));
562  else
563  f.AddLine(_("Success Criteria 1.4.7 of WCAG 2.0: Fail"));
564 
565  f.AddLine(wxT(""));
566  f.AddLine(_("Data gathered"));
567  wxString sNow;
568  wxDateTime now = wxDateTime::Now();
569  int year = now.GetYear();
570  wxDateTime::Month month = now.GetMonth();
571  wxString monthName = now.GetMonthName(month);
572  int dom = now.GetDay();
573  int hour = now.GetHour();
574  int minute = now.GetMinute();
575  int second = now.GetSecond();
576  sNow = wxString::Format(wxT("%d %s %02d %02dh %02dm %02ds"),
577  dom, monthName, year, hour, minute, second);
578  f.AddLine(sNow);
579 
580  f.AddLine(wxT("==================================="));
581  f.AddLine(wxT(""));
582 
583 #ifdef __WXMAC__
584  f.Write(wxTextFileType_Mac);
585 #else
586  f.Write();
587 #endif
588  f.Close();
589 }
590 
591 void ContrastDialog::OnReset(wxCommandEvent & /*event*/)
592 {
597  mForegroundIsDefined = false;
598  mBackgroundIsDefined = false;
599 
600  mForegroundRMSText->SetName(_("No foreground measured")); // Read by screen-readers
601  mBackgroundRMSText->SetName(_("No background measured"));
602  mForegroundRMSText->ChangeValue(wxT("")); // Displayed value
603  mBackgroundRMSText->ChangeValue(wxT(""));
604  mPassFailText->ChangeValue(wxT(""));
605  mDiffText->ChangeValue(wxT(""));
606 }
void OnClose(wxCommandEvent &event)
Definition: Contrast.cpp:335
double mProjectRate
Definition: Contrast.h:50
double t0() const
#define WCAG2_PASS
Definition: Contrast.cpp:40
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI...
Definition: ShuttleGui.h:409
SelectedRegion selectedRegion
Definition: ViewInfo.h:162
bool mForegroundIsDefined
Definition: Contrast.h:73
wxWindow * AddWindow(wxWindow *pWindow, int Flags=wxALIGN_CENTRE|wxALL)
Definition: ShuttleGui.cpp:288
double mT1
Definition: Contrast.h:49
void OnGetURL(wxCommandEvent &event)
Definition: Contrast.cpp:328
auto SelectedLeaders() -> TrackIterRange< TrackType >
Definition: Track.h:1297
wxTextCtrl * mDiffText
Definition: Contrast.h:69
wxButton * m_pButton_Export
Definition: Contrast.h:39
void EndMultiColumn()
wxString label
Definition: Tags.cpp:733
void results()
Definition: Contrast.cpp:434
int AudacityMessageBox(const wxString &message, const wxString &caption=AudacityMessageBoxCaptionStr(), long style=wxOK|wxCENTRE, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
Definition: ErrorDialog.h:92
#define DB_MAX_LIMIT
Definition: Contrast.cpp:39
void OnExport(wxCommandEvent &event)
Definition: Contrast.cpp:493
wxButton * m_pButton_UseCurrentF
Definition: Contrast.h:36
Options & AutoPos(bool enable)
double t1() const
wxButton * m_pButton_GetURL
Definition: Contrast.h:38
Wrap wxMessageDialog so that caption IS translatable.
Definition: ErrorDialog.h:129
wxTextCtrl * mForegroundRMSText
Definition: Contrast.h:66
wxTextCtrl * mPassFailText
Definition: Contrast.h:68
auto Selected() -> TrackIterRange< TrackType >
Definition: Track.h:1263
#define safenew
Definition: Audacity.h:230
void EndHorizontalLay()
void OnGetForeground(wxCommandEvent &event)
Definition: Contrast.cpp:343
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:174
wxTextCtrl * AddTextBox(const wxString &Caption, const wxString &Value, const int nChars)
Definition: ShuttleGui.cpp:548
void SetStartAndEndTime()
Definition: Contrast.cpp:112
void OnReset(wxCommandEvent &event)
Definition: Contrast.cpp:591
NumericTextCtrl * mForegroundStartT
Definition: Contrast.h:43
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
wxTextCtrl * mBackgroundRMSText
Definition: Contrast.h:67
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
wxButton * m_pButton_UseCurrentB
Definition: Contrast.h:37
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
ShuttleGui & Id(int id)
ViewInfo mViewInfo
Definition: Project.h:555
static void ShowHelp(wxWindow *parent, const wxString &localFileName, const wxString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Definition: HelpSystem.cpp:194
void AddFixedText(const wxString &Str, bool bCenter=false)
Definition: ShuttleGui.cpp:405
wxButton * m_pButton_Close
Definition: Contrast.h:41
bool GetDB(float &dB)
Definition: Contrast.cpp:43
void AddTitle(const wxString &Prompt)
Centred text string.
Definition: ShuttleGui.cpp:274
wxButton * m_pButton_Reset
Definition: Contrast.h:40
void SetValue(double newValue)
void OnGetBackground(wxCommandEvent &event)
Definition: Contrast.cpp:358
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
ContrastDialog(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &pos)
Definition: Contrast.cpp:169
teShuttleMode GetMode()
Definition: ShuttleGui.h:425
double mT0
Definition: Contrast.h:48
static wxString SelectFile(Operation op, const wxString &message, const wxString &default_path, const wxString &default_filename, const wxString &default_extension, const wxString &wildcard, int flags, wxWindow *parent)
Definition: FileNames.cpp:427
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
#define LINEAR_TO_DB(x)
Definition: Audacity.h:217
Options & ReadOnly(bool enable)
AUDACITY_DLL_API AudacityProject * GetActiveProject()
Definition: Project.cpp:311
float foregrounddB
Definition: Contrast.h:71
wxStaticBox * StartStatic(const wxString &Str, int iProp=0)
Definition: ShuttleGui.cpp:771
static NumericFormatId HundredthsFormat()
static void OnChar(wxKeyEvent &event)
Definition: Contrast.cpp:154
void AddStandardButtons(long buttons=eOkButton|eCancelButton, wxButton *extra=NULL)
double GetRate() const
Definition: Project.h:216
END_EVENT_TABLE()
TrackList * GetTracks()
Definition: Project.h:209
Options & MenuEnabled(bool enable)
NumericTextCtrl * mBackgroundStartT
Definition: Contrast.h:45
float backgrounddB
Definition: Contrast.h:72
void SetBorder(int Border)
Definition: ShuttleGui.h:286
const wxString & GetFileName()
Definition: Project.h:319
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1356
NumericTextCtrl * mForegroundEndT
Definition: Contrast.h:44
wxButton * AddButton(const wxString &Text, int PositionFlags=wxALIGN_CENTRE)
Definition: ShuttleGui.cpp:349
bool mBackgroundIsDefined
Definition: Contrast.h:74
void SetStretchyCol(int i)
Used to modify an already placed FlexGridSizer to make a column stretchy.
Definition: ShuttleGui.cpp:203
NumericTextCtrl * mBackgroundEndT
Definition: Contrast.h:46