Audacity 3.2.0
Public Member Functions | Static Public Member Functions | Public Attributes | List of all members
WaveClipSpectrumCache Struct Referencefinal

#include <SpectrumCache.h>

Inheritance diagram for WaveClipSpectrumCache:
[legend]
Collaboration diagram for WaveClipSpectrumCache:
[legend]

Public Member Functions

 WaveClipSpectrumCache (size_t nChannels)
 
 ~WaveClipSpectrumCache () override
 
std::unique_ptr< WaveClipListenerClone () const override
 
void MarkChanged () noexcept override
 
void Invalidate () override
 
bool GetSpectrogram (const WaveChannelInterval &clip, const float *&spectrogram, SpectrogramSettings &spectrogramSettings, const sampleCount *&where, size_t numPixels, double t0, double pixelsPerSecond)
 
void MakeStereo (WaveClipListener &&other, bool aligned) override
 
void SwapChannels () override
 Default implementation does nothing. More...
 
void Erase (size_t index) override
 
- Public Member Functions inherited from WaveClipListener
virtual ~WaveClipListener ()=0
 
virtual void MarkChanged () noexcept=0
 
virtual void Invalidate ()=0
 
virtual void WriteXMLAttributes (XMLWriter &writer) const
 
virtual bool HandleXMLAttribute (const std::string_view &attr, const XMLAttributeValueView &valueView)
 
virtual void MakeStereo (WaveClipListener &&other, bool aligned)
 
virtual void SwapChannels ()
 Default implementation does nothing. More...
 
virtual void Erase (size_t index)
 

Static Public Member Functions

static WaveClipSpectrumCacheGet (const WaveChannelInterval &clip)
 

Public Attributes

std::vector< std::unique_ptr< SpecPxCache > > mSpecPxCaches
 
std::vector< std::unique_ptr< SpecCache > > mSpecCaches
 
int mDirty { 0 }
 

Detailed Description

Definition at line 105 of file SpectrumCache.h.

Constructor & Destructor Documentation

◆ WaveClipSpectrumCache()

WaveClipSpectrumCache::WaveClipSpectrumCache ( size_t  nChannels)
explicit

Definition at line 575 of file SpectrumCache.cpp.

576 : mSpecCaches(nChannels)
577 , mSpecPxCaches(nChannels)
578{
579 for (auto &pCache : mSpecCaches)
580 pCache = std::make_unique<SpecCache>();
581}
std::vector< std::unique_ptr< SpecPxCache > > mSpecPxCaches
std::vector< std::unique_ptr< SpecCache > > mSpecCaches

References mSpecCaches.

◆ ~WaveClipSpectrumCache()

WaveClipSpectrumCache::~WaveClipSpectrumCache ( )
override

Definition at line 583 of file SpectrumCache.cpp.

584{
585}

Member Function Documentation

◆ Clone()

std::unique_ptr< WaveClipListener > WaveClipSpectrumCache::Clone ( ) const
override

Definition at line 587 of file SpectrumCache.cpp.

588{
589 // Don't need to copy contents
590 return std::make_unique<WaveClipSpectrumCache>(mSpecCaches.size());
591}

References mSpecCaches.

◆ Erase()

void WaveClipSpectrumCache::Erase ( size_t  index)
overridevirtual

Erase attachment at a given index, if it existed, moving later-indexed attachments to earlier indices

Default implementation does nothing

Reimplemented from WaveClipListener.

Definition at line 632 of file SpectrumCache.cpp.

633{
634 if (index < mSpecCaches.size())
635 mSpecCaches.erase(mSpecCaches.begin() + index);
636 if (index < mSpecPxCaches.size())
637 mSpecPxCaches.erase(mSpecPxCaches.begin() + index);
638}

References mSpecCaches, and mSpecPxCaches.

◆ Get()

WaveClipSpectrumCache & WaveClipSpectrumCache::Get ( const WaveChannelInterval clip)
static

Definition at line 598 of file SpectrumCache.cpp.

599{
600 return const_cast<WaveClip&>(clip.GetClip()) // Consider it mutable data
601 .Attachments::Get< WaveClipSpectrumCache >( sKeyS );
602}
static WaveClip::Attachments::RegisteredFactory sKeyS
WaveClip & GetClip()
Definition: WaveClip.h:96
This allows multiple clips to be a part of one WaveTrack.
Definition: WaveClip.h:238

References WaveClipChannel::GetClip(), and sKeyS.

Referenced by anonymous_namespace{SpectrumView.cpp}::DrawClipSpectrum().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetSpectrogram()

