Browse Source

Aiff float support.

tags/2021-05-28
jules 13 years ago
parent
commit
fdfdc2bbbf
4 changed files with 51 additions and 39 deletions
  1. +29
    -27
      modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp
  2. +4
    -8
      modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp
  3. +15
    -0
      modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h
  4. +3
    -4
      modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp

+ 29
- 27
modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp View File

@@ -314,6 +314,11 @@ public:
{ {
littleEndian = true; littleEndian = true;
} }
else if (compType == chunkName ("fl32") || compType == chunkName ("FL32"))
{
littleEndian = false;
usesFloatingPointData = true;
}
else else
{ {
sampleRate = 0; sampleRate = 0;
@@ -429,15 +434,14 @@ public:
zeromem (tempBuffer + bytesRead, (size_t) (numThisTime * bytesPerFrame - bytesRead)); zeromem (tempBuffer + bytesRead, (size_t) (numThisTime * bytesPerFrame - bytesRead));
} }
jassert (! usesFloatingPointData); // (would need to add support for this if it's possible)
if (littleEndian) 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 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; startOffsetInDestBuffer += numThisTime;
numSamples -= numThisTime; numSamples -= numThisTime;
@@ -447,7 +451,8 @@ public:
} }
template <typename Endianness> 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 const void* sourceData, int numChannels, int numSamples) noexcept
{ {
switch (bitsPerSample) switch (bitsPerSample)
@@ -455,7 +460,8 @@ public:
case 8: ReadHelper<AudioData::Int32, AudioData::Int8, Endianness>::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; 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 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 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; default: jassertfalse; break;
} }
} }
@@ -677,11 +683,11 @@ public:
if (littleEndian) if (littleEndian)
AiffAudioFormatReader::copySampleData<AudioData::LittleEndian> AiffAudioFormatReader::copySampleData<AudioData::LittleEndian>
(bitsPerSample, destSamples, startOffsetInDestBuffer,
(bitsPerSample, usesFloatingPointData, destSamples, startOffsetInDestBuffer,
numDestChannels, sampleToPointer (startSampleInFile), (int) numChannels, numSamples); numDestChannels, sampleToPointer (startSampleInFile), (int) numChannels, numSamples);
else else
AiffAudioFormatReader::copySampleData<AudioData::BigEndian> AiffAudioFormatReader::copySampleData<AudioData::BigEndian>
(bitsPerSample, destSamples, startOffsetInDestBuffer,
(bitsPerSample, usesFloatingPointData, destSamples, startOffsetInDestBuffer,
numDestChannels, sampleToPointer (startSampleInFile), (int) numChannels, numSamples); numDestChannels, sampleToPointer (startSampleInFile), (int) numChannels, numSamples);
return true; return true;
@@ -709,7 +715,8 @@ public:
case 8: scanMinAndMax<AudioData::UInt8> (startSampleInFile, numSamples, min0, max0, min1, max1); break; 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 16: scanMinAndMax<AudioData::Int16> (startSampleInFile, numSamples, min0, max0, min1, max1); break;
case 24: scanMinAndMax<AudioData::Int24> (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; default: jassertfalse; break;
} }
} }
@@ -721,26 +728,21 @@ private:
void scanMinAndMax (int64 startSampleInFile, int64 numSamples, void scanMinAndMax (int64 startSampleInFile, int64 numSamples,
float& min0, float& max0, float& min1, float& max1) const noexcept float& min0, float& max0, float& min1, float& max1) const noexcept
{ {
if (littleEndian)
scanMinAndMax2<SampleType, AudioData::LittleEndian> (startSampleInFile, numSamples, min0, max0, min1, max1);
scanMinAndMax2<SampleType> (0, startSampleInFile, numSamples, min0, max0);
if (numChannels > 1)
scanMinAndMax2<SampleType> (1, startSampleInFile, numSamples, min1, max1);
else else
scanMinAndMax2<SampleType, AudioData::BigEndian> (startSampleInFile, numSamples, min0, max0, min1, max1);
min1 = max1 = 0;
} }
template <typename SampleType, typename Endianness>
void scanMinAndMax2 (int64 startSampleInFile, int64 numSamples,
float& min0, float& max0, float& min1, float& max1) const noexcept
template <typename SampleType>
void scanMinAndMax2 (int channel, int64 startSampleInFile, int64 numSamples, float& mn, float& mx) const noexcept
{ {
typedef AudioData::Pointer <SampleType, Endianness, AudioData::Interleaved, AudioData::Const> SourceType;
SourceType (sampleToPointer (startSampleInFile), (int) numChannels)
.findMinAndMax ((size_t) numSamples, min0, max0);
if (numChannels > 1)
SourceType (addBytesToPointer (sampleToPointer (startSampleInFile), bitsPerSample / 8), (int) numChannels)
.findMinAndMax ((size_t) numSamples, min1, max1);
if (littleEndian)
scanMinAndMaxInterleaved<SampleType, AudioData::LittleEndian> (channel, startSampleInFile, numSamples, mn, mx);
else else
min1 = max1 = 0;
scanMinAndMaxInterleaved<SampleType, AudioData::BigEndian> (channel, startSampleInFile, numSamples, mn, mx);
} }
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedAiffReader) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedAiffReader)


+ 4
- 8
modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp 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 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 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); 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; default: jassertfalse; break;
} }
} }
@@ -1057,16 +1057,12 @@ public:
private: private:
template <typename SampleType> template <typename SampleType>
void scanMinAndMax (int64 startSampleInFile, int64 numSamples, 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) 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 else
min1 = max1 = 0; min1 = max1 = 0;
} }


+ 15
- 0
modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h View File

@@ -80,10 +80,25 @@ protected:
int64 dataChunkStart, dataLength; int64 dataChunkStart, dataLength;
int bytesPerFrame; int bytesPerFrame;
/** Converts a sample index to a byte position in the file. */
inline int64 sampleToFilePos (int64 sample) const noexcept { return dataChunkStart + sample * bytesPerFrame; } 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; } 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()); } 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) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedAudioFormatReader)
}; };


+ 3
- 4
modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp View File

@@ -36,10 +36,9 @@ public:
void messageCallback() 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: private:


Loading…
Cancel
Save