Skip to content

Commit

Permalink
Allow Buffer to have a custom channel alignment (#492)
Browse files Browse the repository at this point in the history
* Allow Buffer to have a custom channel alignment

* Fix tests compilation
  • Loading branch information
jatinchowdhury18 authored Feb 15, 2024
1 parent 518de8c commit b963190
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 35 deletions.
56 changes: 28 additions & 28 deletions modules/dsp/chowdsp_buffers/Buffers/chowdsp_Buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

namespace chowdsp
{
template <typename SampleType>
Buffer<SampleType>::Buffer (int numChannels, int numSamples)
template <typename SampleType, size_t alignment>
Buffer<SampleType, alignment>::Buffer (int numChannels, int numSamples)
{
setMaxSize (numChannels, numSamples);
}

template <typename SampleType>
void Buffer<SampleType>::setMaxSize (int numChannels, int numSamples)
template <typename SampleType, size_t alignment>
void Buffer<SampleType, alignment>::setMaxSize (int numChannels, int numSamples)
{
// Make sure we don't have any null internal buffers
jassert (juce::isPositiveAndNotGreaterThan (numChannels, maxNumChannels));
Expand Down Expand Up @@ -37,8 +37,8 @@ void Buffer<SampleType>::setMaxSize (int numChannels, int numSamples)
setCurrentSize (numChannels, numSamples);
}

template <typename SampleType>
void Buffer<SampleType>::setCurrentSize (int numChannels, int numSamples) noexcept
template <typename SampleType, size_t alignment>
void Buffer<SampleType, alignment>::setCurrentSize (int numChannels, int numSamples) noexcept
{
// trying to set a current size, but we don't have enough memory allocated!
jassert (numSamples * numChannels <= (int) rawData.size());
Expand All @@ -56,79 +56,79 @@ void Buffer<SampleType>::setCurrentSize (int numChannels, int numSamples) noexce
currentNumSamples = numSamples;
}

template <typename SampleType>
SampleType* Buffer<SampleType>::getWritePointer (int channel) noexcept
template <typename SampleType, size_t alignment>
SampleType* Buffer<SampleType, alignment>::getWritePointer (int channel) noexcept
{
hasBeenCleared = false;
return channelPointers[(size_t) channel];
}

template <typename SampleType>
const SampleType* Buffer<SampleType>::getReadPointer (int channel) const noexcept
template <typename SampleType, size_t alignment>
const SampleType* Buffer<SampleType, alignment>::getReadPointer (int channel) const noexcept
{
return channelPointers[(size_t) channel];
}

template <typename SampleType>
nonstd::span<SampleType> Buffer<SampleType>::getWriteSpan (int channel) noexcept
template <typename SampleType, size_t alignment>
nonstd::span<SampleType> Buffer<SampleType, alignment>::getWriteSpan (int channel) noexcept
{
hasBeenCleared = false;
return { channelPointers[(size_t) channel], (size_t) currentNumSamples };
}

template <typename SampleType>
nonstd::span<const SampleType> Buffer<SampleType>::getReadSpan (int channel) const noexcept
template <typename SampleType, size_t alignment>
nonstd::span<const SampleType> Buffer<SampleType, alignment>::getReadSpan (int channel) const noexcept
{
return { channelPointers[(size_t) channel], (size_t) currentNumSamples };
}

template <typename SampleType>
SampleType** Buffer<SampleType>::getArrayOfWritePointers() noexcept
template <typename SampleType, size_t alignment>
SampleType** Buffer<SampleType, alignment>::getArrayOfWritePointers() noexcept
{
hasBeenCleared = false;
return channelPointers.data();
}

template <typename SampleType>
const SampleType** Buffer<SampleType>::getArrayOfReadPointers() const noexcept
template <typename SampleType, size_t alignment>
const SampleType** Buffer<SampleType, alignment>::getArrayOfReadPointers() const noexcept
{
return const_cast<const SampleType**> (channelPointers.data()); // NOSONAR (using const_cast to be more strict)
}

#if CHOWDSP_USING_JUCE
template <typename SampleType>
template <typename SampleType, size_t alignment>
template <typename T>
std::enable_if_t<buffer_detail::IsFloatOrDouble<T>, juce::AudioBuffer<SampleType>> Buffer<SampleType>::toAudioBuffer()
std::enable_if_t<buffer_detail::IsFloatOrDouble<T>, juce::AudioBuffer<SampleType>> Buffer<SampleType, alignment>::toAudioBuffer()
{
return { getArrayOfWritePointers(), currentNumChannels, currentNumSamples };
}

template <typename SampleType>
template <typename SampleType, size_t alignment>
template <typename T>
std::enable_if_t<buffer_detail::IsFloatOrDouble<T>, juce::AudioBuffer<SampleType>> Buffer<SampleType>::toAudioBuffer() const
std::enable_if_t<buffer_detail::IsFloatOrDouble<T>, juce::AudioBuffer<SampleType>> Buffer<SampleType, alignment>::toAudioBuffer() const
{
return { const_cast<SampleType* const*> (getArrayOfReadPointers()), currentNumChannels, currentNumSamples }; // NOSONAR
}

#if JUCE_MODULE_AVAILABLE_juce_dsp
template <typename SampleType>
template <typename SampleType, size_t alignment>
template <typename T>
std::enable_if_t<buffer_detail::IsFloatOrDouble<T>, AudioBlock<SampleType>> Buffer<SampleType>::toAudioBlock()
std::enable_if_t<buffer_detail::IsFloatOrDouble<T>, AudioBlock<SampleType>> Buffer<SampleType, alignment>::toAudioBlock()
{
return { getArrayOfWritePointers(), (size_t) currentNumChannels, (size_t) currentNumSamples };
}

template <typename SampleType>
template <typename SampleType, size_t alignment>
template <typename T>
std::enable_if_t<buffer_detail::IsFloatOrDouble<T>, AudioBlock<const SampleType>> Buffer<SampleType>::toAudioBlock() const
std::enable_if_t<buffer_detail::IsFloatOrDouble<T>, AudioBlock<const SampleType>> Buffer<SampleType, alignment>::toAudioBlock() const
{
return { getArrayOfReadPointers(), (size_t) currentNumChannels, (size_t) currentNumSamples };
}
#endif
#endif

template <typename SampleType>
void Buffer<SampleType>::clear() noexcept
template <typename SampleType, size_t alignment>
void Buffer<SampleType, alignment>::clear() noexcept
{
if (hasBeenCleared)
return;
Expand Down
17 changes: 12 additions & 5 deletions modules/dsp/chowdsp_buffers/Buffers/chowdsp_Buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,13 @@ namespace buffer_detail

/**
* An audio sample buffer that allocates its own memory.
*
* By default each buffer channel will be aligned to the appropriate SIMD
* byte boundary, unless CHOWDSP_NO_XSIMD is enabled. If you would like to
* provide a custom alignment, you can specify the alignment as the second
* template argument.
*/
template <typename SampleType>
template <typename SampleType, size_t alignment = 0>
class Buffer
{
public:
Expand All @@ -43,10 +48,10 @@ class Buffer
Buffer (int numChannels, int numSamples);

/** Move constructor */
Buffer (Buffer<SampleType>&&) noexcept = default;
Buffer (Buffer&&) noexcept = default;

/** Move assignment */
Buffer<SampleType>& operator= (Buffer<SampleType>&&) noexcept = default;
Buffer& operator= (Buffer&&) noexcept = default;

/**
* Sets the maximum size that this buffer can have, and sets the current size as well.
Expand Down Expand Up @@ -116,11 +121,13 @@ class Buffer

private:
#if ! CHOWDSP_NO_XSIMD
using Allocator = xsimd::default_allocator<SampleType>;
using Allocator = std::conditional_t<alignment == 0,
xsimd::default_allocator<SampleType>,
xsimd::aligned_allocator<SampleType, alignment>>;
#else
using Allocator = std::allocator<SampleType>;
#endif
std::vector<SampleType, Allocator> rawData;
std::vector<SampleType, Allocator> rawData {};

int currentNumChannels = 0;
int currentNumSamples = 0;
Expand Down
3 changes: 2 additions & 1 deletion modules/dsp/chowdsp_simd/chowdsp_simd.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wcast-align",
"-Wc++98-compat-extra-semi",
"-Wshorten-64-to-32",
"-Wfloat-equal",
"-Woverflow")
"-Woverflow",
"-Wdeprecated")
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4244)
#include "third_party/xsimd/include/xsimd/xsimd.hpp"
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
Expand Down
5 changes: 4 additions & 1 deletion tests/dsp_tests/chowdsp_buffers_test/BufferTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wfloat-equal")

template class chowdsp::Buffer<int>;

template <typename T>
using TestBuffer = chowdsp::Buffer<T>;

template <typename T>
using TestStaticBuffer = chowdsp::StaticBuffer<T, 2, 128>;

TEMPLATE_PRODUCT_TEST_CASE ("Buffer Test", "[dsp][buffers][simd]", (chowdsp::Buffer, TestStaticBuffer), (float, double, xsimd::batch<float>, xsimd::batch<double>, int, std::string))
TEMPLATE_PRODUCT_TEST_CASE ("Buffer Test", "[dsp][buffers][simd]", (TestBuffer, TestStaticBuffer), (float, double, xsimd::batch<float>, xsimd::batch<double>, int, std::string))
{
using BufferType = TestType;
using SampleType = typename BufferType::Type;
Expand Down

0 comments on commit b963190

Please sign in to comment.