diff --git a/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp index 62b5e75149..fd2188026f 100644 --- a/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp @@ -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 (bitsPerSample, destSamples, startOffsetInDestBuffer, - numDestChannels, tempBuffer, (int) numChannels, numThisTime); + copySampleData (bitsPerSample, usesFloatingPointData, + destSamples, startOffsetInDestBuffer, numDestChannels, + tempBuffer, (int) numChannels, numThisTime); else - copySampleData (bitsPerSample, destSamples, startOffsetInDestBuffer, - numDestChannels, tempBuffer, (int) numChannels, numThisTime); - + copySampleData (bitsPerSample, usesFloatingPointData, + destSamples, startOffsetInDestBuffer, numDestChannels, + tempBuffer, (int) numChannels, numThisTime); startOffsetInDestBuffer += numThisTime; numSamples -= numThisTime; @@ -447,7 +451,8 @@ public: } template - 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::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; case 16: ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; case 24: ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; - case 32: ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; + case 32: if (usesFloatingPointData) ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); + else ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; default: jassertfalse; break; } } @@ -677,11 +683,11 @@ public: if (littleEndian) AiffAudioFormatReader::copySampleData - (bitsPerSample, destSamples, startOffsetInDestBuffer, + (bitsPerSample, usesFloatingPointData, destSamples, startOffsetInDestBuffer, numDestChannels, sampleToPointer (startSampleInFile), (int) numChannels, numSamples); else AiffAudioFormatReader::copySampleData - (bitsPerSample, destSamples, startOffsetInDestBuffer, + (bitsPerSample, usesFloatingPointData, destSamples, startOffsetInDestBuffer, numDestChannels, sampleToPointer (startSampleInFile), (int) numChannels, numSamples); return true; @@ -709,7 +715,8 @@ public: case 8: scanMinAndMax (startSampleInFile, numSamples, min0, max0, min1, max1); break; case 16: scanMinAndMax (startSampleInFile, numSamples, min0, max0, min1, max1); break; case 24: scanMinAndMax (startSampleInFile, numSamples, min0, max0, min1, max1); break; - case 32: scanMinAndMax (startSampleInFile, numSamples, min0, max0, min1, max1); break; + case 32: if (usesFloatingPointData) scanMinAndMax (startSampleInFile, numSamples, min0, max0, min1, max1); + else scanMinAndMax (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 (startSampleInFile, numSamples, min0, max0, min1, max1); - else - scanMinAndMax2 (startSampleInFile, numSamples, min0, max0, min1, max1); - } - - template - void scanMinAndMax2 (int64 startSampleInFile, int64 numSamples, - float& min0, float& max0, float& min1, float& max1) const noexcept - { - typedef AudioData::Pointer SourceType; - - SourceType (sampleToPointer (startSampleInFile), (int) numChannels) - .findMinAndMax ((size_t) numSamples, min0, max0); + scanMinAndMax2 (0, startSampleInFile, numSamples, min0, max0); if (numChannels > 1) - SourceType (addBytesToPointer (sampleToPointer (startSampleInFile), bitsPerSample / 8), (int) numChannels) - .findMinAndMax ((size_t) numSamples, min1, max1); + scanMinAndMax2 (1, startSampleInFile, numSamples, min1, max1); else min1 = max1 = 0; } + template + void scanMinAndMax2 (int channel, int64 startSampleInFile, int64 numSamples, float& mn, float& mx) const noexcept + { + if (littleEndian) + scanMinAndMaxInterleaved (channel, startSampleInFile, numSamples, mn, mx); + else + scanMinAndMaxInterleaved (channel, startSampleInFile, numSamples, mn, mx); + } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedAiffReader) }; diff --git a/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp index 2e4cb88b85..2cc3eac66e 100644 --- a/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp @@ -755,7 +755,7 @@ public: case 16: ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; case 24: ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; case 32: if (usesFloatingPointData) ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); - else ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; + else ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; default: jassertfalse; break; } } @@ -1057,16 +1057,12 @@ public: private: template 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 SourceType; - - SourceType (sampleToPointer (startSampleInFile), (int) numChannels) - .findMinAndMax ((size_t) numSamples, min0, max0); + scanMinAndMaxInterleaved (0, startSampleInFile, numSamples, min0, max0); if (numChannels > 1) - SourceType (addBytesToPointer (sampleToPointer (startSampleInFile), bitsPerSample / 8), (int) numChannels) - .findMinAndMax ((size_t) numSamples, min1, max1); + scanMinAndMaxInterleaved (1, startSampleInFile, numSamples, min1, max1); else min1 = max1 = 0; } diff --git a/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h b/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h index 70016a3028..28155f7f06 100644 --- a/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h +++ b/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h @@ -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 + void scanMinAndMaxInterleaved (int channel, int64 startSampleInFile, int64 numSamples, float& mn, float& mx) const noexcept + { + typedef AudioData::Pointer SourceType; + + SourceType (addBytesToPointer (sampleToPointer (startSampleInFile), (bitsPerSample / 8) * channel), (int) numChannels) + .findMinAndMax ((size_t) numSamples, mn, mx); + } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedAudioFormatReader) }; diff --git a/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp b/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp index 2a61011362..1f614a6739 100644 --- a/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp +++ b/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp @@ -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: