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 MaxChannels the maximum number of channels in the buffer
* @tparam Alignment the alignment for the buffers * @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 { class AudioBuffer {
public: public:
using value_type = typename std::remove_cv<Type>::type; using value_type = typename std::remove_cv<Type>::type;
@ -35,6 +37,13 @@ public:
using iterator = pointer; using iterator = pointer;
using const_iterator = const_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 * @brief Construct a new Audio Buffer object
* *
@ -55,7 +64,7 @@ public:
, numFrames(numFrames) , numFrames(numFrames)
{ {
for (size_t i = 0; i < numChannels; ++i) 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; bool returnedOK = true;
for (size_t i = 0; i < numChannels; ++i) 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) if (returnedOK)
numFrames = newSize; numFrames = newSize;
@ -86,7 +95,7 @@ public:
void resize(size_t newSize) void resize(size_t newSize)
{ {
for (size_t i = 0; i < numChannels; ++i) for (size_t i = 0; i < numChannels; ++i)
buffers[i]->resize(newSize); buffers[i]->resize(newSize + PaddingTotal);
numFrames = newSize; numFrames = newSize;
} }
@ -101,7 +110,7 @@ public:
{ {
ASSERT(channelIndex < numChannels); ASSERT(channelIndex < numChannels);
if (channelIndex < numChannels) if (channelIndex < numChannels)
return buffers[channelIndex]->data(); return buffers[channelIndex]->data() + PaddingLeft;
return {}; return {};
} }
@ -116,7 +125,7 @@ public:
{ {
ASSERT(channelIndex < numChannels); ASSERT(channelIndex < numChannels);
if (channelIndex < numChannels) if (channelIndex < numChannels)
return buffers[channelIndex]->end(); return buffers[channelIndex]->end() - PaddingRight;
return {}; return {};
} }
@ -131,7 +140,7 @@ public:
{ {
ASSERT(channelIndex < numChannels); ASSERT(channelIndex < numChannels);
if (channelIndex < numChannels) if (channelIndex < numChannels)
return buffers[channelIndex]->data(); return buffers[channelIndex]->data() + PaddingLeft;
return {}; return {};
} }
@ -146,7 +155,7 @@ public:
{ {
ASSERT(channelIndex < numChannels); ASSERT(channelIndex < numChannels);
if (channelIndex < numChannels) if (channelIndex < numChannels)
return buffers[channelIndex]->end(); return buffers[channelIndex]->end() - PaddingRight;
return {}; return {};
} }
@ -161,7 +170,7 @@ public:
{ {
ASSERT(channelIndex < numChannels); ASSERT(channelIndex < numChannels);
if (channelIndex < numChannels) if (channelIndex < numChannels)
return { buffers[channelIndex]->data(), buffers[channelIndex]->size() }; return { buffers[channelIndex]->data() + PaddingLeft, numFrames };
return {}; return {};
} }
@ -184,7 +193,7 @@ public:
void addChannel() void addChannel()
{ {
if (numChannels < MaxChannels) 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(buffers[channelIndex] != nullptr);
ASSERT(frameIndex < numFrames); ASSERT(frameIndex < numFrames);
return *(buffers[channelIndex]->data() + frameIndex); return *(buffers[channelIndex]->data() + PaddingLeft + frameIndex);
} }
/** /**
@ -265,8 +274,10 @@ public:
*/ */
void clear() void clear()
{ {
for (size_t i = 0; i < numChannels; ++i) for (size_t i = 0; i < numChannels; ++i) {
fill<Type>(getSpan(i), Type{ 0.0 }); 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 * @brief Convert implicitly to a pointer of channels
*/ */
operator const float* const*() const noexcept operator const Type* const*() const noexcept
{ {
return buffers.data(); return buffers.data();
} }
@ -292,7 +303,7 @@ public:
/** /**
* @brief Convert implicitly to a pointer of channels * @brief Convert implicitly to a pointer of channels
*/ */
operator float* const*() noexcept operator Type* const*() noexcept
{ {
return buffers.data(); return buffers.data();
} }