Audacity  3.0.3
TwoPassSimpleMono.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  TwoPassSimpleMono.cpp
6 
7  Dominic Mazzoni
8 
9 *******************************************************************//*******************************************************************/
19 
20 
21 
22 #include "TwoPassSimpleMono.h"
23 
24 #include "../WaveTrack.h"
25 
27 {
28  mPass = 0;
29  mSecondPassDisabled = false;
30 
31  InitPass1();
32  this->CopyInputTracks(); // Set up mOutputTracks.
33 
35  const_cast<AudacityProject*>( FindProject() ) );
36  for (auto track : mOutputTracks->Selected< WaveTrack >()) {
37  mWorkTracks->Add(track->EmptyCopy())->ConvertToSampleFormat(floatSample);
38  if( mT0 > 0 )
39  mWorkTracks->back()->InsertSilence(0, mT0);
40  }
41 
44 
45  bool bGoodResult = ProcessPass();
46 
47  if (bGoodResult && !mSecondPassDisabled)
48  {
49  mPass = 1;
50  if (InitPass2())
51  bGoodResult = ProcessPass();
52  }
53 
54  mWorkTracks->Clear();
55  mWorkTracks.reset();
56 
57  this->ReplaceProcessedTracks(bGoodResult);
58  return bGoodResult;
59 }
60 
62 {
63  //Iterate over each track
64  mCurTrackNum = 0;
65 
66  auto outTracks = (*mTrackLists[1 - mPass])->Selected< WaveTrack >().begin();
67  for( auto track : (*mTrackLists[mPass])->Selected< WaveTrack >() ) {
68  auto outTrack = *outTracks;
69 
70  //Get start and end times from track
71  double trackStart = track->GetStartTime();
72  double trackEnd = track->GetEndTime();
73 
74  //Set the current bounds to whichever left marker is
75  //greater and whichever right marker is less:
76  mCurT0 = mT0 < trackStart? trackStart: mT0;
77  mCurT1 = mT1 > trackEnd? trackEnd: mT1;
78 
79  // Process only if the right marker is to the right of the left marker
80  if (mCurT1 > mCurT0) {
81 
82  //Transform the marker timepoints to samples
83  auto start = track->TimeToLongSamples(mCurT0);
84  auto end = track->TimeToLongSamples(mCurT1);
85 
86  //Get the track rate and samples
87  mCurRate = track->GetRate();
88  mCurChannel = track->GetChannel();
89 
90  //NewTrackPass1/2() returns true by default
91  bool ret;
92  if (mPass == 0)
93  ret = NewTrackPass1();
94  else
95  ret = NewTrackPass2();
96  if (!ret)
97  return false;
98 
99  //ProcessOne() (implemented below) processes a single track
100  if (!ProcessOne(track, outTrack, start, end))
101  return false;
102  }
103 
104  mCurTrackNum++;
105  outTracks++;
106  }
107 
108  return true;
109 }
110 
111 
112 //ProcessOne() takes a track, transforms it to bunch of buffer-blocks,
113 //and executes TwoBufferProcessPass1 or TwoBufferProcessPass2 on these blocks
115  sampleCount start, sampleCount end)
116 {
117  bool ret;
118 
119  //Get the length of the buffer (as double). len is
120  //used simple to calculate a progress meter, so it is easier
121  //to make it a double now than it is to do it later
122  auto len = (end - start).as_double();
123  auto maxblock = track->GetMaxBlockSize();
124 
125  //Initiate a processing buffer. This buffer will (most likely)
126  //be shorter than the length of the track being processed.
127  Floats buffer1{ maxblock };
128  Floats buffer2{ maxblock };
129  auto samples1 = limitSampleBufferSize(
130  std::min( maxblock, track->GetBestBlockSize(start) ), end - start );
131 
132  //Get the samples from the track and put them in the buffer
133  track->Get((samplePtr) buffer1.get(), floatSample, start, samples1);
134 
135  // Process the first buffer with a NULL previous buffer
136  if (mPass == 0)
137  ret = TwoBufferProcessPass1(NULL, 0, buffer1.get(), samples1);
138  else
139  ret = TwoBufferProcessPass2(NULL, 0, buffer1.get(), samples1);
140  if (!ret)
141  //Return false because the effect failed.
142  return false;
143 
144  //Go through the track one buffer at a time. s counts which
145  //sample the current buffer starts at.
146  auto s = start + samples1;
147  while (s < end) {
148  //Get a block of samples (smaller than the size of the buffer)
149  //Adjust the block size if it is the final block in the track
150  auto samples2 = limitSampleBufferSize(
151  std::min( track->GetBestBlockSize(s), maxblock ), end - s
152  );
153 
154  //Get the samples from the track and put them in the buffer
155  track->Get((samplePtr)buffer2.get(), floatSample, s, samples2);
156 
157  //Process the buffer. If it fails, clean up and exit.
158  if (mPass == 0)
159  ret = TwoBufferProcessPass1(buffer1.get(), samples1, buffer2.get(), samples2);
160  else
161  ret = TwoBufferProcessPass2(buffer1.get(), samples1, buffer2.get(), samples2);
162  if (!ret)
163  //Return false because the effect failed.
164  return false;
165 
166  //Processing succeeded. copy the newly-changed samples back
167  //onto the track.
168  if (mSecondPassDisabled || mPass != 0) {
169  outTrack->Set((samplePtr)buffer1.get(), floatSample, s - samples1, samples1);
170  }
171  else {
172  outTrack->Append((samplePtr)buffer1.get(), floatSample, samples1);
173  }
174 
175  //Increment s one blockfull of samples
176  s += samples2;
177 
178  //Update the Progress meter
180  ret = TotalProgress(
181  (mCurTrackNum + (s-start).as_double()/len) /
182  GetNumWaveTracks());
183  else
184  ret = TotalProgress(
185  (mCurTrackNum + (s-start).as_double()/len + GetNumWaveTracks()*mPass) /
186  (GetNumWaveTracks()*2));
187  if (ret)
188  //Return false because the effect failed.
189  return false;
190 
191  // Rotate the buffers
192  buffer1.swap(buffer2);
193 
194  std::swap(samples1, samples2);
195  }
196 
197  // Send the last buffer with a NULL pointer for the current buffer
198  if (mPass == 0)
199  ret = TwoBufferProcessPass1(buffer1.get(), samples1, NULL, 0);
200  else
201  ret = TwoBufferProcessPass2(buffer1.get(), samples1, NULL, 0);
202 
203  if (!ret)
204  //Return false because the effect failed.
205  return false;
206 
207  //Processing succeeded. copy the newly-changed samples back
208  //onto the track.
209  if (mSecondPassDisabled || mPass != 0) {
210  outTrack->Set((samplePtr)buffer1.get(), floatSample, s - samples1, samples1);
211  }
212  else {
213  outTrack->Append((samplePtr)buffer1.get(), floatSample, samples1);
214  outTrack->Flush();
215  }
216 
217  //Return true because the effect processing succeeded.
218  return true;
219 }
220 
222 {
223  return true;
224 }
225 
227 {
228  return true;
229 }
230 
231 //Initialisations before the first pass
233 {
234  return true;
235 }
236 
237 //Initialisations before the second pass.
238 //Return true if you actually want the second pass to go ahead
240 {
241  return true;
242 }
243 
EffectTwoPassSimpleMono::InitPass1
bool InitPass1() override
Definition: TwoPassSimpleMono.cpp:232
WaveTrack::Flush
void Flush()
Flush must be called after last Append.
Definition: WaveTrack.cpp:1608
EffectTwoPassSimpleMono::mSecondPassDisabled
bool mSecondPassDisabled
Definition: TwoPassSimpleMono.h:76
Effect::FindProject
const AudacityProject * FindProject() const
Definition: Effect.cpp:2271
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:68
EffectTwoPassSimpleMono::mPass
int mPass
Definition: TwoPassSimpleMono.h:75
EffectTwoPassSimpleMono::TwoBufferProcessPass1
virtual bool TwoBufferProcessPass1(float *buffer1, size_t len1, float *WXUNUSED(buffer2), size_t WXUNUSED(len2))
Definition: TwoPassSimpleMono.h:57
EffectTwoPassSimpleMono::InitPass2
bool InitPass2() override
Definition: TwoPassSimpleMono.cpp:239
EffectTwoPassSimpleMono::ProcessPass
bool ProcessPass() override
Definition: TwoPassSimpleMono.cpp:61
Effect::CopyInputTracks
void CopyInputTracks(bool allSyncLockSelected=false)
Definition: Effect.cpp:2070
EffectTwoPassSimpleMono::mWorkTracks
std::shared_ptr< TrackList > mWorkTracks
Definition: TwoPassSimpleMono.h:78
Effect::mT1
double mT1
Definition: Effect.h:466
EffectTwoPassSimpleMono::Process
bool Process() override
Definition: TwoPassSimpleMono.cpp:26
EffectTwoPassSimpleMono::mCurT1
double mCurT1
Definition: TwoPassSimpleMono.h:73
floatSample
@ floatSample
Definition: Types.h:714
EffectTwoPassSimpleMono::mCurT0
double mCurT0
Definition: TwoPassSimpleMono.h:72
EffectTwoPassSimpleMono::NewTrackPass2
virtual bool NewTrackPass2()
Definition: TwoPassSimpleMono.cpp:226
WaveTrack::Get
bool Get(samplePtr buffer, sampleFormat format, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
Definition: WaveTrack.cpp:1895
limitSampleBufferSize
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: Types.h:698
WaveTrack::Set
void Set(constSamplePtr buffer, sampleFormat format, sampleCount start, size_t len)
Definition: WaveTrack.cpp:1978
samplePtr
char * samplePtr
Definition: Types.h:729
Effect::mT0
double mT0
Definition: Effect.h:465
EffectTwoPassSimpleMono::NewTrackPass1
virtual bool NewTrackPass1()
Definition: TwoPassSimpleMono.cpp:221
Effect::ReplaceProcessedTracks
void ReplaceProcessedTracks(const bool bGoodResult)
Definition: Effect.cpp:2192
anonymous_namespace{NoteTrack.cpp}::swap
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:733
TwoPassSimpleMono.h
WaveTrack::Append
bool Append(constSamplePtr buffer, sampleFormat format, size_t len, unsigned int stride=1)
Append the sample data to the WaveTrack. You must call Flush() after the last Append.
Definition: WaveTrack.cpp:1541
Effect::mOutputTracks
std::shared_ptr< TrackList > mOutputTracks
Definition: Effect.h:464
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
WaveTrack::GetMaxBlockSize
size_t GetMaxBlockSize() const
Definition: WaveTrack.cpp:1578
EffectTwoPassSimpleMono::mCurTrackNum
int mCurTrackNum
Definition: TwoPassSimpleMono.h:70
sampleCount
Definition: Types.h:581
EffectTwoPassSimpleMono::mTrackLists
std::shared_ptr< TrackList > * mTrackLists[2]
Definition: TwoPassSimpleMono.h:79
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:112
TrackList::Create
static std::shared_ptr< TrackList > Create(AudacityProject *pOwner)
Definition: Track.cpp:512
Effect::TotalProgress
bool TotalProgress(double frac, const TranslatableString &={})
Definition: Effect.cpp:2016
EffectTwoPassSimpleMono::mCurChannel
int mCurChannel
Definition: TwoPassSimpleMono.h:74
Effect::GetNumWaveTracks
int GetNumWaveTracks()
Definition: Effect.h:344
EffectTwoPassSimpleMono::TwoBufferProcessPass2
virtual bool TwoBufferProcessPass2(float *buffer1, size_t len1, float *WXUNUSED(buffer2), size_t WXUNUSED(len2))
Definition: TwoPassSimpleMono.h:60
EffectTwoPassSimpleMono::ProcessOne
bool ProcessOne(WaveTrack *t, WaveTrack *outTrack, sampleCount start, sampleCount end)
Definition: TwoPassSimpleMono.cpp:114
WaveTrack::GetBestBlockSize
size_t GetBestBlockSize(sampleCount t) const
Definition: WaveTrack.cpp:1560
ArrayOf< float >
EffectTwoPassSimpleMono::mCurRate
double mCurRate
Definition: TwoPassSimpleMono.h:71