Audacity  2.2.2
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 #include "../Audacity.h"
23 #include "FindClipping.h"
24 
25 #include <math.h>
26 
27 #include <wx/intl.h>
28 
29 #include "../ShuttleGui.h"
30 #include "../widgets/valnum.h"
31 #include "../widgets/ErrorDialog.h"
32 
33 #include "../LabelTrack.h"
34 #include "../WaveTrack.h"
35 #include "../MemoryX.h"
36 
37 // Define keys, defaults, minimums, and maximums for the effect parameters
38 //
39 // Name Type Key Def Min Max Scale
40 Param( Start, int, wxT("Duty Cycle Start"), 3, 1, INT_MAX, 1 );
41 Param( Stop, int, wxT("Duty Cycle End"), 3, 1, INT_MAX, 1 );
42 
44 {
45  mStart = DEF_Start;
46  mStop = DEF_Stop;
47 }
48 
50 {
51 }
52 
53 // IdentInterface implementation
54 
56 {
58 }
59 
61 {
62  return _("Creates labels where clipping is detected");
63 }
64 
66 {
67  return wxT("Find_Clipping");
68 }
69 
70 // EffectDefinitionInterface implementation
71 
73 {
74  return EffectTypeAnalyze;
75 }
76 
77 // EffectClientInterface implementation
79  S.SHUTTLE_PARAM( mStart, Start );
80  S.SHUTTLE_PARAM( mStop, Stop );
81  return true;
82 }
83 
85 {
86  parms.Write(KEY_Start, mStart);
87  parms.Write(KEY_Stop, mStop);
88 
89  return true;
90 }
91 
93 {
94  ReadAndVerifyInt(Start);
95  ReadAndVerifyInt(Stop);
96 
97  mStart = Start;
98  mStop = Stop;
99 
100  return true;
101 }
102 
103 // Effect implementation
104 
106 {
107  std::shared_ptr<AddedAnalysisTrack> addedTrack;
108  Maybe<ModifiedAnalysisTrack> modifiedTrack;
109  const wxString name{ _("Clipping") };
110 
111  LabelTrack *lt = NULL;
113  for (Track *t = iter.First(); t; t = iter.Next()) {
114  if (t->GetName() == name) {
115  lt = (LabelTrack *)t;
116  break;
117  }
118  }
119 
120  if (!lt)
121  addedTrack = (AddAnalysisTrack(name)), lt = addedTrack->get();
122  else
123  modifiedTrack.create(ModifyAnalysisTrack(lt, name)), lt = modifiedTrack->get();
124 
125  int count = 0;
126 
127  // JC: Only process selected tracks.
129  WaveTrack *t = (WaveTrack *) waves.First();
130  while (t) {
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  t = (WaveTrack *) waves.Next();
148  }
149 
150  // No cancellation, so commit the addition of the track.
151  if (addedTrack)
152  addedTrack->Commit();
153  if (modifiedTrack)
154  modifiedTrack->Commit();
155  return true;
156 }
157 
159  int count,
160  const WaveTrack * wt,
161  sampleCount start,
162  sampleCount len)
163 {
164  bool bGoodResult = true;
165  size_t blockSize = (mStart * 1000);
166 
167  if (len < mStart) {
168  return true;
169  }
170 
171  Floats buffer;
172  try {
173  // mStart should be positive.
174  // if we are throwing bad_alloc and mStart is negative, find out why.
175  if (mStart < 0 || (int)blockSize < mStart)
176  // overflow
177  throw std::bad_alloc{};
178  buffer.reinit(blockSize);
179  }
180  catch( const std::bad_alloc & ) {
181  Effect::MessageBox(_("Requested value exceeds memory capacity."));
182  return false;
183  }
184 
185  float *ptr = buffer.get();
186 
187  decltype(len) s = 0, startrun = 0, stoprun = 0, samps = 0;
188  decltype(blockSize) block = 0;
189  double startTime = -1.0;
190 
191  while (s < len) {
192  if (block == 0) {
193  if (TrackProgress(count,
194  s.as_double() /
195  len.as_double() )) {
196  bGoodResult = false;
197  break;
198  }
199 
200  block = limitSampleBufferSize( blockSize, len - s );
201 
202  wt->Get((samplePtr)buffer.get(), floatSample, start + s, block);
203  ptr = buffer.get();
204  }
205 
206  float v = fabs(*ptr++);
207  if (v >= MAX_AUDIO) {
208  if (startrun == 0) {
209  startTime = wt->LongSamplesToTime(start + s);
210  samps = 0;
211  }
212  else {
213  stoprun = 0;
214  }
215  startrun++;
216  samps++;
217  }
218  else {
219  if (startrun >= mStart) {
220  stoprun++;
221  samps++;
222 
223  if (stoprun >= mStop) {
224  lt->AddLabel(SelectedRegion(startTime,
225  wt->LongSamplesToTime(start + s - mStop)),
226  wxString::Format(wxT("%lld of %lld"), startrun.as_long_long(), (samps - mStop).as_long_long()),
227  -2);
228  startrun = 0;
229  stoprun = 0;
230  samps = 0;
231  }
232  }
233  else {
234  startrun = 0;
235  }
236  }
237 
238  s++;
239  block--;
240  }
241 
242  return bGoodResult;
243 }
244 
246 {
247  S.StartMultiColumn(2, wxALIGN_CENTER);
248  {
249  IntegerValidator<int> vldStart(&mStart);
250  vldStart.SetMin(MIN_Start);
251  S.TieTextBox(_("Start threshold (samples):"),
252  mStart,
253  10)->SetValidator(vldStart);
254 
255  IntegerValidator<int> vldStop(&mStop);
256  vldStop.SetMin(MIN_Stop);
257  S.TieTextBox(_("Stop threshold (samples):"),
258  mStop,
259  10)->SetValidator(vldStop);
260  }
261  S.EndMultiColumn();
262 }
263 
265 {
268 
269  return true;
270 }
271 
273 {
274  if (!mUIParent->Validate())
275  {
276  return false;
277  }
278 
281 
282  return true;
283 }
double mT1
Definition: Effect.h:461
#define FINDCLIPPING_PLUGIN_SYMBOL
Definition: FindClipping.h:23
int MessageBox(const wxString &message, long style=DefaultMessageBoxStyle, const wxString &titleStr=wxString{})
Definition: Effect.cpp:2660
bool TrackProgress(int whichTrack, double frac, const wxString &=wxEmptyString)
Definition: Effect.cpp:1985
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI...
Definition: ShuttleGui.h:409
Param(Start, int, wxT("Duty Cycle Start"), 3, 1, INT_MAX, 1)
int mStart
Using int rather than sampleCount because values are only ever small numbers.
Definition: FindClipping.h:61
EffectType GetType() override
void reinit(Integral count, bool initialize=false)
Definition: MemoryX.h:117
int mStop
Using int rather than sampleCount because values are only ever small numbers.
Definition: FindClipping.h:62
void PopulateOrExchange(ShuttleGui &S) override
void EndMultiColumn()
IdentInterfaceSymbol GetSymbol() override
double as_double() const
Definition: Types.h:88
Definition: MemoryX.h:204
double GetEndTime() const override
Get the time at which the last clip in the track ends, plus recorded stuff.
Definition: WaveTrack.cpp:1873
std::shared_ptr< AddedAnalysisTrack > AddAnalysisTrack(const wxString &name=wxString())
Definition: Effect.cpp:2104
Shuttle that deals with parameters. This is a base class with lots of virtual functions that do nothi...
Definition: Shuttle.h:60
ModifiedAnalysisTrack ModifyAnalysisTrack(const LabelTrack *pOrigTrack, const wxString &name=wxString())
Definition: Effect.cpp:2155
TrackList * inputTracks() const
Definition: Effect.h:458
bool DefineParams(ShuttleParams &S) override
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: Types.h:178
Track * Next(bool skiplinked=false) override
Definition: Track.cpp:569
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:113
virtual ~EffectFindClipping()
double GetStartTime() const override
Get the time at which the first clip in the track starts.
Definition: WaveTrack.cpp:1853
bool SetAutomationParameters(CommandParameters &parms) override
bool TransferDataToWindow() override
#define ReadAndVerifyInt(name)
Definition: Effect.h:797
Defines a selected portion of a project.
wxString GetDescription() override
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the Shuttle cla...
char * samplePtr
Definition: Types.h:203
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
Fundamental data object of Audacity, placed in the TrackPanel. Classes derived form it include the Wa...
Definition: Track.h:101
IdentInterfaceSymbol pairs a persistent string identifier used internally with an optional...
bool TransferDataFromWindow() override
bool Process() override
wxWindow * mUIParent
Definition: Effect.h:472
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
bool ProcessOne(LabelTrack *lt, int count, const WaveTrack *wt, sampleCount start, sampleCount len)
bool GetAutomationParameters(CommandParameters &parms) override
EffectType
const wxChar * name
Definition: Distortion.cpp:94
sampleCount TimeToLongSamples(double t0) const
Convert correctly between an (absolute) time in seconds and a number of samples.
Definition: WaveTrack.cpp:1843
Track * First(TrackList *val=NULL) override
Definition: Track.cpp:558
wxString ManualPage() override
bool Get(samplePtr buffer, sampleFormat format, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true, sampleCount *pNumCopied=nullptr) const
Definition: WaveTrack.cpp:1971
double LongSamplesToTime(sampleCount pos) const
Convert correctly between an number of samples and an (absolute) time in seconds. ...
Definition: WaveTrack.cpp:1848
int AddLabel(const SelectedRegion &region, const wxString &title=wxT(""), int restoreFocus=-1)
void create(Args &&...args)
Definition: MemoryX.h:251
#define MAX_AUDIO
Definition: Audacity.h:219
double mT0
Definition: Effect.h:460
wxTextCtrl * TieTextBox(const wxString &Prompt, WrappedType &WrappedRef, const int nChars)
LabelTrack * get() const
Definition: Effect.h:418