bool WaveClipSpectrumCache::GetSpectrogram ( const WaveChannelInterval clip,
const float *&  spectrogram,
SpectrogramSettings spectrogramSettings,
const sampleCount *&  where,
size_t  numPixels,
double  t0,
double  pixelsPerSecond 
)

Getting high-level data for screen display

Definition at line 461 of file SpectrumCache.cpp.

467{
468 auto &mSpecCache = mSpecCaches[clip.GetChannelIndex()];
469
470 const auto sampleRate = clip.GetRate();
471 const auto stretchRatio = clip.GetStretchRatio();
472 const auto samplesPerPixel = sampleRate / pixelsPerSecond / stretchRatio;
473
474 //Trim offset comparison failure forces spectrogram cache rebuild
475 //and skip copying "unchanged" data after clip border was trimmed.
476 bool match = mSpecCache && mSpecCache->leftTrim == clip.GetTrimLeft() &&
477 mSpecCache->rightTrim == clip.GetTrimRight() &&
478 mSpecCache->len > 0 &&
479 mSpecCache->Matches(mDirty, samplesPerPixel, settings);
480
481 if (match && mSpecCache->start == t0 && mSpecCache->len >= numPixels)
482 {
483 spectrogram = &mSpecCache->freq[0];
484 where = &mSpecCache->where[0];
485
486 return false; //hit cache completely
487 }
488
489 // Caching is not implemented for reassignment, unless for
490 // a complete hit, because of the complications of time reassignment
492 match = false;
493
494 // Free the cache when it won't cause a major stutter.
495 // If the window size changed, we know there is nothing to be copied
496 // If we zoomed out, or resized, we can give up memory. But not too much -
497 // up to 2x extra is needed at the end of the clip to prevent stutter.
498 if (mSpecCache->freq.capacity() > 2.1 * mSpecCache->freq.size() ||
499 mSpecCache->windowSize*mSpecCache->zeroPaddingFactor <
500 settings.WindowSize()*settings.ZeroPaddingFactor())
501 {
502 match = false;
503 mSpecCache = std::make_unique<SpecCache>();
504 }
505
506 int oldX0 = 0;
507 double correction = 0.0;
508
509 int copyBegin = 0, copyEnd = 0;
510 if (match) {
512 mSpecCache->where, mSpecCache->len, numPixels, t0, sampleRate,
513 stretchRatio, samplesPerPixel, oldX0, correction);
514 // Remember our first pixel maps to oldX0 in the old cache,
515 // possibly out of bounds.
516 // For what range of pixels can data be copied?
517 copyBegin = std::min((int)numPixels, std::max(0, -oldX0));
518 copyEnd = std::min((int)numPixels, std::max(0,
519 (int)mSpecCache->len - oldX0
520 ));
521 }
522
523 // Resize the cache, keep the contents unchanged.
524 mSpecCache->Grow(numPixels, settings, samplesPerPixel, t0);
525 mSpecCache->leftTrim = clip.GetTrimLeft();
526 mSpecCache->rightTrim = clip.GetTrimRight();
527 auto nBins = settings.NBins();
528
529 // Optimization: if the old cache is good and overlaps
530 // with the current one, re-use as much of the cache as
531 // possible
532 if (copyEnd > copyBegin)
533 {
534 // memmove is required since dst/src overlap
535 memmove(&mSpecCache->freq[nBins * copyBegin],
536 &mSpecCache->freq[nBins * (copyBegin + oldX0)],
537 nBins * (copyEnd - copyBegin) * sizeof(float));
538 }
539
540 // Reassignment accumulates, so it needs a zeroed buffer
542 {
543 // The cache could theoretically copy from the middle, resulting
544 // in two regions to update. This won't happen in zoom, since
545 // old cache doesn't match. It won't happen in resize, since the
546 // spectrum view is pinned to left side of window.
547 wxASSERT(
548 (copyBegin >= 0 && copyEnd == (int)numPixels) || // copied the end
549 (copyBegin == 0 && copyEnd <= (int)numPixels) // copied the beginning
550 );
551
552 int zeroBegin = copyBegin > 0 ? 0 : copyEnd-copyBegin;
553 int zeroEnd = copyBegin > 0 ? copyBegin : numPixels;
554
555 memset(&mSpecCache->freq[nBins*zeroBegin], 0, nBins*(zeroEnd-zeroBegin)*sizeof(float));
556 }
557
558 // purposely offset the display 1/2 sample to the left (as compared
559 // to waveform display) to properly center response of the FFT
560 constexpr auto addBias = true;
562 mSpecCache->where, numPixels, addBias, correction, t0, sampleRate,
563 stretchRatio, samplesPerPixel);
564
565 mSpecCache->Populate(
566 settings, clip, copyBegin, copyEnd, numPixels, pixelsPerSecond);
567
568 mSpecCache->dirty = mDirty;
569 spectrogram = &mSpecCache->freq[0];
570 where = &mSpecCache->where[0];
571
572 return true;
573}
int min(int a, int b)
static Settings & settings()
Definition: TrackInfo.cpp:47
size_t GetChannelIndex() const
Definition: WaveClip.h:99
double GetTrimRight() const
Definition: WaveClip.cpp:183
int GetRate() const override
Definition: WaveClip.cpp:193
double GetTrimLeft() const
Definition: WaveClip.cpp:110
double GetStretchRatio() const override
Definition: WaveClip.cpp:218
AUDACITY_DLL_API void fillWhere(std::vector< sampleCount > &where, size_t len, bool addBias, double correction, double t0, double sampleRate, double stretchRatio, double samplesPerPixel)
AUDACITY_DLL_API void findCorrection(const std::vector< sampleCount > &oldWhere, size_t oldLen, size_t newLen, double t0, double sampleRate, double stretchRatio, double samplesPerPixel, int &oldX0, double &correction)

References SpectrogramSettings::algReassignment, WaveClipUIUtilities::fillWhere(), WaveClipUIUtilities::findCorrection(), WaveClipChannel::GetChannelIndex(), WaveClipChannel::GetRate(), WaveClipChannel::GetStretchRatio(), WaveClipChannel::GetTrimLeft(), WaveClipChannel::GetTrimRight(), mDirty, min(), mSpecCaches, anonymous_namespace{ClipSegmentTest.cpp}::sampleRate, and settings().

Referenced by anonymous_namespace{SpectrumView.cpp}::DrawClipSpectrum().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Invalidate()

void WaveClipSpectrumCache::Invalidate ( )
overridevirtual

Implements WaveClipListener.

Definition at line 609 of file SpectrumCache.cpp.

610{
611 // Invalidate the spectrum display cache
612 for (auto &pCache : mSpecCaches)
613 pCache = std::make_unique<SpecCache>();
614}

References mSpecCaches.

◆ MakeStereo()

void WaveClipSpectrumCache::MakeStereo ( WaveClipListener &&  other,
bool  aligned 
)
overridevirtual

Append the other's attachments to this, assuming concrete subclasses are the same

Default implementation does nothing

Parameters
alignedwhether the strong invariant condition on the clip may be assumed
Precondition
typeid(*this) == typeid(other)

Reimplemented from WaveClipListener.

Definition at line 616 of file SpectrumCache.cpp.

617{
618 auto pOther = dynamic_cast<WaveClipSpectrumCache *>(&other);
619 assert(pOther); // precondition
620 mSpecCaches.push_back(move(pOther->mSpecCaches[0]));
621 mSpecPxCaches.push_back(move(pOther->mSpecPxCaches[0]));
622}

References mSpecCaches, and mSpecPxCaches.

◆ MarkChanged()

void WaveClipSpectrumCache::MarkChanged ( )
overridevirtualnoexcept

Implements WaveClipListener.

Definition at line 604 of file SpectrumCache.cpp.

605{
606 ++mDirty;
607}

References mDirty.

◆ SwapChannels()

void WaveClipSpectrumCache::SwapChannels ( )
overridevirtual

Default implementation does nothing.

Reimplemented from WaveClipListener.

Definition at line 624 of file SpectrumCache.cpp.

625{
626 mSpecCaches.resize(2);
628 mSpecPxCaches.resize(2);
630}
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:628

References mSpecCaches, mSpecPxCaches, and anonymous_namespace{NoteTrack.cpp}::swap().

Here is the call graph for this function:

Member Data Documentation

◆ mDirty

int WaveClipSpectrumCache::mDirty { 0 }

Definition at line 115 of file SpectrumCache.h.

Referenced by GetSpectrogram(), and MarkChanged().

◆ mSpecCaches

std::vector<std::unique_ptr<SpecCache> > WaveClipSpectrumCache::mSpecCaches

◆ mSpecPxCaches

std::vector<std::unique_ptr<SpecPxCache> > WaveClipSpectrumCache::mSpecPxCaches

Definition at line 113 of file SpectrumCache.h.

Referenced by Erase(), MakeStereo(), and SwapChannels().


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