Loading...
Searching...
No Matches
juce_AudioBlock.h
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce::dsp
{
#ifndef DOXYGEN
namespace SampleTypeHelpers // Internal classes needed for handling sample type classes
{
template <typename T, bool = std::is_floating_point_v<T>>
struct ElementType
{
using Type = T;
};
template <typename T>
struct ElementType<const T, false>
{
using Type = const typename T::value_type;
};
template <typename T>
struct ElementType<T, false>
{
using Type = typename T::value_type;
};
}
#endif
//==============================================================================
template <typename SampleType>
class AudioBlock
{
private:
template <typename OtherSampleType>
using MayUseConvertingConstructor =
std::enable_if_t<std::is_same_v<std::remove_const_t<SampleType>,
std::remove_const_t<OtherSampleType>>
&& std::is_const_v<SampleType>
&& ! std::is_const_v<OtherSampleType>,
int>;
public:
//==============================================================================
using NumericType = typename SampleTypeHelpers::ElementType<SampleType>::Type;
//==============================================================================
AudioBlock() noexcept = default;
constexpr AudioBlock (SampleType* const* channelData,
size_t numberOfChannels, size_t numberOfSamples) noexcept
: channels (channelData),
numChannels (static_cast<ChannelCountType> (numberOfChannels)),
numSamples (numberOfSamples)
{
}
constexpr AudioBlock (SampleType* const* channelData, size_t numberOfChannels,
size_t startSampleIndex, size_t numberOfSamples) noexcept
: channels (channelData),
numChannels (static_cast<ChannelCountType> (numberOfChannels)),
startSample (startSampleIndex),
numSamples (numberOfSamples)
{
}
AudioBlock (HeapBlock<char>& heapBlockToUseForAllocation,
size_t numberOfChannels, size_t numberOfSamples,
size_t alignmentInBytes = defaultAlignment) noexcept
: numChannels (static_cast<ChannelCountType> (numberOfChannels)),
numSamples (numberOfSamples)
{
auto roundedUpNumSamples = (numberOfSamples + elementMask) & ~elementMask;
auto channelSize = sizeof (SampleType) * roundedUpNumSamples;
auto channelListBytes = sizeof (SampleType*) * numberOfChannels;
auto extraBytes = alignmentInBytes - 1;
heapBlockToUseForAllocation.malloc (channelListBytes + extraBytes + channelSize * numberOfChannels);
auto* chanArray = unalignedPointerCast<SampleType**> (heapBlockToUseForAllocation.getData());
channels = chanArray;
auto* data = unalignedPointerCast<SampleType*> (addBytesToPointer (chanArray, channelListBytes));
data = snapPointerToAlignment (data, alignmentInBytes);
for (ChannelCountType i = 0; i < numChannels; ++i)
{
chanArray[i] = data;
data += roundedUpNumSamples;
}
}
template <typename OtherSampleType>
constexpr AudioBlock (AudioBuffer<OtherSampleType>& buffer) noexcept
: channels (buffer.getArrayOfWritePointers()),
numChannels (static_cast<ChannelCountType> (buffer.getNumChannels())),
numSamples (static_cast<size_t> (buffer.getNumSamples()))
{
}
template <typename OtherSampleType>
constexpr AudioBlock (const AudioBuffer<OtherSampleType>& buffer) noexcept
: channels (buffer.getArrayOfReadPointers()),
numChannels (static_cast<ChannelCountType> (buffer.getNumChannels())),
numSamples (static_cast<size_t> (buffer.getNumSamples()))
{
}
template <typename OtherSampleType>
AudioBlock (AudioBuffer<OtherSampleType>& buffer, size_t startSampleIndex) noexcept
: channels (buffer.getArrayOfWritePointers()),
numChannels (static_cast<ChannelCountType> (buffer.getNumChannels())),
startSample (startSampleIndex),
numSamples (static_cast<size_t> (buffer.getNumSamples()) - startSampleIndex)
{
jassert (startSample < static_cast<size_t> (buffer.getNumSamples()));
}
AudioBlock (const AudioBlock& other) noexcept = default;
AudioBlock& operator= (const AudioBlock& other) noexcept = default;
template <typename OtherSampleType, MayUseConvertingConstructor<OtherSampleType> = 0>
AudioBlock (const AudioBlock<OtherSampleType>& other) noexcept
: channels { other.channels },
numChannels { other.numChannels },
startSample { other.startSample },
numSamples { other.numSamples }
{
}
template <typename OtherSampleType, MayUseConvertingConstructor<OtherSampleType> = 0>
AudioBlock& operator= (const AudioBlock<OtherSampleType>& other) noexcept
{
AudioBlock blockCopy { other };
swap (blockCopy);
return *this;
}
void swap (AudioBlock& other) noexcept
{
std::swap (other.channels, channels);
std::swap (other.numChannels, numChannels);
std::swap (other.startSample, startSample);
std::swap (other.numSamples, numSamples);
}
//==============================================================================
template <typename OtherSampleType>
constexpr bool operator== (const AudioBlock<OtherSampleType>& other) const noexcept
{
return std::equal (channels,
channels + numChannels,
other.channels,
other.channels + other.numChannels)
&& startSample == other.startSample
&& numSamples == other.numSamples;
}
template <typename OtherSampleType>
constexpr bool operator!= (const AudioBlock<OtherSampleType>& other) const noexcept
{
return ! (*this == other);
}
//==============================================================================
constexpr size_t getNumChannels() const noexcept { return static_cast<size_t> (numChannels); }
constexpr size_t getNumSamples() const noexcept { return numSamples; }
SampleType* getChannelPointer (size_t channel) const noexcept
{
jassert (channel < numChannels);
jassert (numSamples > 0);
return channels[channel] + startSample;
}
AudioBlock getSingleChannelBlock (size_t channel) const noexcept
{
jassert (channel < numChannels);
return AudioBlock (channels + channel, 1, startSample, numSamples);
}
AudioBlock getSubsetChannelBlock (size_t channelStart, size_t numChannelsToUse) const noexcept
{
jassert (channelStart < numChannels);
jassert ((channelStart + numChannelsToUse) <= numChannels);
return AudioBlock (channels + channelStart, numChannelsToUse, startSample, numSamples);
}
SampleType getSample (int channel, int sampleIndex) const noexcept
{
jassert (isPositiveAndBelow (channel, numChannels));
jassert (isPositiveAndBelow (sampleIndex, numSamples));
return channels[channel][(size_t) startSample + (size_t) sampleIndex];
}
void setSample (int destChannel, int destSample, SampleType newValue) const noexcept
{
jassert (isPositiveAndBelow (destChannel, numChannels));
jassert (isPositiveAndBelow (destSample, numSamples));
channels[destChannel][(size_t) startSample + (size_t) destSample] = newValue;
}
void addSample (int destChannel, int destSample, SampleType valueToAdd) const noexcept
{
jassert (isPositiveAndBelow (destChannel, numChannels));
jassert (isPositiveAndBelow (destSample, numSamples));
channels[destChannel][(size_t) startSample + (size_t) destSample] += valueToAdd;
}
//==============================================================================
AudioBlock& clear() noexcept { clearInternal(); return *this; }
const AudioBlock& clear() const noexcept { clearInternal(); return *this; }
AudioBlock& JUCE_VECTOR_CALLTYPE fill (NumericType value) noexcept { fillInternal (value); return *this; }
const AudioBlock& JUCE_VECTOR_CALLTYPE fill (NumericType value) const noexcept { fillInternal (value); return *this; }
template <typename OtherSampleType>
AudioBlock& copyFrom (const AudioBlock<OtherSampleType>& src) noexcept { copyFromInternal (src); return *this; }
template <typename OtherSampleType>
const AudioBlock& copyFrom (const AudioBlock<OtherSampleType>& src) const noexcept { copyFromInternal (src); return *this; }
template <typename OtherNumericType>
AudioBlock& copyFrom (const AudioBuffer<OtherNumericType>& src,
size_t srcPos = 0, size_t dstPos = 0,
size_t numElements = std::numeric_limits<size_t>::max()) { copyFromInternal (src, srcPos, dstPos, numElements); return *this; }
template <typename OtherNumericType>
const AudioBlock& copyFrom (const AudioBuffer<OtherNumericType>& src,
size_t srcPos = 0, size_t dstPos = 0,
size_t numElements = std::numeric_limits<size_t>::max()) const { copyFromInternal (src, srcPos, dstPos, numElements); return *this; }
void copyTo (AudioBuffer<std::remove_const_t<NumericType>>& dst, size_t srcPos = 0, size_t dstPos = 0,
size_t numElements = std::numeric_limits<size_t>::max()) const
{
auto dstlen = static_cast<size_t> (dst.getNumSamples()) / sizeFactor;
auto n = jmin (numSamples - srcPos, dstlen - dstPos, numElements) * sizeFactor;
auto maxChannels = jmin (static_cast<size_t> (dst.getNumChannels()), static_cast<size_t> (numChannels));
for (size_t ch = 0; ch < maxChannels; ++ch)
FloatVectorOperations::copy (dst.getWritePointer ((int) ch, (int) (dstPos * sizeFactor)),
getDataPointer (ch) + (srcPos * sizeFactor),
n);
}
AudioBlock& move (size_t srcPos, size_t dstPos,
size_t numElements = std::numeric_limits<size_t>::max()) noexcept { moveInternal (srcPos, dstPos, numElements); return *this; }
const AudioBlock& move (size_t srcPos, size_t dstPos,
size_t numElements = std::numeric_limits<size_t>::max()) const noexcept { moveInternal (srcPos, dstPos, numElements); return *this; }
//==============================================================================
AudioBlock getSubBlock (size_t newOffset, size_t newLength) const noexcept
{
jassert (newOffset < numSamples);
jassert (newOffset + newLength <= numSamples);
return AudioBlock (channels, numChannels, startSample + newOffset, newLength);
}
AudioBlock getSubBlock (size_t newOffset) const noexcept
{
return getSubBlock (newOffset, getNumSamples() - newOffset);
}
//==============================================================================
AudioBlock& JUCE_VECTOR_CALLTYPE add (NumericType value) noexcept { addInternal (value); return *this; }
const AudioBlock& JUCE_VECTOR_CALLTYPE add (NumericType value) const noexcept { addInternal (value); return *this; }
template <typename OtherSampleType>
AudioBlock& add (AudioBlock<OtherSampleType> src) noexcept { addInternal (src); return *this; }
template <typename OtherSampleType>
const AudioBlock& add (AudioBlock<OtherSampleType> src) const noexcept { addInternal (src); return *this; }
template <typename OtherSampleType>
AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithSumOf (AudioBlock<OtherSampleType> src, NumericType value) noexcept { replaceWithSumOfInternal (src, value); return *this; }
template <typename OtherSampleType>
const AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithSumOf (AudioBlock<OtherSampleType> src, NumericType value) const noexcept { replaceWithSumOfInternal (src, value); return *this; }
template <typename Src1SampleType, typename Src2SampleType>
AudioBlock& replaceWithSumOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { replaceWithSumOfInternal (src1, src2); return *this; }
template <typename Src1SampleType, typename Src2SampleType>
const AudioBlock& replaceWithSumOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { replaceWithSumOfInternal (src1, src2); return *this; }
//==============================================================================
AudioBlock& JUCE_VECTOR_CALLTYPE subtract (NumericType value) noexcept { subtractInternal (value); return *this; }
const AudioBlock& JUCE_VECTOR_CALLTYPE subtract (NumericType value) const noexcept { subtractInternal (value); return *this; }
template <typename OtherSampleType>
AudioBlock& subtract (AudioBlock<OtherSampleType> src) noexcept { subtractInternal (src); return *this; }
template <typename OtherSampleType>
const AudioBlock& subtract (AudioBlock<OtherSampleType> src) const noexcept { subtractInternal (src); return *this; }
template <typename OtherSampleType>
AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithDifferenceOf (AudioBlock<OtherSampleType> src, NumericType value) noexcept { replaceWithDifferenceOfInternal (src, value); return *this; }
template <typename OtherSampleType>
const AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithDifferenceOf (AudioBlock<OtherSampleType> src, NumericType value) const noexcept { replaceWithDifferenceOfInternal (src, value); return *this; }
template <typename Src1SampleType, typename Src2SampleType>
AudioBlock& replaceWithDifferenceOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { replaceWithDifferenceOfInternal (src1, src2); return *this; }
template <typename Src1SampleType, typename Src2SampleType>
const AudioBlock& replaceWithDifferenceOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { replaceWithDifferenceOfInternal (src1, src2); return *this; }
//==============================================================================
AudioBlock& JUCE_VECTOR_CALLTYPE multiplyBy (NumericType value) noexcept { multiplyByInternal (value); return *this; }
const AudioBlock& JUCE_VECTOR_CALLTYPE multiplyBy (NumericType value) const noexcept { multiplyByInternal (value); return *this; }
template <typename OtherSampleType>
AudioBlock& multiplyBy (AudioBlock<OtherSampleType> src) noexcept { multiplyByInternal (src); return *this; }
template <typename OtherSampleType>
const AudioBlock& multiplyBy (AudioBlock<OtherSampleType> src) const noexcept { multiplyByInternal (src); return *this; }
template <typename OtherSampleType>
AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithProductOf (AudioBlock<OtherSampleType> src, NumericType value) noexcept { replaceWithProductOfInternal (src, value); return *this; }
template <typename OtherSampleType>
const AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithProductOf (AudioBlock<OtherSampleType> src, NumericType value) const noexcept { replaceWithProductOfInternal (src, value); return *this; }
template <typename Src1SampleType, typename Src2SampleType>
AudioBlock& replaceWithProductOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { replaceWithProductOfInternal (src1, src2); return *this; }
template <typename Src1SampleType, typename Src2SampleType>
const AudioBlock& replaceWithProductOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { replaceWithProductOfInternal (src1, src2); return *this; }
//==============================================================================
template <typename OtherSampleType, typename SmoothingType>
AudioBlock& multiplyBy (SmoothedValue<OtherSampleType, SmoothingType>& value) noexcept { multiplyByInternal (value); return *this; }
template <typename OtherSampleType, typename SmoothingType>
const AudioBlock& multiplyBy (SmoothedValue<OtherSampleType, SmoothingType>& value) const noexcept { multiplyByInternal (value); return *this; }
template <typename BlockSampleType, typename SmootherSampleType, typename SmoothingType>
AudioBlock& replaceWithProductOf (AudioBlock<BlockSampleType> src, SmoothedValue<SmootherSampleType, SmoothingType>& value) noexcept { replaceWithProductOfInternal (src, value); return *this; }
template <typename BlockSampleType, typename SmootherSampleType, typename SmoothingType>
const AudioBlock& replaceWithProductOf (AudioBlock<BlockSampleType> src, SmoothedValue<SmootherSampleType, SmoothingType>& value) const noexcept { replaceWithProductOfInternal (src, value); return *this; }
//==============================================================================
template <typename OtherSampleType>
AudioBlock& JUCE_VECTOR_CALLTYPE addProductOf (AudioBlock<OtherSampleType> src, NumericType factor) noexcept { addProductOfInternal (src, factor); return *this; }
template <typename OtherSampleType>
const AudioBlock& JUCE_VECTOR_CALLTYPE addProductOf (AudioBlock<OtherSampleType> src, NumericType factor) const noexcept { addProductOfInternal (src, factor); return *this; }
template <typename Src1SampleType, typename Src2SampleType>
AudioBlock& addProductOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { addProductOfInternal (src1, src2); return *this; }
template <typename Src1SampleType, typename Src2SampleType>
const AudioBlock& addProductOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { addProductOfInternal (src1, src2); return *this; }
//==============================================================================
AudioBlock& negate() noexcept { negateInternal(); return *this; }
const AudioBlock& negate() const noexcept { negateInternal(); return *this; }
template <typename OtherSampleType>
AudioBlock& replaceWithNegativeOf (AudioBlock<OtherSampleType> src) noexcept { replaceWithNegativeOfInternal (src); return *this; }
template <typename OtherSampleType>
const AudioBlock& replaceWithNegativeOf (AudioBlock<OtherSampleType> src) const noexcept { replaceWithNegativeOfInternal (src); return *this; }
template <typename OtherSampleType>
AudioBlock& replaceWithAbsoluteValueOf (AudioBlock<OtherSampleType> src) noexcept { replaceWithAbsoluteValueOfInternal (src); return *this; }
template <typename OtherSampleType>
const AudioBlock& replaceWithAbsoluteValueOf (AudioBlock<OtherSampleType> src) const noexcept { replaceWithAbsoluteValueOfInternal (src); return *this; }
//==============================================================================
template <typename Src1SampleType, typename Src2SampleType>
AudioBlock& replaceWithMinOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { replaceWithMinOfInternal (src1, src2); return *this; }
template <typename Src1SampleType, typename Src2SampleType>
const AudioBlock& replaceWithMinOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { replaceWithMinOfInternal (src1, src2); return *this; }
template <typename Src1SampleType, typename Src2SampleType>
AudioBlock& replaceWithMaxOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { replaceWithMaxOfInternal (src1, src2); return *this; }
template <typename Src1SampleType, typename Src2SampleType>
const AudioBlock& replaceWithMaxOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { replaceWithMaxOfInternal (src1, src2); return *this; }
//==============================================================================
Range<std::remove_const_t<NumericType>> findMinAndMax() const noexcept
{
if (numChannels == 0)
return {};
auto n = numSamples * sizeFactor;
auto minmax = FloatVectorOperations::findMinAndMax (getDataPointer (0), n);
for (size_t ch = 1; ch < numChannels; ++ch)
minmax = minmax.getUnionWith (FloatVectorOperations::findMinAndMax (getDataPointer (ch), n));
return minmax;
}
//==============================================================================
// Convenient operator wrappers.
AudioBlock& JUCE_VECTOR_CALLTYPE operator+= (NumericType value) noexcept { return add (value); }
const AudioBlock& JUCE_VECTOR_CALLTYPE operator+= (NumericType value) const noexcept { return add (value); }
AudioBlock& operator+= (AudioBlock src) noexcept { return add (src); }
const AudioBlock& operator+= (AudioBlock src) const noexcept { return add (src); }
AudioBlock& JUCE_VECTOR_CALLTYPE operator-= (NumericType value) noexcept { return subtract (value); }
const AudioBlock& JUCE_VECTOR_CALLTYPE operator-= (NumericType value) const noexcept { return subtract (value); }
AudioBlock& operator-= (AudioBlock src) noexcept { return subtract (src); }
const AudioBlock& operator-= (AudioBlock src) const noexcept { return subtract (src); }
AudioBlock& JUCE_VECTOR_CALLTYPE operator*= (NumericType value) noexcept { return multiplyBy (value); }
const AudioBlock& JUCE_VECTOR_CALLTYPE operator*= (NumericType value) const noexcept { return multiplyBy (value); }
AudioBlock& operator*= (AudioBlock src) noexcept { return multiplyBy (src); }
const AudioBlock& operator*= (AudioBlock src) const noexcept { return multiplyBy (src); }
template <typename OtherSampleType, typename SmoothingType>
AudioBlock& operator*= (SmoothedValue<OtherSampleType, SmoothingType>& value) noexcept { return multiplyBy (value); }
template <typename OtherSampleType, typename SmoothingType>
const AudioBlock& operator*= (SmoothedValue<OtherSampleType, SmoothingType>& value) const noexcept { return multiplyBy (value); }
//==============================================================================
// This class can only be used with floating point types
static_assert (std::is_same_v<std::remove_const_t<SampleType>, float>
|| std::is_same_v<std::remove_const_t<SampleType>, double>
#if JUCE_USE_SIMD
|| std::is_same_v<std::remove_const_t<SampleType>, SIMDRegister<float>>
|| std::is_same_v<std::remove_const_t<SampleType>, SIMDRegister<double>>
#endif
, "AudioBlock only supports single or double precision floating point types");
//==============================================================================
template <typename Src1SampleType, typename Src2SampleType, typename FunctionType>
static void process (AudioBlock<Src1SampleType> inBlock, AudioBlock<Src2SampleType> outBlock, FunctionType&& function)
{
auto len = inBlock.getNumSamples();
auto numChans = inBlock.getNumChannels();
jassert (len == outBlock.getNumSamples());
jassert (numChans == outBlock.getNumChannels());
for (ChannelCountType c = 0; c < numChans; ++c)
{
auto* src = inBlock.getChannelPointer (c);
auto* dst = outBlock.getChannelPointer (c);
for (size_t i = 0; i < len; ++i)
dst[i] = function (src[i]);
}
}
private:
NumericType* getDataPointer (size_t channel) const noexcept
{
return reinterpret_cast<NumericType*> (getChannelPointer (channel));
}
//==============================================================================
void JUCE_VECTOR_CALLTYPE clearInternal() const noexcept
{
auto n = numSamples * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::clear (getDataPointer (ch), n);
}
void JUCE_VECTOR_CALLTYPE fillInternal (NumericType value) const noexcept
{
auto n = numSamples * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::fill (getDataPointer (ch), value, n);
}
template <typename OtherSampleType>
void copyFromInternal (const AudioBlock<OtherSampleType>& src) const noexcept
{
auto maxChannels = jmin (src.numChannels, numChannels);
auto n = jmin (src.numSamples * src.sizeFactor, numSamples * sizeFactor);
for (size_t ch = 0; ch < maxChannels; ++ch)
FloatVectorOperations::copy (getDataPointer (ch), src.getDataPointer (ch), n);
}
template <typename OtherNumericType>
void copyFromInternal (const AudioBuffer<OtherNumericType>& src, size_t srcPos, size_t dstPos, size_t numElements) const
{
auto srclen = static_cast<size_t> (src.getNumSamples()) / sizeFactor;
auto n = jmin (srclen - srcPos, numSamples - dstPos, numElements) * sizeFactor;
auto maxChannels = jmin (static_cast<size_t> (src.getNumChannels()), static_cast<size_t> (numChannels));
for (size_t ch = 0; ch < maxChannels; ++ch)
FloatVectorOperations::copy (getDataPointer (ch) + (dstPos * sizeFactor),
src.getReadPointer ((int) ch, (int) (srcPos * sizeFactor)),
n);
}
void moveInternal (size_t srcPos, size_t dstPos,
size_t numElements = std::numeric_limits<size_t>::max()) const noexcept
{
jassert (srcPos <= numSamples && dstPos <= numSamples);
auto len = jmin (numSamples - srcPos, numSamples - dstPos, numElements) * sizeof (SampleType);
if (len != 0)
for (size_t ch = 0; ch < numChannels; ++ch)
::memmove (getChannelPointer (ch) + dstPos,
getChannelPointer (ch) + srcPos, len);
}
//==============================================================================
void JUCE_VECTOR_CALLTYPE addInternal (NumericType value) const noexcept
{
auto n = numSamples * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::add (getDataPointer (ch), value, n);
}
template <typename OtherSampleType>
void addInternal (AudioBlock<OtherSampleType> src) const noexcept
{
jassert (numChannels == src.numChannels);
auto n = jmin (numSamples, src.numSamples) * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::add (getDataPointer (ch), src.getDataPointer (ch), n);
}
template <typename OtherSampleType>
void JUCE_VECTOR_CALLTYPE replaceWithSumOfInternal (AudioBlock<OtherSampleType> src, NumericType value) const noexcept
{
jassert (numChannels == src.numChannels);
auto n = jmin (numSamples, src.numSamples) * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::add (getDataPointer (ch), src.getDataPointer (ch), value, n);
}
template <typename Src1SampleType, typename Src2SampleType>
void replaceWithSumOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept
{
jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
auto n = jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::add (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
}
//==============================================================================
constexpr void JUCE_VECTOR_CALLTYPE subtractInternal (NumericType value) const noexcept
{
addInternal (value * static_cast<NumericType> (-1.0));
}
template <typename OtherSampleType>
void subtractInternal (AudioBlock<OtherSampleType> src) const noexcept
{
jassert (numChannels == src.numChannels);
auto n = jmin (numSamples, src.numSamples) * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::subtract (getDataPointer (ch), src.getDataPointer (ch), n);
}
template <typename OtherSampleType>
void JUCE_VECTOR_CALLTYPE replaceWithDifferenceOfInternal (AudioBlock<OtherSampleType> src, NumericType value) const noexcept
{
replaceWithSumOfInternal (src, static_cast<NumericType> (-1.0) * value);
}
template <typename Src1SampleType, typename Src2SampleType>
void replaceWithDifferenceOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept
{
jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
auto n = jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::subtract (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
}
//==============================================================================
void JUCE_VECTOR_CALLTYPE multiplyByInternal (NumericType value) const noexcept
{
auto n = numSamples * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::multiply (getDataPointer (ch), value, n);
}
template <typename OtherSampleType>
void multiplyByInternal (AudioBlock<OtherSampleType> src) const noexcept
{
jassert (numChannels == src.numChannels);
auto n = jmin (numSamples, src.numSamples) * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::multiply (getDataPointer (ch), src.getDataPointer (ch), n);
}
template <typename OtherSampleType>
void JUCE_VECTOR_CALLTYPE replaceWithProductOfInternal (AudioBlock<OtherSampleType> src, NumericType value) const noexcept
{
jassert (numChannels == src.numChannels);
auto n = jmin (numSamples, src.numSamples) * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::multiply (getDataPointer (ch), src.getDataPointer (ch), value, n);
}
template <typename Src1SampleType, typename Src2SampleType>
void replaceWithProductOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept
{
jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
auto n = jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::multiply (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
}
template <typename OtherSampleType, typename SmoothingType>
void multiplyByInternal (SmoothedValue<OtherSampleType, SmoothingType>& value) const noexcept
{
if (! value.isSmoothing())
{
multiplyByInternal ((NumericType) value.getTargetValue());
}
else
{
for (size_t i = 0; i < numSamples; ++i)
{
const auto scaler = (NumericType) value.getNextValue();
for (size_t ch = 0; ch < numChannels; ++ch)
getDataPointer (ch)[i] *= scaler;
}
}
}
template <typename BlockSampleType, typename SmootherSampleType, typename SmoothingType>
void replaceWithProductOfInternal (AudioBlock<BlockSampleType> src, SmoothedValue<SmootherSampleType, SmoothingType>& value) const noexcept
{
jassert (numChannels == src.numChannels);
if (! value.isSmoothing())
{
replaceWithProductOfInternal (src, (NumericType) value.getTargetValue());
}
else
{
auto n = jmin (numSamples, src.numSamples) * sizeFactor;
for (size_t i = 0; i < n; ++i)
{
const auto scaler = (NumericType) value.getNextValue();
for (size_t ch = 0; ch < numChannels; ++ch)
getDataPointer (ch)[i] = scaler * src.getChannelPointer (ch)[i];
}
}
}
//==============================================================================
template <typename OtherSampleType>
void JUCE_VECTOR_CALLTYPE addProductOfInternal (AudioBlock<OtherSampleType> src, NumericType factor) const noexcept
{
jassert (numChannels == src.numChannels);
auto n = jmin (numSamples, src.numSamples) * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::addWithMultiply (getDataPointer (ch), src.getDataPointer (ch), factor, n);
}
template <typename Src1SampleType, typename Src2SampleType>
void addProductOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept
{
jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
auto n = jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::addWithMultiply (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
}
//==============================================================================
constexpr void negateInternal() const noexcept
{
multiplyByInternal (static_cast<NumericType> (-1.0));
}
template <typename OtherSampleType>
void replaceWithNegativeOfInternal (AudioBlock<OtherSampleType> src) const noexcept
{
jassert (numChannels == src.numChannels);
auto n = jmin (numSamples, src.numSamples) * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::negate (getDataPointer (ch), src.getDataPointer (ch), n);
}
template <typename OtherSampleType>
void replaceWithAbsoluteValueOfInternal (AudioBlock<OtherSampleType> src) const noexcept
{
jassert (numChannels == src.numChannels);
auto n = jmin (numSamples, src.numSamples) * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::abs (getDataPointer (ch), src.getDataPointer (ch), n);
}
//==============================================================================
template <typename Src1SampleType, typename Src2SampleType>
void replaceWithMinOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept
{
jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
auto n = jmin (src1.numSamples, src2.numSamples, numSamples) * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::min (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
}
template <typename Src1SampleType, typename Src2SampleType>
void replaceWithMaxOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept
{
jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
auto n = jmin (src1.numSamples, src2.numSamples, numSamples) * sizeFactor;
for (size_t ch = 0; ch < numChannels; ++ch)
FloatVectorOperations::max (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
}
//==============================================================================
using ChannelCountType = unsigned int;
//==============================================================================
static constexpr size_t sizeFactor = sizeof (SampleType) / sizeof (NumericType);
static constexpr size_t elementMask = sizeFactor - 1;
static constexpr size_t byteMask = (sizeFactor * sizeof (NumericType)) - 1;
#if JUCE_USE_SIMD
static constexpr size_t defaultAlignment = sizeof (SIMDRegister<NumericType>);
#else
static constexpr size_t defaultAlignment = sizeof (NumericType);
#endif
SampleType* const* channels;
ChannelCountType numChannels = 0;
size_t startSample = 0, numSamples = 0;
template <typename OtherSampleType>
friend class AudioBlock;
};
} // namespace juce::dsp
juce::AudioBuffer
Definition juce_AudioSampleBuffer.h:34
juce::HeapBlock
Definition juce_HeapBlock.h:87
juce::Range
Definition juce_Range.h:40
juce::SmoothedValue
Definition juce_SmoothedValue.h:227
juce::dsp::AudioBlock
Definition juce_AudioBlock.h:68
juce::dsp::AudioBlock::addProductOf
AudioBlock & addProductOf(AudioBlock< Src1SampleType > src1, AudioBlock< Src2SampleType > src2) noexcept
Definition juce_AudioBlock.h:483
juce::dsp::AudioBlock::copyFrom
AudioBlock & copyFrom(const AudioBuffer< OtherNumericType > &src, size_t srcPos=0, size_t dstPos=0, size_t numElements=std::numeric_limits< size_t >::max())
Definition juce_AudioBlock.h:323
juce::dsp::AudioBlock::process
static void process(AudioBlock< Src1SampleType > inBlock, AudioBlock< Src2SampleType > outBlock, FunctionType &&function)
Definition juce_AudioBlock.h:574
juce::dsp::AudioBlock::getSubBlock
AudioBlock getSubBlock(size_t newOffset, size_t newLength) const noexcept
Definition juce_AudioBlock.h:369
juce::dsp::AudioBlock::subtract
AudioBlock &JUCE_VECTOR_CALLTYPE subtract(NumericType value) noexcept
Definition juce_AudioBlock.h:417
juce::dsp::AudioBlock::replaceWithProductOf
AudioBlock &JUCE_VECTOR_CALLTYPE replaceWithProductOf(AudioBlock< OtherSampleType > src, NumericType value) noexcept
Definition juce_AudioBlock.h:451
juce::dsp::AudioBlock::getSubsetChannelBlock
AudioBlock getSubsetChannelBlock(size_t channelStart, size_t numChannelsToUse) const noexcept
Definition juce_AudioBlock.h:257
juce::dsp::AudioBlock::setSample
void setSample(int destChannel, int destSample, SampleType newValue) const noexcept
Definition juce_AudioBlock.h:282
juce::dsp::AudioBlock::replaceWithDifferenceOf
AudioBlock & replaceWithDifferenceOf(AudioBlock< Src1SampleType > src1, AudioBlock< Src2SampleType > src2) noexcept
Definition juce_AudioBlock.h:434
juce::dsp::AudioBlock::getNumChannels
constexpr size_t getNumChannels() const noexcept
Definition juce_AudioBlock.h:233
juce::dsp::AudioBlock::replaceWithSumOf
AudioBlock &JUCE_VECTOR_CALLTYPE replaceWithSumOf(AudioBlock< OtherSampleType > src, NumericType value) noexcept
Definition juce_AudioBlock.h:405
juce::dsp::AudioBlock::replaceWithMaxOf
AudioBlock & replaceWithMaxOf(AudioBlock< Src1SampleType > src1, AudioBlock< Src2SampleType > src2) noexcept
Definition juce_AudioBlock.h:513
juce::dsp::AudioBlock::copyTo
void copyTo(AudioBuffer< std::remove_const_t< NumericType > > &dst, size_t srcPos=0, size_t dstPos=0, size_t numElements=std::numeric_limits< size_t >::max()) const
Definition juce_AudioBlock.h:338
juce::dsp::AudioBlock::getChannelPointer
SampleType * getChannelPointer(size_t channel) const noexcept
Definition juce_AudioBlock.h:239
juce::dsp::AudioBlock::negate
AudioBlock & negate() noexcept
Definition juce_AudioBlock.h:489
juce::dsp::AudioBlock::replaceWithNegativeOf
AudioBlock & replaceWithNegativeOf(AudioBlock< OtherSampleType > src) noexcept
Definition juce_AudioBlock.h:494
juce::dsp::AudioBlock::replaceWithDifferenceOf
AudioBlock &JUCE_VECTOR_CALLTYPE replaceWithDifferenceOf(AudioBlock< OtherSampleType > src, NumericType value) noexcept
Definition juce_AudioBlock.h:428
juce::dsp::AudioBlock::replaceWithSumOf
AudioBlock & replaceWithSumOf(AudioBlock< Src1SampleType > src1, AudioBlock< Src2SampleType > src2) noexcept
Definition juce_AudioBlock.h:411
juce::dsp::AudioBlock::AudioBlock
AudioBlock(AudioBuffer< OtherSampleType > &buffer, size_t startSampleIndex) noexcept
Definition juce_AudioBlock.h:176
juce::dsp::AudioBlock::multiplyBy
AudioBlock &JUCE_VECTOR_CALLTYPE multiplyBy(NumericType value) noexcept
Definition juce_AudioBlock.h:440
juce::dsp::AudioBlock::add
AudioBlock &JUCE_VECTOR_CALLTYPE add(NumericType value) noexcept
Definition juce_AudioBlock.h:394
juce::dsp::AudioBlock::AudioBlock
constexpr AudioBlock(AudioBuffer< OtherSampleType > &buffer) noexcept
Definition juce_AudioBlock.h:150
juce::dsp::AudioBlock::add
AudioBlock & add(AudioBlock< OtherSampleType > src) noexcept
Definition juce_AudioBlock.h:399
juce::dsp::AudioBlock::move
AudioBlock & move(size_t srcPos, size_t dstPos, size_t numElements=std::numeric_limits< size_t >::max()) noexcept
Definition juce_AudioBlock.h:354
juce::dsp::AudioBlock::replaceWithProductOf
AudioBlock & replaceWithProductOf(AudioBlock< Src1SampleType > src1, AudioBlock< Src2SampleType > src2) noexcept
Definition juce_AudioBlock.h:457
juce::dsp::AudioBlock::multiplyBy
AudioBlock & multiplyBy(SmoothedValue< OtherSampleType, SmoothingType > &value) noexcept
Definition juce_AudioBlock.h:464
juce::dsp::AudioBlock::replaceWithAbsoluteValueOf
AudioBlock & replaceWithAbsoluteValueOf(AudioBlock< OtherSampleType > src) noexcept
Definition juce_AudioBlock.h:500
juce::dsp::AudioBlock::copyFrom
AudioBlock & copyFrom(const AudioBlock< OtherSampleType > &src) noexcept
Definition juce_AudioBlock.h:312
juce::dsp::AudioBlock::addProductOf
AudioBlock &JUCE_VECTOR_CALLTYPE addProductOf(AudioBlock< OtherSampleType > src, NumericType factor) noexcept
Definition juce_AudioBlock.h:477
juce::dsp::AudioBlock::getSingleChannelBlock
AudioBlock getSingleChannelBlock(size_t channel) const noexcept
Definition juce_AudioBlock.h:247
juce::dsp::AudioBlock::AudioBlock
constexpr AudioBlock(const AudioBuffer< OtherSampleType > &buffer) noexcept
Definition juce_AudioBlock.h:163
juce::dsp::AudioBlock::getSample
SampleType getSample(int channel, int sampleIndex) const noexcept
Definition juce_AudioBlock.h:270
juce::dsp::AudioBlock::subtract
AudioBlock & subtract(AudioBlock< OtherSampleType > src) noexcept
Definition juce_AudioBlock.h:422
juce::dsp::AudioBlock::getSubBlock
AudioBlock getSubBlock(size_t newOffset) const noexcept
Definition juce_AudioBlock.h:387
juce::dsp::AudioBlock::replaceWithMinOf
AudioBlock & replaceWithMinOf(AudioBlock< Src1SampleType > src1, AudioBlock< Src2SampleType > src2) noexcept
Definition juce_AudioBlock.h:507
juce::dsp::AudioBlock::getNumSamples
constexpr size_t getNumSamples() const noexcept
Definition juce_AudioBlock.h:236
juce::dsp::AudioBlock::addSample
void addSample(int destChannel, int destSample, SampleType valueToAdd) const noexcept
Definition juce_AudioBlock.h:294
juce::dsp::AudioBlock::clear
AudioBlock & clear() noexcept
Definition juce_AudioBlock.h:303
juce::dsp::AudioBlock::AudioBlock
AudioBlock() noexcept=default
juce::dsp::AudioBlock::fill
AudioBlock &JUCE_VECTOR_CALLTYPE fill(NumericType value) noexcept
Definition juce_AudioBlock.h:307
juce::dsp::AudioBlock::AudioBlock
constexpr AudioBlock(SampleType *const *channelData, size_t numberOfChannels, size_t startSampleIndex, size_t numberOfSamples) noexcept
Definition juce_AudioBlock.h:104
juce::dsp::AudioBlock::AudioBlock
AudioBlock(HeapBlock< char > &heapBlockToUseForAllocation, size_t numberOfChannels, size_t numberOfSamples, size_t alignmentInBytes=defaultAlignment) noexcept
Definition juce_AudioBlock.h:118
juce::dsp::AudioBlock::replaceWithProductOf
AudioBlock & replaceWithProductOf(AudioBlock< BlockSampleType > src, SmoothedValue< SmootherSampleType, SmoothingType > &value) noexcept
Definition juce_AudioBlock.h:470
juce::dsp::AudioBlock::findMinAndMax
Range< std::remove_const_t< NumericType > > findMinAndMax() const noexcept
Definition juce_AudioBlock.h:519
juce::dsp::AudioBlock::multiplyBy
AudioBlock & multiplyBy(AudioBlock< OtherSampleType > src) noexcept
Definition juce_AudioBlock.h:445