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:
|
public:
|
||||||
AudioBuffer() = default;
|
AudioBuffer() = default;
|
||||||
|
|
||||||
AudioBuffer(int numFrames)
|
AudioBuffer(int numFrames)
|
||||||
{
|
{
|
||||||
resize(numFrames);
|
resize(numFrames);
|
||||||
|
|
@ -19,9 +18,13 @@ public:
|
||||||
{
|
{
|
||||||
// should have a positive number of frames...
|
// should have a positive number of frames...
|
||||||
ASSERT(numFrames >= 0);
|
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;
|
this->numFrames = numFrames;
|
||||||
|
for (auto channelIndex = 0; channelIndex < NumChannels; ++channelIndex)
|
||||||
|
channels[channelIndex] = buffer.data() + channelIndex * (numFrames + padding);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -37,37 +40,19 @@ public:
|
||||||
|
|
||||||
Type* getChannel(int channelIndex) noexcept
|
Type* getChannel(int channelIndex) noexcept
|
||||||
{
|
{
|
||||||
ASSERT(channelIndex >= 0);
|
return channels[channelIndex];
|
||||||
if (channelIndex < NumChannels)
|
|
||||||
return buffer.data() + numFrames * channelIndex;
|
|
||||||
else
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* begin(int channelIndex) noexcept
|
Type* begin(int channelIndex) noexcept
|
||||||
{
|
{
|
||||||
ASSERT(channelIndex >= 0);
|
|
||||||
return buffer.data() + numFrames * channelIndex;
|
return buffer.data() + numFrames * channelIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* end(int channelIndex) noexcept
|
Type* end(int channelIndex) noexcept
|
||||||
{
|
{
|
||||||
ASSERT(channelIndex >= 0);
|
|
||||||
return buffer.data() + numFrames * (channelIndex + 1);
|
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
|
Type& operator()(int channelIndex, int sampleIndex) noexcept
|
||||||
{
|
{
|
||||||
return getSample(channelIndex, sampleIndex);
|
return getSample(channelIndex, sampleIndex);
|
||||||
|
|
@ -78,7 +63,13 @@ public:
|
||||||
bool empty() const noexcept { return numFrames == 0; }
|
bool empty() const noexcept { return numFrames == 0; }
|
||||||
|
|
||||||
private:
|
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 numFrames { 0 };
|
||||||
|
int totalSize { 0 };
|
||||||
|
int padding { 0 };
|
||||||
|
std::array<Type*, NumChannels> channels;
|
||||||
Buffer<Type, Alignment> buffer {};
|
Buffer<Type, Alignment> buffer {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -123,10 +114,7 @@ public:
|
||||||
|
|
||||||
Type* getChannel(int channelIndex) noexcept
|
Type* getChannel(int channelIndex) noexcept
|
||||||
{
|
{
|
||||||
if (channelIndex < NumChannels)
|
return buffers[channelIndex].data();
|
||||||
return &buffers[channelIndex].data();
|
|
||||||
else
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* begin(int channelIndex) noexcept
|
Type* begin(int channelIndex) noexcept
|
||||||
|
|
@ -139,16 +127,6 @@ public:
|
||||||
return buffers[channelIndex].end();
|
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 getNumFrames() const noexcept { return numFrames; }
|
||||||
int getNumChannels() const noexcept { return NumChannels; }
|
int getNumChannels() const noexcept { return NumChannels; }
|
||||||
bool empty() const noexcept { return numFrames == 0; }
|
bool empty() const noexcept { return numFrames == 0; }
|
||||||
|
|
|
||||||
|
|
@ -110,4 +110,109 @@ TEST_CASE("[AudioBuffer/SplitBuffer] Iterators")
|
||||||
|
|
||||||
for (auto chanIdx = 0; chanIdx < splitBuffer.getNumChannels(); ++chanIdx)
|
for (auto chanIdx = 0; chanIdx < splitBuffer.getNumChannels(); ++chanIdx)
|
||||||
REQUIRE( std::all_of(splitBuffer.begin(chanIdx), splitBuffer.end(chanIdx), [fillValue](auto value) { return value == fillValue; }) );
|
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