Audacity 3.2.0
Classes | Public Member Functions | Protected Member Functions | Static Protected Member Functions | Private Member Functions | Private Attributes | List of all members
SpectralDataManager::Worker Class Reference

#include <SpectralDataManager.h>

Inheritance diagram for SpectralDataManager::Worker:
[legend]
Collaboration diagram for SpectralDataManager::Worker:
[legend]

Classes

struct  MyWindow
 

Public Member Functions

 Worker (WaveChannel *pChannel, const Setting &setting)
 
 ~Worker ()
 
bool Process (const WaveChannel &channel, const std::shared_ptr< SpectralData > &sDataPtr)
 
int ProcessSnapping (const WaveChannel &channel, long long int startSC, int hopSize, size_t winSize, double threshold, int targetFreqBin)
 
std::vector< int > ProcessOvertones (const WaveChannel &channel, long long int startSC, int hopSize, size_t winSize, double threshold, int targetFreqBin)
 
- Public Member Functions inherited from TrackSpectrumTransformer
 TrackSpectrumTransformer (WaveChannel *pOutputTrack, bool needsOutput, eWindowFunctions inWindowType, eWindowFunctions outWindowType, size_t windowSize, unsigned stepsPerWindow, bool leadingPadding, bool trailingPadding)
 
 ~TrackSpectrumTransformer () override
 
bool Process (const WindowProcessor &processor, const WaveChannel &channel, size_t queueLength, sampleCount start, sampleCount len)
 Invokes Start(), ProcessSamples(), and Finish() More...
 
- Public Member Functions inherited from SpectrumTransformer
 SpectrumTransformer (bool needsOutput, eWindowFunctions inWindowType, eWindowFunctions outWindowType, size_t windowSize, unsigned stepsPerWindow, bool leadingPadding, bool trailingPadding)
 
virtual ~SpectrumTransformer ()
 
bool NeedsOutput () const
 
bool Start (size_t queueLength)
 Call once before a sequence of calls to ProcessSamples; Invokes DoStart. More...
 
bool ProcessSamples (const WindowProcessor &processor, const float *buffer, size_t len)
 Call multiple times. More...
 
bool Finish (const WindowProcessor &processor)
 
virtual std::unique_ptr< WindowNewWindow (size_t windowSize)
 Allocates a window to place in the queue. More...
 
virtual bool DoStart ()
 Called before any calls to ProcessWindow. More...
 
virtual void DoOutput (const float *outBuffer, size_t mStepSize)=0
 Called within ProcessSamples if output was requested. More...
 
virtual bool DoFinish ()
 Called after the last call to ProcessWindow(). More...
 
size_t TotalQueueSize () const
 Useful functions to implement WindowProcesser: More...
 
size_t CurrentQueueSize () const
 How many windows in the queue have been filled? More...
 
bool QueueIsFull () const
 
WindowNth (int n)
 Access the queue, so you can inspect and modify any window in it. More...
 
WindowNewest ()
 
WindowLatest ()
 

Protected Member Functions

MyWindowNthWindow (int nn)
 
std::unique_ptr< WindowNewWindow (size_t windowSize) override
 Allocates a window to place in the queue. More...
 
bool DoStart () override
 Called before any calls to ProcessWindow. More...
 
bool DoFinish () override
 Called after the last call to ProcessWindow(). More...
 
- Protected Member Functions inherited from TrackSpectrumTransformer
bool DoStart () override
 Called before any calls to ProcessWindow. More...
 
void DoOutput (const float *outBuffer, size_t mStepSize) override
 Called within ProcessSamples if output was requested. More...
 
bool DoFinish () override
 Called after the last call to ProcessWindow(). More...
 

Static Protected Member Functions

static bool Processor (SpectrumTransformer &transformer)
 
static bool OvertonesProcessor (SpectrumTransformer &transformer)
 
static bool SnappingProcessor (SpectrumTransformer &transformer)
 

Private Member Functions

bool ApplyEffectToSelection ()
 

Private Attributes

std::shared_ptr< SpectralDatampSpectralData
 
int mWindowCount { 0 }
 
double mSnapSamplingRate
 
double mSnapThreshold
 
double mOvertonesThreshold
 
std::vector< int > mOvertonesTargetFreqBin
 
int mSnapTargetFreqBin
 
int mSnapReturnFreqBin { -1 }
 
long long mStartHopNum { 0 }
 

Additional Inherited Members

- Public Types inherited from SpectrumTransformer
using FloatVector = std::vector< float >
 
using WindowProcessor = std::function< bool(SpectrumTransformer &) >
 Type of function that transforms windows in the queue. More...
 
- Static Public Member Functions inherited from TrackSpectrumTransformer
static bool PostProcess (WaveTrack &outputTrack, sampleCount len)
 Final flush and trimming of tail samples. More...
 
- Protected Attributes inherited from SpectrumTransformer
const size_t mWindowSize
 
const size_t mSpectrumSize
 
const unsigned mStepsPerWindow
 
const size_t mStepSize
 
const bool mLeadingPadding
 
const bool mTrailingPadding
 

Detailed Description

Definition at line 40 of file SpectralDataManager.h.

Constructor & Destructor Documentation

◆ Worker()

SpectralDataManager::Worker::Worker ( WaveChannel pChannel,
const Setting setting 
)

Definition at line 150 of file SpectralDataManager.cpp.

152 : TrackSpectrumTransformer{ pChannel,
153 setting.mNeedOutput, setting.mInWindowType, setting.mOutWindowType,
154 setting.mWindowSize, setting.mStepsPerWindow,
155 setting.mLeadingPadding, setting.mTrailingPadding
156 }
157// Work members
158{
159}
Subclass of SpectrumTransformer that rewrites a track.

◆ ~Worker()

SpectralDataManager::Worker::~Worker ( )
default

Member Function Documentation

◆ ApplyEffectToSelection()

bool SpectralDataManager::Worker::ApplyEffectToSelection ( )
private

Definition at line 323 of file SpectralDataManager.cpp.

323 {
324 auto &record = NthWindow(0);
325
326 for(auto &spectralDataMap: mpSpectralData->dataHistory){
327 // For all added frequency
328 for(const int &freqBin: spectralDataMap[mStartHopNum]){
329 record.mRealFFTs[freqBin] = 0;
330 record.mImagFFTs[freqBin] = 0;
331 }
332 }
333
334 mWindowCount++;
335 mStartHopNum ++;
336 return true;
337}
std::shared_ptr< SpectralData > mpSpectralData

◆ DoFinish()

bool SpectralDataManager::Worker::DoFinish ( )
overrideprotectedvirtual

Called after the last call to ProcessWindow().

Returns
false to abort processing. Default implementation just returns true.

Reimplemented from SpectrumTransformer.

Definition at line 166 of file SpectralDataManager.cpp.

166 {
168}
bool DoFinish() override
Called after the last call to ProcessWindow().

References TrackSpectrumTransformer::DoFinish().

Here is the call graph for this function:

◆ DoStart()

bool SpectralDataManager::Worker::DoStart ( )
overrideprotectedvirtual

Called before any calls to ProcessWindow.

More queue initializations can be done here.

Returns
false to abort processing. Default implementation just returns true.

Reimplemented from SpectrumTransformer.

Definition at line 163 of file SpectralDataManager.cpp.

163 {
165}
bool DoStart() override
Called before any calls to ProcessWindow.

References TrackSpectrumTransformer::DoStart().

Here is the call graph for this function:

◆ NewWindow()

auto SpectralDataManager::Worker::NewWindow ( size_t  windowSize)
overrideprotectedvirtual

Allocates a window to place in the queue.

Only when initializing – windows are recycled thereafter. You can derive from Window to add fields, and then override this factory function.

Reimplemented from SpectrumTransformer.

Definition at line 339 of file SpectralDataManager.cpp.

341{
342 return std::make_unique<MyWindow>(windowSize);
343}

◆ NthWindow()

MyWindow & SpectralDataManager::Worker::NthWindow ( int  nn)
inlineprotected

Definition at line 71 of file SpectralDataManager.h.

71 {
72 return static_cast<MyWindow&>(Nth(nn));
73 }
Window & Nth(int n)
Access the queue, so you can inspect and modify any window in it.

References SpectrumTransformer::Nth().

Here is the call graph for this function:

◆ OvertonesProcessor()

bool SpectralDataManager::Worker::OvertonesProcessor ( SpectrumTransformer transformer)
staticprotected

Definition at line 255 of file SpectralDataManager.cpp.

255 {
256 auto &worker = static_cast<Worker &>(transformer);
257 // Compute power spectrum in the newest window
258 {
259 MyWindow &record = worker.NthWindow(0);
260 float *pSpectrum = &record.mSpectrums[0];
261 const double dc = record.mRealFFTs[0];
262 *pSpectrum++ = dc * dc;
263 float *pReal = &record.mRealFFTs[1], *pImag = &record.mImagFFTs[1];
264 for (size_t nn = worker.mSpectrumSize - 2; nn--;) {
265 const double re = *pReal++, im = *pImag++;
266 *pSpectrum++ = re * re + im * im;
267 }
268 const double nyquist = record.mImagFFTs[0];
269 *pSpectrum = nyquist * nyquist;
270
271 const double &spectrumSize = worker.mSpectrumSize;
272 const int &targetBin = worker.mSnapTargetFreqBin;
273
274 float targetValue = record.mSpectrums[targetBin];
275
276 double fundamental = targetBin;
277 int overtone = 2, binNum = 0;
278 pSpectrum = &record.mSpectrums[0];
279 while ( fundamental >= 1 &&
280 ( binNum = lrint( fundamental * overtone ) ) < spectrumSize) {
281 // Examine a few bins each way up and down
282 constexpr int tolerance = 3;
283 auto begin = pSpectrum + std::max( 0, binNum - (tolerance + 1) );
284 auto end = pSpectrum +
285 std::min<size_t>( spectrumSize, binNum + (tolerance + 1) + 1 );
286 auto peak = std::max_element( begin, end );
287
288 // Abandon if the peak is too far up or down
289 if ( peak == begin || peak == end - 1 )
290 break;
291
292 int newBin = peak - pSpectrum;
293 worker.mOvertonesTargetFreqBin.push_back(newBin);
294 // Correct the estimate of the fundamental
295 fundamental = double(newBin) / overtone++;
296 }
297 }
298 return true;
299}
Worker(WaveChannel *pChannel, const Setting &setting)
#define lrint(dbl)
Definition: float_cast.h:169
const char * end(const char *str) noexcept
Definition: StringUtils.h:106
const char * begin(const char *str) noexcept
Definition: StringUtils.h:101

References details::begin(), details::end(), lrint, and SpectralDataManager::Worker::MyWindow::mSpectrums.

Here is the call graph for this function:

◆ Process()

bool SpectralDataManager::Worker::Process ( const WaveChannel channel,
const std::shared_ptr< SpectralData > &  sDataPtr 
)

Definition at line 170 of file SpectralDataManager.cpp.

172{
173 mpSpectralData = pSpectralData;
174 const auto hopSize = mpSpectralData->GetHopSize();
175 const auto startSample = mpSpectralData->GetStartSample();
176 // Correct the first hop num, because SpectrumTransformer will send
177 // a few initial windows that overlay the range only partially
178 mStartHopNum = startSample / hopSize - (mStepsPerWindow - 1);
179 mWindowCount = 0;
181 mpSpectralData->GetCorrectedStartSample(), mpSpectralData->GetLength());
182}
static bool Processor(SpectrumTransformer &transformer)
const unsigned mStepsPerWindow
bool Process(const WindowProcessor &processor, const WaveChannel &channel, size_t queueLength, sampleCount start, sampleCount len)
Invokes Start(), ProcessSamples(), and Finish()

References TrackSpectrumTransformer::Process().

Here is the call graph for this function:

◆ Processor()

bool SpectralDataManager::Worker::Processor ( SpectrumTransformer transformer)
staticprotected

Definition at line 301 of file SpectralDataManager.cpp.

302{
303 auto &worker = static_cast<Worker &>(transformer);
304 // Compute power spectrum in the newest window
305 {
306 MyWindow &record = worker.NthWindow(0);
307 float *pSpectrum = &record.mSpectrums[0];
308 const double dc = record.mRealFFTs[0];
309 *pSpectrum++ = dc * dc;
310 float *pReal = &record.mRealFFTs[1], *pImag = &record.mImagFFTs[1];
311 for (size_t nn = worker.mSpectrumSize - 2; nn--;) {
312 const double re = *pReal++, im = *pImag++;
313 *pSpectrum++ = re * re + im * im;
314 }
315 const double nyquist = record.mImagFFTs[0];
316 *pSpectrum = nyquist * nyquist;
317 }
318
319 worker.ApplyEffectToSelection();
320 return true;
321}

References SpectralDataManager::Worker::MyWindow::mSpectrums.

◆ ProcessOvertones()

std::vector< int > SpectralDataManager::Worker::ProcessOvertones ( const WaveChannel channel,
long long int  startSC,
int  hopSize,
size_t  winSize,
double  threshold,
int  targetFreqBin 
)

Definition at line 201 of file SpectralDataManager.cpp.

204{
205 mOvertonesThreshold = threshold;
206 mSnapTargetFreqBin = targetFreqBin;
207 mSnapSamplingRate = channel.GetTrack().GetRate();
208
209 startSC = std::max(static_cast<long long>(0), startSC - 2 * hopSize);
210 // The calculated multiple frequency peaks will be stored in mOvertonesTargetFreqBin
212 OvertonesProcessor, channel, 1, startSC, winSize);
213 return move( mOvertonesTargetFreqBin );
214 }
std::vector< int > mOvertonesTargetFreqBin
static bool OvertonesProcessor(SpectrumTransformer &transformer)
WaveTrack & GetTrack()
Definition: WaveTrack.h:840
double GetRate() const override
Definition: WaveTrack.cpp:798

