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)
142 FloatVectorOperations::copy (channels[i], other.channels[i], size);
155 setSize (other.getNumChannels(), other.getNumSamples(),
false,
false,
false);
165 for (
int i = 0; i < numChannels; ++i)
166 FloatVectorOperations::copy (channels[i], other.channels[i], size);
181 : numChannels (other.numChannels),
183 allocatedBytes (other.allocatedBytes),
184 allocatedData (std::move (other.allocatedData)),
185 isClear (other.isClear)
187 if (numChannels < (
int) numElementsInArray (preallocatedChannelSpace))
189 channels = preallocatedChannelSpace;
191 for (
int i = 0; i < numChannels; ++i)
192 preallocatedChannelSpace[i] = other.channels[i];
196 channels = other.channels;
199 other.numChannels = 0;
201 other.allocatedBytes = 0;
207 numChannels = other.numChannels;
209 allocatedBytes = other.allocatedBytes;
210 allocatedData = std::move (other.allocatedData);
211 isClear = other.isClear;
213 if (numChannels < (
int) numElementsInArray (preallocatedChannelSpace))
215 channels = preallocatedChannelSpace;
217 for (
int i = 0; i < numChannels; ++i)
218 preallocatedChannelSpace[i] = other.channels[i];
222 channels = other.channels;
225 other.numChannels = 0;
227 other.allocatedBytes = 0;
476 if (allocatedBytes != 0)
479 allocatedData.
free();
524 template <
typename OtherType>
529 if (other.hasBeenCleared())
539 auto* dest = channels[
chan];
540 auto*
src = other.getReadPointer (
chan);
542 for (
int i = 0; i < size; ++i)
543 dest[i] =
static_cast<Type
> (
src[i]);
560 for (
int i = 0; i < numChannels; ++i)
562 JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4661)
563 FloatVectorOperations::clear (channels[i], size);
564 JUCE_END_IGNORE_WARNINGS_MSVC
583 void clear (
int startSample,
int numSamples)
noexcept
585 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
589 for (
int i = 0; i < numChannels; ++i)
590 FloatVectorOperations::clear (channels[i] + startSample, numSamples);
592 isClear = (startSample == 0 && numSamples == size);
606 void clear (
int channel,
int startSample,
int numSamples)
noexcept
608 jassert (isPositiveAndBelow (channel, numChannels));
609 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
612 FloatVectorOperations::clear (channels[channel] + startSample, numSamples);
642 jassert (isPositiveAndBelow (channel, numChannels));
657 jassert (isPositiveAndBelow (
destChannel, numChannels));
658 jassert (isPositiveAndBelow (
destSample, size));
673 jassert (isPositiveAndBelow (
destChannel, numChannels));
674 jassert (isPositiveAndBelow (
destSample, size));
684 void applyGain (
int channel,
int startSample,
int numSamples, Type gain)
noexcept
686 jassert (isPositiveAndBelow (channel, numChannels));
687 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
689 if (! approximatelyEqual (gain, Type (1)) && ! isClear)
691 auto* d = channels[channel] + startSample;
693 if (approximatelyEqual (gain, Type()))
694 FloatVectorOperations::clear (d, numSamples);
696 FloatVectorOperations::multiply (d, gain, numSamples);
705 void applyGain (
int startSample,
int numSamples, Type gain)
noexcept
707 for (
int i = 0; i < numChannels; ++i)
708 applyGain (i, startSample, numSamples, gain);
737 jassert (isPositiveAndBelow (channel, numChannels));
738 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
741 auto* d = channels[channel] + startSample;
743 while (--numSamples >= 0)
764 for (
int i = 0; i < numChannels; ++i)
792 jassert (&source !=
this
796 jassert (isPositiveAndBelow (
destChannel, numChannels));
798 jassert (isPositiveAndBelow (
sourceChannel, source.numChannels));
801 if (! approximatelyEqual (
gainToApplyToSource, (Type) 0) && numSamples > 0 && ! source.isClear)
806 JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4661)
815 FloatVectorOperations::copy (d, s, numSamples);
822 FloatVectorOperations::add (d, s, numSamples);
825 JUCE_END_IGNORE_WARNINGS_MSVC
849 jassert (isPositiveAndBelow (
destChannel, numChannels));
851 jassert (source !=
nullptr);
864 FloatVectorOperations::copy (d, source, numSamples);
871 FloatVectorOperations::add (d, source, numSamples);
908 jassert (isPositiveAndBelow (
destChannel, numChannels));
910 jassert (source !=
nullptr);
918 while (--numSamples >= 0)
943 int numSamples)
noexcept
945 jassert (&source !=
this
949 jassert (isPositiveAndBelow (
destChannel, numChannels));
951 jassert (isPositiveAndBelow (
sourceChannel, source.numChannels));
986 int numSamples)
noexcept
988 jassert (isPositiveAndBelow (
destChannel, numChannels));
990 jassert (source !=
nullptr);
1018 jassert (isPositiveAndBelow (
destChannel, numChannels));
1020 jassert (source !=
nullptr);
1026 if (! approximatelyEqual (gain, Type (1)))
1028 if (approximatelyEqual (gain, Type()))
1031 FloatVectorOperations::clear (d, numSamples);
1036 FloatVectorOperations::copyWithMultiply (d, source, gain, numSamples);
1042 FloatVectorOperations::copy (d, source, numSamples);
1080 jassert (isPositiveAndBelow (
destChannel, numChannels));
1082 jassert (source !=
nullptr);
1090 while (--numSamples >= 0)
1107 jassert (isPositiveAndBelow (channel, numChannels));
1108 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
1111 return { Type (0), Type (0) };
1113 return FloatVectorOperations::findMinAndMax (channels[channel] + startSample, numSamples);
1117 Type
getMagnitude (
int channel,
int startSample,
int numSamples)
const noexcept
1119 jassert (isPositiveAndBelow (channel, numChannels));
1120 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
1125 auto r =
findMinMax (channel, startSample, numSamples);
1127 return jmax (r.getStart(), -r.getStart(), r.getEnd(), -r.getEnd());
1136 for (
int i = 0; i < numChannels; ++i)
1143 Type
getRMSLevel (
int channel,
int startSample,
int numSamples)
const noexcept
1145 jassert (isPositiveAndBelow (channel, numChannels));
1146 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
1151 auto* data = channels[channel] + startSample;
1154 for (
int i = 0; i < numSamples; ++i)
1160 return static_cast<Type
> (std::sqrt (sum / numSamples));
1164 void reverse (
int channel,
int startSample,
int numSamples)
const noexcept
1166 jassert (isPositiveAndBelow (channel, numChannels));
1167 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
1170 std::reverse (channels[channel] + startSample,
1171 channels[channel] + startSample + numSamples);
1175 void reverse (
int startSample,
int numSamples)
const noexcept
1177 for (
int i = 0; i < numChannels; ++i)
1178 reverse (i, startSample, numSamples);
1189 #if (! JUCE_GCC || (__GNUC__ * 100 + __GNUC_MINOR__) >= 409)
1190 static_assert (
alignof (Type) <= maxAlignment,
1191 "AudioBuffer cannot hold types with alignment requirements larger than that guaranteed by malloc");
1193 jassert (size >= 0);
1203 allocatedData.
malloc (allocatedBytes);
1207 for (
int i = 0; i < numChannels; ++i)
1213 channels[numChannels] =
nullptr;
1217 void allocateChannels (Type*
const*
dataToReferTo,
int offset)
1219 jassert (offset >= 0);
1222 if (numChannels < (
int) numElementsInArray (preallocatedChannelSpace))
1224 channels =
static_cast<Type**
> (preallocatedChannelSpace);
1228 allocatedData.
malloc (numChannels + 1,
sizeof (Type*));
1229 channels = unalignedPointerCast<Type**> (allocatedData.
get());
1232 for (
int i = 0; i < numChannels; ++i)
1235 jassert (dataToReferTo[i] !=
nullptr);
1236 channels[i] = dataToReferTo[i] + offset;
1239 channels[numChannels] =
nullptr;
1247 static constexpr size_t getMaxAlignment() noexcept
1249 constexpr size_t alignments[] {
alignof (std::max_align_t),
1253 alignof (
long double),
1254 alignof (
short int),
1257 alignof (
long long int),
1262 alignof (
wchar_t) };
1266 for (
const auto elem : alignments)
1267 max = jmax (max, elem);
1272 int numChannels = 0, size = 0;
1273 size_t allocatedBytes = 0;
1275 HeapBlock<char, true> allocatedData;
1276 Type* preallocatedChannelSpace[32];
1277 bool isClear =
false;
1278 static constexpr size_t maxAlignment = getMaxAlignment();
1284template <
typename Type>
1285bool operator== (
const AudioBuffer<Type>& a,
const AudioBuffer<Type>& b)
1287 if (a.getNumChannels() != b.getNumChannels())
1290 for (
auto c = 0; c < a.getNumChannels(); ++c)
1292 const auto begin = [c] (
auto& x) {
return x.getReadPointer (c); };
1293 const auto end = [c] (
auto& x) {
return x.getReadPointer (c) + x.getNumSamples(); };
1295 if (! std::equal (begin (a), end (a), begin (b), end (b)))
1302template <
typename Type>
1303bool operator!= (
const AudioBuffer<Type>& a,
const AudioBuffer<Type>& b)
1318using AudioSampleBuffer = AudioBuffer<float>;
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 setNotClear() noexcept
void applyGain(int startSample, int numSamples, Type gain) noexcept
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 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)
void setDataToReferTo(Type *const *dataToReferTo, int newNumChannels, int newStartSample, int newNumSamples)
const Type *const * getArrayOfReadPointers() const noexcept
void setDataToReferTo(Type *const *dataToReferTo, int newNumChannels, int newNumSamples)
AudioBuffer(AudioBuffer &&other) noexcept
Type *const * getArrayOfWritePointers() noexcept
void clear(int startSample, int numSamples) 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
void applyGain(int channel, int startSample, int numSamples, Type gain) noexcept
void clear(SizeType numElements) noexcept
void swapWith(HeapBlock< ElementType, otherBlockThrows > &other) noexcept
void malloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
ElementType * get() const noexcept
void allocate(SizeType newNumElements, bool initialiseToZero)