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