Audacity  2.2.2
CompareAudioCommand.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity - A Digital Audio Editor
4  Copyright 1999-2009 Audacity Team
5  License: wxwidgets
6 
7  Dan Horgan
8 
9 ******************************************************************//*******************************************************************/
19 
20 #include "CompareAudioCommand.h"
21 #include "../Project.h"
22 #include "Command.h"
23 #include "../WaveTrack.h"
24 
26 {
27  return wxT("CompareAudio");
28 }
29 
31 {
32  auto thresholdValidator = make_movable<DoubleValidator>();
33  signature.AddParameter(wxT("Threshold"), 0.0, std::move(thresholdValidator));
34 }
35 
36 CommandHolder CompareAudioCommandType::Create(std::unique_ptr<CommandOutputTarget> &&target)
37 {
38  return std::make_shared<CompareAudioCommand>(*this, std::move(target));
39 }
40 
41 // Update member variables with project selection data (and validate)
43 {
44  // Get the selected time interval
45  mT0 = proj.mViewInfo.selectedRegion.t0();
46  mT1 = proj.mViewInfo.selectedRegion.t1();
47  if (mT0 >= mT1)
48  {
49  Error(wxT("There is no selection!"));
50  return false;
51  }
52 
53  // Get the selected tracks and check that there are at least two to
54  // compare
56  mTrack0 = (WaveTrack*)(iter.First());
57  if (mTrack0 == NULL)
58  {
59  Error(wxT("No tracks selected! Select two tracks to compare."));
60  return false;
61  }
62  mTrack1 = (WaveTrack*)(iter.Next());
63  if (mTrack1 == NULL)
64  {
65  Error(wxT("Only one track selected! Select two tracks to compare."));
66  return false;
67  }
68  if (iter.Next() != NULL)
69  {
70  Status(wxT("More than two tracks selected - only the first two will be compared."));
71  }
72  return true;
73 }
74 
75 double CompareAudioCommand::CompareSample(double value1, double value2)
76 {
77  return fabs(value1 - value2);
78 }
79 
80 inline int min(int a, int b)
81 {
82  return (a < b) ? a : b;
83 }
84 
86 {
87  if (!GetSelection(*context.GetProject()))
88  {
89  return false;
90  }
91 
92  wxString msg = wxT("Comparing tracks '");
93  msg += mTrack0->GetName() + wxT("' and '")
94  + mTrack1->GetName() + wxT("'.");
95  Status(msg);
96 
97  long errorCount = 0;
98  double errorThreshold = GetDouble(wxT("Threshold"));
99 
100  // Initialize buffers for track data to be analyzed
101  auto buffSize = std::min(mTrack0->GetMaxBlockSize(), mTrack1->GetMaxBlockSize());
102 
103  Floats buff0{ buffSize };
104  Floats buff1{ buffSize };
105 
106  // Compare tracks block by block
107  auto s0 = mTrack0->TimeToLongSamples(mT0);
108  auto s1 = mTrack0->TimeToLongSamples(mT1);
109  auto position = s0;
110  auto length = s1 - s0;
111  while (position < s1)
112  {
113  // Get a block of data into the buffers
114  auto block = limitSampleBufferSize(
115  mTrack0->GetBestBlockSize(position), s1 - position
116  );
117  mTrack0->Get((samplePtr)buff0.get(), floatSample, position, block);
118  mTrack1->Get((samplePtr)buff1.get(), floatSample, position, block);
119 
120  for (decltype(block) buffPos = 0; buffPos < block; ++buffPos)
121  {
122  if (CompareSample(buff0[buffPos], buff1[buffPos]) > errorThreshold)
123  {
124  ++errorCount;
125  }
126  }
127 
128  position += block;
129  Progress(
130  (position - s0).as_double() /
131  length.as_double()
132  );
133  }
134 
135  // Output the results
136  double errorSeconds = mTrack0->LongSamplesToTime(errorCount);
137  Status(wxString::Format(wxT("%li"), errorCount));
138  Status(wxString::Format(wxT("%.4f"), errorSeconds));
139  Status(wxString::Format(wxT("Finished comparison: %li samples (%.3f seconds) exceeded the error threshold of %f."), errorCount, errorSeconds, errorThreshold));
140  return true;
141 }
double t0() const
const WaveTrack * mTrack1
SelectedRegion selectedRegion
Definition: ViewInfo.h:160
bool Get(samplePtr buffer, sampleFormat format, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true) const
Definition: WaveTrack.cpp:1950
double CompareSample(double value1, double value2)
std::shared_ptr< Command > CommandHolder
void AddParameter(const wxString &name, const wxVariant &dft, movable_ptr< Validator > &&valid)
Contains declaration of Command base class.
bool Apply(CommandExecutionContext context) override
double t1() const
size_t GetBestBlockSize(sampleCount t) const
Definition: WaveTrack.cpp:1586
Contains declaration of CompareAudioCommand and CompareAudioCommandType classes.
bool GetSelection(AudacityProject &proj)
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:161
double GetDouble(const wxString &paramName)
Definition: Command.cpp:156
const WaveTrack * mTrack0
CommandHolder Create(std::unique_ptr< CommandOutputTarget > &&target) override
void BuildSignature(CommandSignature &signature) override
Postcondition: signature is a 'signature' map containing parameter.
void Progress(double completed)
Definition: Command.cpp:173
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
void Status(const wxString &status) override
Definition: Command.cpp:178
ViewInfo mViewInfo
Definition: Project.h:545
int min(int a, int b)
wxString GetName() const
Definition: Track.h:212
size_t GetMaxBlockSize() const
Definition: WaveTrack.cpp:1604
sampleCount TimeToLongSamples(double t0) const
Convert correctly between an (absolute) time in seconds and a number of samples.
Definition: WaveTrack.cpp:1822
wxString BuildName() override
Represents a context to which a command may be applied.
Definition: Command.h:50
TrackList * GetTracks()
Definition: Project.h:177
double LongSamplesToTime(sampleCount pos) const
Convert correctly between an number of samples and an (absolute) time in seconds. ...
Definition: WaveTrack.cpp:1827
AudacityProject * GetProject() const
Definition: Command.h:60
Class that maps parameter names to default values and validators.
void Error(const wxString &message) override
Definition: Command.cpp:183