mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Added a template to allow the HeapBlock class to be given signed ints or other types that are not size_t for its size parameters
This commit is contained in:
parent
13ccdf9411
commit
369d59f656
32 changed files with 189 additions and 199 deletions
|
|
@ -89,14 +89,12 @@ class AudioThumbnail::LevelDataSource : public TimeSliceClient
|
|||
{
|
||||
public:
|
||||
LevelDataSource (AudioThumbnail& thumb, AudioFormatReader* newReader, int64 hash)
|
||||
: lengthInSamples (0), numSamplesFinished (0), sampleRate (0), numChannels (0),
|
||||
hashCode (hash), owner (thumb), reader (newReader), lastReaderUseTime (0)
|
||||
: hashCode (hash), owner (thumb), reader (newReader)
|
||||
{
|
||||
}
|
||||
|
||||
LevelDataSource (AudioThumbnail& thumb, InputSource* src)
|
||||
: lengthInSamples (0), numSamplesFinished (0), sampleRate (0), numChannels (0),
|
||||
hashCode (src->hashCode()), owner (thumb), source (src), lastReaderUseTime (0)
|
||||
: hashCode (src->hashCode()), owner (thumb), source (src)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -179,7 +177,6 @@ public:
|
|||
|
||||
{
|
||||
const ScopedLock sl (readerLock);
|
||||
|
||||
createReader();
|
||||
|
||||
if (reader != nullptr)
|
||||
|
|
@ -207,17 +204,17 @@ public:
|
|||
return (int) (originalSample / owner.samplesPerThumbSample);
|
||||
}
|
||||
|
||||
int64 lengthInSamples, numSamplesFinished;
|
||||
double sampleRate;
|
||||
unsigned int numChannels;
|
||||
int64 hashCode;
|
||||
int64 lengthInSamples = 0, numSamplesFinished = 0;
|
||||
double sampleRate = 0;
|
||||
unsigned int numChannels = 0;
|
||||
int64 hashCode = 0;
|
||||
|
||||
private:
|
||||
AudioThumbnail& owner;
|
||||
ScopedPointer<InputSource> source;
|
||||
ScopedPointer<AudioFormatReader> reader;
|
||||
CriticalSection readerLock;
|
||||
uint32 lastReaderUseTime;
|
||||
uint32 lastReaderUseTime = 0;
|
||||
|
||||
void createReader()
|
||||
{
|
||||
|
|
@ -232,23 +229,23 @@ private:
|
|||
|
||||
if (! isFullyLoaded())
|
||||
{
|
||||
const int numToDo = (int) jmin (256 * (int64) owner.samplesPerThumbSample, lengthInSamples - numSamplesFinished);
|
||||
auto numToDo = (int) jmin (256 * (int64) owner.samplesPerThumbSample, lengthInSamples - numSamplesFinished);
|
||||
|
||||
if (numToDo > 0)
|
||||
{
|
||||
int64 startSample = numSamplesFinished;
|
||||
auto startSample = numSamplesFinished;
|
||||
|
||||
const int firstThumbIndex = sampleToThumbSample (startSample);
|
||||
const int lastThumbIndex = sampleToThumbSample (startSample + numToDo);
|
||||
const int numThumbSamps = lastThumbIndex - firstThumbIndex;
|
||||
auto firstThumbIndex = sampleToThumbSample (startSample);
|
||||
auto lastThumbIndex = sampleToThumbSample (startSample + numToDo);
|
||||
auto numThumbSamps = lastThumbIndex - firstThumbIndex;
|
||||
|
||||
HeapBlock<MinMaxValue> levelData ((size_t) numThumbSamps * numChannels);
|
||||
HeapBlock<MinMaxValue> levelData ((unsigned int) numThumbSamps * numChannels);
|
||||
HeapBlock<MinMaxValue*> levels (numChannels);
|
||||
|
||||
for (int i = 0; i < (int) numChannels; ++i)
|
||||
levels[i] = levelData + i * numThumbSamps;
|
||||
|
||||
HeapBlock<Range<float> > levelsRead (numChannels);
|
||||
HeapBlock<Range<float>> levelsRead (numChannels);
|
||||
|
||||
for (int i = 0; i < numThumbSamps; ++i)
|
||||
{
|
||||
|
|
@ -283,7 +280,7 @@ public:
|
|||
ensureSize (numThumbSamples);
|
||||
}
|
||||
|
||||
inline MinMaxValue* getData (const int thumbSampleIndex) noexcept
|
||||
inline MinMaxValue* getData (int thumbSampleIndex) noexcept
|
||||
{
|
||||
jassert (thumbSampleIndex < data.size());
|
||||
return data.getRawDataPointer() + thumbSampleIndex;
|
||||
|
|
@ -305,7 +302,7 @@ public:
|
|||
|
||||
while (startSample <= endSample)
|
||||
{
|
||||
const MinMaxValue& v = data.getReference (startSample);
|
||||
auto& v = data.getReference (startSample);
|
||||
|
||||
if (v.getMinValue() < mn) mn = v.getMinValue();
|
||||
if (v.getMaxValue() > mx) mx = v.getMaxValue();
|
||||
|
|
@ -323,14 +320,14 @@ public:
|
|||
result.set (1, 0);
|
||||
}
|
||||
|
||||
void write (const MinMaxValue* const values, const int startIndex, const int numValues)
|
||||
void write (const MinMaxValue* values, int startIndex, int numValues)
|
||||
{
|
||||
resetPeak();
|
||||
|
||||
if (startIndex + numValues > data.size())
|
||||
ensureSize (startIndex + numValues);
|
||||
|
||||
MinMaxValue* const dest = getData (startIndex);
|
||||
auto* dest = getData (startIndex);
|
||||
|
||||
for (int i = 0; i < numValues; ++i)
|
||||
dest[i] = values[i];
|
||||
|
|
@ -345,9 +342,10 @@ public:
|
|||
{
|
||||
if (peakLevel < 0)
|
||||
{
|
||||
for (int i = 0; i < data.size(); ++i)
|
||||
for (auto& s : data)
|
||||
{
|
||||
const int peak = data[i].getPeak();
|
||||
auto peak = s.getPeak();
|
||||
|
||||
if (peak > peakLevel)
|
||||
peakLevel = peak;
|
||||
}
|
||||
|
|
@ -360,9 +358,10 @@ private:
|
|||
Array<MinMaxValue> data;
|
||||
int peakLevel;
|
||||
|
||||
void ensureSize (const int thumbSamples)
|
||||
void ensureSize (int thumbSamples)
|
||||
{
|
||||
const int extraNeeded = thumbSamples - data.size();
|
||||
auto extraNeeded = thumbSamples - data.size();
|
||||
|
||||
if (extraNeeded > 0)
|
||||
data.insertMultiple (-1, MinMaxValue(), extraNeeded);
|
||||
}
|
||||
|
|
@ -372,12 +371,7 @@ private:
|
|||
class AudioThumbnail::CachedWindow
|
||||
{
|
||||
public:
|
||||
CachedWindow()
|
||||
: cachedStart (0), cachedTimePerPixel (0),
|
||||
numChannelsCached (0), numSamplesCached (0),
|
||||
cacheNeedsRefilling (true)
|
||||
{
|
||||
}
|
||||
CachedWindow() {}
|
||||
|
||||
void invalidate()
|
||||
{
|
||||
|
|
@ -394,28 +388,28 @@ public:
|
|||
numChans, sampsPerThumbSample, levelData, chans)
|
||||
&& isPositiveAndBelow (channelNum, numChannelsCached))
|
||||
{
|
||||
const Rectangle<int> clip (g.getClipBounds().getIntersection (area.withWidth (jmin (numSamplesCached, area.getWidth()))));
|
||||
auto clip = g.getClipBounds().getIntersection (area.withWidth (jmin (numSamplesCached, area.getWidth())));
|
||||
|
||||
if (! clip.isEmpty())
|
||||
{
|
||||
const float topY = (float) area.getY();
|
||||
const float bottomY = (float) area.getBottom();
|
||||
const float midY = (topY + bottomY) * 0.5f;
|
||||
const float vscale = verticalZoomFactor * (bottomY - topY) / 256.0f;
|
||||
auto topY = (float) area.getY();
|
||||
auto bottomY = (float) area.getBottom();
|
||||
auto midY = (topY + bottomY) * 0.5f;
|
||||
auto vscale = verticalZoomFactor * (bottomY - topY) / 256.0f;
|
||||
|
||||
const MinMaxValue* cacheData = getData (channelNum, clip.getX() - area.getX());
|
||||
auto* cacheData = getData (channelNum, clip.getX() - area.getX());
|
||||
|
||||
RectangleList<float> waveform;
|
||||
waveform.ensureStorageAllocated (clip.getWidth());
|
||||
|
||||
float x = (float) clip.getX();
|
||||
auto x = (float) clip.getX();
|
||||
|
||||
for (int w = clip.getWidth(); --w >= 0;)
|
||||
{
|
||||
if (cacheData->isNonZero())
|
||||
{
|
||||
const float top = jmax (midY - cacheData->getMaxValue() * vscale - 0.3f, topY);
|
||||
const float bottom = jmin (midY - cacheData->getMinValue() * vscale + 0.3f, bottomY);
|
||||
auto top = jmax (midY - cacheData->getMaxValue() * vscale - 0.3f, topY);
|
||||
auto bottom = jmin (midY - cacheData->getMinValue() * vscale + 0.3f, bottomY);
|
||||
|
||||
waveform.addWithoutMerging (Rectangle<float> (x, top, 1.0f, bottom - top));
|
||||
}
|
||||
|
|
@ -431,15 +425,15 @@ public:
|
|||
|
||||
private:
|
||||
Array<MinMaxValue> data;
|
||||
double cachedStart, cachedTimePerPixel;
|
||||
int numChannelsCached, numSamplesCached;
|
||||
bool cacheNeedsRefilling;
|
||||
double cachedStart = 0, cachedTimePerPixel = 0;
|
||||
int numChannelsCached = 0, numSamplesCached = 0;
|
||||
bool cacheNeedsRefilling = true;
|
||||
|
||||
bool refillCache (const int numSamples, double startTime, const double endTime,
|
||||
const double rate, const int numChans, const int sampsPerThumbSample,
|
||||
bool refillCache (int numSamples, double startTime, double endTime,
|
||||
double rate, int numChans, int sampsPerThumbSample,
|
||||
LevelDataSource* levelData, const OwnedArray<ThumbData>& chans)
|
||||
{
|
||||
const double timePerPixel = (endTime - startTime) / numSamples;
|
||||
auto timePerPixel = (endTime - startTime) / numSamples;
|
||||
|
||||
if (numSamples <= 0 || timePerPixel <= 0.0 || rate <= 0)
|
||||
{
|
||||
|
|
@ -466,13 +460,13 @@ private:
|
|||
|
||||
if (timePerPixel * rate <= sampsPerThumbSample && levelData != nullptr)
|
||||
{
|
||||
int sample = roundToInt (startTime * rate);
|
||||
Array<Range<float> > levels;
|
||||
auto sample = roundToInt (startTime * rate);
|
||||
Array<Range<float>> levels;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < numSamples; ++i)
|
||||
{
|
||||
const int nextSample = roundToInt ((startTime + timePerPixel) * rate);
|
||||
auto nextSample = roundToInt ((startTime + timePerPixel) * rate);
|
||||
|
||||
if (sample >= 0)
|
||||
{
|
||||
|
|
@ -485,7 +479,7 @@ private:
|
|||
{
|
||||
levelData->getLevels (sample, jmax (1, nextSample - sample), levels);
|
||||
|
||||
const int totalChans = jmin (levels.size(), numChannelsCached);
|
||||
auto totalChans = jmin (levels.size(), numChannelsCached);
|
||||
|
||||
for (int chan = 0; chan < totalChans; ++chan)
|
||||
getData (chan, i)->setFloat (levels.getReference (chan));
|
||||
|
|
@ -507,14 +501,14 @@ private:
|
|||
ThumbData* channelData = chans.getUnchecked (channelNum);
|
||||
MinMaxValue* cacheData = getData (channelNum, 0);
|
||||
|
||||
const double timeToThumbSampleFactor = rate / (double) sampsPerThumbSample;
|
||||
auto timeToThumbSampleFactor = rate / (double) sampsPerThumbSample;
|
||||
|
||||
startTime = cachedStart;
|
||||
int sample = roundToInt (startTime * timeToThumbSampleFactor);
|
||||
auto sample = roundToInt (startTime * timeToThumbSampleFactor);
|
||||
|
||||
for (int i = numSamples; --i >= 0;)
|
||||
{
|
||||
const int nextSample = roundToInt ((startTime + timePerPixel) * timeToThumbSampleFactor);
|
||||
auto nextSample = roundToInt ((startTime + timePerPixel) * timeToThumbSampleFactor);
|
||||
|
||||
channelData->getMinMax (sample, nextSample, *cacheData);
|
||||
|
||||
|
|
@ -538,7 +532,7 @@ private:
|
|||
|
||||
void ensureSize (const int numSamples)
|
||||
{
|
||||
const int itemsRequired = numSamples * numChannelsCached;
|
||||
auto itemsRequired = numSamples * numChannelsCached;
|
||||
|
||||
if (data.size() < itemsRequired)
|
||||
data.insertMultiple (-1, MinMaxValue(), itemsRequired - data.size());
|
||||
|
|
@ -552,11 +546,7 @@ AudioThumbnail::AudioThumbnail (const int originalSamplesPerThumbnailSample,
|
|||
: formatManagerToUse (formatManager),
|
||||
cache (cacheToUse),
|
||||
window (new CachedWindow()),
|
||||
samplesPerThumbSample (originalSamplesPerThumbnailSample),
|
||||
totalSamples (0),
|
||||
numSamplesFinished (0),
|
||||
numChannels (0),
|
||||
sampleRate (0)
|
||||
samplesPerThumbSample (originalSamplesPerThumbnailSample)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -710,26 +700,26 @@ void AudioThumbnail::addBlock (const int64 startSample, const AudioSampleBuffer&
|
|||
&& startOffsetInBuffer >= 0
|
||||
&& startOffsetInBuffer + numSamples <= incoming.getNumSamples());
|
||||
|
||||
const int firstThumbIndex = (int) (startSample / samplesPerThumbSample);
|
||||
const int lastThumbIndex = (int) ((startSample + numSamples + (samplesPerThumbSample - 1)) / samplesPerThumbSample);
|
||||
const int numToDo = lastThumbIndex - firstThumbIndex;
|
||||
auto firstThumbIndex = (int) (startSample / samplesPerThumbSample);
|
||||
auto lastThumbIndex = (int) ((startSample + numSamples + (samplesPerThumbSample - 1)) / samplesPerThumbSample);
|
||||
auto numToDo = lastThumbIndex - firstThumbIndex;
|
||||
|
||||
if (numToDo > 0)
|
||||
{
|
||||
const int numChans = jmin (channels.size(), incoming.getNumChannels());
|
||||
auto numChans = jmin (channels.size(), incoming.getNumChannels());
|
||||
|
||||
const HeapBlock<MinMaxValue> thumbData ((size_t) (numToDo * numChans));
|
||||
const HeapBlock<MinMaxValue*> thumbChannels ((size_t) numChans);
|
||||
const HeapBlock<MinMaxValue> thumbData (numToDo * numChans);
|
||||
const HeapBlock<MinMaxValue*> thumbChannels (numChans);
|
||||
|
||||
for (int chan = 0; chan < numChans; ++chan)
|
||||
{
|
||||
const float* const sourceData = incoming.getReadPointer (chan, startOffsetInBuffer);
|
||||
MinMaxValue* const dest = thumbData + numToDo * chan;
|
||||
auto* sourceData = incoming.getReadPointer (chan, startOffsetInBuffer);
|
||||
auto* dest = thumbData + numToDo * chan;
|
||||
thumbChannels [chan] = dest;
|
||||
|
||||
for (int i = 0; i < numToDo; ++i)
|
||||
{
|
||||
const int start = i * samplesPerThumbSample;
|
||||
auto start = i * samplesPerThumbSample;
|
||||
dest[i].setFloat (FloatVectorOperations::findMinAndMax (sourceData + start, jmin (samplesPerThumbSample, numSamples - start)));
|
||||
}
|
||||
}
|
||||
|
|
@ -745,8 +735,8 @@ void AudioThumbnail::setLevels (const MinMaxValue* const* values, int thumbIndex
|
|||
for (int i = jmin (numChans, channels.size()); --i >= 0;)
|
||||
channels.getUnchecked(i)->write (values[i], thumbIndex, numValues);
|
||||
|
||||
const int64 start = thumbIndex * (int64) samplesPerThumbSample;
|
||||
const int64 end = (thumbIndex + numValues) * (int64) samplesPerThumbSample;
|
||||
auto start = thumbIndex * (int64) samplesPerThumbSample;
|
||||
auto end = (thumbIndex + numValues) * (int64) samplesPerThumbSample;
|
||||
|
||||
if (numSamplesFinished >= start && end > numSamplesFinished)
|
||||
numSamplesFinished = end;
|
||||
|
|
@ -787,23 +777,23 @@ float AudioThumbnail::getApproximatePeak() const
|
|||
const ScopedLock sl (lock);
|
||||
int peak = 0;
|
||||
|
||||
for (int i = channels.size(); --i >= 0;)
|
||||
peak = jmax (peak, channels.getUnchecked(i)->getPeak());
|
||||
for (auto* c : channels)
|
||||
peak = jmax (peak, c->getPeak());
|
||||
|
||||
return jlimit (0, 127, peak) / 127.0f;
|
||||
}
|
||||
|
||||
void AudioThumbnail::getApproximateMinMax (const double startTime, const double endTime, const int channelIndex,
|
||||
void AudioThumbnail::getApproximateMinMax (double startTime, double endTime, int channelIndex,
|
||||
float& minValue, float& maxValue) const noexcept
|
||||
{
|
||||
const ScopedLock sl (lock);
|
||||
MinMaxValue result;
|
||||
const ThumbData* const data = channels [channelIndex];
|
||||
auto* data = channels [channelIndex];
|
||||
|
||||
if (data != nullptr && sampleRate > 0)
|
||||
{
|
||||
const int firstThumbIndex = (int) ((startTime * sampleRate) / samplesPerThumbSample);
|
||||
const int lastThumbIndex = (int) (((endTime * sampleRate) + samplesPerThumbSample - 1) / samplesPerThumbSample);
|
||||
auto firstThumbIndex = (int) ((startTime * sampleRate) / samplesPerThumbSample);
|
||||
auto lastThumbIndex = (int) (((endTime * sampleRate) + samplesPerThumbSample - 1) / samplesPerThumbSample);
|
||||
|
||||
data->getMinMax (jmax (0, firstThumbIndex), lastThumbIndex, result);
|
||||
}
|
||||
|
|
@ -826,10 +816,10 @@ void AudioThumbnail::drawChannels (Graphics& g, const Rectangle<int>& area, doub
|
|||
{
|
||||
for (int i = 0; i < numChannels; ++i)
|
||||
{
|
||||
const int y1 = roundToInt ((i * area.getHeight()) / numChannels);
|
||||
const int y2 = roundToInt (((i + 1) * area.getHeight()) / numChannels);
|
||||
auto y1 = roundToInt ((i * area.getHeight()) / numChannels);
|
||||
auto y2 = roundToInt (((i + 1) * area.getHeight()) / numChannels);
|
||||
|
||||
drawChannel (g, Rectangle<int> (area.getX(), area.getY() + y1, area.getWidth(), y2 - y1),
|
||||
drawChannel (g, { area.getX(), area.getY() + y1, area.getWidth(), y2 - y1 },
|
||||
startTimeSeconds, endTimeSeconds, i, verticalZoomFactor);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,10 +210,10 @@ private:
|
|||
ScopedPointer<CachedWindow> window;
|
||||
OwnedArray<ThumbData> channels;
|
||||
|
||||
int32 samplesPerThumbSample;
|
||||
int64 totalSamples, numSamplesFinished;
|
||||
int32 numChannels;
|
||||
double sampleRate;
|
||||
int32 samplesPerThumbSample = 0;
|
||||
int64 totalSamples = 0, numSamplesFinished = 0;
|
||||
int32 numChannels = 0;
|
||||
double sampleRate = 0;
|
||||
CriticalSection lock;
|
||||
|
||||
void clearChannelData();
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ void AudioProcessorPlayer::audioDeviceAboutToStart (AudioIODevice* const device)
|
|||
numOutputChans = numChansOut;
|
||||
|
||||
messageCollector.reset (sampleRate);
|
||||
channels.calloc ((size_t) jmax (numChansIn, numChansOut) + 2);
|
||||
channels.calloc (jmax (numChansIn, numChansOut) + 2);
|
||||
|
||||
if (processor != nullptr)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue