mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-11 23:54:18 +00:00
Aiff float support.
This commit is contained in:
parent
79099619f9
commit
fdfdc2bbbf
4 changed files with 52 additions and 40 deletions
|
|
@ -314,6 +314,11 @@ public:
|
|||
{
|
||||
littleEndian = true;
|
||||
}
|
||||
else if (compType == chunkName ("fl32") || compType == chunkName ("FL32"))
|
||||
{
|
||||
littleEndian = false;
|
||||
usesFloatingPointData = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sampleRate = 0;
|
||||
|
|
@ -429,15 +434,14 @@ public:
|
|||
zeromem (tempBuffer + bytesRead, (size_t) (numThisTime * bytesPerFrame - bytesRead));
|
||||
}
|
||||
|
||||
jassert (! usesFloatingPointData); // (would need to add support for this if it's possible)
|
||||
|
||||
if (littleEndian)
|
||||
copySampleData<AudioData::LittleEndian> (bitsPerSample, destSamples, startOffsetInDestBuffer,
|
||||
numDestChannels, tempBuffer, (int) numChannels, numThisTime);
|
||||
copySampleData<AudioData::LittleEndian> (bitsPerSample, usesFloatingPointData,
|
||||
destSamples, startOffsetInDestBuffer, numDestChannels,
|
||||
tempBuffer, (int) numChannels, numThisTime);
|
||||
else
|
||||
copySampleData<AudioData::BigEndian> (bitsPerSample, destSamples, startOffsetInDestBuffer,
|
||||
numDestChannels, tempBuffer, (int) numChannels, numThisTime);
|
||||
|
||||
copySampleData<AudioData::BigEndian> (bitsPerSample, usesFloatingPointData,
|
||||
destSamples, startOffsetInDestBuffer, numDestChannels,
|
||||
tempBuffer, (int) numChannels, numThisTime);
|
||||
|
||||
startOffsetInDestBuffer += numThisTime;
|
||||
numSamples -= numThisTime;
|
||||
|
|
@ -447,7 +451,8 @@ public:
|
|||
}
|
||||
|
||||
template <typename Endianness>
|
||||
static void copySampleData (unsigned int bitsPerSample, int* const* destSamples, int startOffsetInDestBuffer, int numDestChannels,
|
||||
static void copySampleData (unsigned int bitsPerSample, const bool usesFloatingPointData,
|
||||
int* const* destSamples, int startOffsetInDestBuffer, int numDestChannels,
|
||||
const void* sourceData, int numChannels, int numSamples) noexcept
|
||||
{
|
||||
switch (bitsPerSample)
|
||||
|
|
@ -455,7 +460,8 @@ public:
|
|||
case 8: ReadHelper<AudioData::Int32, AudioData::Int8, Endianness>::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break;
|
||||
case 16: ReadHelper<AudioData::Int32, AudioData::Int16, Endianness>::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break;
|
||||
case 24: ReadHelper<AudioData::Int32, AudioData::Int24, Endianness>::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break;
|
||||
case 32: ReadHelper<AudioData::Int32, AudioData::Int32, Endianness>::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break;
|
||||
case 32: if (usesFloatingPointData) ReadHelper<AudioData::Float32, AudioData::Float32, Endianness>::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples);
|
||||
else ReadHelper<AudioData::Int32, AudioData::Int32, Endianness>::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break;
|
||||
default: jassertfalse; break;
|
||||
}
|
||||
}
|
||||
|
|
@ -677,11 +683,11 @@ public:
|
|||
|
||||
if (littleEndian)
|
||||
AiffAudioFormatReader::copySampleData<AudioData::LittleEndian>
|
||||
(bitsPerSample, destSamples, startOffsetInDestBuffer,
|
||||
(bitsPerSample, usesFloatingPointData, destSamples, startOffsetInDestBuffer,
|
||||
numDestChannels, sampleToPointer (startSampleInFile), (int) numChannels, numSamples);
|
||||
else
|
||||
AiffAudioFormatReader::copySampleData<AudioData::BigEndian>
|
||||
(bitsPerSample, destSamples, startOffsetInDestBuffer,
|
||||
(bitsPerSample, usesFloatingPointData, destSamples, startOffsetInDestBuffer,
|
||||
numDestChannels, sampleToPointer (startSampleInFile), (int) numChannels, numSamples);
|
||||
|
||||
return true;
|
||||
|
|
@ -709,7 +715,8 @@ public:
|
|||
case 8: scanMinAndMax<AudioData::UInt8> (startSampleInFile, numSamples, min0, max0, min1, max1); break;
|
||||
case 16: scanMinAndMax<AudioData::Int16> (startSampleInFile, numSamples, min0, max0, min1, max1); break;
|
||||
case 24: scanMinAndMax<AudioData::Int24> (startSampleInFile, numSamples, min0, max0, min1, max1); break;
|
||||
case 32: scanMinAndMax<AudioData::Int32> (startSampleInFile, numSamples, min0, max0, min1, max1); break;
|
||||
case 32: if (usesFloatingPointData) scanMinAndMax<AudioData::Float32> (startSampleInFile, numSamples, min0, max0, min1, max1);
|
||||
else scanMinAndMax<AudioData::Int32> (startSampleInFile, numSamples, min0, max0, min1, max1); break;
|
||||
default: jassertfalse; break;
|
||||
}
|
||||
}
|
||||
|
|
@ -721,28 +728,23 @@ private:
|
|||
void scanMinAndMax (int64 startSampleInFile, int64 numSamples,
|
||||
float& min0, float& max0, float& min1, float& max1) const noexcept
|
||||
{
|
||||
if (littleEndian)
|
||||
scanMinAndMax2<SampleType, AudioData::LittleEndian> (startSampleInFile, numSamples, min0, max0, min1, max1);
|
||||
else
|
||||
scanMinAndMax2<SampleType, AudioData::BigEndian> (startSampleInFile, numSamples, min0, max0, min1, max1);
|
||||
}
|
||||
|
||||
template <typename SampleType, typename Endianness>
|
||||
void scanMinAndMax2 (int64 startSampleInFile, int64 numSamples,
|
||||
float& min0, float& max0, float& min1, float& max1) const noexcept
|
||||
{
|
||||
typedef AudioData::Pointer <SampleType, Endianness, AudioData::Interleaved, AudioData::Const> SourceType;
|
||||
|
||||
SourceType (sampleToPointer (startSampleInFile), (int) numChannels)
|
||||
.findMinAndMax ((size_t) numSamples, min0, max0);
|
||||
scanMinAndMax2<SampleType> (0, startSampleInFile, numSamples, min0, max0);
|
||||
|
||||
if (numChannels > 1)
|
||||
SourceType (addBytesToPointer (sampleToPointer (startSampleInFile), bitsPerSample / 8), (int) numChannels)
|
||||
.findMinAndMax ((size_t) numSamples, min1, max1);
|
||||
scanMinAndMax2<SampleType> (1, startSampleInFile, numSamples, min1, max1);
|
||||
else
|
||||
min1 = max1 = 0;
|
||||
}
|
||||
|
||||
template <typename SampleType>
|
||||
void scanMinAndMax2 (int channel, int64 startSampleInFile, int64 numSamples, float& mn, float& mx) const noexcept
|
||||
{
|
||||
if (littleEndian)
|
||||
scanMinAndMaxInterleaved<SampleType, AudioData::LittleEndian> (channel, startSampleInFile, numSamples, mn, mx);
|
||||
else
|
||||
scanMinAndMaxInterleaved<SampleType, AudioData::BigEndian> (channel, startSampleInFile, numSamples, mn, mx);
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedAiffReader)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -755,7 +755,7 @@ public:
|
|||
case 16: ReadHelper<AudioData::Int32, AudioData::Int16, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break;
|
||||
case 24: ReadHelper<AudioData::Int32, AudioData::Int24, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break;
|
||||
case 32: if (usesFloatingPointData) ReadHelper<AudioData::Float32, AudioData::Float32, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples);
|
||||
else ReadHelper<AudioData::Int32, AudioData::Int32, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break;
|
||||
else ReadHelper<AudioData::Int32, AudioData::Int32, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break;
|
||||
default: jassertfalse; break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1057,16 +1057,12 @@ public:
|
|||
private:
|
||||
template <typename SampleType>
|
||||
void scanMinAndMax (int64 startSampleInFile, int64 numSamples,
|
||||
float& min0, float& max0, float& min1, float& max1) const
|
||||
float& min0, float& max0, float& min1, float& max1) const noexcept
|
||||
{
|
||||
typedef AudioData::Pointer <SampleType, AudioData::LittleEndian, AudioData::Interleaved, AudioData::Const> SourceType;
|
||||
|
||||
SourceType (sampleToPointer (startSampleInFile), (int) numChannels)
|
||||
.findMinAndMax ((size_t) numSamples, min0, max0);
|
||||
scanMinAndMaxInterleaved<SampleType, AudioData::LittleEndian> (0, startSampleInFile, numSamples, min0, max0);
|
||||
|
||||
if (numChannels > 1)
|
||||
SourceType (addBytesToPointer (sampleToPointer (startSampleInFile), bitsPerSample / 8), (int) numChannels)
|
||||
.findMinAndMax ((size_t) numSamples, min1, max1);
|
||||
scanMinAndMaxInterleaved<SampleType, AudioData::LittleEndian> (1, startSampleInFile, numSamples, min1, max1);
|
||||
else
|
||||
min1 = max1 = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,10 +80,25 @@ protected:
|
|||
int64 dataChunkStart, dataLength;
|
||||
int bytesPerFrame;
|
||||
|
||||
/** Converts a sample index to a byte position in the file. */
|
||||
inline int64 sampleToFilePos (int64 sample) const noexcept { return dataChunkStart + sample * bytesPerFrame; }
|
||||
|
||||
/** Converts a byte position in the file to a sample index. */
|
||||
inline int64 filePosToSample (int64 filePos) const noexcept { return (filePos - dataChunkStart) / bytesPerFrame; }
|
||||
|
||||
/** Converts a sample index to a pointer to the mapped file memory. */
|
||||
inline const void* sampleToPointer (int64 sample) const noexcept { return addBytesToPointer (map->getData(), sampleToFilePos (sample) - map->getRange().getStart()); }
|
||||
|
||||
/** Used by AudioFormatReader subclasses to scan for min/max ranges in interleaved data. */
|
||||
template <typename SampleType, typename Endianness>
|
||||
void scanMinAndMaxInterleaved (int channel, int64 startSampleInFile, int64 numSamples, float& mn, float& mx) const noexcept
|
||||
{
|
||||
typedef AudioData::Pointer <SampleType, Endianness, AudioData::Interleaved, AudioData::Const> SourceType;
|
||||
|
||||
SourceType (addBytesToPointer (sampleToPointer (startSampleInFile), (bitsPerSample / 8) * channel), (int) numChannels)
|
||||
.findMinAndMax ((size_t) numSamples, mn, mx);
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedAudioFormatReader)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -36,10 +36,9 @@ public:
|
|||
|
||||
void messageCallback()
|
||||
{
|
||||
const ActionBroadcaster* const b = broadcaster;
|
||||
|
||||
if (b != nullptr && b->actionListeners.contains (listener))
|
||||
listener->actionListenerCallback (message);
|
||||
if (const ActionBroadcaster* const b = broadcaster)
|
||||
if (b->actionListeners.contains (listener))
|
||||
listener->actionListenerCallback (message);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue