Fixes to Analyze Contrast

Now supports stereo tracks. Several tweaks to error messages,
validation logic, and accuracy improvements.
Includes a fix for summary64K (incorrect rms drawn on zoomed
out waveform).
This commit is contained in:
Steve Daulton 2016-06-21 22:05:49 +01:00
parent 04377f71c6
commit 03915b4438
5 changed files with 130 additions and 199 deletions

View File

@ -218,9 +218,11 @@ void *BlockFile::CalcSummary(samplePtr buffer, sampleCount len,
float min, max;
float sumsq;
double totalSquares = 0.0;
// Recalc 256 summaries
sumLen = (len + 255) / 256;
int summaries = 256;
for (i = 0; i < sumLen; i++) {
min = fbuffer[i * 256];
@ -238,19 +240,25 @@ void *BlockFile::CalcSummary(samplePtr buffer, sampleCount len,
max = f1;
}
totalSquares += sumsq;
float rms = (float)sqrt(sumsq / jcount);
summary256[i * 3] = min;
summary256[i * 3 + 1] = max;
summary256[i * 3 + 2] = rms;
summary256[i * 3 + 2] = rms; // The rms is correct, but this may be for less than 256 samples in last loop.
}
for (i = sumLen; i < mSummaryInfo.frames256; i++) {
// filling in the remaining bits with non-harming/contributing values
// rms values are not "non-harming", so keep count of them:
summaries--;
summary256[i * 3] = FLT_MAX; // min
summary256[i * 3 + 1] = -FLT_MAX; // max
summary256[i * 3 + 2] = 0.0f; // rms
}
// Calculate now while we can do it accurately
mRMS = sqrt(totalSquares/len);
// Recalc 64K summaries
sumLen = (len + 65535) / 65536;
@ -268,36 +276,32 @@ void *BlockFile::CalcSummary(samplePtr buffer, sampleCount len,
sumsq += r1*r1;
}
float rms = (float)sqrt(sumsq / 256); // the '256' is not quite right at the edges as not all summary256 entries will be filled with useful values
float rms = (float)sqrt(sumsq / (float)((i < sumLen -1)? 256.0 : summaries));
summary64K[i * 3] = min;
summary64K[i * 3 + 1] = max;
summary64K[i * 3 + 2] = rms;
}
for (i = sumLen; i < mSummaryInfo.frames64K; i++) {
wxASSERT_MSG(false, wxT("Out of data for mSummaryInfo")); // Do we ever get here?
summary64K[i * 3] = 0.0f; // probably should be FLT_MAX, need a test case
summary64K[i * 3 + 1] = 0.0f; // probably should be -FLT_MAX, need a test case
summary64K[i * 3 + 2] = 0.0f;
summary64K[i * 3 + 2] = 0.0f; // just padding
}
// Recalc block-level summary
// Recalc block-level summary (mRMS already calculated)
min = summary64K[0];
max = summary64K[1];
sumsq = (float)summary64K[2];
sumsq *= sumsq;
for (i = 1; i < sumLen; i++) {
if (summary64K[3*i] < min)
min = summary64K[3*i];
if (summary64K[3*i+1] > max)
max = summary64K[3*i+1];
float r1 = (float)summary64K[3*i+2];
sumsq += (r1*r1);
}
mMin = min;
mMax = max;
mRMS = sqrt(sumsq / sumLen);
delete[] fbuffer;

View File

@ -5364,26 +5364,10 @@ void AudacityProject::OnContrast()
if(!mContrastDialog)
{
wxPoint where;
where.x = 150;
where.y = 150;
mContrastDialog = new ContrastDialog(this, -1, _("Contrast Analysis (WCAG 2 compliance)"), where);
mContrastDialog->bFGset = false;
mContrastDialog->bBGset = false;
}
// Zero dialog boxes. Do we need to do this here?
if( !mContrastDialog->bFGset )
{
mContrastDialog->mForegroundStartT->SetValue(0.0);
mContrastDialog->mForegroundEndT->SetValue(0.0);
}
if( !mContrastDialog->bBGset )
{
mContrastDialog->mBackgroundStartT->SetValue(0.0);
mContrastDialog->mBackgroundEndT->SetValue(0.0);
}
mContrastDialog->CentreOnParent();

View File

@ -1976,6 +1976,8 @@ bool WaveTrack::GetMinMax(float *min, float *max,
bool WaveTrack::GetRMS(float *rms, double t0, double t1)
{
*rms = float(0.0);
if (t0 > t1)
return false;
@ -1990,7 +1992,10 @@ bool WaveTrack::GetRMS(float *rms, double t0, double t1)
{
WaveClip* clip = it->GetData();
if (t1 >= clip->GetStartTime() && t0 <= clip->GetEndTime())
// If t1 == clip->GetStartTime() or t0 == clip->GetEndTime(), then the clip
// is not inside the selection, so we don't want it.
// if (t1 >= clip->GetStartTime() && t0 <= clip->GetEndTime())
if (t1 > clip->GetStartTime() && t0 < clip->GetEndTime())
{
float cliprms;
sampleCount clipStart, clipEnd;

View File

@ -14,7 +14,6 @@
#include "../AudacityApp.h"
#include "../FFT.h"
#include "../WaveTrack.h"
#include "../Prefs.h"
#include "../Project.h"
@ -23,7 +22,7 @@
#include "../widgets/LinkingHtmlWindow.h"
#include "../widgets/HelpSystem.h"
#include "../widgets/NumericTextCtrl.h"
#include "FileDialog.h"
#include "../lib-src/FileDialog/FileDialog.h"
#include <cmath>
#include <limits>
@ -33,29 +32,12 @@
#define finite(x) _finite(x)
#endif
// all these headers may not be needed
#include <wx/file.h>
#include <wx/ffile.h>
#include <wx/bitmap.h>
#include <wx/brush.h>
#include <wx/button.h>
#include <wx/datetime.h>
#include <wx/dcmemory.h>
#include <wx/file.h>
#include <wx/image.h>
#include <wx/intl.h>
#include <wx/msgdlg.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/valtext.h>
#include <wx/log.h>
#include "../PlatformCompatibility.h"
#define DB_MIN_LIMIT -600.0 // Minimum dB level that we measure.
#define DB_MAX_LIMIT 0.0 // TODO: We should probably fail WCAG2 if audio is massively distorted.
#define DB_MAX_LIMIT 0.0 // Audio is massively distorted.
#define WCAG2_PASS 20.0 // dB difference required to pass WCAG2 test.
bool ContrastDialog::GetDB(float &dB)
@ -63,45 +45,40 @@ bool ContrastDialog::GetDB(float &dB)
float rms = float(0.0);
int numberSelecteTracks = 0;
// For stereo tracks: sqrt((mean(L)+mean(R))/2)
bool isStereo = false;
double meanSq = 0.0;
AudacityProject *p = GetActiveProject();
SelectedTrackListOfKindIterator iter(Track::Wave, p->GetTracks());
WaveTrack *t = (WaveTrack *) iter.First();
while (t) {
// TODO: Handle stereo tracks
numberSelecteTracks++;
if (numberSelecteTracks > 1) {
if (numberSelecteTracks > 1 && !isStereo) {
wxMessageDialog m(NULL, _("You can only measure one track at a time."), _("Error"), wxOK);
m.ShowModal();
return false;
}
isStereo = t->GetLinked();
if(mT0 > mT1)
{
wxMessageDialog m(NULL, _("Start time after end time!\nPlease enter reasonable times."), _("Error"), wxOK);
m.ShowModal();
return false;
}
wxASSERT(mT0 <= mT1);
// FIXME: See bugs 1361 and 1362
// Ignore whitespace beyond ends of track.
if(mT0 < t->GetStartTime())
mT0 = t->GetStartTime();
if(mT1 > t->GetEndTime())
mT1 = t->GetEndTime();
wxLogDebug(wxT("mT0 = %.20f mT1 = %.10f"),mT0 ,mT1);
// TODO: Let's use the actual selected samples
sampleCount SelT0 = t->TimeToLongSamples(mT0);
sampleCount SelT1 = t->TimeToLongSamples(mT1);
if(SelT0 > SelT1)
{
// FIXME: Bad error message. This should never happen.
wxMessageDialog m(NULL, _("Times are not reasonable!\nPlease enter reasonable times."), _("Error"), wxOK);
wxMessageDialog m(NULL, _("Invalid audio selection.\nPlease ensure that audio is selected."), _("Error"), wxOK);
m.ShowModal();
return false;
}
if(SelT0 == SelT1)
{
wxMessageDialog m(NULL, _("Nothing to measure.\nPlease select a section of a track."), _("Error"), wxOK);
@ -110,8 +87,12 @@ bool ContrastDialog::GetDB(float &dB)
}
((WaveTrack *)t)->GetRMS(&rms, mT0, mT1);
meanSq += rms * rms;
t = (WaveTrack *) iter.Next();
}
// TODO: This works for stereo, provided the audio clips are in both channels.
// We should really count gaps between clips as silence.
rms = (meanSq > 0.0)? sqrt(meanSq/(double)numberSelecteTracks) : 0.0;
if(numberSelecteTracks == 0) {
wxMessageDialog m(NULL, _("Please select an audio track."), _("Error"), wxOK);
@ -119,30 +100,17 @@ bool ContrastDialog::GetDB(float &dB)
return false;
}
dB = (rms < 1.0E-30)? DB_MIN_LIMIT : LINEAR_TO_DB(rms);
wxLogDebug(wxT("RMS = %g"), rms);
dB = (rms == 0.0)? -INFINITY : LINEAR_TO_DB(rms);
return true;
}
double ContrastDialog::GetStartTime()
void ContrastDialog::SetStartAndEndTime()
{
return(mT0);
AudacityProject *p = GetActiveProject();
mT0 = p->mViewInfo.selectedRegion.t0();
mT1 = p->mViewInfo.selectedRegion.t1();
}
void ContrastDialog::SetStartTime(double t)
{
mT0 = t;
}
double ContrastDialog::GetEndTime()
{
return(mT1);
}
void ContrastDialog::SetEndTime(double t)
{
mT1 = t;
}
// WDR: class implementations
@ -153,9 +121,7 @@ void ContrastDialog::SetEndTime(double t)
// WDR: event table for ContrastDialog
enum {
ID_BUTTON_GETFOREGROUND = 10001,
ID_BUTTON_GETBACKGROUND,
ID_BUTTON_USECURRENTF,
ID_BUTTON_USECURRENTF = 10001,
ID_BUTTON_USECURRENTB,
ID_BUTTON_GETURL,
ID_BUTTON_EXPORT,
@ -172,10 +138,8 @@ enum {
};
BEGIN_EVENT_TABLE(ContrastDialog,wxDialog)
EVT_BUTTON(ID_BUTTON_GETFOREGROUND, ContrastDialog::OnGetForegroundDB)
EVT_BUTTON(ID_BUTTON_GETBACKGROUND, ContrastDialog::OnGetBackgroundDB)
EVT_BUTTON(ID_BUTTON_USECURRENTF, ContrastDialog::OnUseSelectionF)
EVT_BUTTON(ID_BUTTON_USECURRENTB, ContrastDialog::OnUseSelectionB)
EVT_BUTTON(ID_BUTTON_USECURRENTF, ContrastDialog::OnGetForeground)
EVT_BUTTON(ID_BUTTON_USECURRENTB, ContrastDialog::OnGetBackground)
EVT_BUTTON(ID_BUTTON_GETURL, ContrastDialog::OnGetURL)
EVT_BUTTON(ID_BUTTON_EXPORT, ContrastDialog::OnExport)
EVT_BUTTON(ID_BUTTON_RESET, ContrastDialog::OnReset)
@ -191,6 +155,8 @@ ContrastDialog::ContrastDialog(wxWindow * parent, wxWindowID id,
{
SetName(GetTitle());
mT0 = 0.0;
mT1 = 0.0;
foregrounddB = 0.0;
backgrounddB = 0.0;
mForegroundIsDefined = false;
@ -264,7 +230,7 @@ ContrastDialog::ContrastDialog(wxWindow * parent, wxWindowID id,
S.AddWindow(mForegroundEndT);
m_pButton_UseCurrentF = S.Id(ID_BUTTON_USECURRENTF).AddButton(_("&Measure selection"));
mForegroundRMSText=S.Id(ID_FOREGROUNDDB_TEXT).AddTextBox(wxT(""), wxT(""), 12);
mForegroundRMSText=S.Id(ID_FOREGROUNDDB_TEXT).AddTextBox(wxT(""), wxT(""), 17);
mForegroundRMSText->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(ContrastDialog::OnChar));
//Background
@ -304,7 +270,7 @@ ContrastDialog::ContrastDialog(wxWindow * parent, wxWindowID id,
S.AddWindow(mBackgroundEndT);
m_pButton_UseCurrentB = S.Id(ID_BUTTON_USECURRENTB).AddButton(_("Mea&sure selection"));
mBackgroundRMSText = S.Id(ID_BACKGROUNDDB_TEXT).AddTextBox(wxT(""), wxT(""), 12);
mBackgroundRMSText = S.Id(ID_BACKGROUNDDB_TEXT).AddTextBox(wxT(""), wxT(""), 17);
mBackgroundRMSText->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(ContrastDialog::OnChar));
}
S.EndMultiColumn();
@ -317,11 +283,11 @@ ContrastDialog::ContrastDialog(wxWindow * parent, wxWindowID id,
S.StartMultiColumn(3, wxCENTER);
{
S.AddFixedText(_("Co&ntrast Result:"));
mPassFailText = S.Id(ID_RESULTS_TEXT).AddTextBox(wxT(""), wxT(""), 40);
mPassFailText = S.Id(ID_RESULTS_TEXT).AddTextBox(wxT(""), wxT(""), 50);
mPassFailText->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(ContrastDialog::OnChar));
m_pButton_Reset = S.Id(ID_BUTTON_RESET).AddButton(_("R&eset"));
S.AddFixedText(_("&Difference:"));
mDiffText = S.Id(ID_RESULTSDB_TEXT).AddTextBox(wxT(""), wxT(""), 30);
mDiffText = S.Id(ID_RESULTSDB_TEXT).AddTextBox(wxT(""), wxT(""), 50);
mDiffText->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(ContrastDialog::OnChar));
m_pButton_Export = S.Id(ID_BUTTON_EXPORT).AddButton(_("E&xport..."));
}
@ -350,24 +316,6 @@ ContrastDialog::~ContrastDialog()
mDiffText->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(ContrastDialog::OnChar));
}
void ContrastDialog::OnGetForegroundDB( wxCommandEvent & WXUNUSED(event))
{
SetStartTime(mForegroundStartT->GetValue()); // FIXME: See bug 1362
SetEndTime(mForegroundEndT->GetValue());
mForegroundIsDefined = GetDB(foregrounddB);
m_pButton_UseCurrentF->SetFocus();
results();
}
void ContrastDialog::OnGetBackgroundDB( wxCommandEvent & WXUNUSED(event))
{
SetStartTime(mBackgroundStartT->GetValue()); // FIXME: See bug 1362
SetEndTime(mBackgroundEndT->GetValue());
mBackgroundIsDefined = GetDB(backgrounddB);
m_pButton_UseCurrentB->SetFocus();
results();
}
void ContrastDialog::OnGetURL(wxCommandEvent & WXUNUSED(event))
{
// Original help page is back on-line (March 2016), but the manual should be more reliable.
@ -377,62 +325,95 @@ void ContrastDialog::OnGetURL(wxCommandEvent & WXUNUSED(event))
void ContrastDialog::OnClose(wxCommandEvent & WXUNUSED(event))
{
wxCommandEvent dummyEvent;
OnReset(dummyEvent);
Show(false);
}
void ContrastDialog::OnUseSelectionF(wxCommandEvent & event)
void ContrastDialog::OnGetForeground(wxCommandEvent & event)
{
// FIXME: Give this function a more appropriate name (if we need it at all).
AudacityProject *p = GetActiveProject();
// FIXME: Why not SelectedTrackListOfKindIterator
TrackListIterator iter(p->GetTracks());
Track *t = iter.First();
while (t) {
if (t->GetSelected() && t->GetKind() == Track::Wave) {
// FIXME: See bug 1362
mForegroundStartT->SetValue(p->mViewInfo.selectedRegion.t0());
mForegroundEndT->SetValue(p->mViewInfo.selectedRegion.t1());
break;
}
t = iter.Next();
SelectedTrackListOfKindIterator iter(Track::Wave, p->GetTracks());
for (Track *t = iter.First(); t; t = iter.Next()) {
mForegroundStartT->SetValue(p->mViewInfo.selectedRegion.t0());
mForegroundEndT->SetValue(p->mViewInfo.selectedRegion.t1());
}
bFGset = true;
OnGetForegroundDB(event);
SetStartAndEndTime();
mForegroundIsDefined = GetDB(foregrounddB);
m_pButton_UseCurrentF->SetFocus();
results();
}
void ContrastDialog::OnUseSelectionB(wxCommandEvent & event)
void ContrastDialog::OnGetBackground(wxCommandEvent & event)
{
// FIXME: Give this function a more appropriate name.
AudacityProject *p = GetActiveProject();
// FIXME: Why not SelectedTrackListOfKindIterator
TrackListIterator iter(p->GetTracks());
Track *t = iter.First();
while (t) {
if (t->GetSelected() && t->GetKind() == Track::Wave) {
// FIXME: See bug 1362
mBackgroundStartT->SetValue(p->mViewInfo.selectedRegion.t0());
mBackgroundEndT->SetValue(p->mViewInfo.selectedRegion.t1());
break;
}
t = iter.Next();
SelectedTrackListOfKindIterator iter(Track::Wave, p->GetTracks());
for (Track *t = iter.First(); t; t = iter.Next()) {
mBackgroundStartT->SetValue(p->mViewInfo.selectedRegion.t0());
mBackgroundEndT->SetValue(p->mViewInfo.selectedRegion.t1());
}
bBGset = true;
OnGetBackgroundDB(event);
SetStartAndEndTime();
mBackgroundIsDefined = GetDB(backgrounddB);
m_pButton_UseCurrentB->SetFocus();
results();
}
void ContrastDialog::results()
{
// TODO: We check for absolute silence here, so should not need to check again later in ::results()
mPassFailText->SetName(wxT(""));
mPassFailText->ChangeValue(wxT(""));
mDiffText->ChangeValue(wxT(""));
// foreground and background defined.
if(mForegroundIsDefined && mBackgroundIsDefined) {
float diffdB = std::fabs(foregrounddB - backgrounddB);
if(foregrounddB > DB_MAX_LIMIT) {
mPassFailText->ChangeValue(_("Foreground level too high"));
}
else if (backgrounddB > DB_MAX_LIMIT) {
mPassFailText->ChangeValue(_("Background level too high"));
}
else if (backgrounddB > foregrounddB) {
mPassFailText->ChangeValue(_("Background higher than foreground"));
}
else if(diffdB > WCAG2_PASS) {
mPassFailText->ChangeValue(_("WCAG2 Pass"));
}
else {
mPassFailText->ChangeValue(_("WCAG2 Fail"));
}
/* i18n-hint: i.e. difference in loudness at the moment. */
mDiffText->SetName(_("Current difference"));
if( diffdB != diffdB ) { // test for NaN, reliant on IEEE implementation
mDiffText->ChangeValue(wxString::Format(_("indeterminate")));
}
else {
if( diffdB != std::numeric_limits<float>::infinity() ) {
mDiffText->ChangeValue(wxString::Format(_("%.2f dB Average RMS"), diffdB));
}
else {
mDiffText->ChangeValue(wxString::Format(_("Infinite dB difference")));
}
}
}
if (mForegroundIsDefined) {
mForegroundRMSText->SetName(_("Measured foreground level")); // Read by screen-readers
if(std::isinf(- foregrounddB))
mForegroundRMSText->ChangeValue(wxString::Format(_("zero")));
else
mForegroundRMSText->ChangeValue(wxString::Format(_("%.1f dB"), foregrounddB)); // i18n-hint: short form of 'decibels'
mForegroundRMSText->ChangeValue(wxString::Format(_("%.2f dB"), foregrounddB)); // i18n-hint: short form of 'decibels'
}
else {
mForegroundRMSText->SetName(_("No foreground measured")); // Read by screen-readers
mForegroundRMSText->ChangeValue(wxString::Format(wxT("")));
mForegroundRMSText->ChangeValue(wxT(""));
mPassFailText->ChangeValue(wxString::Format(_("Foreground not yet measured")));
}
if (mBackgroundIsDefined) {
@ -440,42 +421,12 @@ void ContrastDialog::results()
if(std::isinf(- backgrounddB))
mBackgroundRMSText->ChangeValue(wxString::Format(_("zero")));
else
mBackgroundRMSText->ChangeValue(wxString::Format(_("%.1f dB"), backgrounddB));
mBackgroundRMSText->ChangeValue(wxString::Format(_("%.2f dB"), backgrounddB));
}
else {
mBackgroundRMSText->SetName(_("No background measured"));
mBackgroundRMSText->ChangeValue(wxString::Format(wxT("")));
}
if(mForegroundIsDefined && mBackgroundIsDefined) {
/* i18n-hint: i.e. difference in loudness at the moment. */
mDiffText->SetName(_("Current difference"));
float diffdB = foregrounddB - backgrounddB;
if(diffdB > WCAG2_PASS) {
mPassFailText->ChangeValue(_("WCAG2 Pass"));
}
else {
mPassFailText->ChangeValue(_("WCAG2 Fail"));
}
// TODO: Check earlier for absolute silence.
if( diffdB != diffdB ) { // test for NaN, reliant on IEEE implementation
mDiffText->ChangeValue(wxString::Format(_("indeterminate")));
}
else {
if( fabs(diffdB) != std::numeric_limits<float>::infinity() ) {
mDiffText->ChangeValue(wxString::Format(_("%.1f dB Average RMS"), diffdB));
}
else {
mDiffText->ChangeValue(wxString::Format(_("infinite dB difference")));
}
}
}
else {
mPassFailText->SetName(wxT(""));
// FIXME: This happens too often. How do we really get here?
mPassFailText->ChangeValue(_("Please enter valid times."));
mDiffText->ChangeValue(wxT(""));
mBackgroundRMSText->ChangeValue(wxT(""));
mPassFailText->ChangeValue(wxString::Format(_("Background not yet measured")));
}
}
@ -526,7 +477,7 @@ void ContrastDialog::OnExport(wxCommandEvent & WXUNUSED(event))
f.AddLine(wxString::Format(_("Time ended = %2d hour(s), %2d minute(s), %.2f seconds."), h, m, s ));
if(mForegroundIsDefined)
if( fabs(foregrounddB) != std::numeric_limits<float>::infinity() )
f.AddLine(wxString::Format(_("Average RMS = %.1f dB."), foregrounddB ));
f.AddLine(wxString::Format(_("Average RMS = %.2f dB."), foregrounddB ));
else
f.AddLine(wxString::Format(_("Average RMS = zero.") ));
else
@ -545,7 +496,7 @@ void ContrastDialog::OnExport(wxCommandEvent & WXUNUSED(event))
f.AddLine(wxString::Format(_("Time ended = %2d hour(s), %2d minute(s), %.2f seconds."), h, m, s ));
if(mBackgroundIsDefined)
if( fabs(backgrounddB) != std::numeric_limits<float>::infinity() )
f.AddLine(wxString::Format(_("Average RMS = %.1f dB."), backgrounddB ));
f.AddLine(wxString::Format(_("Average RMS = %.2f dB."), backgrounddB ));
else
f.AddLine(wxString::Format(_("Average RMS = zero.") ));
else
@ -557,7 +508,7 @@ void ContrastDialog::OnExport(wxCommandEvent & WXUNUSED(event))
f.AddLine(wxString::Format(_("Difference is indeterminate.") ));
else
if( fabs(diffdB) != std::numeric_limits<float>::infinity() )
f.AddLine(wxString::Format(_("Difference = %.1f Average RMS dB."), diffdB ));
f.AddLine(wxString::Format(_("Difference = %.2f Average RMS dB."), diffdB ));
else
f.AddLine(wxString::Format(_("Difference = infinite Average RMS dB.")));
if( diffdB > 20. )
@ -593,18 +544,15 @@ void ContrastDialog::OnExport(wxCommandEvent & WXUNUSED(event))
void ContrastDialog::OnReset(wxCommandEvent & event)
{
bFGset = false; // TODO: Is this necessary?
bBGset = false; // TODO: Is this necessary?
mForegroundStartT->SetValue(0.0); // FIXME: See bug 1361
mForegroundEndT->SetValue(0.0); // FIXME: See bug 1361
mBackgroundStartT->SetValue(0.0); // FIXME: See bug 1361
mBackgroundEndT->SetValue(0.0); // FIXME: See bug 1361
mForegroundStartT->SetValue(0.0);
mForegroundEndT->SetValue(0.0);
mBackgroundStartT->SetValue(0.0);
mBackgroundEndT->SetValue(0.0);
mForegroundIsDefined = false;
mBackgroundIsDefined = false;
mForegroundRMSText->SetName(_("No foreground measured")); // Read by screen-readers
mForegroundRMSText->SetName(_("No background measured"));
mBackgroundRMSText->SetName(_("No background measured"));
mForegroundRMSText->ChangeValue(wxT("")); // Displayed value
mBackgroundRMSText->ChangeValue(wxT(""));
mPassFailText->ChangeValue(wxT(""));
@ -613,6 +561,7 @@ void ContrastDialog::OnReset(wxCommandEvent & event)
void ContrastDialog::OnChar(wxKeyEvent & event)
{
// Is this still required?
if (event.GetKeyCode() == WXK_TAB) {
event.Skip();
return;

View File

@ -10,7 +10,6 @@
#define __AUDACITY_CONTRAST_DIALOG__
#include <wx/dialog.h>
#include <wx/slider.h>
class wxButton;
class wxSizer;
@ -35,9 +34,6 @@ public:
const wxString & title, const wxPoint & pos);
~ContrastDialog();
void OnGetForegroundDB( wxCommandEvent &event );
void OnGetBackgroundDB( wxCommandEvent &event );
wxButton * m_pButton_UseCurrentF;
wxButton * m_pButton_UseCurrentB;
wxButton * m_pButton_GetURL;
@ -50,8 +46,6 @@ public:
NumericTextCtrl *mBackgroundStartT;
NumericTextCtrl *mBackgroundEndT;
bool bFGset;
bool bBGset;
double mT0;
double mT1;
double mProjectRate;
@ -64,10 +58,8 @@ private:
// handlers
void OnGetURL(wxCommandEvent &event);
void OnExport(wxCommandEvent &event);
void OnForegroundStartT(wxCommandEvent & event);
void OnForegroundEndT(wxCommandEvent & event);
void OnUseSelectionF(wxCommandEvent & event);
void OnUseSelectionB(wxCommandEvent & event);
void OnGetForeground(wxCommandEvent & event);
void OnGetBackground(wxCommandEvent & event);
void results();
void OnReset(wxCommandEvent & event);
void OnClose(wxCommandEvent & event);
@ -87,10 +79,7 @@ private:
bool mDoBackground;
bool GetDB(float & dB);
double GetStartTime();
void SetStartTime(double);
double GetEndTime();
void SetEndTime(double);
void SetStartAndEndTime();
double length;