References WaveTrack::GetRate(), WaveChannel::GetTrack(), and TrackSpectrumTransformer::Process().

Here is the call graph for this function:

◆ ProcessSnapping()

int SpectralDataManager::Worker::ProcessSnapping ( const WaveChannel channel,
long long int  startSC,
int  hopSize,
size_t  winSize,
double  threshold,
int  targetFreqBin 
)

Definition at line 184 of file SpectralDataManager.cpp.

187{
188 mSnapThreshold = threshold;
189 mSnapTargetFreqBin = targetFreqBin;
190 mSnapSamplingRate = channel.GetTrack().GetRate();
191
192 startSC = std::max(static_cast<long long>(0), startSC - 2 * hopSize);
193 // The calculated frequency peak will be stored in mReturnFreq
195 1, startSC, winSize))
196 return 0;
197
198 return mSnapReturnFreqBin;
199}
static bool SnappingProcessor(SpectrumTransformer &transformer)

References WaveTrack::GetRate(), WaveChannel::GetTrack(), and TrackSpectrumTransformer::Process().

Here is the call graph for this function:

◆ SnappingProcessor()

bool SpectralDataManager::Worker::SnappingProcessor ( SpectrumTransformer transformer)
staticprotected

Definition at line 216 of file SpectralDataManager.cpp.

216 {
217 auto &worker = static_cast<Worker &>(transformer);
218 // Compute power spectrum in the newest window
219 {
220 MyWindow &record = worker.NthWindow(0);
221 float *pSpectrum = &record.mSpectrums[0];
222 const double dc = record.mRealFFTs[0];
223 *pSpectrum++ = dc * dc;
224 float *pReal = &record.mRealFFTs[1], *pImag = &record.mImagFFTs[1];
225 for (size_t nn = worker.mSpectrumSize - 2; nn--;) {
226 const double re = *pReal++, im = *pImag++;
227 *pSpectrum++ = re * re + im * im;
228 }
229 const double nyquist = record.mImagFFTs[0];
230 *pSpectrum = nyquist * nyquist;
231
232 const double &sr = worker.mSnapSamplingRate;
233 const double nyquistRate = sr / 2;
234 const double &threshold = worker.mSnapThreshold;
235 const double &spectrumSize = worker.mSpectrumSize;
236 const int &targetBin = worker.mSnapTargetFreqBin;
237
238 int binBound = spectrumSize * threshold;
239 float maxValue = std::numeric_limits<float>::min();
240
241 // Skip the first and last bin
242 for(int i = -binBound; i < binBound; i++){
243 int idx = std::clamp(targetBin + i, 0, static_cast<int>(spectrumSize - 1));
244 if(record.mSpectrums[idx] > maxValue){
245 maxValue = record.mSpectrums[idx];
246 // Update the return frequency
247 worker.mSnapReturnFreqBin = idx;
248 }
249 }
250 }
251
252 return true;
253}
int min(int a, int b)

References min(), and SpectralDataManager::Worker::MyWindow::mSpectrums.

Here is the call graph for this function:

Member Data Documentation

◆ mOvertonesTargetFreqBin

std::vector<int> SpectralDataManager::Worker::mOvertonesTargetFreqBin
private

Definition at line 88 of file SpectralDataManager.h.

◆ mOvertonesThreshold

double SpectralDataManager::Worker::mOvertonesThreshold
private

Definition at line 87 of file SpectralDataManager.h.

◆ mpSpectralData

std::shared_ptr<SpectralData> SpectralDataManager::Worker::mpSpectralData
private

Definition at line 83 of file SpectralDataManager.h.

◆ mSnapReturnFreqBin

int SpectralDataManager::Worker::mSnapReturnFreqBin { -1 }
private

Definition at line 90 of file SpectralDataManager.h.

◆ mSnapSamplingRate

double SpectralDataManager::Worker::mSnapSamplingRate
private

Definition at line 85 of file SpectralDataManager.h.

◆ mSnapTargetFreqBin

int SpectralDataManager::Worker::mSnapTargetFreqBin
private

Definition at line 89 of file SpectralDataManager.h.

◆ mSnapThreshold

double SpectralDataManager::Worker::mSnapThreshold
private

Definition at line 86 of file SpectralDataManager.h.

◆ mStartHopNum

long long SpectralDataManager::Worker::mStartHopNum { 0 }
private

Definition at line 91 of file SpectralDataManager.h.

◆ mWindowCount

int SpectralDataManager::Worker::mWindowCount { 0 }
private

Definition at line 84 of file SpectralDataManager.h.


The documentation for this class was generated from the following files: