32template <
typename Type>
39 : channels (
static_cast<Type**> (preallocatedChannelSpace))
58 jassert (size >= 0 && numChannels >= 0);
123 : numChannels (
other.numChannels),
125 allocatedBytes (
other.allocatedBytes)
127 if (allocatedBytes == 0)
129 allocateChannels (
other.channels, 0);
141 for (
int i = 0; i < numChannels; ++i)
164 for (
int i = 0; i < numChannels; ++i)
179 : numChannels (
other.numChannels),
181 allocatedBytes (
other.allocatedBytes),
182 allocatedData (std::move (
other.allocatedData)),
183 isClear (
other.isClear.load())
185 if (numChannels < (
int) numElementsInArray (preallocatedChannelSpace))
187 channels = preallocatedChannelSpace;
189 for (
int i = 0; i < numChannels; ++i)
190 preallocatedChannelSpace[i] =
other.channels[i];
194 channels =
other.channels;
197 other.numChannels = 0;
199 other.allocatedBytes = 0;
205 numChannels =
other.numChannels;
207 allocatedBytes =
other.allocatedBytes;
208 allocatedData = std::move (
other.allocatedData);
209 isClear =
other.isClear.load();
211 if (numChannels < (
int) numElementsInArray (preallocatedChannelSpace))
213 channels = preallocatedChannelSpace;
215 for (
int i = 0; i < numChannels; ++i)
216 preallocatedChannelSpace[i] =
other.channels[i];
220 channels =
other.channels;
223 other.numChannels = 0;
225 other.allocatedBytes = 0;
393 channels =
reinterpret_cast<Type**
> (allocatedData.
get());
438 if (allocatedBytes != 0)
441 allocatedData.
free();
480 template <
typename OtherType>
485 if (
other.hasBeenCleared())
495 auto* dest = channels[
chan];
498 for (
int i = 0; i < size; ++i)
499 dest[i] =
static_cast<Type
> (
src[i]);
510 for (
int i = 0; i < numChannels; ++i)
522 void clear (
int startSample,
int numSamples)
noexcept
524 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
528 if (startSample == 0 && numSamples == size)
531 for (
int i = 0; i < numChannels; ++i)
541 void clear (
int channel,
int startSample,
int numSamples)
noexcept
543 jassert (isPositiveAndBelow (channel, numChannels));
544 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
566 jassert (isPositiveAndBelow (channel, numChannels));
578 jassert (isPositiveAndBelow (
destChannel, numChannels));
579 jassert (isPositiveAndBelow (
destSample, size));
591 jassert (isPositiveAndBelow (
destChannel, numChannels));
592 jassert (isPositiveAndBelow (
destSample, size));
602 void applyGain (
int channel,
int startSample,
int numSamples, Type gain)
noexcept
604 jassert (isPositiveAndBelow (channel, numChannels));
605 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
607 if (gain != Type (1) && ! isClear)
609 auto* d = channels[channel] + startSample;
623 void applyGain (
int startSample,
int numSamples, Type gain)
noexcept
625 for (
int i = 0; i < numChannels; ++i)
626 applyGain (i, startSample, numSamples, gain);
655 jassert (isPositiveAndBelow (channel, numChannels));
656 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
659 auto* d = channels[channel] + startSample;
661 while (--numSamples >= 0)
682 for (
int i = 0; i < numChannels; ++i)
708 jassert (isPositiveAndBelow (
destChannel, numChannels));
710 jassert (isPositiveAndBelow (
sourceChannel, source.numChannels));
754 jassert (isPositiveAndBelow (
destChannel, numChannels));
756 jassert (source !=
nullptr);
806 jassert (isPositiveAndBelow (
destChannel, numChannels));
808 jassert (source !=
nullptr);
816 while (--numSamples >= 0)
841 int numSamples)
noexcept
844 jassert (isPositiveAndBelow (
destChannel, numChannels));
846 jassert (isPositiveAndBelow (
sourceChannel, source.numChannels));
878 int numSamples)
noexcept
880 jassert (isPositiveAndBelow (
destChannel, numChannels));
882 jassert (source !=
nullptr);
907 jassert (isPositiveAndBelow (
destChannel, numChannels));
909 jassert (source !=
nullptr);
915 if (gain != Type (1))
962 jassert (isPositiveAndBelow (
destChannel, numChannels));
964 jassert (source !=
nullptr);
972 while (--numSamples >= 0)
989 jassert (isPositiveAndBelow (channel, numChannels));
990 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
993 return { Type (0), Type (0) };
999 Type
getMagnitude (
int channel,
int startSample,
int numSamples)
const noexcept
1001 jassert (isPositiveAndBelow (channel, numChannels));
1002 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
1007 auto r =
findMinMax (channel, startSample, numSamples);
1009 return jmax (r.getStart(), -r.getStart(), r.getEnd(), -r.getEnd());
1018 for (
int i = 0; i < numChannels; ++i)
1025 Type
getRMSLevel (
int channel,
int startSample,
int numSamples)
const noexcept
1027 jassert (isPositiveAndBelow (channel, numChannels));
1028 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
1033 auto* data = channels[channel] + startSample;
1036 for (
int i = 0; i < numSamples; ++i)
1042 return static_cast<Type
> (std::sqrt (sum / numSamples));
1046 void reverse (
int channel,
int startSample,
int numSamples)
const noexcept
1048 jassert (isPositiveAndBelow (channel, numChannels));
1049 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
1052 std::reverse (channels[channel] + startSample,
1053 channels[channel] + startSample + numSamples);
1057 void reverse (
int startSample,
int numSamples)
const noexcept
1059 for (
int i = 0; i < numChannels; ++i)
1060 reverse (i, startSample, numSamples);
1069 int numChannels = 0, size = 0;
1070 size_t allocatedBytes = 0;
1073 Type* preallocatedChannelSpace[32];
1074 std::atomic<bool> isClear {
false };
1078 static_assert (std::alignment_of<Type>::value <= std::alignment_of<std::max_align_t>::value,
1079 "AudioBuffer cannot hold types with alignment requirements larger than that guaranteed by malloc");
1080 jassert (size >= 0);
1090 allocatedData.malloc (allocatedBytes);
1091 channels =
reinterpret_cast<Type**
> (allocatedData.get());
1094 for (
int i = 0; i < numChannels; ++i)
1100 channels[numChannels] =
nullptr;
1104 void allocateChannels (Type*
const* dataToReferTo,
int offset)
1106 jassert (offset >= 0);
1109 if (numChannels < (
int) numElementsInArray (preallocatedChannelSpace))
1111 channels =
static_cast<Type**
> (preallocatedChannelSpace);
1115 allocatedData.malloc (numChannels + 1,
sizeof (Type*));
1116 channels =
reinterpret_cast<Type**
> (allocatedData.get());
1119 for (
int i = 0; i < numChannels; ++i)
1122 jassert (dataToReferTo[i] !=
nullptr);
1123 channels[i] = dataToReferTo[i] + offset;
1126 channels[numChannels] =
nullptr;
1143using AudioSampleBuffer = AudioBuffer<float>;
int size() const noexcept
AudioBuffer(Type *const *dataToReferTo, int numChannelsToUse, int startSample, int numSamples)
void setSize(int newNumChannels, int newNumSamples, bool keepExistingContent=false, bool clearExtraSpace=false, bool avoidReallocating=false)
Type getMagnitude(int channel, int startSample, int numSamples) const noexcept
AudioBuffer(Type *const *dataToReferTo, int numChannelsToUse, int numSamples)
Type getSample(int channel, int sampleIndex) const noexcept
void applyGain(Type gain) noexcept
Range< Type > findMinMax(int channel, int startSample, int numSamples) const noexcept
AudioBuffer(const AudioBuffer &other)
const Type * getReadPointer(int channelNumber, int sampleIndex) const noexcept
void makeCopyOf(const AudioBuffer< OtherType > &other, bool avoidReallocating=false)
void applyGain(int startSample, int numSamples, Type gain) noexcept
void setDataToReferTo(Type **dataToReferTo, int newNumChannels, int newNumSamples)
void copyFromWithRamp(int destChannel, int destStartSample, const Type *source, int numSamples, Type startGain, Type endGain) noexcept
void addSample(int destChannel, int destSample, Type valueToAdd) noexcept
Type getRMSLevel(int channel, int startSample, int numSamples) const noexcept
Type * getWritePointer(int channelNumber) noexcept
void copyFrom(int destChannel, int destStartSample, const Type *source, int numSamples) noexcept
int getNumChannels() const noexcept
Type * getWritePointer(int channelNumber, int sampleIndex) noexcept
int getNumSamples() const noexcept
void clear(int channel, int startSample, int numSamples) noexcept
void copyFrom(int destChannel, int destStartSample, const Type *source, int numSamples, Type gain) noexcept
void applyGainRamp(int channel, int startSample, int numSamples, Type startGain, Type endGain) noexcept
void setDataToReferTo(Type **dataToReferTo, int newNumChannels, int newStartSample, int newNumSamples)
void copyFrom(int destChannel, int destStartSample, const AudioBuffer &source, int sourceChannel, int sourceStartSample, int numSamples) noexcept
void reverse(int startSample, int numSamples) const noexcept
void addFromWithRamp(int destChannel, int destStartSample, const Type *source, int numSamples, Type startGain, Type endGain) noexcept
Type getMagnitude(int startSample, int numSamples) const noexcept
void reverse(int channel, int startSample, int numSamples) const noexcept
void setSample(int destChannel, int destSample, Type newValue) noexcept
void addFrom(int destChannel, int destStartSample, const AudioBuffer &source, int sourceChannel, int sourceStartSample, int numSamples, Type gainToApplyToSource=Type(1)) noexcept
bool hasBeenCleared() const noexcept
const Type * getReadPointer(int channelNumber) const noexcept
AudioBuffer & operator=(const AudioBuffer &other)
AudioBuffer(AudioBuffer &&other) noexcept
void clear(int startSample, int numSamples) noexcept
const Type ** getArrayOfReadPointers() const noexcept
AudioBuffer(int numChannelsToAllocate, int numSamplesToAllocate)
void addFrom(int destChannel, int destStartSample, const Type *source, int numSamples, Type gainToApplyToSource=Type(1)) noexcept
void applyGainRamp(int startSample, int numSamples, Type startGain, Type endGain) noexcept
Type ** getArrayOfWritePointers() noexcept
void applyGain(int channel, int startSample, int numSamples, Type gain) noexcept
static void JUCE_CALLTYPE multiply(float *dest, const float *src, int numValues) noexcept
static void JUCE_CALLTYPE clear(float *dest, int numValues) noexcept
static void JUCE_CALLTYPE copyWithMultiply(float *dest, const float *src, float multiplier, int numValues) noexcept
static void JUCE_CALLTYPE copy(float *dest, const float *src, int numValues) noexcept
static void JUCE_CALLTYPE addWithMultiply(float *dest, const float *src, float multiplier, int numValues) noexcept
static Range< float > JUCE_CALLTYPE findMinAndMax(const float *src, int numValues) noexcept
static void JUCE_CALLTYPE add(float *dest, float amountToAdd, int numValues) noexcept
void clear(SizeType numElements) noexcept
void swapWith(HeapBlock< ElementType, otherBlockThrows > &other) noexcept
ElementType * get() const noexcept
void allocate(SizeType newNumElements, bool initialiseToZero)