mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-02-02 03:20:06 +00:00
Added a version of AudioFormatReader::readMaxLevels() which takes any number of channels.
This commit is contained in:
parent
5c7bf01c16
commit
7b5b6cbd71
2 changed files with 75 additions and 86 deletions
|
|
@ -173,35 +173,54 @@ void AudioFormatReader::read (AudioSampleBuffer* buffer,
|
|||
}
|
||||
}
|
||||
|
||||
template <typename SampleType>
|
||||
static Range<SampleType> getChannelMinAndMax (SampleType* channel, int numSamples) noexcept
|
||||
void AudioFormatReader::readMaxLevels (int64 startSampleInFile, int64 numSamples,
|
||||
Range<float>* const results, const int channelsToRead)
|
||||
{
|
||||
return Range<SampleType>::findMinAndMax (channel, numSamples);
|
||||
}
|
||||
jassert (channelsToRead > 0 && channelsToRead <= numChannels);
|
||||
|
||||
static Range<float> getChannelMinAndMax (float* channel, int numSamples) noexcept
|
||||
{
|
||||
return FloatVectorOperations::findMinAndMax (channel, numSamples);
|
||||
}
|
||||
|
||||
template <typename SampleType>
|
||||
static void getStereoMinAndMax (SampleType* const* channels, const int numChannels, const int numSamples,
|
||||
SampleType& lmin, SampleType& lmax, SampleType& rmin, SampleType& rmax)
|
||||
{
|
||||
Range<SampleType> range (getChannelMinAndMax (channels[0], numSamples));
|
||||
lmax = jmax (lmax, range.getEnd());
|
||||
lmin = jmin (lmin, range.getStart());
|
||||
|
||||
if (numChannels > 1)
|
||||
if (numSamples <= 0)
|
||||
{
|
||||
range = getChannelMinAndMax (channels[1], numSamples);
|
||||
rmax = jmax (rmax, range.getEnd());
|
||||
rmin = jmin (rmin, range.getStart());
|
||||
for (int i = 0; i < channelsToRead; ++i)
|
||||
results[i] = Range<float>();
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
const int bufferSize = (int) jmin (numSamples, (int64) 4096);
|
||||
AudioSampleBuffer tempSampleBuffer ((int) channelsToRead, bufferSize);
|
||||
|
||||
float* const* const floatBuffer = tempSampleBuffer.getArrayOfWritePointers();
|
||||
int* const* intBuffer = reinterpret_cast<int* const*> (floatBuffer);
|
||||
bool isFirstBlock = true;
|
||||
|
||||
while (numSamples > 0)
|
||||
{
|
||||
rmax = lmax;
|
||||
rmin = lmin;
|
||||
const int numToDo = (int) jmin (numSamples, (int64) bufferSize);
|
||||
if (! read (intBuffer, channelsToRead, startSampleInFile, numToDo, false))
|
||||
break;
|
||||
|
||||
for (int i = 0; i < channelsToRead; ++i)
|
||||
{
|
||||
Range<float> r;
|
||||
|
||||
if (usesFloatingPointData)
|
||||
{
|
||||
r = FloatVectorOperations::findMinAndMax (floatBuffer[i], numToDo);
|
||||
}
|
||||
else
|
||||
{
|
||||
Range<int> intRange (Range<int>::findMinAndMax (intBuffer[i], numToDo));
|
||||
|
||||
r = Range<float> (intRange.getStart() / (float) std::numeric_limits<int>::max(),
|
||||
intRange.getEnd() / (float) std::numeric_limits<int>::max());
|
||||
}
|
||||
|
||||
results[i] = isFirstBlock ? r : results[i].getUnionWith (r);
|
||||
}
|
||||
|
||||
isFirstBlock = false;
|
||||
numSamples -= numToDo;
|
||||
startSampleInFile += numToDo;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -209,66 +228,20 @@ void AudioFormatReader::readMaxLevels (int64 startSampleInFile, int64 numSamples
|
|||
float& lowestLeft, float& highestLeft,
|
||||
float& lowestRight, float& highestRight)
|
||||
{
|
||||
if (numSamples <= 0)
|
||||
Range<float> levels[2];
|
||||
readMaxLevels (startSampleInFile, numSamples, levels, jmin (2, (int) numChannels));
|
||||
lowestLeft = levels[0].getStart();
|
||||
highestLeft = levels[0].getEnd();
|
||||
|
||||
if (numChannels > 1)
|
||||
{
|
||||
lowestLeft = 0;
|
||||
lowestRight = 0;
|
||||
highestLeft = 0;
|
||||
highestRight = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const int bufferSize = (int) jmin (numSamples, (int64) 4096);
|
||||
AudioSampleBuffer tempSampleBuffer ((int) numChannels, bufferSize);
|
||||
|
||||
float* const* const floatBuffer = tempSampleBuffer.getArrayOfWritePointers();
|
||||
int* const* intBuffer = reinterpret_cast<int* const*> (floatBuffer);
|
||||
|
||||
if (usesFloatingPointData)
|
||||
{
|
||||
float lmin = 1.0e6f;
|
||||
float lmax = -lmin;
|
||||
float rmin = lmin;
|
||||
float rmax = lmax;
|
||||
|
||||
while (numSamples > 0)
|
||||
{
|
||||
const int numToDo = (int) jmin (numSamples, (int64) bufferSize);
|
||||
if (! read (intBuffer, 2, startSampleInFile, numToDo, false))
|
||||
break;
|
||||
|
||||
numSamples -= numToDo;
|
||||
startSampleInFile += numToDo;
|
||||
getStereoMinAndMax (floatBuffer, (int) numChannels, numToDo, lmin, lmax, rmin, rmax);
|
||||
}
|
||||
|
||||
lowestLeft = lmin;
|
||||
highestLeft = lmax;
|
||||
lowestRight = rmin;
|
||||
highestRight = rmax;
|
||||
lowestRight = levels[1].getStart();
|
||||
highestRight = levels[1].getEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
int lmax = std::numeric_limits<int>::min();
|
||||
int lmin = std::numeric_limits<int>::max();
|
||||
int rmax = std::numeric_limits<int>::min();
|
||||
int rmin = std::numeric_limits<int>::max();
|
||||
|
||||
while (numSamples > 0)
|
||||
{
|
||||
const int numToDo = (int) jmin (numSamples, (int64) bufferSize);
|
||||
if (! read (intBuffer, 2, startSampleInFile, numToDo, false))
|
||||
break;
|
||||
|
||||
numSamples -= numToDo;
|
||||
startSampleInFile += numToDo;
|
||||
getStereoMinAndMax (intBuffer, (int) numChannels, numToDo, lmin, lmax, rmin, rmax);
|
||||
}
|
||||
|
||||
lowestLeft = lmin / (float) std::numeric_limits<int>::max();
|
||||
highestLeft = lmax / (float) std::numeric_limits<int>::max();
|
||||
lowestRight = rmin / (float) std::numeric_limits<int>::max();
|
||||
highestRight = rmax / (float) std::numeric_limits<int>::max();
|
||||
lowestRight = lowestLeft;
|
||||
highestRight = highestLeft;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,6 +121,25 @@ public:
|
|||
bool useReaderLeftChan,
|
||||
bool useReaderRightChan);
|
||||
|
||||
/** Finds the highest and lowest sample levels from a section of the audio stream.
|
||||
|
||||
This will read a block of samples from the stream, and measure the
|
||||
highest and lowest sample levels from the channels in that section, returning
|
||||
these as normalised floating-point levels.
|
||||
|
||||
@param startSample the offset into the audio stream to start reading from. It's
|
||||
ok for this to be beyond the start or end of the stream.
|
||||
@param numSamples how many samples to read
|
||||
@param results this array will be filled with Range values for each channel.
|
||||
The array must contain numChannels elements.
|
||||
@param numChannelsToRead the number of channels of data to scan. This must be
|
||||
more than zero, but not more than the total number of channels
|
||||
that the reader contains
|
||||
@see read
|
||||
*/
|
||||
virtual void readMaxLevels (int64 startSample, int64 numSamples,
|
||||
Range<float>* results, int numChannelsToRead);
|
||||
|
||||
/** Finds the highest and lowest sample levels from a section of the audio stream.
|
||||
|
||||
This will read a block of samples from the stream, and measure the
|
||||
|
|
@ -138,12 +157,9 @@ public:
|
|||
channel (if there is one)
|
||||
@see read
|
||||
*/
|
||||
virtual void readMaxLevels (int64 startSample,
|
||||
int64 numSamples,
|
||||
float& lowestLeft,
|
||||
float& highestLeft,
|
||||
float& lowestRight,
|
||||
float& highestRight);
|
||||
virtual void readMaxLevels (int64 startSample, int64 numSamples,
|
||||
float& lowestLeft, float& highestLeft,
|
||||
float& lowestRight, float& highestRight);
|
||||
|
||||
/** Scans the source looking for a sample whose magnitude is in a specified range.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue