Hi,
I’m trying to draw a waveform using the tracktion SmartThumbnail.
To take care of the zoom i store in an EditViewState two variables ( viewX1 and viewX2 ) that match the left visibile view time and the right visible view time.
I’ve also a TrackComponent where that displays the ClipComponent on the screen in this way :
auto pos = clip->getPosition();
int x1 = editViewState.timeToX(pos.getStart().inSeconds(), getWidth(), viewX1 , viewX2);
int x2 = editViewState.timeToX(pos.getEnd().inSeconds(), getWidth(), viewX1 , viewX2);
if (clipComp) {
clipComp->setBounds(x1, 0, x2 - x1, getHeight());
}
In the paint() of the clipComponent :
void AudioClipComponent::paint(Graphics& g)
{
if (editViewState.drawWaveforms && thumbnail != nullptr)
drawWaveform(g, *getWaveAudioClip(), *thumbnail, Colours::black.withAlpha(0.5f),
getX(), getWidth(), getY(), getHeight(), 0);
}
void AudioClipComponent::drawWaveform(Graphics& g, te::AudioClipBase& c, te::SmartThumbnail& thumb, Colour colour, int left, int right, int y, int h, int xOffset) {
auto getTimeRangeForDrawing = [this](const int l, const int r) -> tracktion::TimeRange
{
if (auto p = findParentComponentOfClass<TrackComponent>())
{
auto t1 = editViewState.xToTime(l, p->getWidth(),viewX1,viewX2,true);
auto t2 = editViewState.xToTime(r, p->getWidth(), viewX1, viewX2,true);
return { TimePosition::fromSeconds( t1 ), TimeDuration::fromSeconds( t2 )};
}
return {};
};
jassert(left <= right);
const auto gain = c.getGain();
const auto pan = thumb.getNumChannels() == 1 ? 0.0f : c.getPan();
const float pv = pan * gain;
const float gainL = (gain - pv);
const float gainR = (gain + pv);
const bool usesTimeStretchedProxy = c.usesTimeStretchedProxy();
const auto clipPos = c.getPosition();
auto offset = clipPos.getOffset();
auto speedRatio = c.getSpeedRatio();
g.setColour(colour);
if (usesTimeStretchedProxy)
{
const Rectangle<int> area(left + xOffset, y, right - left, h);
if (!thumb.isOutOfDate())
{
drawChannels(g, thumb, area, false,
getTimeRangeForDrawing(left, right),
c.isLeftChannelActive(), c.isRightChannelActive(),
gainL, gainR);
}
}
else if (c.getLoopLength() == 0s)
{
auto region = getTimeRangeForDrawing(left, right);
auto t1 = (region.getStart() + offset) * speedRatio;
auto t2 = (region.getEnd() + offset) * speedRatio;
auto area = Rectangle<int>( left + xOffset, y, right - left, h );
g.reduceClipRegion(area);
drawChannels(g, thumb,
area,
false, { t1, t2 },
c.isLeftChannelActive(), c.isRightChannelActive(),
gainL, gainR);
}
}
The problem is :
When the clipComponent width is very huge, the drawChannels(…) will call the refillCache(…) method that use the width as numSamples taking so much time.
There is a way to improve performance with a very large zoom ?
@dave96 How did you do in tracktion to make the wraveform drawing so performance ?