Skip to content

Commit

Permalink
Fixes the stretched tracks painting
Browse files Browse the repository at this point in the history
  • Loading branch information
crsib committed Apr 26, 2024
1 parent ae0ab08 commit 3f0401a
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 31 deletions.
29 changes: 20 additions & 9 deletions libraries/lib-wave-track-paint/GraphicsDataCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ void GraphicsDataCacheBase::Invalidate()
mLookup.clear();
}

double GraphicsDataCacheBase::GetSampleRate() const noexcept
double GraphicsDataCacheBase::GetScaledSampleRate() const noexcept
{
return mSampleRate;
return mScaledSampleRate;
}

void GraphicsDataCacheBase::UpdateViewportWidth(int64_t width) noexcept
Expand All @@ -95,10 +95,21 @@ int64_t GraphicsDataCacheBase::GetMaxViewportWidth() const noexcept
}

GraphicsDataCacheBase::GraphicsDataCacheBase(double sampleRate)
: mSampleRate(sampleRate)
: mScaledSampleRate { sampleRate }
{
}

void GraphicsDataCacheBase::SetScaledSampleRate(double scaledSampleRate)
{
if (
std::abs(mScaledSampleRate - scaledSampleRate) <=
std::numeric_limits<double>::epsilon())
return;

mScaledSampleRate = scaledSampleRate;
Invalidate();
}

void GraphicsDataCacheElementBase::Dispose()
{
}
Expand All @@ -112,7 +123,7 @@ GraphicsDataCacheBase::BaseLookupResult
GraphicsDataCacheBase::PerformBaseLookup(
const ZoomInfo& zoomInfo, double t0, double t1)
{
if (bool(t0 > t1) || IsSameSample(mSampleRate, t0, t1))
if (bool(t0 > t1) || IsSameSample(mScaledSampleRate, t0, t1))
return {};

const double pixelsPerSecond = zoomInfo.GetZoom();
Expand All @@ -129,15 +140,15 @@ GraphicsDataCacheBase::PerformBaseLookup(
const int64_t cacheLeftColumn = cacheLeft * CacheElementWidth;
const int64_t cacheRightColumn = cacheRight * CacheElementWidth;

const double samplesPerPixel = mSampleRate / pixelsPerSecond;
const double samplesPerPixel = mScaledSampleRate / pixelsPerSecond;

UpdateViewportWidth(width);

mNewLookupItems.clear();
mNewLookupItems.reserve(cacheItemsCount);

const auto ppsMatchRange =
GetPPSMatchRange(mLookup, pixelsPerSecond, mSampleRate);
GetPPSMatchRange(mLookup, pixelsPerSecond, mScaledSampleRate);

for (int64_t itemIndex = 0; itemIndex < cacheItemsCount; ++itemIndex)
{
Expand Down Expand Up @@ -170,7 +181,7 @@ GraphicsDataCacheBase::PerformBaseLookup(
std::merge(
mLookup.begin(), mLookup.end(), mNewLookupItems.begin(),
mNewLookupItems.end(), std::back_inserter(mLookupHelper),
[sampleRate = mSampleRate](auto lhs, auto rhs)
[sampleRate = mScaledSampleRate](auto lhs, auto rhs)
{ return IsKeyLess(sampleRate, lhs.Key, rhs.Key); });

std::swap(mLookup, mLookupHelper);
Expand Down Expand Up @@ -265,7 +276,7 @@ GraphicsDataCacheBase::PerformBaseLookup(GraphicsDataCacheKey key)
auto insertedPosition = mLookup.insert(
std::upper_bound(
mLookup.begin(), mLookup.end(), key,
[sampleRate = mSampleRate](auto lhs, auto rhs)
[sampleRate = mScaledSampleRate](auto lhs, auto rhs)
{
if constexpr (std::is_same_v<
std::decay_t<decltype(lhs)>, GraphicsDataCacheKey>)
Expand Down Expand Up @@ -315,7 +326,7 @@ GraphicsDataCacheBase::FindKey(GraphicsDataCacheKey key)
{
return std::find_if(
mLookup.begin(), mLookup.end(),
[sampleRate = mSampleRate, key](auto lhs)
[sampleRate = mScaledSampleRate, key](auto lhs)
{ return IsSameKey(sampleRate, lhs.Key, key); });
}

Expand Down
12 changes: 7 additions & 5 deletions libraries/lib-wave-track-paint/GraphicsDataCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,15 @@ class WAVE_TRACK_PAINT_API GraphicsDataCacheBase /* not final */
void Invalidate();

//! Returns the sample rate associated with cache
double GetSampleRate() const noexcept;
double GetScaledSampleRate() const noexcept;

void UpdateViewportWidth(int64_t width) noexcept;
int64_t GetMaxViewportWidth() const noexcept;

protected:
explicit GraphicsDataCacheBase(double sampleRate);
explicit GraphicsDataCacheBase(double scaledSampleRate);

void SetScaledSampleRate(double scaledSampleRate);

//! Element of the cache lookup
struct WAVE_TRACK_PAINT_API LookupElement final
Expand Down Expand Up @@ -128,7 +130,7 @@ class WAVE_TRACK_PAINT_API GraphicsDataCacheBase /* not final */
std::vector<size_t> mLRUHelper;

// Sample rate associated with this cache
double mSampleRate {}; // DV: Why do we use double for sample rate? I don't know
double mScaledSampleRate {}; // DV: Why do we use double for sample rate? I don't know

// The max width of the request processed in pixels
int64_t mMaxWidth { 1600 };
Expand Down Expand Up @@ -236,8 +238,8 @@ class GraphicsDataCache /* not final */ : public GraphicsDataCacheBase

using Initializer = std::function<bool(const GraphicsDataCacheKey& Key, CacheElementType& element)>;

explicit GraphicsDataCache(double sampleRate, ElementFactory elementFactory)
: GraphicsDataCacheBase(sampleRate), mElementFactory(std::move(elementFactory))
explicit GraphicsDataCache(double scaledSampleRate, ElementFactory elementFactory)
: GraphicsDataCacheBase(scaledSampleRate), mElementFactory(std::move(elementFactory))
{
}

Expand Down
27 changes: 19 additions & 8 deletions libraries/lib-wave-track-paint/waveform/WaveBitmapCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include "Envelope.h"
#include "FrameStatistics.h"

#include "WaveClip.h"

// The worst case scenario is:
// blank -> background -> min -> rms -> max -> backgroud -> blank
// So we have 7 stops
Expand Down Expand Up @@ -153,7 +155,7 @@ struct WaveBitmapCache::LookupHelper final
{
envelope->GetValues(
EnvelopeValues.data(), static_cast<int>(EnvelopeValues.size()),
key.FirstSample / cache->GetSampleRate(),
key.FirstSample / cache->GetScaledSampleRate(),
1.0 / key.PixelsPerSecond);

for (size_t column = 0; column < columnsCount; ++column)
Expand Down Expand Up @@ -183,7 +185,7 @@ struct WaveBitmapCache::LookupHelper final
const auto clipColors = cache->mPaintParamters.ClippingColors;
const auto showRMS = cache->mPaintParamters.ShowRMS;

auto firstPixel = int64_t(key.FirstSample / cache->GetSampleRate() * key.PixelsPerSecond + 0.5);
auto firstPixel = int64_t(key.FirstSample / cache->GetScaledSampleRate() * key.PixelsPerSecond + 0.5);

const auto selFirst = cache->mSelection.FirstPixel;
const auto selLast = cache->mSelection.LastPixel;
Expand Down Expand Up @@ -293,12 +295,21 @@ struct WaveBitmapCache::LookupHelper final
bool IsComplete { 0 };
};

WaveBitmapCache::WaveBitmapCache(std::shared_ptr<WaveDataCache> dataCache,
ElementFactory elementFactory,
double sampleRate)
: GraphicsDataCache(sampleRate, std::move(elementFactory))

, mLookupHelper(std::make_unique<LookupHelper>(std::move(dataCache)))
WaveBitmapCache::WaveBitmapCache(
const WaveClip& waveClip, std::shared_ptr<WaveDataCache> dataCache,
ElementFactory elementFactory)
: GraphicsDataCache { waveClip.GetRate() / waveClip.GetStretchRatio(),
std::move(elementFactory) }
, mLookupHelper { std::make_unique<LookupHelper>(std::move(dataCache)) }
, mWaveClip { waveClip }
, mStretchChangedSubscription {
const_cast<WaveClip&>(waveClip)
.Observer::Publisher<StretchRatioChange>::Subscribe(
[this](const StretchRatioChange&) {
SetScaledSampleRate(
mWaveClip.GetRate() / mWaveClip.GetStretchRatio());
})
}
{
}

Expand Down
10 changes: 7 additions & 3 deletions libraries/lib-wave-track-paint/waveform/WaveBitmapCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
#include <memory>

#include "GraphicsDataCache.h"
#include "Observer.h"
#include "waveform/WavePaintParameters.h"

class wxBitmap;
class wxImage;
class WaveDataCache;
class Envelope;
class WaveClip;

//! An element, that contains a rasterized bitmap matching the WaveDataCacheElement
class WAVE_TRACK_PAINT_API WaveBitmapCacheElement :
Expand All @@ -40,9 +42,8 @@ class WAVE_TRACK_PAINT_API WaveBitmapCache final :
public GraphicsDataCache<WaveBitmapCacheElement>
{
public:
WaveBitmapCache(std::shared_ptr<WaveDataCache> dataCache,
ElementFactory elementFactory,
double sampleRate);
WaveBitmapCache(const WaveClip& waveClip, std::shared_ptr<WaveDataCache> dataCache,
ElementFactory elementFactory);
~WaveBitmapCache() override;

WaveBitmapCache& SetPaintParameters(const WavePaintParameters& params);
Expand Down Expand Up @@ -73,4 +74,7 @@ class WAVE_TRACK_PAINT_API WaveBitmapCache final :

const Envelope* mEnvelope { nullptr };
size_t mEnvelopeVersion { 0 };

const WaveClip& mWaveClip;
Observer::Subscription mStretchChangedSubscription;
};
15 changes: 12 additions & 3 deletions libraries/lib-wave-track-paint/waveform/WaveDataCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,9 +253,18 @@ MakeDefaultDataProvider(const WaveClip& clip, int channelIndex)

WaveDataCache::WaveDataCache(const WaveClip& waveClip, int channelIndex)
: GraphicsDataCache<WaveCacheElement>(
waveClip.GetRate(),
waveClip.GetRate() / waveClip.GetStretchRatio(),
[] { return std::make_unique<WaveCacheElement>(); })
, mProvider(MakeDefaultDataProvider(waveClip, channelIndex))
, mProvider { MakeDefaultDataProvider(waveClip, channelIndex) }
, mWaveClip { waveClip }
, mStretchChangedSubscription {
const_cast<WaveClip&>(waveClip)
.Observer::Publisher<StretchRatioChange>::Subscribe(
[this](const StretchRatioChange&) {
SetScaledSampleRate(
mWaveClip.GetRate() / mWaveClip.GetStretchRatio());
})
}
{
}

Expand All @@ -270,7 +279,7 @@ bool WaveDataCache::InitializeElement(
int64_t firstSample = key.FirstSample;

const size_t samplesPerColumn =
static_cast<size_t>(std::max(0.0, GetSampleRate() / key.PixelsPerSecond));
static_cast<size_t>(std::max(0.0, GetScaledSampleRate() / key.PixelsPerSecond));

const size_t elementSamplesCount =
samplesPerColumn * WaveDataCache::CacheElementWidth;
Expand Down
4 changes: 4 additions & 0 deletions libraries/lib-wave-track-paint/waveform/WaveDataCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "GraphicsDataCache.h"
#include "WaveData.h"
#include "Observer.h"

class WaveClip;

Expand Down Expand Up @@ -103,4 +104,7 @@ class WAVE_TRACK_PAINT_API WaveDataCache final :
DataProvider mProvider;

WaveCacheSampleBlock mCachedBlock;

const WaveClip& mWaveClip;
Observer::Subscription mStretchChangedSubscription;
};
8 changes: 5 additions & 3 deletions src/tracks/playabletrack/wavetrack/ui/WaveformView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,8 @@ class WaveformPainter final
auto dataCache = std::make_shared<WaveDataCache>(clip, channelIndex);

auto bitmapCache = std::make_unique<WaveBitmapCache>(
dataCache,
[] { return std::make_unique<WaveBitmapCacheElementWX>(); },
dataCache->GetSampleRate());
clip, dataCache,
[] { return std::make_unique<WaveBitmapCacheElementWX>(); });

mChannelCaches.push_back(
{ std::move(dataCache), std::move(bitmapCache) });
Expand Down Expand Up @@ -290,7 +289,10 @@ class WaveformPainter final
void Invalidate() override
{
for (auto& channelCache : mChannelCaches)
{
channelCache.DataCache->Invalidate();
channelCache.BitmapCache->Invalidate();
}
}

std::unique_ptr<WaveClipListener> Clone() const override
Expand Down

0 comments on commit 3f0401a

Please sign in to comment.