Alignment for channels within an AudioBuffer
This commit is contained in:
parent
844480fc1e
commit
5894b6cfb6
2 changed files with 118 additions and 35 deletions
|
|
@ -9,7 +9,6 @@ class AudioBuffer
|
|||
{
|
||||
public:
|
||||
AudioBuffer() = default;
|
||||
|
||||
AudioBuffer(int numFrames)
|
||||
{
|
||||
resize(numFrames);
|
||||
|
|
@ -19,9 +18,13 @@ public:
|
|||
{
|
||||
// should have a positive number of frames...
|
||||
ASSERT(numFrames >= 0);
|
||||
if (buffer.resize(static_cast<size_t>(NumChannels * numFrames)))
|
||||
padding = TypeAlignment - (numFrames & TypeAlignmentMask);
|
||||
totalSize = NumChannels * (numFrames + padding);
|
||||
if (buffer.resize(static_cast<size_t>(totalSize)))
|
||||
{
|
||||
this->numFrames = numFrames;
|
||||
for (auto channelIndex = 0; channelIndex < NumChannels; ++channelIndex)
|
||||
channels[channelIndex] = buffer.data() + channelIndex * (numFrames + padding);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -37,37 +40,19 @@ public:
|
|||
|
||||
Type* getChannel(int channelIndex) noexcept
|
||||
{
|
||||
ASSERT(channelIndex >= 0);
|
||||
if (channelIndex < NumChannels)
|
||||
return buffer.data() + numFrames * channelIndex;
|
||||
else
|
||||
return nullptr;
|
||||
return channels[channelIndex];
|
||||
}
|
||||
|
||||
Type* begin(int channelIndex) noexcept
|
||||
{
|
||||
ASSERT(channelIndex >= 0);
|
||||
return buffer.data() + numFrames * channelIndex;
|
||||
}
|
||||
|
||||
Type* end(int channelIndex) noexcept
|
||||
{
|
||||
ASSERT(channelIndex >= 0);
|
||||
return buffer.data() + numFrames * (channelIndex + 1);
|
||||
}
|
||||
|
||||
// const Type* cbegin(int channelIndex) noexcept
|
||||
// {
|
||||
// ASSERT(channelIndex >= 0);
|
||||
// return buffer.data() + numFrames * channelIndex;
|
||||
// }
|
||||
|
||||
// const Type* cend(int channelIndex) noexcept
|
||||
// {
|
||||
// ASSERT(channelIndex >= 0);
|
||||
// return buffer.data() + numFrames * (channelIndex + 1);
|
||||
// }
|
||||
|
||||
Type& operator()(int channelIndex, int sampleIndex) noexcept
|
||||
{
|
||||
return getSample(channelIndex, sampleIndex);
|
||||
|
|
@ -78,7 +63,13 @@ public:
|
|||
bool empty() const noexcept { return numFrames == 0; }
|
||||
|
||||
private:
|
||||
static constexpr auto TypeAlignment { Alignment / sizeof(Type) };
|
||||
static constexpr auto TypeAlignmentMask { TypeAlignment - 1 };
|
||||
static_assert(TypeAlignment * sizeof(Type) == Alignment, "The alignment does not appear to be divided by the size of the Type");
|
||||
int numFrames { 0 };
|
||||
int totalSize { 0 };
|
||||
int padding { 0 };
|
||||
std::array<Type*, NumChannels> channels;
|
||||
Buffer<Type, Alignment> buffer {};
|
||||
};
|
||||
|
||||
|
|
@ -123,10 +114,7 @@ public:
|
|||
|
||||
Type* getChannel(int channelIndex) noexcept
|
||||
{
|
||||
if (channelIndex < NumChannels)
|
||||
return &buffers[channelIndex].data();
|
||||
else
|
||||
return nullptr;
|
||||
return buffers[channelIndex].data();
|
||||
}
|
||||
|
||||
Type* begin(int channelIndex) noexcept
|
||||
|
|
@ -139,16 +127,6 @@ public:
|
|||
return buffers[channelIndex].end();
|
||||
}
|
||||
|
||||
// const Type* cbegin(int channelIndex) noexcept
|
||||
// {
|
||||
// return buffers[channelIndex].cbegin();
|
||||
// }
|
||||
|
||||
// const Type* cend(int channelIndex) noexcept
|
||||
// {
|
||||
// return buffers[channelIndex].cend();
|
||||
// }
|
||||
|
||||
int getNumFrames() const noexcept { return numFrames; }
|
||||
int getNumChannels() const noexcept { return NumChannels; }
|
||||
bool empty() const noexcept { return numFrames == 0; }
|
||||
|
|
|
|||
|
|
@ -110,4 +110,109 @@ TEST_CASE("[AudioBuffer/SplitBuffer] Iterators")
|
|||
|
||||
for (auto chanIdx = 0; chanIdx < splitBuffer.getNumChannels(); ++chanIdx)
|
||||
REQUIRE( std::all_of(splitBuffer.begin(chanIdx), splitBuffer.end(chanIdx), [fillValue](auto value) { return value == fillValue; }) );
|
||||
}
|
||||
|
||||
template<class Type, unsigned int NumChannels, unsigned int Alignment = 16>
|
||||
void channelAlignmentTest(int size)
|
||||
{
|
||||
static constexpr auto AlignmentMask { Alignment - 1 };
|
||||
const Type fillValue { 2 };
|
||||
AudioBuffer<Type, NumChannels, Alignment> buffer(size);
|
||||
for (auto chanIdx = 0; chanIdx < NumChannels; ++chanIdx)
|
||||
REQUIRE( ((size_t)buffer.getChannel(chanIdx) & AlignmentMask) == 0 );
|
||||
|
||||
SplitAudioBuffer<Type, NumChannels, Alignment> splitBuffer(size);
|
||||
for (auto chanIdx = 0; chanIdx < NumChannels; ++chanIdx)
|
||||
REQUIRE( ((size_t)splitBuffer.getChannel(chanIdx) & AlignmentMask) == 0 );
|
||||
}
|
||||
|
||||
TEST_CASE("[AudioBuffer/SplitBuffer] Channel alignments (floats)")
|
||||
{
|
||||
channelAlignmentTest<float, 1>(4);
|
||||
channelAlignmentTest<float, 1>(5);
|
||||
channelAlignmentTest<float, 1>(8);
|
||||
channelAlignmentTest<float, 1>(256);
|
||||
channelAlignmentTest<float, 1>(257);
|
||||
channelAlignmentTest<float, 1>(1023);
|
||||
channelAlignmentTest<float, 1>(1024);
|
||||
channelAlignmentTest<float, 1>(65537);
|
||||
channelAlignmentTest<float, 1>(65536);
|
||||
channelAlignmentTest<float, 1>(65535);
|
||||
|
||||
channelAlignmentTest<float, 2>(4);
|
||||
channelAlignmentTest<float, 2>(5);
|
||||
channelAlignmentTest<float, 2>(8);
|
||||
channelAlignmentTest<float, 2>(256);
|
||||
channelAlignmentTest<float, 2>(257);
|
||||
channelAlignmentTest<float, 2>(1023);
|
||||
channelAlignmentTest<float, 2>(1024);
|
||||
channelAlignmentTest<float, 2>(65537);
|
||||
channelAlignmentTest<float, 2>(65536);
|
||||
channelAlignmentTest<float, 2>(65535);
|
||||
|
||||
channelAlignmentTest<float, 3>(4);
|
||||
channelAlignmentTest<float, 3>(5);
|
||||
channelAlignmentTest<float, 3>(8);
|
||||
channelAlignmentTest<float, 3>(256);
|
||||
channelAlignmentTest<float, 3>(257);
|
||||
channelAlignmentTest<float, 3>(1023);
|
||||
channelAlignmentTest<float, 3>(1024);
|
||||
channelAlignmentTest<float, 3>(65537);
|
||||
channelAlignmentTest<float, 3>(65536);
|
||||
channelAlignmentTest<float, 3>(65535);
|
||||
|
||||
channelAlignmentTest<float, 4>(4);
|
||||
channelAlignmentTest<float, 4>(5);
|
||||
channelAlignmentTest<float, 4>(8);
|
||||
channelAlignmentTest<float, 4>(256);
|
||||
channelAlignmentTest<float, 4>(257);
|
||||
channelAlignmentTest<float, 4>(1023);
|
||||
channelAlignmentTest<float, 4>(1024);
|
||||
channelAlignmentTest<float, 4>(65537);
|
||||
channelAlignmentTest<float, 4>(65536);
|
||||
channelAlignmentTest<float, 4>(65535);
|
||||
|
||||
channelAlignmentTest<float, 1, 4>(4);
|
||||
channelAlignmentTest<float, 1, 4>(5);
|
||||
channelAlignmentTest<float, 1, 4>(8);
|
||||
channelAlignmentTest<float, 1, 4>(256);
|
||||
channelAlignmentTest<float, 1, 4>(257);
|
||||
channelAlignmentTest<float, 1, 4>(1023);
|
||||
channelAlignmentTest<float, 1, 4>(1024);
|
||||
channelAlignmentTest<float, 1, 4>(65537);
|
||||
channelAlignmentTest<float, 1, 4>(65536);
|
||||
channelAlignmentTest<float, 1, 4>(65535);
|
||||
|
||||
channelAlignmentTest<float, 2, 4>(4);
|
||||
channelAlignmentTest<float, 2, 4>(5);
|
||||
channelAlignmentTest<float, 2, 4>(8);
|
||||
channelAlignmentTest<float, 2, 4>(256);
|
||||
channelAlignmentTest<float, 2, 4>(257);
|
||||
channelAlignmentTest<float, 2, 4>(1023);
|
||||
channelAlignmentTest<float, 2, 4>(1024);
|
||||
channelAlignmentTest<float, 2, 4>(65537);
|
||||
channelAlignmentTest<float, 2, 4>(65536);
|
||||
channelAlignmentTest<float, 2, 4>(65535);
|
||||
|
||||
channelAlignmentTest<float, 1, 8>(4);
|
||||
channelAlignmentTest<float, 1, 8>(5);
|
||||
channelAlignmentTest<float, 1, 8>(8);
|
||||
channelAlignmentTest<float, 1, 8>(256);
|
||||
channelAlignmentTest<float, 1, 8>(257);
|
||||
channelAlignmentTest<float, 1, 8>(1023);
|
||||
channelAlignmentTest<float, 1, 8>(1024);
|
||||
channelAlignmentTest<float, 1, 8>(65537);
|
||||
channelAlignmentTest<float, 1, 8>(65536);
|
||||
channelAlignmentTest<float, 1, 8>(65535);
|
||||
|
||||
channelAlignmentTest<float, 2, 8>(4);
|
||||
channelAlignmentTest<float, 2, 8>(5);
|
||||
channelAlignmentTest<float, 2, 8>(8);
|
||||
channelAlignmentTest<float, 2, 8>(256);
|
||||
channelAlignmentTest<float, 2, 8>(257);
|
||||
channelAlignmentTest<float, 2, 8>(1023);
|
||||
channelAlignmentTest<float, 2, 8>(1024);
|
||||
channelAlignmentTest<float, 2, 8>(65537);
|
||||
channelAlignmentTest<float, 2, 8>(65536);
|
||||
channelAlignmentTest<float, 2, 8>(65535);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue