Support fixed padding for AudioBuffer

This commit is contained in:
Jean Pierre Cimalando 2020-06-11 02:54:10 +02:00
parent abd951a92b
commit 50efcfc95a

View file

@ -26,7 +26,9 @@ namespace sfz
* @tparam MaxChannels the maximum number of channels in the buffer
* @tparam Alignment the alignment for the buffers
*/
template <class Type, size_t MaxChannels = sfz::config::numChannels, unsigned int Alignment = SIMDConfig::defaultAlignment>
template <class Type, size_t MaxChannels = sfz::config::numChannels,
unsigned int Alignment = SIMDConfig::defaultAlignment,
size_t PaddingLeft_ = 0, size_t PaddingRight = 0>
class AudioBuffer {
public:
using value_type = typename std::remove_cv<Type>::type;
@ -35,6 +37,13 @@ public:
using iterator = pointer;
using const_iterator = const_pointer;
enum {
//! Increased left padding to preserve required alignment
PaddingLeft = PaddingLeft_ + (Alignment - (PaddingLeft_ % Alignment)) % Alignment,
//! Total padding left and right
PaddingTotal = PaddingLeft + PaddingRight,
};
/**
* @brief Construct a new Audio Buffer object
*
@ -55,7 +64,7 @@ public:
, numFrames(numFrames)
{
for (size_t i = 0; i < numChannels; ++i)
buffers[i] = absl::make_unique<buffer_type>(numFrames);
buffers[i] = absl::make_unique<buffer_type>(numFrames + PaddingTotal);
}
/**
@ -70,7 +79,7 @@ public:
bool returnedOK = true;
for (size_t i = 0; i < numChannels; ++i)
returnedOK &= buffers[i]->resize(newSize, std::nothrow);
returnedOK &= buffers[i]->resize(newSize + PaddingTotal, std::nothrow);
if (returnedOK)
numFrames = newSize;
@ -86,7 +95,7 @@ public:
void resize(size_t newSize)
{
for (size_t i = 0; i < numChannels; ++i)
buffers[i]->resize(newSize);
buffers[i]->resize(newSize + PaddingTotal);
numFrames = newSize;
}
@ -101,7 +110,7 @@ public:
{
ASSERT(channelIndex < numChannels);
if (channelIndex < numChannels)
return buffers[channelIndex]->data();
return buffers[channelIndex]->data() + PaddingLeft;
return {};
}
@ -116,7 +125,7 @@ public:
{
ASSERT(channelIndex < numChannels);
if (channelIndex < numChannels)
return buffers[channelIndex]->end();
return buffers[channelIndex]->end() - PaddingRight;
return {};
}
@ -131,7 +140,7 @@ public:
{
ASSERT(channelIndex < numChannels);
if (channelIndex < numChannels)
return buffers[channelIndex]->data();
return buffers[channelIndex]->data() + PaddingLeft;
return {};
}
@ -146,7 +155,7 @@ public:
{
ASSERT(channelIndex < numChannels);
if (channelIndex < numChannels)
return buffers[channelIndex]->end();
return buffers[channelIndex]->end() - PaddingRight;
return {};
}
@ -161,7 +170,7 @@ public:
{
ASSERT(channelIndex < numChannels);
if (channelIndex < numChannels)
return { buffers[channelIndex]->data(), buffers[channelIndex]->size() };
return { buffers[channelIndex]->data() + PaddingLeft, numFrames };
return {};
}
@ -184,7 +193,7 @@ public:
void addChannel()
{
if (numChannels < MaxChannels)
buffers[numChannels++] = absl::make_unique<buffer_type>(numFrames);
buffers[numChannels++] = absl::make_unique<buffer_type>(numFrames + PaddingTotal);
}
/**
@ -233,7 +242,7 @@ public:
ASSERT(buffers[channelIndex] != nullptr);
ASSERT(frameIndex < numFrames);
return *(buffers[channelIndex]->data() + frameIndex);
return *(buffers[channelIndex]->data() + PaddingLeft + frameIndex);
}
/**
@ -265,8 +274,10 @@ public:
*/
void clear()
{
for (size_t i = 0; i < numChannels; ++i)
fill<Type>(getSpan(i), Type{ 0.0 });
for (size_t i = 0; i < numChannels; ++i) {
absl::Span<Type> paddedSpan { buffers[i]->data(), numFrames + PaddingTotal };
fill<Type>(paddedSpan, Type{ 0.0 });
}
}
/**
@ -284,7 +295,7 @@ public:
/**
* @brief Convert implicitly to a pointer of channels
*/
operator const float* const*() const noexcept
operator const Type* const*() const noexcept
{
return buffers.data();
}
@ -292,7 +303,7 @@ public:
/**
* @brief Convert implicitly to a pointer of channels
*/
operator float* const*() noexcept
operator Type* const*() noexcept
{
return buffers.data();
}