70 template <
typename OtherSampleType>
71 using MayUseConvertingConstructor =
72 std::enable_if_t<std::is_same_v<std::remove_const_t<SampleType>,
73 std::remove_const_t<OtherSampleType>>
74 && std::is_const_v<SampleType>
75 && ! std::is_const_v<OtherSampleType>,
80 using NumericType =
typename SampleTypeHelpers::ElementType<SampleType>::Type;
149 template <
typename OtherSampleType>
151 : channels (buffer.getArrayOfWritePointers()),
153 numSamples (
static_cast<size_t> (buffer.getNumSamples()))
162 template <
typename OtherSampleType>
164 : channels (buffer.getArrayOfReadPointers()),
166 numSamples (
static_cast<size_t> (buffer.getNumSamples()))
175 template <
typename OtherSampleType>
177 : channels (buffer.getArrayOfWritePointers()),
180 numSamples (
static_cast<size_t> (buffer.getNumSamples()) -
startSampleIndex)
182 jassert (startSample <
static_cast<size_t> (buffer.getNumSamples()));
188 template <
typename OtherSampleType, MayUseConvertingConstructor<OtherSampleType> = 0>
190 : channels { other.channels },
191 numChannels { other.numChannels },
192 startSample { other.startSample },
193 numSamples { other.numSamples }
197 template <
typename OtherSampleType, MayUseConvertingConstructor<OtherSampleType> = 0>
198 AudioBlock& operator= (
const AudioBlock<OtherSampleType>& other)
noexcept
205 void swap (AudioBlock& other)
noexcept
207 std::swap (other.channels, channels);
208 std::swap (other.numChannels, numChannels);
209 std::swap (other.startSample, startSample);
210 std::swap (other.numSamples, numSamples);
214 template <
typename OtherSampleType>
215 constexpr bool operator== (
const AudioBlock<OtherSampleType>& other)
const noexcept
217 return std::equal (channels,
218 channels + numChannels,
220 other.channels + other.numChannels)
221 && startSample == other.startSample
222 && numSamples == other.numSamples;
225 template <
typename OtherSampleType>
226 constexpr bool operator!= (
const AudioBlock<OtherSampleType>& other)
const noexcept
228 return ! (*
this == other);
241 jassert (channel < numChannels);
242 jassert (numSamples > 0);
243 return channels[channel] + startSample;
249 jassert (channel < numChannels);
250 return AudioBlock (channels + channel, 1, startSample, numSamples);
272 jassert (isPositiveAndBelow (channel, numChannels));
273 jassert (isPositiveAndBelow (
sampleIndex, numSamples));
284 jassert (isPositiveAndBelow (
destChannel, numChannels));
285 jassert (isPositiveAndBelow (
destSample, numSamples));
296 jassert (isPositiveAndBelow (
destChannel, numChannels));
297 jassert (isPositiveAndBelow (
destSample, numSamples));
307 AudioBlock& JUCE_VECTOR_CALLTYPE
fill (NumericType value)
noexcept { fillInternal (value);
return *
this; }
308 const AudioBlock& JUCE_VECTOR_CALLTYPE
fill (NumericType value)
const noexcept { fillInternal (value);
return *
this; }
311 template <
typename OtherSampleType>
313 template <
typename OtherSampleType>
322 template <
typename OtherNumericType>
326 template <
typename OtherNumericType>
339 size_t numElements = std::numeric_limits<size_t>::max())
const
341 auto dstlen =
static_cast<size_t> (
dst.getNumSamples()) / sizeFactor;
343 auto maxChannels = jmin (
static_cast<size_t> (
dst.getNumChannels()),
static_cast<size_t> (numChannels));
346 FloatVectorOperations::copy (
dst.getWritePointer ((
int)
ch, (
int) (
dstPos * sizeFactor)),
347 getDataPointer (
ch) + (
srcPos * sizeFactor),
394 AudioBlock& JUCE_VECTOR_CALLTYPE
add (NumericType value)
noexcept { addInternal (value);
return *
this; }
395 const AudioBlock& JUCE_VECTOR_CALLTYPE
add (NumericType value)
const noexcept { addInternal (value);
return *
this; }
398 template <
typename OtherSampleType>
400 template <
typename OtherSampleType>
404 template <
typename OtherSampleType>
406 template <
typename OtherSampleType>
410 template <
typename Src1SampleType,
typename Src2SampleType>
412 template <
typename Src1SampleType,
typename Src2SampleType>
417 AudioBlock& JUCE_VECTOR_CALLTYPE
subtract (NumericType value)
noexcept { subtractInternal (value);
return *
this; }
418 const AudioBlock& JUCE_VECTOR_CALLTYPE
subtract (NumericType value)
const noexcept { subtractInternal (value);
return *
this; }
421 template <
typename OtherSampleType>
423 template <
typename OtherSampleType>
427 template <
typename OtherSampleType>
429 template <
typename OtherSampleType>
433 template <
typename Src1SampleType,
typename Src2SampleType>
435 template <
typename Src1SampleType,
typename Src2SampleType>
440 AudioBlock& JUCE_VECTOR_CALLTYPE
multiplyBy (NumericType value)
noexcept { multiplyByInternal (value);
return *
this; }
441 const AudioBlock& JUCE_VECTOR_CALLTYPE
multiplyBy (NumericType value)
const noexcept { multiplyByInternal (value);
return *
this; }
444 template <
typename OtherSampleType>
446 template <
typename OtherSampleType>
450 template <
typename OtherSampleType>
452 template <
typename OtherSampleType>
456 template <
typename Src1SampleType,
typename Src2SampleType>
458 template <
typename Src1SampleType,
typename Src2SampleType>
463 template <
typename OtherSampleType,
typename SmoothingType>
465 template <
typename OtherSampleType,
typename SmoothingType>
469 template <
typename BlockSampleType,
typename SmootherSampleType,
typename SmoothingType>
471 template <
typename BlockSampleType,
typename SmootherSampleType,
typename SmoothingType>
476 template <
typename OtherSampleType>
478 template <
typename OtherSampleType>
482 template <
typename Src1SampleType,
typename Src2SampleType>
484 template <
typename Src1SampleType,
typename Src2SampleType>
493 template <
typename OtherSampleType>
495 template <
typename OtherSampleType>
499 template <
typename OtherSampleType>
501 template <
typename OtherSampleType>
506 template <
typename Src1SampleType,
typename Src2SampleType>
508 template <
typename Src1SampleType,
typename Src2SampleType>
512 template <
typename Src1SampleType,
typename Src2SampleType>
514 template <
typename Src1SampleType,
typename Src2SampleType>
521 if (numChannels == 0)
524 auto n = numSamples * sizeFactor;
525 auto minmax = FloatVectorOperations::findMinAndMax (getDataPointer (0), n);
527 for (
size_t ch = 1;
ch < numChannels; ++
ch)
528 minmax =
minmax.getUnionWith (FloatVectorOperations::findMinAndMax (getDataPointer (
ch), n));
536 const AudioBlock& JUCE_VECTOR_CALLTYPE
operator+= (NumericType value)
const noexcept {
return add (value); }
538 AudioBlock& operator+= (AudioBlock src)
noexcept {
return add (src); }
539 const AudioBlock& operator+= (AudioBlock src)
const noexcept {
return add (src); }
541 AudioBlock& JUCE_VECTOR_CALLTYPE operator-= (NumericType value)
noexcept {
return subtract (value); }
542 const AudioBlock& JUCE_VECTOR_CALLTYPE operator-= (NumericType value)
const noexcept {
return subtract (value); }
545 const AudioBlock& operator-= (AudioBlock src)
const noexcept {
return subtract (src); }
547 AudioBlock& JUCE_VECTOR_CALLTYPE operator*= (NumericType value)
noexcept {
return multiplyBy (value); }
548 const AudioBlock& JUCE_VECTOR_CALLTYPE operator*= (NumericType value)
const noexcept {
return multiplyBy (value); }
553 template <
typename OtherSampleType,
typename SmoothingType>
554 AudioBlock& operator*= (SmoothedValue<OtherSampleType, SmoothingType>& value)
noexcept {
return multiplyBy (value); }
555 template <
typename OtherSampleType,
typename SmoothingType>
556 const AudioBlock& operator*= (SmoothedValue<OtherSampleType, SmoothingType>& value)
const noexcept {
return multiplyBy (value); }
560 static_assert (std::is_same_v<std::remove_const_t<SampleType>,
float>
561 || std::is_same_v<std::remove_const_t<SampleType>,
double>
563 || std::is_same_v<std::remove_const_t<SampleType>, SIMDRegister<float>>
564 || std::is_same_v<std::remove_const_t<SampleType>, SIMDRegister<double>>
566 ,
"AudioBlock only supports single or double precision floating point types");
573 template <
typename Src1SampleType,
typename Src2SampleType,
typename FunctionType>
587 for (
size_t i = 0; i <
len; ++i)
588 dst[i] = function (
src[i]);
593 NumericType* getDataPointer (
size_t channel)
const noexcept
601 auto n = numSamples * sizeFactor;
603 for (
size_t ch = 0;
ch < numChannels; ++
ch)
604 FloatVectorOperations::clear (getDataPointer (
ch), n);
607 void JUCE_VECTOR_CALLTYPE fillInternal (NumericType value)
const noexcept
609 auto n = numSamples * sizeFactor;
611 for (
size_t ch = 0; ch < numChannels; ++ch)
612 FloatVectorOperations::fill (getDataPointer (ch), value, n);
615 template <
typename OtherSampleType>
616 void copyFromInternal (
const AudioBlock<OtherSampleType>& src)
const noexcept
618 auto maxChannels = jmin (src.numChannels, numChannels);
619 auto n = jmin (src.numSamples * src.sizeFactor, numSamples * sizeFactor);
621 for (
size_t ch = 0; ch < maxChannels; ++ch)
622 FloatVectorOperations::copy (getDataPointer (ch), src.getDataPointer (ch), n);
625 template <
typename OtherNumericType>
626 void copyFromInternal (
const AudioBuffer<OtherNumericType>& src,
size_t srcPos,
size_t dstPos,
size_t numElements)
const
628 auto srclen =
static_cast<size_t> (src.getNumSamples()) / sizeFactor;
629 auto n = jmin (srclen - srcPos, numSamples - dstPos, numElements) * sizeFactor;
630 auto maxChannels = jmin (
static_cast<size_t> (src.getNumChannels()),
static_cast<size_t> (numChannels));
632 for (
size_t ch = 0; ch < maxChannels; ++ch)
633 FloatVectorOperations::copy (getDataPointer (ch) + (dstPos * sizeFactor),
634 src.getReadPointer ((
int) ch, (
int) (srcPos * sizeFactor)),
638 void moveInternal (
size_t srcPos,
size_t dstPos,
639 size_t numElements = std::numeric_limits<size_t>::max()) const noexcept
641 jassert (srcPos <= numSamples && dstPos <= numSamples);
642 auto len = jmin (numSamples - srcPos, numSamples - dstPos, numElements) *
sizeof (SampleType);
645 for (
size_t ch = 0; ch < numChannels; ++ch)
651 void JUCE_VECTOR_CALLTYPE addInternal (NumericType value)
const noexcept
653 auto n = numSamples * sizeFactor;
655 for (
size_t ch = 0; ch < numChannels; ++ch)
656 FloatVectorOperations::add (getDataPointer (ch), value, n);
659 template <
typename OtherSampleType>
660 void addInternal (AudioBlock<OtherSampleType> src)
const noexcept
662 jassert (numChannels == src.numChannels);
663 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
665 for (
size_t ch = 0; ch < numChannels; ++ch)
666 FloatVectorOperations::add (getDataPointer (ch), src.getDataPointer (ch), n);
669 template <
typename OtherSampleType>
670 void JUCE_VECTOR_CALLTYPE replaceWithSumOfInternal (AudioBlock<OtherSampleType> src, NumericType value)
const noexcept
672 jassert (numChannels == src.numChannels);
673 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
675 for (
size_t ch = 0; ch < numChannels; ++ch)
676 FloatVectorOperations::add (getDataPointer (ch), src.getDataPointer (ch), value, n);
679 template <
typename Src1SampleType,
typename Src2SampleType>
680 void replaceWithSumOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2)
const noexcept
682 jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
683 auto n = jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor;
685 for (
size_t ch = 0; ch < numChannels; ++ch)
686 FloatVectorOperations::add (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
690 constexpr void JUCE_VECTOR_CALLTYPE subtractInternal (NumericType value)
const noexcept
692 addInternal (value *
static_cast<NumericType
> (-1.0));
695 template <
typename OtherSampleType>
696 void subtractInternal (AudioBlock<OtherSampleType> src)
const noexcept
698 jassert (numChannels == src.numChannels);
699 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
701 for (
size_t ch = 0; ch < numChannels; ++ch)
702 FloatVectorOperations::subtract (getDataPointer (ch), src.getDataPointer (ch), n);
705 template <
typename OtherSampleType>
706 void JUCE_VECTOR_CALLTYPE replaceWithDifferenceOfInternal (AudioBlock<OtherSampleType> src, NumericType value)
const noexcept
708 replaceWithSumOfInternal (src,
static_cast<NumericType
> (-1.0) * value);
711 template <
typename Src1SampleType,
typename Src2SampleType>
712 void replaceWithDifferenceOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2)
const noexcept
714 jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
715 auto n = jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor;
717 for (
size_t ch = 0; ch < numChannels; ++ch)
718 FloatVectorOperations::subtract (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
722 void JUCE_VECTOR_CALLTYPE multiplyByInternal (NumericType value)
const noexcept
724 auto n = numSamples * sizeFactor;
726 for (
size_t ch = 0; ch < numChannels; ++ch)
727 FloatVectorOperations::multiply (getDataPointer (ch), value, n);
730 template <
typename OtherSampleType>
731 void multiplyByInternal (AudioBlock<OtherSampleType> src)
const noexcept
733 jassert (numChannels == src.numChannels);
734 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
736 for (
size_t ch = 0; ch < numChannels; ++ch)
737 FloatVectorOperations::multiply (getDataPointer (ch), src.getDataPointer (ch), n);
740 template <
typename OtherSampleType>
741 void JUCE_VECTOR_CALLTYPE replaceWithProductOfInternal (AudioBlock<OtherSampleType> src, NumericType value)
const noexcept
743 jassert (numChannels == src.numChannels);
744 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
746 for (
size_t ch = 0; ch < numChannels; ++ch)
747 FloatVectorOperations::multiply (getDataPointer (ch), src.getDataPointer (ch), value, n);
750 template <
typename Src1SampleType,
typename Src2SampleType>
751 void replaceWithProductOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2)
const noexcept
753 jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
754 auto n = jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor;
756 for (
size_t ch = 0; ch < numChannels; ++ch)
757 FloatVectorOperations::multiply (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
760 template <
typename OtherSampleType,
typename SmoothingType>
761 void multiplyByInternal (SmoothedValue<OtherSampleType, SmoothingType>& value)
const noexcept
763 if (! value.isSmoothing())
765 multiplyByInternal ((NumericType) value.getTargetValue());
769 for (
size_t i = 0; i < numSamples; ++i)
771 const auto scaler = (NumericType) value.getNextValue();
773 for (
size_t ch = 0; ch < numChannels; ++ch)
774 getDataPointer (ch)[i] *= scaler;
779 template <
typename BlockSampleType,
typename SmootherSampleType,
typename SmoothingType>
780 void replaceWithProductOfInternal (AudioBlock<BlockSampleType> src, SmoothedValue<SmootherSampleType, SmoothingType>& value)
const noexcept
782 jassert (numChannels == src.numChannels);
784 if (! value.isSmoothing())
786 replaceWithProductOfInternal (src, (NumericType) value.getTargetValue());
790 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
792 for (
size_t i = 0; i < n; ++i)
794 const auto scaler = (NumericType) value.getNextValue();
796 for (
size_t ch = 0; ch < numChannels; ++ch)
797 getDataPointer (ch)[i] = scaler * src.getChannelPointer (ch)[i];
803 template <
typename OtherSampleType>
804 void JUCE_VECTOR_CALLTYPE addProductOfInternal (AudioBlock<OtherSampleType> src, NumericType factor)
const noexcept
806 jassert (numChannels == src.numChannels);
807 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
809 for (
size_t ch = 0; ch < numChannels; ++ch)
810 FloatVectorOperations::addWithMultiply (getDataPointer (ch), src.getDataPointer (ch), factor, n);
813 template <
typename Src1SampleType,
typename Src2SampleType>
814 void addProductOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2)
const noexcept
816 jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
817 auto n = jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor;
819 for (
size_t ch = 0; ch < numChannels; ++ch)
820 FloatVectorOperations::addWithMultiply (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
824 constexpr void negateInternal() const noexcept
826 multiplyByInternal (
static_cast<NumericType
> (-1.0));
829 template <
typename OtherSampleType>
830 void replaceWithNegativeOfInternal (AudioBlock<OtherSampleType> src)
const noexcept
832 jassert (numChannels == src.numChannels);
833 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
835 for (
size_t ch = 0; ch < numChannels; ++ch)
836 FloatVectorOperations::negate (getDataPointer (ch), src.getDataPointer (ch), n);
839 template <
typename OtherSampleType>
840 void replaceWithAbsoluteValueOfInternal (AudioBlock<OtherSampleType> src)
const noexcept
842 jassert (numChannels == src.numChannels);
843 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
845 for (
size_t ch = 0; ch < numChannels; ++ch)
846 FloatVectorOperations::abs (getDataPointer (ch), src.getDataPointer (ch), n);
850 template <
typename Src1SampleType,
typename Src2SampleType>
851 void replaceWithMinOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2)
const noexcept
853 jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
854 auto n = jmin (src1.numSamples, src2.numSamples, numSamples) * sizeFactor;
856 for (
size_t ch = 0; ch < numChannels; ++ch)
857 FloatVectorOperations::min (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
860 template <
typename Src1SampleType,
typename Src2SampleType>
861 void replaceWithMaxOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2)
const noexcept
863 jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
864 auto n = jmin (src1.numSamples, src2.numSamples, numSamples) * sizeFactor;
866 for (
size_t ch = 0; ch < numChannels; ++ch)
867 FloatVectorOperations::max (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
871 using ChannelCountType =
unsigned int;
874 static constexpr size_t sizeFactor =
sizeof (SampleType) /
sizeof (NumericType);
875 static constexpr size_t elementMask = sizeFactor - 1;
876 static constexpr size_t byteMask = (sizeFactor *
sizeof (NumericType)) - 1;
879 static constexpr size_t defaultAlignment =
sizeof (SIMDRegister<NumericType>);
881 static constexpr size_t defaultAlignment =
sizeof (NumericType);
884 SampleType*
const* channels;
885 ChannelCountType numChannels = 0;
886 size_t startSample = 0, numSamples = 0;
888 template <
typename OtherSampleType>