mirror of
https://github.com/cookiengineer/audacity
synced 2026-02-09 05:01:57 +01:00
Locate and position the current Audacity source code, and clear a variety of old junk out of the way into junk-branches
This commit is contained in:
153
src/commands/CompareAudioCommand.cpp
Normal file
153
src/commands/CompareAudioCommand.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity - A Digital Audio Editor
|
||||
Copyright 1999-2009 Audacity Team
|
||||
License: wxwidgets
|
||||
|
||||
Dan Horgan
|
||||
|
||||
******************************************************************//**
|
||||
|
||||
\file CompareAudioCommand.cpp
|
||||
\brief Contains definitions for CompareAudioCommand class
|
||||
|
||||
\class CompareAudioCommand
|
||||
\brief Returns information about the amount of audio that is about a certain
|
||||
threshold of difference in two selected tracks
|
||||
|
||||
*//*******************************************************************/
|
||||
|
||||
#include "CompareAudioCommand.h"
|
||||
#include "../Project.h"
|
||||
#include "Command.h"
|
||||
|
||||
wxString CompareAudioCommandType::BuildName()
|
||||
{
|
||||
return wxT("CompareAudio");
|
||||
}
|
||||
|
||||
void CompareAudioCommandType::BuildSignature(CommandSignature &signature)
|
||||
{
|
||||
DoubleValidator *thresholdValidator = new DoubleValidator();
|
||||
signature.AddParameter(wxT("Threshold"), 0.0, thresholdValidator);
|
||||
}
|
||||
|
||||
Command *CompareAudioCommandType::Create(CommandOutputTarget *target)
|
||||
{
|
||||
return new CompareAudioCommand(*this, target);
|
||||
}
|
||||
|
||||
// Update member variables with project selection data (and validate)
|
||||
bool CompareAudioCommand::GetSelection(AudacityProject &proj)
|
||||
{
|
||||
// Get the selected time interval
|
||||
mT0 = proj.mViewInfo.sel0;
|
||||
mT1 = proj.mViewInfo.sel1;
|
||||
if (mT0 >= mT1)
|
||||
{
|
||||
Error(wxT("There is no selection!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the selected tracks and check that there are at least two to
|
||||
// compare
|
||||
SelectedTrackListOfKindIterator iter(Track::Wave, proj.GetTracks());
|
||||
mTrack0 = (WaveTrack*)(iter.First());
|
||||
if (mTrack0 == NULL)
|
||||
{
|
||||
Error(wxT("No tracks selected! Select two tracks to compare."));
|
||||
return false;
|
||||
}
|
||||
mTrack1 = (WaveTrack*)(iter.Next());
|
||||
if (mTrack1 == NULL)
|
||||
{
|
||||
Error(wxT("Only one track selected! Select two tracks to compare."));
|
||||
return false;
|
||||
}
|
||||
if (iter.Next() != NULL)
|
||||
{
|
||||
Status(wxT("More than two tracks selected - only the first two will be compared."));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
double CompareAudioCommand::CompareSample(double value1, double value2)
|
||||
{
|
||||
return fabs(value1 - value2);
|
||||
}
|
||||
|
||||
inline int min(int a, int b)
|
||||
{
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
|
||||
bool CompareAudioCommand::Apply(CommandExecutionContext context)
|
||||
{
|
||||
if (!GetSelection(*context.proj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
wxString msg = wxT("Comparing tracks '");
|
||||
msg += mTrack0->GetName() + wxT("' and '")
|
||||
+ mTrack1->GetName() + wxT("'.");
|
||||
Status(msg);
|
||||
|
||||
long errorCount = 0;
|
||||
double errorThreshold = GetDouble(wxT("Threshold"));
|
||||
|
||||
// Initialize buffers for track data to be analyzed
|
||||
int buffSize = min(mTrack0->GetMaxBlockSize(), mTrack1->GetMaxBlockSize());
|
||||
float *buff0 = new float[buffSize];
|
||||
float *buff1 = new float[buffSize];
|
||||
|
||||
// Compare tracks block by block
|
||||
long s0 = mTrack0->TimeToLongSamples(mT0);
|
||||
long s1 = mTrack0->TimeToLongSamples(mT1);
|
||||
long position = s0;
|
||||
long length = s1 - s0;
|
||||
while (position < s1)
|
||||
{
|
||||
// Get a block of data into the buffers
|
||||
sampleCount block = mTrack0->GetBestBlockSize(position);
|
||||
if (position + block > s1)
|
||||
{
|
||||
block = s1 - position;
|
||||
}
|
||||
mTrack0->Get((samplePtr)buff0, floatSample, position, block);
|
||||
mTrack1->Get((samplePtr)buff1, floatSample, position, block);
|
||||
|
||||
int buffPos = 0;
|
||||
for (buffPos = 0; buffPos < block; ++buffPos)
|
||||
{
|
||||
if (CompareSample(buff0[buffPos], buff1[buffPos]) > errorThreshold)
|
||||
{
|
||||
++errorCount;
|
||||
}
|
||||
}
|
||||
|
||||
position += block;
|
||||
Progress((position - mT0) / length);
|
||||
}
|
||||
|
||||
delete [] buff0;
|
||||
delete [] buff1;
|
||||
|
||||
// Output the results
|
||||
double errorSeconds = mTrack0->LongSamplesToTime(errorCount);
|
||||
Status(wxString::Format(wxT("%i"), errorCount));
|
||||
Status(wxString::Format(wxT("%.4f"), errorSeconds));
|
||||
Status(wxString::Format(wxT("Finished comparison: %i samples (%.3f seconds) exceeded the error threshold of %f."), errorCount, errorSeconds, errorThreshold));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
|
||||
// version control system. Please do not modify past this point.
|
||||
//
|
||||
// Local Variables:
|
||||
// c-basic-offset: 3
|
||||
// indent-tabs-mode: nil
|
||||
// End:
|
||||
//
|
||||
// vim: et sts=3 sw=3
|
||||
// arch-tag: TBD
|
||||
Reference in New Issue
Block a user