Audacity 3.2.0
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(settings);
46
47 if (bGoodResult && !mSecondPassDisabled)
48 {
49 mPass = 1;
50 if (InitPass2())
51 bGoodResult = ProcessPass(settings);
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
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->GetFloats(buffer1.get(), 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->GetFloats(buffer2.get(), 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) /
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
int min(int a, int b)
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:23
@ floatSample
Definition: SampleFormat.h:34
char * samplePtr
Definition: SampleFormat.h:49
static Settings & settings()
Definition: TrackInfo.cpp:87
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:89
double mT1
Definition: EffectBase.h:107
std::shared_ptr< TrackList > mOutputTracks
Definition: EffectBase.h:105
double mT0
Definition: EffectBase.h:106
void ReplaceProcessedTracks(const bool bGoodResult)
Definition: EffectBase.cpp:236
const AudacityProject * FindProject() const
Definition: EffectBase.cpp:315
void CopyInputTracks(bool allSyncLockSelected=false)
Definition: Effect.cpp:741
bool TotalProgress(double frac, const TranslatableString &={}) const
Definition: Effect.cpp:685
int GetNumWaveTracks() const
Definition: Effect.h:187
Performs effect computation.
bool ProcessPass(EffectSettings &settings)
virtual bool TwoBufferProcessPass1(float *buffer1, size_t len1, float *WXUNUSED(buffer2), size_t WXUNUSED(len2))
bool ProcessOne(WaveTrack *t, WaveTrack *outTrack, sampleCount start, sampleCount end)
bool Process(EffectInstance &instance, EffectSettings &settings) override
Actually do the effect here.
std::shared_ptr< TrackList > * mTrackLists[2]
virtual bool TwoBufferProcessPass2(float *buffer1, size_t len1, float *WXUNUSED(buffer2), size_t WXUNUSED(len2))
std::shared_ptr< TrackList > mWorkTracks
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: SampleTrack.h:67
static std::shared_ptr< TrackList > Create(AudacityProject *pOwner)
Definition: Track.cpp:502
A Track that contains audio waveform data.
Definition: WaveTrack.h:57
size_t GetMaxBlockSize() const override
This returns a nonnegative number of samples meant to size a memory buffer.
Definition: WaveTrack.cpp:1806
size_t GetBestBlockSize(sampleCount t) const override
This returns a nonnegative number of samples meant to size a memory buffer.
Definition: WaveTrack.cpp:1788
void Flush() override
Definition: WaveTrack.cpp:1836
void Set(constSamplePtr buffer, sampleFormat format, sampleCount start, size_t len)
Definition: WaveTrack.cpp:2195
bool Append(constSamplePtr buffer, sampleFormat format, size_t len, unsigned int stride=1) override
Definition: WaveTrack.cpp:1766
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:18
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:753
Externalized state of a plug-in.