36 template <
typename Type>
43 : channels (static_cast<Type**> (preallocatedChannelSpace))
58 int numSamplesToAllocate)
59 : numChannels (numChannelsToAllocate),
60 size (numSamplesToAllocate)
62 jassert (size >= 0 && numChannels >= 0);
84 : numChannels (numChannelsToUse),
87 jassert (dataToReferTo !=
nullptr);
88 jassert (numChannelsToUse >= 0 && numSamples >= 0);
89 allocateChannels (dataToReferTo, 0);
109 int numChannelsToUse,
112 : numChannels (numChannelsToUse),
115 jassert (dataToReferTo !=
nullptr);
116 jassert (numChannelsToUse >= 0 && startSample >= 0 && numSamples >= 0);
117 allocateChannels (dataToReferTo, startSample);
127 : numChannels (other.numChannels),
129 allocatedBytes (other.allocatedBytes)
131 if (allocatedBytes == 0)
133 allocateChannels (other.channels, 0);
145 for (
int i = 0; i < numChannels; ++i)
168 for (
int i = 0; i < numChannels; ++i)
183 : numChannels (other.numChannels),
185 allocatedBytes (other.allocatedBytes),
186 allocatedData (std::move (other.allocatedData)),
187 isClear (other.isClear)
189 if (numChannels < (
int) numElementsInArray (preallocatedChannelSpace))
191 channels = preallocatedChannelSpace;
193 for (
int i = 0; i < numChannels; ++i)
194 preallocatedChannelSpace[i] = other.channels[i];
198 channels = other.channels;
201 other.numChannels = 0;
203 other.allocatedBytes = 0;
209 numChannels = other.numChannels;
211 allocatedBytes = other.allocatedBytes;
212 allocatedData = std::move (other.allocatedData);
213 isClear = other.isClear;
215 if (numChannels < (
int) numElementsInArray (preallocatedChannelSpace))
217 channels = preallocatedChannelSpace;
219 for (
int i = 0; i < numChannels; ++i)
220 preallocatedChannelSpace[i] = other.channels[i];
224 channels = other.channels;
227 other.numChannels = 0;
229 other.allocatedBytes = 0;
253 jassert (isPositiveAndBelow (channelNumber, numChannels));
254 return channels[channelNumber];
266 jassert (isPositiveAndBelow (channelNumber, numChannels));
267 jassert (isPositiveAndBelow (sampleIndex, size));
268 return channels[channelNumber] + sampleIndex;
279 jassert (isPositiveAndBelow (channelNumber, numChannels));
281 return channels[channelNumber];
292 jassert (isPositiveAndBelow (channelNumber, numChannels));
293 jassert (isPositiveAndBelow (sampleIndex, size));
295 return channels[channelNumber] + sampleIndex;
337 bool keepExistingContent =
false,
338 bool clearExtraSpace =
false,
339 bool avoidReallocating =
false)
341 jassert (newNumChannels >= 0);
342 jassert (newNumSamples >= 0);
344 if (newNumSamples != size || newNumChannels != numChannels)
346 auto allocatedSamplesPerChannel = ((size_t) newNumSamples + 3) & ~3u;
347 auto channelListSize = ((
sizeof (Type*) * (
size_t) (newNumChannels + 1)) + 15) & ~15u;
348 auto newTotalBytes = ((size_t) newNumChannels * (
size_t) allocatedSamplesPerChannel *
sizeof (Type))
349 + channelListSize + 32;
351 if (keepExistingContent)
353 if (avoidReallocating && newNumChannels <= numChannels && newNumSamples <= size)
360 newData.
allocate (newTotalBytes, clearExtraSpace || isClear);
362 auto numSamplesToCopy = (size_t) jmin (newNumSamples, size);
364 auto newChannels =
reinterpret_cast<Type**
> (newData.
get());
365 auto newChan =
reinterpret_cast<Type*
> (newData + channelListSize);
367 for (
int j = 0; j < newNumChannels; ++j)
369 newChannels[j] = newChan;
370 newChan += allocatedSamplesPerChannel;
375 auto numChansToCopy = jmin (numChannels, newNumChannels);
377 for (
int i = 0; i < numChansToCopy; ++i)
382 allocatedBytes = newTotalBytes;
383 channels = newChannels;
388 if (avoidReallocating && allocatedBytes >= newTotalBytes)
390 if (clearExtraSpace || isClear)
391 allocatedData.
clear (newTotalBytes);
395 allocatedBytes = newTotalBytes;
396 allocatedData.
allocate (newTotalBytes, clearExtraSpace || isClear);
397 channels =
reinterpret_cast<Type**
> (allocatedData.
get());
400 auto* chan =
reinterpret_cast<Type*
> (allocatedData + channelListSize);
402 for (
int i = 0; i < newNumChannels; ++i)
405 chan += allocatedSamplesPerChannel;
409 channels[newNumChannels] =
nullptr;
410 size = newNumSamples;
411 numChannels = newNumChannels;
439 jassert (dataToReferTo !=
nullptr);
440 jassert (newNumChannels >= 0 && newNumSamples >= 0);
442 if (allocatedBytes != 0)
445 allocatedData.
free();
448 numChannels = newNumChannels;
449 size = newNumSamples;
451 allocateChannels (dataToReferTo, newStartSample);
484 template <
typename OtherType>
497 for (
int chan = 0; chan < numChannels; ++chan)
499 auto* dest = channels[chan];
502 for (
int i = 0; i < size; ++i)
503 dest[i] =
static_cast<Type
> (src[i]);
514 for (
int i = 0; i < numChannels; ++i)
526 void clear (
int startSample,
int numSamples) noexcept
528 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
532 if (startSample == 0 && numSamples == size)
535 for (
int i = 0; i < numChannels; ++i)
545 void clear (
int channel,
int startSample,
int numSamples) noexcept
547 jassert (isPositiveAndBelow (channel, numChannels));
548 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
568 Type
getSample (
int channel,
int sampleIndex)
const noexcept
570 jassert (isPositiveAndBelow (channel, numChannels));
571 jassert (isPositiveAndBelow (sampleIndex, size));
572 return *(channels[channel] + sampleIndex);
580 void setSample (
int destChannel,
int destSample, Type newValue) noexcept
582 jassert (isPositiveAndBelow (destChannel, numChannels));
583 jassert (isPositiveAndBelow (destSample, size));
584 *(channels[destChannel] + destSample) = newValue;
593 void addSample (
int destChannel,
int destSample, Type valueToAdd) noexcept
595 jassert (isPositiveAndBelow (destChannel, numChannels));
596 jassert (isPositiveAndBelow (destSample, size));
597 *(channels[destChannel] + destSample) += valueToAdd;
606 void applyGain (
int channel,
int startSample,
int numSamples, Type gain) noexcept
608 jassert (isPositiveAndBelow (channel, numChannels));
609 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
611 if (gain != Type (1) && ! isClear)
613 auto* d = channels[channel] + startSample;
627 void applyGain (
int startSample,
int numSamples, Type gain) noexcept
629 for (
int i = 0; i < numChannels; ++i)
630 applyGain (i, startSample, numSamples, gain);
649 Type startGain, Type endGain) noexcept
653 if (startGain == endGain)
655 applyGain (channel, startSample, numSamples, startGain);
659 jassert (isPositiveAndBelow (channel, numChannels));
660 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
662 const auto increment = (endGain - startGain) / (
float) numSamples;
663 auto* d = channels[channel] + startSample;
665 while (--numSamples >= 0)
668 startGain += increment;
684 Type startGain, Type endGain) noexcept
686 for (
int i = 0; i < numChannels; ++i)
687 applyGainRamp (i, startSample, numSamples, startGain, endGain);
707 int sourceStartSample,
709 Type gainToApplyToSource = Type (1)) noexcept
711 jassert (&source !=
this || sourceChannel != destChannel);
712 jassert (isPositiveAndBelow (destChannel, numChannels));
713 jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size);
714 jassert (isPositiveAndBelow (sourceChannel, source.numChannels));
715 jassert (sourceStartSample >= 0 && sourceStartSample + numSamples <= source.size);
717 if (gainToApplyToSource != 0 && numSamples > 0 && ! source.isClear)
719 auto* d = channels[destChannel] + destStartSample;
720 auto* s = source.channels[sourceChannel] + sourceStartSample;
726 if (gainToApplyToSource != Type (1))
733 if (gainToApplyToSource != Type (1))
756 Type gainToApplyToSource = Type (1)) noexcept
758 jassert (isPositiveAndBelow (destChannel, numChannels));
759 jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size);
760 jassert (source !=
nullptr);
762 if (gainToApplyToSource != 0 && numSamples > 0)
764 auto* d = channels[destChannel] + destStartSample;
770 if (gainToApplyToSource != Type (1))
777 if (gainToApplyToSource != Type (1))
802 Type endGain) noexcept
804 if (startGain == endGain)
806 addFrom (destChannel, destStartSample, source, numSamples, startGain);
810 jassert (isPositiveAndBelow (destChannel, numChannels));
811 jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size);
812 jassert (source !=
nullptr);
817 const auto increment = (endGain - startGain) / numSamples;
818 auto* d = channels[destChannel] + destStartSample;
820 while (--numSamples >= 0)
822 *d++ += startGain * *source++;
823 startGain += increment;
844 int sourceStartSample,
845 int numSamples) noexcept
847 jassert (&source !=
this || sourceChannel != destChannel);
848 jassert (isPositiveAndBelow (destChannel, numChannels));
849 jassert (destStartSample >= 0 && destStartSample + numSamples <= size);
850 jassert (isPositiveAndBelow (sourceChannel, source.numChannels));
851 jassert (sourceStartSample >= 0 && numSamples >= 0 && sourceStartSample + numSamples <= source.size);
864 source.channels[sourceChannel] + sourceStartSample,
882 int numSamples) noexcept
884 jassert (isPositiveAndBelow (destChannel, numChannels));
885 jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size);
886 jassert (source !=
nullptr);
911 jassert (isPositiveAndBelow (destChannel, numChannels));
912 jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size);
913 jassert (source !=
nullptr);
917 auto* d = channels[destChannel] + destStartSample;
919 if (gain != Type (1))
958 Type endGain) noexcept
960 if (startGain == endGain)
962 copyFrom (destChannel, destStartSample, source, numSamples, startGain);
966 jassert (isPositiveAndBelow (destChannel, numChannels));
967 jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size);
968 jassert (source !=
nullptr);
973 const auto increment = (endGain - startGain) / numSamples;
974 auto* d = channels[destChannel] + destStartSample;
976 while (--numSamples >= 0)
978 *d++ = startGain * *source++;
979 startGain += increment;
993 jassert (isPositiveAndBelow (channel, numChannels));
994 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
997 return { Type (0), Type (0) };
1003 Type
getMagnitude (
int channel,
int startSample,
int numSamples)
const noexcept
1005 jassert (isPositiveAndBelow (channel, numChannels));
1006 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
1011 auto r =
findMinMax (channel, startSample, numSamples);
1013 return jmax (r.getStart(), -r.getStart(), r.getEnd(), -r.getEnd());
1022 for (
int i = 0; i < numChannels; ++i)
1023 mag = jmax (mag,
getMagnitude (i, startSample, numSamples));
1029 Type
getRMSLevel (
int channel,
int startSample,
int numSamples)
const noexcept
1031 jassert (isPositiveAndBelow (channel, numChannels));
1032 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
1034 if (numSamples <= 0 || channel < 0 || channel >= numChannels || isClear)
1037 auto* data = channels[channel] + startSample;
1040 for (
int i = 0; i < numSamples; ++i)
1042 auto sample = data[i];
1043 sum += sample * sample;
1046 return static_cast<Type
> (std::sqrt (sum / numSamples));
1050 void reverse (
int channel,
int startSample,
int numSamples)
const noexcept
1052 jassert (isPositiveAndBelow (channel, numChannels));
1053 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
1056 std::reverse (channels[channel] + startSample,
1057 channels[channel] + startSample + numSamples);
1061 void reverse (
int startSample,
int numSamples)
const noexcept
1063 for (
int i = 0; i < numChannels; ++i)
1064 reverse (i, startSample, numSamples);
1073 int numChannels = 0, size = 0;
1074 size_t allocatedBytes = 0;
1077 Type* preallocatedChannelSpace[32];
1078 bool isClear =
false;
1082 jassert (size >= 0);
1083 auto channelListSize =
sizeof (Type*) * (
size_t) (numChannels + 1);
1084 allocatedBytes = (size_t) numChannels * (
size_t) size *
sizeof (Type) + channelListSize + 32;
1085 allocatedData.
malloc (allocatedBytes);
1086 channels =
reinterpret_cast<Type**
> (allocatedData.
get());
1087 auto chan =
reinterpret_cast<Type*
> (allocatedData + channelListSize);
1089 for (
int i = 0; i < numChannels; ++i)
1095 channels[numChannels] =
nullptr;
1099 void allocateChannels (Type*
const* dataToReferTo,
int offset)
1101 jassert (offset >= 0);
1104 if (numChannels < (
int) numElementsInArray (preallocatedChannelSpace))
1106 channels =
static_cast<Type**
> (preallocatedChannelSpace);
1110 allocatedData.
malloc (numChannels + 1,
sizeof (Type*));
1111 channels =
reinterpret_cast<Type**
> (allocatedData.
get());
1114 for (
int i = 0; i < numChannels; ++i)
1117 jassert (dataToReferTo[i] !=
nullptr);
1118 channels[i] = dataToReferTo[i] + offset;
1121 channels[numChannels] =
nullptr;
1138 using AudioSampleBuffer = AudioBuffer<float>;