Audacity  3.0.3
FindClipping.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  FindClipping.cpp
6 
7  Leland Lucius
8 
9 *******************************************************************//****************************************************************//*******************************************************************/
20 
21 
22 
23 #include "FindClipping.h"
24 #include "LoadEffects.h"
25 
26 #include <math.h>
27 
28 #include <wx/intl.h>
29 
30 #include "../Shuttle.h"
31 #include "../ShuttleGui.h"
32 #include "../widgets/valnum.h"
33 #include "../widgets/AudacityMessageBox.h"
34 
35 #include "../LabelTrack.h"
36 #include "../WaveTrack.h"
37 
38 // Define keys, defaults, minimums, and maximums for the effect parameters
39 //
40 // Name Type Key Def Min Max Scale
41 Param( Start, int, wxT("Duty Cycle Start"), 3, 1, INT_MAX, 1 );
42 Param( Stop, int, wxT("Duty Cycle End"), 3, 1, INT_MAX, 1 );
43 
45 { XO("Find Clipping") };
46 
48 
50 {
51  mStart = DEF_Start;
52  mStop = DEF_Stop;
53 }
54 
56 {
57 }
58 
59 // ComponentInterface implementation
60 
62 {
63  return Symbol;
64 }
65 
67 {
68  return XO("Creates labels where clipping is detected");
69 }
70 
72 {
73  return L"Find_Clipping";
74 }
75 
76 // EffectDefinitionInterface implementation
77 
79 {
80  return EffectTypeAnalyze;
81 }
82 
83 // EffectClientInterface implementation
85  S.SHUTTLE_PARAM( mStart, Start );
86  S.SHUTTLE_PARAM( mStop, Stop );
87  return true;
88 }
89 
91 {
92  parms.Write(KEY_Start, mStart);
93  parms.Write(KEY_Stop, mStop);
94 
95  return true;
96 }
97 
99 {
100  ReadAndVerifyInt(Start);
101  ReadAndVerifyInt(Stop);
102 
103  mStart = Start;
104  mStop = Stop;
105 
106  return true;
107 }
108 
109 // Effect implementation
110 
112 {
113  std::shared_ptr<AddedAnalysisTrack> addedTrack;
114  Optional<ModifiedAnalysisTrack> modifiedTrack;
115  const wxString name{ _("Clipping") };
116 
117  auto clt = *inputTracks()->Any< const LabelTrack >().find_if(
118  [&]( const Track *track ){ return track->GetName() == name; } );
119 
120  LabelTrack *lt{};
121  if (!clt)
122  addedTrack = (AddAnalysisTrack(name)), lt = addedTrack->get();
123  else
124  modifiedTrack.emplace(ModifyAnalysisTrack(clt, name)),
125  lt = modifiedTrack->get();
126 
127  int count = 0;
128 
129  // JC: Only process selected tracks.
130  for (auto t : inputTracks()->Selected< const WaveTrack >()) {
131  double trackStart = t->GetStartTime();
132  double trackEnd = t->GetEndTime();
133  double t0 = mT0 < trackStart ? trackStart : mT0;
134  double t1 = mT1 > trackEnd ? trackEnd : mT1;
135 
136  if (t1 > t0) {
137  auto start = t->TimeToLongSamples(t0);
138  auto end = t->TimeToLongSamples(t1);
139  auto len = end - start;
140 
141  if (!ProcessOne(lt, count, t, start, len)) {
142  return false;
143  }
144  }
145 
146  count++;
147  }
148 
149  // No cancellation, so commit the addition of the track.
150  if (addedTrack)
151  addedTrack->Commit();
152  if (modifiedTrack)
153  modifiedTrack->Commit();
154  return true;
155 }
156 
158  int count,
159  const WaveTrack * wt,
160  sampleCount start,
161  sampleCount len)
162 {
163  bool bGoodResult = true;
164  size_t blockSize = (mStart * 1000);
165 
166  if (len < mStart) {
167  return true;
168  }
169 
170  Floats buffer;
171  try {
172  // mStart should be positive.
173  // if we are throwing bad_alloc and mStart is negative, find out why.
174  if (mStart < 0 || (int)blockSize < mStart)
175  // overflow
176  throw std::bad_alloc{};
177  buffer.reinit(blockSize);
178  }
179  catch( const std::bad_alloc & ) {
180  Effect::MessageBox( XO("Requested value exceeds memory capacity.") );
181  return false;
182  }
183 
184  float *ptr = buffer.get();
185 
186  decltype(len) s = 0, startrun = 0, stoprun = 0, samps = 0;
187  decltype(blockSize) block = 0;
188  double startTime = -1.0;
189 
190  while (s < len) {
191  if (block == 0) {
192  if (TrackProgress(count,
193  s.as_double() /
194  len.as_double() )) {
195  bGoodResult = false;
196  break;
197  }
198 
199  block = limitSampleBufferSize( blockSize, len - s );
200 
201  wt->GetFloats(buffer.get(), start + s, block);
202  ptr = buffer.get();
203  }
204 
205  float v = fabs(*ptr++);
206  if (v >= MAX_AUDIO) {
207  if (startrun == 0) {
208  startTime = wt->LongSamplesToTime(start + s);
209  samps = 0;
210  }
211  else {
212  stoprun = 0;
213  }
214  startrun++;
215  samps++;
216  }
217  else {
218  if (startrun >= mStart) {
219  stoprun++;
220  samps++;
221 
222  if (stoprun >= mStop) {
223  lt->AddLabel(SelectedRegion(startTime,
224  wt->LongSamplesToTime(start + s - mStop)),
225  wxString::Format(wxT("%lld of %lld"), startrun.as_long_long(), (samps - mStop).as_long_long()));
226  startrun = 0;
227  stoprun = 0;
228  samps = 0;
229  }
230  }
231  else {
232  startrun = 0;
233  }
234  }
235 
236  s++;
237  block--;
238  }
239 
240  return bGoodResult;
241 }
242 
244 {
245  S.StartMultiColumn(2, wxALIGN_CENTER);
246  {
247  S.Validator<IntegerValidator<int>>(
248  &mStart, NumValidatorStyle::DEFAULT, MIN_Start)
249  .TieTextBox(XXO("&Start threshold (samples):"), mStart, 10);
250 
251  S.Validator<IntegerValidator<int>>(
252  &mStop, NumValidatorStyle::DEFAULT, MIN_Stop)
253  .TieTextBox(XXO("St&op threshold (samples):"), mStop, 10);
254  }
255  S.EndMultiColumn();
256 }
257 
259 {
262 
263  return true;
264 }
265 
267 {
268  if (!mUIParent->Validate())
269  {
270  return false;
271  }
272 
275 
276  return true;
277 }
Optional::emplace
X & emplace(Args &&... args)
Definition: MemoryX.h:193
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
CommandParameters
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the Shuttle cla...
Definition: EffectAutomationParameters.h:67
EffectFindClipping::ManualPage
ManualPageID ManualPage() override
Definition: FindClipping.cpp:71
EffectFindClipping::GetSymbol
ComponentInterfaceSymbol GetSymbol() override
Definition: FindClipping.cpp:61
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:69
EffectFindClipping::TransferDataFromWindow
bool TransferDataFromWindow() override
Definition: FindClipping.cpp:266
Optional
Like a smart pointer, allows for object to not exist (nullptr)
Definition: MemoryX.h:144
eIsGettingFromDialog
@ eIsGettingFromDialog
Definition: ShuttleGui.h:39
Effect::MessageBox
int MessageBox(const TranslatableString &message, long style=DefaultMessageBoxStyle, const TranslatableString &titleStr={})
Definition: Effect.cpp:2481
Effect::AddedAnalysisTrack::get
LabelTrack * get() const
Definition: Effect.h:392
Track::GetName
wxString GetName() const
Definition: Track.h:410
LabelTrack::GetStartTime
double GetStartTime() const override
Definition: LabelTrack.cpp:316
Effect::mT1
double mT1
Definition: Effect.h:467
ArrayOf::reinit
void reinit(Integral count, bool initialize=false)
Definition: MemoryX.h:57
EffectFindClipping::ProcessOne
bool ProcessOne(LabelTrack *lt, int count, const WaveTrack *wt, sampleCount start, sampleCount len)
Definition: FindClipping.cpp:157
EffectFindClipping::SetAutomationParameters
bool SetAutomationParameters(CommandParameters &parms) override
Definition: FindClipping.cpp:98
Effect::ModifyAnalysisTrack
ModifiedAnalysisTrack ModifyAnalysisTrack(const LabelTrack *pOrigTrack, const wxString &name=wxString())
Definition: Effect.cpp:2185
XO
#define XO(s)
Definition: Internat.h:31
ShuttleParams
Shuttle that deals with parameters. This is a base class with lots of virtual functions that do nothi...
Definition: Shuttle.h:62
LabelTrack
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:88
ShuttleGuiBase::EndMultiColumn
void EndMultiColumn()
Definition: ShuttleGui.cpp:1238
FindClipping.h
eIsSettingToDialog
@ eIsSettingToDialog
Definition: ShuttleGui.h:40
ComponentInterfaceSymbol
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Definition: ComponentInterfaceSymbol.h:27
Effect::AddAnalysisTrack
std::shared_ptr< AddedAnalysisTrack > AddAnalysisTrack(const wxString &name=wxString())
Definition: Effect.cpp:2134
LabelTrack::AddLabel
int AddLabel(const SelectedRegion &region, const wxString &title)
Definition: LabelTrack.cpp:931
EffectFindClipping::DefineParams
bool DefineParams(ShuttleParams &S) override
Definition: FindClipping.cpp:84
EffectFindClipping::TransferDataToWindow
bool TransferDataToWindow() override
Definition: FindClipping.cpp:258
EffectFindClipping::EffectFindClipping
EffectFindClipping()
Definition: FindClipping.cpp:49
ReadAndVerifyInt
#define ReadAndVerifyInt(name)
Definition: Effect.h:632
XXO
#define XXO(s)
Definition: Internat.h:44
Effect::inputTracks
const TrackList * inputTracks() const
Definition: Effect.h:463
anonymous_namespace{FindClipping.cpp}::reg
BuiltinEffectsModule::Registration< EffectFindClipping > reg
Definition: FindClipping.cpp:47
Effect::mT0
double mT0
Definition: Effect.h:466
sampleCount::as_double
double as_double() const
Definition: SampleCount.h:45
EffectFindClipping::GetType
EffectType GetType() override
Definition: FindClipping.cpp:78
EffectFindClipping::mStop
int mStop
Using int rather than sampleCount because values are only ever small numbers.
Definition: FindClipping.h:60
WaveTrack::LongSamplesToTime
double LongSamplesToTime(sampleCount pos) const
Convert correctly between a number of samples and an (absolute) time in seconds.
Definition: WaveTrack.cpp:1775
ShuttleGuiBase::StartMultiColumn
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
Definition: ShuttleGui.cpp:1229
name
const TranslatableString name
Definition: Distortion.cpp:98
ShuttleGui::Validator
ShuttleGui & Validator(const Factory &f)
Definition: ShuttleGui.h:678
EffectFindClipping::Symbol
static const ComponentInterfaceSymbol Symbol
Definition: FindClipping.h:24
EffectFindClipping::Process
bool Process() override
Definition: FindClipping.cpp:111
Effect::ModifiedAnalysisTrack::Commit
void Commit()
Definition: Effect.cpp:2169
LoadEffects.h
Effect::ModifiedAnalysisTrack::get
LabelTrack * get() const
Definition: Effect.h:423
BuiltinEffectsModule::Registration
Definition: LoadEffects.h:40
Track
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:239
Effect::mUIParent
wxWindow * mUIParent
Definition: Effect.h:478
TaggedIdentifier< ManualPageIDTag >
_
#define _(s)
Definition: Internat.h:75
sampleCount
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:18
EffectTypeAnalyze
@ EffectTypeAnalyze
Definition: EffectInterface.h:60
EffectFindClipping::~EffectFindClipping
virtual ~EffectFindClipping()
Definition: FindClipping.cpp:55
TrackList::Any
auto Any() -> TrackIterRange< TrackType >
Definition: Track.h:1355
Param
Param(Start, int, wxT("Duty Cycle Start"), 3, 1, INT_MAX, 1)
EffectType
EffectType
Definition: EffectInterface.h:55
limitSampleBufferSize
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:21
WaveTrack::GetFloats
bool GetFloats(float *buffer, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
Retrieve samples from a track in floating-point format, regardless of the storage format.
Definition: WaveTrack.h:261
TrackList::Selected
auto Selected() -> TrackIterRange< TrackType >
Definition: Track.h:1372
Effect::TrackProgress
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={})
Definition: Effect.cpp:2024
ArrayOf< float >
MAX_AUDIO
#define MAX_AUDIO
Definition: MemoryX.h:631
EffectFindClipping::GetAutomationParameters
bool GetAutomationParameters(CommandParameters &parms) override
Definition: FindClipping.cpp:90
EffectFindClipping::mStart
int mStart
Using int rather than sampleCount because values are only ever small numbers.
Definition: FindClipping.h:59
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:631
EffectFindClipping::GetDescription
TranslatableString GetDescription() override
Definition: FindClipping.cpp:66
Effect::AddedAnalysisTrack::Commit
void Commit()
Definition: Effect.cpp:2121
SelectedRegion
Defines a selected portion of a project.
Definition: SelectedRegion.h:38
EffectFindClipping::PopulateOrExchange
void PopulateOrExchange(ShuttleGui &S) override
Definition: FindClipping.cpp:243