Audacity 3.2.0
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
13#include "Contrast.h"
14
15#include "../CommonCommandFlags.h"
16#include "WaveTrack.h"
17#include "Prefs.h"
18#include "Project.h"
19#include "ProjectFileIO.h"
20#include "ProjectRate.h"
21#include "../ProjectWindow.h"
22#include "SelectFile.h"
23#include "ShuttleGui.h"
24#include "FileNames.h"
25#include "ViewInfo.h"
26#include "HelpSystem.h"
27#include "../widgets/NumericTextCtrl.h"
28#include "AudacityMessageBox.h"
29#include "../widgets/VetoDialogHook.h"
30
31#include <cmath>
32#include <limits>
33
34#if defined(__WXMSW__) && !defined(__CYGWIN__)
35#include <float.h>
36#define finite(x) _finite(x)
37#endif
38
39#include <wx/button.h>
40#include <wx/valtext.h>
41#include <wx/log.h>
42#include <wx/wfstream.h>
43#include <wx/txtstrm.h>
44#include <wx/textctrl.h>
45
47
49
50#define DB_MAX_LIMIT 0.0 // Audio is massively distorted.
51#define WCAG2_PASS 20.0 // dB difference required to pass WCAG2 test.
52
53
54bool ContrastDialog::GetDB(float &dB)
55{
56 float rms = float(0.0);
57
58 // For stereo tracks: sqrt((mean(L)+mean(R))/2)
59 double meanSq = 0.0;
60
61 auto p = FindProjectFromWindow( this );
62 auto range =
64 auto numberSelectedTracks = range.size();
65 if (numberSelectedTracks > 1) {
67 nullptr,
68 XO("You can only measure one track at a time."),
69 XO("Error"),
70 wxOK);
71 m.ShowModal();
72 return false;
73 }
74 if(numberSelectedTracks == 0) {
76 nullptr,
77 XO("Please select an audio track."),
78 XO("Error"),
79 wxOK);
80 m.ShowModal();
81 return false;
82 }
83
84 const auto channels = TrackList::Channels( *range.begin() );
85 for ( auto t : channels ) {
86 wxASSERT(mT0 <= mT1);
87
88 // Ignore whitespace beyond ends of track.
89 if(mT0 < t->GetStartTime())
90 mT0 = t->GetStartTime();
91 if(mT1 > t->GetEndTime())
92 mT1 = t->GetEndTime();
93
94 auto SelT0 = t->TimeToLongSamples(mT0);
95 auto SelT1 = t->TimeToLongSamples(mT1);
96
97 if(SelT0 > SelT1)
98 {
100 nullptr,
101 XO("Invalid audio selection.\nPlease ensure that audio is selected."),
102 XO("Error"),
103 wxOK);
104 m.ShowModal();
105 return false;
106 }
107
108 if(SelT0 == SelT1)
109 {
111 nullptr,
112 XO("Nothing to measure.\nPlease select a section of a track."),
113 XO("Error"),
114 wxOK);
115 m.ShowModal();
116 return false;
117 }
118
119 // Don't throw in this analysis dialog
120 rms = t->GetRMS(mT0, mT1, false);
121 meanSq += rms * rms;
122 }
123 // TODO: This works for stereo, provided the audio clips are in both channels.
124 // We should really count gaps between clips as silence.
125 rms = (meanSq > 0.0)
126 ? sqrt( meanSq/static_cast<double>( channels.size() ) )
127 : 0.0;
128
129 // Gives warning C4056, Overflow in floating-point constant arithmetic
130 // -INFINITY is intentional here.
131 // Looks like we are stuck with this warning, as
132 // #pragma warning( disable : 4056)
133 // even around the whole function does not disable it successfully.
134
135 dB = (rms == 0.0)? -INFINITY : LINEAR_TO_DB(rms);
136 return true;
137}
138
140{
141 auto p = FindProjectFromWindow( this );
142 auto &selectedRegion = ViewInfo::Get( *p ).selectedRegion;
143 mT0 = selectedRegion.t0();
144 mT1 = selectedRegion.t1();
145}
146
147
148// WDR: class implementations
149
150//----------------------------------------------------------------------------
151// ContrastDialog
152//----------------------------------------------------------------------------
153
154// WDR: event table for ContrastDialog
155
156enum {
159 //ID_BUTTON_GETURL,
162 //ID_BUTTON_CLOSE,
172
173BEGIN_EVENT_TABLE(ContrastDialog,wxDialogWrapper)
181
182void ContrastDialog::OnChar(wxKeyEvent &event)
183{
184 // Is this still required?
185 if (event.GetKeyCode() == WXK_TAB) {
186 // pass to next handler
187 event.Skip();
188 return;
189 }
190
191 // ignore any other key
192 event.Skip(false);
193 return;
194}
195
196ContrastDialog::ContrastDialog(wxWindow * parent, wxWindowID id,
198 const wxPoint & pos):
199 wxDialogWrapper(parent, id, title, pos, wxDefaultSize,
200 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX )
201{
202 SetName();
203
204 mT0 = 0.0;
205 mT1 = 0.0;
206 foregrounddB = 0.0;
207 backgrounddB = 0.0;
208 mForegroundIsDefined = false;
209 mBackgroundIsDefined = false;
210
211 // NULL out the control members until the controls are created.
212 mForegroundStartT = NULL;
213 mForegroundEndT = NULL;
214 mBackgroundStartT = NULL;
215 mBackgroundEndT = NULL;
216 wxString number;
217
218 auto p = FindProjectFromWindow( this );
220
221 const auto options = NumericTextCtrl::Options{}
222 .AutoPos(true)
223 .MenuEnabled(false)
224 .ReadOnly(true);
225
226 ShuttleGui S(this, eIsCreating);
227
228 S.SetBorder(5);
229 S.StartHorizontalLay(wxCENTER, false);
230 {
231 S.AddTitle(
232 /* i18n-hint: RMS abbreviates root mean square, a certain averaging method */
233 XO("Contrast Analyzer, for measuring RMS volume differences between two selections of audio."));
234 }
235 S.EndHorizontalLay();
236 S.StartStatic( XO("Parameters") );
237 {
238 S.StartMultiColumn(5, wxEXPAND);
239 {
240
241 // Headings
242 S.AddFixedText( {} ); // spacer
243 S.AddFixedText(XO("Start"));
244 S.AddFixedText(XO("End"));
245 S.AddFixedText( {} ); // spacer
246 S.AddFixedText(XO("Volume "));
247
248 //Foreground
249 S.AddFixedText(XO("&Foreground:"), false);
250 if (S.GetMode() == eIsCreating)
251 {
254 S.GetParent(), ID_FOREGROUNDSTART_T,
257 0.0,
258 options);
259 }
260 S.Name(XO("Foreground start time"))
261 .AddWindow(mForegroundStartT);
262
263 if (S.GetMode() == eIsCreating)
264 {
267 S.GetParent(), ID_FOREGROUNDEND_T,
270 0.0,
271 options);
272 }
273 S.Name(XO("Foreground end time"))
274 .AddWindow(mForegroundEndT);
275
276 m_pButton_UseCurrentF = S.Id(ID_BUTTON_USECURRENTF).AddButton(XXO("&Measure selection"));
278 .ConnectRoot(wxEVT_KEY_DOWN,
280 .AddTextBox( {}, wxT(""), 17);
281
282 //Background
283 S.AddFixedText(XO("&Background:"));
284 if (S.GetMode() == eIsCreating)
285 {
288 S.GetParent(), ID_BACKGROUNDSTART_T,
291 0.0,
292 options);
293 }
294 S.Name(XO("Background start time"))
295 .AddWindow(mBackgroundStartT);
296
297 if (S.GetMode() == eIsCreating)
298 {
301 S.GetParent(), ID_BACKGROUNDEND_T,
304 0.0,
305 options);
306 }
307 S.Name(XO("Background end time"))
308 .AddWindow(mBackgroundEndT);
309
310 m_pButton_UseCurrentB = S.Id(ID_BUTTON_USECURRENTB).AddButton(XXO("Mea&sure selection"));
312 .ConnectRoot(wxEVT_KEY_DOWN,
314 .AddTextBox( {}, wxT(""), 17);
315 }
316 S.EndMultiColumn();
317 }
318 S.EndStatic();
319
320 //Result
321 S.StartStatic( XO("Result") );
322 {
323 S.StartMultiColumn(3, wxCENTER);
324 {
325 auto label = XO("Co&ntrast Result:");
326 S.AddFixedText(label);
328 .Name(label)
329 .ConnectRoot(wxEVT_KEY_DOWN,
331 .AddTextBox( {}, wxT(""), 50);
332 m_pButton_Reset = S.Id(ID_BUTTON_RESET).AddButton(XXO("R&eset"));
333
334 label = XO("&Difference:");
335 S.AddFixedText(label);
337 .Name(label)
338 .ConnectRoot(wxEVT_KEY_DOWN,
340 .AddTextBox( {}, wxT(""), 50);
341 m_pButton_Export = S.Id(ID_BUTTON_EXPORT).AddButton(XXO("E&xport..."));
342 }
343 S.EndMultiColumn();
344 }
345 S.EndStatic();
346 S.AddStandardButtons(eCloseButton |eHelpButton);
347#if 0
348 S.StartMultiColumn(3, wxEXPAND);
349 {
350 S.SetStretchyCol(1);
351 m_pButton_GetURL = S.Id(ID_BUTTON_GETURL).AddButton(XO("&Help"));
352 S.AddFixedText({}); // spacer
353 m_pButton_Close = S.Id(ID_BUTTON_CLOSE).AddButton(XO("&Close"));
354 }
355 S.EndMultiColumn();
356#endif
357 Layout();
358 Fit();
359 SetMinSize(GetSize());
360 Center();
361}
362
363void ContrastDialog::OnGetURL(wxCommandEvent & WXUNUSED(event))
364{
365 // Original help page is back on-line (March 2016), but the manual should be more reliable.
366 // http://www.eramp.com/WCAG_2_audio_contrast_tool_help.htm
367 HelpSystem::ShowHelp(this, L"Contrast");
368}
369
370void ContrastDialog::OnClose(wxCommandEvent & WXUNUSED(event))
371{
372 wxCommandEvent dummyEvent;
373 OnReset(dummyEvent);
374
375 Show(false);
376}
377
378void ContrastDialog::OnGetForeground(wxCommandEvent & /*event*/)
379{
380 auto p = FindProjectFromWindow( this );
381 auto &selectedRegion = ViewInfo::Get( *p ).selectedRegion;
382
383 if( TrackList::Get( *p ).Selected< const WaveTrack >() ) {
384 mForegroundStartT->SetValue(selectedRegion.t0());
385 mForegroundEndT->SetValue(selectedRegion.t1());
386 }
387
390 m_pButton_UseCurrentF->SetFocus();
391 results();
392}
393
394void ContrastDialog::OnGetBackground(wxCommandEvent & /*event*/)
395{
396 auto p = FindProjectFromWindow( this );
397 auto &selectedRegion = ViewInfo::Get( *p ).selectedRegion;
398
399 if( TrackList::Get( *p ).Selected< const WaveTrack >() ) {
400 mBackgroundStartT->SetValue(selectedRegion.t0());
401 mBackgroundEndT->SetValue(selectedRegion.t1());
402 }
403
406 m_pButton_UseCurrentB->SetFocus();
407 results();
408}
409
410namespace {
411 // PRL: I gathered formatting into these functions, and eliminated some
412 // repetitions, and removed the redundant word "Average" as applied to RMS.
413 // Should these variations in formats be collapsed further?
414
415 // Pass nullptr when value is not yet defined
417 {
418
419 /* i18n-hint: RMS abbreviates root mean square, a certain averaging method */
420 auto format0 = XO("RMS = %s.");
421
422 /* i18n-hint: dB abbreviates decibels */
423 auto format1 = XO("%s dB");
424
425 TranslatableString value;
426
427 if ( pValue ) {
428 if( fabs( *pValue ) != std::numeric_limits<float>::infinity() ) {
429 auto number = wxString::Format( wxT("%.2f"), *pValue );
430 value = format1.Format( number );
431 }
432 else
433 value = XO("zero");
434 }
435 else
436 value = format1.Format( "" );
437
438 return format0.Format( value );
439 }
440
442 {
443 if( diffdB != diffdB ) // test for NaN, reliant on IEEE implementation
444 return XO("indeterminate");
445 else {
446 if( diffdB != std::numeric_limits<float>::infinity() )
447 /* i18n-hint: dB abbreviates decibels
448 * RMS abbreviates root mean square, a certain averaging method */
449 return XO("%.2f dB RMS").Format( diffdB );
450 else
451 /* i18n-hint: dB abbreviates decibels */
452 return XO("Infinite dB difference");
453 }
454 }
455
457 {
458 if( diffdB != diffdB ) //test for NaN, reliant on IEEE implementation
459 return XO("Difference is indeterminate.");
460 else
461 if( fabs(diffdB) != std::numeric_limits<float>::infinity() )
462 /* i18n-hint: dB abbreviates decibels
463 RMS abbreviates root mean square, a certain averaging method */
464 return XO("Difference = %.2f RMS dB.").Format( diffdB );
465 else
466 /* i18n-hint: dB abbreviates decibels
467 RMS abbreviates root mean square, a certain averaging method */
468 return XO("Difference = infinite RMS dB.");
469 }
470}
471
473{
474 mPassFailText->SetName(wxT(""));
475 mPassFailText->ChangeValue(wxT(""));
476 mDiffText->ChangeValue(wxT(""));
477
478 // foreground and background defined.
480 float diffdB = std::fabs(foregrounddB - backgrounddB);
482 mPassFailText->ChangeValue(_("Foreground level too high"));
483 }
484 else if (backgrounddB > DB_MAX_LIMIT) {
485 mPassFailText->ChangeValue(_("Background level too high"));
486 }
487 else if (backgrounddB > foregrounddB) {
488 mPassFailText->ChangeValue(_("Background higher than foreground"));
489 }
490 else if(diffdB > WCAG2_PASS) {
491 /* i18n-hint: WCAG2 is the 'Web Content Accessibility Guidelines (WCAG) 2.0', see http://www.w3.org/TR/WCAG20/ */
492 mPassFailText->ChangeValue(_("WCAG2 Pass"));
493 }
494 else {
495 /* i18n-hint: WCAG abbreviates Web Content Accessibility Guidelines */
496 mPassFailText->ChangeValue(_("WCAG2 Fail"));
497 }
498
499 /* i18n-hint: i.e. difference in loudness at the moment. */
500 mDiffText->SetName(_("Current difference"));
501 mDiffText->ChangeValue( FormatDifference( diffdB ).Translation() );
502 }
503
505 mForegroundRMSText->SetName(_("Measured foreground level")); // Read by screen-readers
506 if(std::isinf(- foregrounddB))
507 mForegroundRMSText->ChangeValue(_("zero"));
508 else
509 // i18n-hint: short form of 'decibels'
510 mForegroundRMSText->ChangeValue(wxString::Format(_("%.2f dB"), foregrounddB));
511 }
512 else {
513 mForegroundRMSText->SetName(_("No foreground measured")); // Read by screen-readers
514 mForegroundRMSText->ChangeValue(wxT(""));
515 mPassFailText->ChangeValue(_("Foreground not yet measured"));
516 }
517
519 mBackgroundRMSText->SetName(_("Measured background level"));
520 if(std::isinf(- backgrounddB))
521 mBackgroundRMSText->ChangeValue(_("zero"));
522 else
523 mBackgroundRMSText->ChangeValue(wxString::Format(_("%.2f dB"), backgrounddB));
524 }
525 else {
526 mBackgroundRMSText->SetName(_("No background measured"));
527 mBackgroundRMSText->ChangeValue(wxT(""));
528 mPassFailText->ChangeValue(_("Background not yet measured"));
529 }
530}
531
532void ContrastDialog::OnExport(wxCommandEvent & WXUNUSED(event))
533{
534 // TODO: Handle silence checks better (-infinity dB)
535 auto project = FindProjectFromWindow( this );
536 wxString fName = wxT("contrast.txt");
537
538 fName = SelectFile(FileNames::Operation::Export,
539 XO("Export Contrast Result As:"),
540 wxEmptyString,
541 fName,
542 wxT("txt"),
544 wxFD_SAVE | wxRESIZE_BORDER,
545 this);
546
547 if (fName.empty())
548 return;
549
550 wxFFileOutputStream ffStream{ fName };
551
552 if (!ffStream.IsOk()) {
553 AudacityMessageBox( XO("Couldn't write to file: %s").Format( fName ) );
554 return;
555 }
556
557 wxTextOutputStream ss(ffStream);
558
559 ss
560 << wxT("===================================") << '\n'
561 /* i18n-hint: WCAG abbreviates Web Content Accessibility Guidelines */
562 << XO("WCAG 2.0 Success Criteria 1.4.7 Contrast Results") << '\n'
563 << '\n'
564 << XO("Filename = %s.").Format( ProjectFileIO::Get(*project).GetFileName() ) << '\n'
565 << '\n'
566 << XO("Foreground") << '\n';
567
568 float t = (float)mForegroundStartT->GetValue();
569 int h = (int)(t/3600); // there must be a standard function for this!
570 int m = (int)((t - h*3600)/60);
571 float s = t - h*3600.0 - m*60.0;
572
573 ss
574 << XO("Time started = %2d hour(s), %2d minute(s), %.2f seconds.")
575 .Format( h, m, s ) << '\n';
576
577 t = (float)mForegroundEndT->GetValue();
578 h = (int)(t/3600);
579 m = (int)((t - h*3600)/60);
580 s = t - h*3600.0 - m*60.0;
581
582 ss
583 << XO("Time ended = %2d hour(s), %2d minute(s), %.2f seconds.")
584 .Format( h, m, s ) << '\n'
585 << FormatRMSMessage( mForegroundIsDefined ? &foregrounddB : nullptr ) << '\n'
586 << '\n'
587 << XO("Background") << '\n';
588
589 t = (float)mBackgroundStartT->GetValue();
590 h = (int)(t/3600);
591 m = (int)((t - h*3600)/60);
592 s = t - h*3600.0 - m*60.0;
593
594 ss
595 << XO("Time started = %2d hour(s), %2d minute(s), %.2f seconds.")
596 .Format( h, m, s ) << '\n';
597
598 t = (float)mBackgroundEndT->GetValue();
599 h = (int)(t/3600);
600 m = (int)((t - h*3600)/60);
601 s = t - h*3600.0 - m*60.0;
602
603 ss
604 << XO("Time ended = %2d hour(s), %2d minute(s), %.2f seconds.")
605 .Format( h, m, s ) << '\n'
606 << FormatRMSMessage( mBackgroundIsDefined ? &backgrounddB : nullptr ) << '\n'
607 << '\n'
608 << XO("Results") << '\n';
609
610 float diffdB = foregrounddB - backgrounddB;
611
612 ss
613 << FormatDifferenceForExport( diffdB ) << '\n'
614 << (( diffdB > 20. )
615 ? XO("Success Criteria 1.4.7 of WCAG 2.0: Pass")
616 : XO("Success Criteria 1.4.7 of WCAG 2.0: Fail")) << '\n'
617 << '\n'
618 << XO("Data gathered") << '\n';
619
620 wxDateTime now = wxDateTime::Now();
621 int year = now.GetYear();
622 wxDateTime::Month month = now.GetMonth();
623 wxString monthName = now.GetMonthName(month);
624 int dom = now.GetDay();
625 int hour = now.GetHour();
626 int minute = now.GetMinute();
627 int second = now.GetSecond();
628 /* i18n-hint: day of month, month, year, hour, minute, second */
629 auto sNow = XO("%d %s %02d %02dh %02dm %02ds")
630 .Format( dom, monthName, year, hour, minute, second );
631
632 ss <<
633 sNow << '\n'
634 << wxT("===================================") << '\n'
635 << '\n';
636}
637
638void ContrastDialog::OnReset(wxCommandEvent & /*event*/)
639{
644 mForegroundIsDefined = false;
645 mBackgroundIsDefined = false;
646
647 mForegroundRMSText->SetName(_("No foreground measured")); // Read by screen-readers
648 mBackgroundRMSText->SetName(_("No background measured"));
649 mForegroundRMSText->ChangeValue(wxT("")); // Displayed value
650 mBackgroundRMSText->ChangeValue(wxT(""));
651 mPassFailText->ChangeValue(wxT(""));
652 mDiffText->ChangeValue(wxT(""));
653}
654
655// Remaining code hooks this add-on into the application
658#include "ProjectWindows.h"
659
660namespace {
661
662// Contrast window attached to each project is built on demand by:
663AttachedWindows::RegisteredFactory sContrastDialogKey{
664 []( AudacityProject &parent ) -> wxWeakRef< wxWindow > {
665 auto &window = ProjectWindow::Get( parent );
666 return safenew ContrastDialog(
667 &window, -1, XO("Contrast Analysis (WCAG 2 compliance)"),
668 wxPoint{ 150, 150 }
669 );
670 }
671};
672
673// Define our extra menu item that invokes that factory
674namespace {
675 void OnContrast(const CommandContext &context)
676 {
677 auto &project = context.project;
678 CommandManager::Get(project).RegisterLastAnalyzer(context); //Register Contrast as Last Analyzer
679 auto contrastDialog = &GetAttachedWindows(project)
681
682 contrastDialog->CentreOnParent();
683 if( VetoDialogHook::Call( contrastDialog ) )
684 return;
685 contrastDialog->Show();
686 }
687}
688
689// Register that menu item
690
691using namespace MenuTable;
692AttachedItem sAttachment{ wxT("Analyze/Analyzers/Windows"),
693 Command( wxT("ContrastAnalyser"), XXO("Contrast..."),
696 wxT("Ctrl+Shift+T") )
697};
698
699}
wxT("CloseDown"))
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
END_EVENT_TABLE()
const ReservedCommandFlag & AudioIONotBusyFlag()
const ReservedCommandFlag & TimeSelectedFlag()
const ReservedCommandFlag & WaveTracksSelectedFlag()
#define WCAG2_PASS
Definition: Contrast.cpp:51
@ ID_BACKGROUNDEND_T
Definition: Contrast.cpp:166
@ ID_FOREGROUNDDB_TEXT
Definition: Contrast.cpp:167
@ ID_BACKGROUNDSTART_T
Definition: Contrast.cpp:165
@ ID_BUTTON_RESET
Definition: Contrast.cpp:161
@ ID_BUTTON_USECURRENTF
Definition: Contrast.cpp:157
@ ID_BACKGROUNDDB_TEXT
Definition: Contrast.cpp:168
@ ID_RESULTSDB_TEXT
Definition: Contrast.cpp:170
@ ID_RESULTS_TEXT
Definition: Contrast.cpp:169
@ ID_BUTTON_USECURRENTB
Definition: Contrast.cpp:158
@ ID_FOREGROUNDSTART_T
Definition: Contrast.cpp:163
@ ID_FOREGROUNDEND_T
Definition: Contrast.cpp:164
@ ID_BUTTON_EXPORT
Definition: Contrast.cpp:160
#define DB_MAX_LIMIT
Definition: Contrast.cpp:50
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
#define _(s)
Definition: Internat.h:73
#define safenew
Definition: MemoryX.h:10
#define LINEAR_TO_DB(x)
Definition: MemoryX.h:562
static const auto title
const NumericConverterType & NumericConverterType_TIME()
an object holding per-project preferred sample rate
AudacityProject * FindProjectFromWindow(wxWindow *pWindow)
AUDACITY_DLL_API AttachedWindows & GetAttachedWindows(AudacityProject &project)
accessors for certain important windows associated with each project
FilePath SelectFile(FileNames::Operation op, const TranslatableString &message, const FilePath &default_path, const FilePath &default_filename, const FileExtension &default_extension, const FileTypes &fileTypes, int flags, wxWindow *parent)
Definition: SelectFile.cpp:17
@ eIsCreating
Definition: ShuttleGui.h:37
@ eCloseButton
Definition: ShuttleGui.h:604
@ eHelpButton
Definition: ShuttleGui.h:598
TranslatableString label
Definition: TagsEditor.cpp:164
#define S(N)
Definition: ToChars.cpp:64
int id
Wrap wxMessageDialog so that caption IS translatable.
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
size_t size() const
How many attachment pointers are in the Site.
Definition: ClientData.h:251
Subclass & Get(const RegisteredFactory &key)
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
Definition: ClientData.h:309
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
void RegisterLastAnalyzer(const CommandContext &context)
static CommandManager & Get(AudacityProject &project)
NumericTextCtrl * mBackgroundStartT
Definition: Contrast.h:43
wxButton * m_pButton_Close
Definition: Contrast.h:39
void OnClose(wxCommandEvent &event)
Definition: Contrast.cpp:370
bool mBackgroundIsDefined
Definition: Contrast.h:73
double mT0
Definition: Contrast.h:46
void OnChar(wxKeyEvent &event)
Definition: Contrast.cpp:182
NumericTextCtrl * mBackgroundEndT
Definition: Contrast.h:44
wxTextCtrl * mBackgroundRMSText
Definition: Contrast.h:66
wxButton * m_pButton_UseCurrentB
Definition: Contrast.h:35
void OnExport(wxCommandEvent &event)
Definition: Contrast.cpp:532
void OnGetBackground(wxCommandEvent &event)
Definition: Contrast.cpp:394
ContrastDialog(wxWindow *parent, wxWindowID id, const TranslatableString &title, const wxPoint &pos)
Definition: Contrast.cpp:196
double mProjectRate
Definition: Contrast.h:48
bool mForegroundIsDefined
Definition: Contrast.h:72
void SetStartAndEndTime()
Definition: Contrast.cpp:139
void results()
Definition: Contrast.cpp:472
double mT1
Definition: Contrast.h:47
NumericTextCtrl * mForegroundStartT
Definition: Contrast.h:41
bool GetDB(float &dB)
Definition: Contrast.cpp:54
void OnReset(wxCommandEvent &event)
Definition: Contrast.cpp:638
wxButton * m_pButton_Export
Definition: Contrast.h:37
void OnGetURL(wxCommandEvent &event)
Definition: Contrast.cpp:363
float foregrounddB
Definition: Contrast.h:70
wxTextCtrl * mForegroundRMSText
Definition: Contrast.h:65
wxButton * m_pButton_Reset
Definition: Contrast.h:38
wxTextCtrl * mDiffText
Definition: Contrast.h:68
wxButton * m_pButton_UseCurrentF
Definition: Contrast.h:34
NumericTextCtrl * mForegroundEndT
Definition: Contrast.h:42
float backgrounddB
Definition: Contrast.h:71
void OnGetForeground(wxCommandEvent &event)
Definition: Contrast.cpp:378
wxTextCtrl * mPassFailText
Definition: Contrast.h:67
wxButton * m_pButton_GetURL
Definition: Contrast.h:36
FILES_API const FileType AllFiles
Definition: FileNames.h:70
FILES_API const FileType TextFiles
Definition: FileNames.h:73
Abstract base class used in importing a file.
static FormatterContext SampleRateContext(double sampleRate)
static result_type Call(Arguments &&...arguments)
Null check of the installed function is done for you.
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Definition: HelpSystem.cpp:233
void SetValue(double newValue)
static ProjectFileIO & Get(AudacityProject &project)
const FilePath & GetFileName() const
static ProjectRate & Get(AudacityProject &project)
Definition: ProjectRate.cpp:28
double GetRate() const
Definition: ProjectRate.cpp:53
static ProjectWindow & Get(AudacityProject &project)
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:625
auto SelectedLeaders() -> TrackIterRange< TrackType >
Definition: Track.h:1353
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:360
auto Selected() -> TrackIterRange< TrackType >
Definition: Track.h:1319
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1406
Holds a msgid for the translation catalog; may also bind format arguments.
TranslatableString & Format(Args &&...args) &
Capture variadic format arguments (by copy) when there is no plural.
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:219
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
A Track that contains audio waveform data.
Definition: WaveTrack.h:51
#define INFINITY
constexpr auto Command
NUMERIC_FORMATS_API NumericFormatSymbol HundredthsFormat()
TranslatableString FormatRMSMessage(float *pValue)
Definition: Contrast.cpp:416
AttachedWindows::RegisteredFactory sContrastDialogKey
Definition: Contrast.cpp:663
TranslatableString FormatDifferenceForExport(float diffdB)
Definition: Contrast.cpp:456
TranslatableString FormatDifference(float diffdB)
Definition: Contrast.cpp:441
__finl float_x4 __vecc sqrt(const float_x4 &a)
Options & MenuEnabled(bool enable)
Options & AutoPos(bool enable)
Options & ReadOnly(bool enable)