1
0
Fork 0
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:
jules 2013-03-12 11:13:53 +00:00
parent 79099619f9
commit fdfdc2bbbf
4 changed files with 52 additions and 40 deletions

View file

@ -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)
};

View file

@ -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;
}

View file

@ -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)
};

View file

@ -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: