#include <ableton/link_audio/AudioBuffer.hpp>
#include <ableton/link_audio/PCMCodec.hpp>
#include <ableton/platforms/stl/Random.hpp>
#include <ableton/test/CatchWrapper.hpp>
#include <array>
namespace ableton
{
namespace link_audio
{
namespace
{
using SampleFormat = int16_t;
using Samples = std::vector<SampleFormat>;
struct Sender
{
void operator()(const AudioBuffer& buffer_) { buffer = buffer_; }
AudioBuffer buffer;
};
struct Successor
{
template <typename Buffer>
void operator()(BufferCallbackHandle<Buffer> handle)
{
inputFrames = handle.mBuffer.mNumFrames;
beginBeats = handle.mBuffer.mBeginBeats;
tempo = handle.mBuffer.mTempo;
cache.resize(handle.mBuffer.mNumFrames * handle.mBuffer.mNumChannels);
std::copy_n(handle.mpSamples,
handle.mBuffer.mNumFrames * handle.mBuffer.mNumChannels,
cache.begin());
}
size_t inputFrames;
Beats beginBeats;
Tempo tempo;
Samples cache;
};
using TestEncoder = PCMEncoder<SampleFormat, Sender&>;
using TestDecoder = PCMDecoder<SampleFormat, Successor&>;
}
TEST_CASE("PCMCodec")
{
const auto bufferSize = 32u;
auto input = Samples(bufferSize);
platforms::stl::Random random;
std::generate(input.begin(), input.end(), [&] { return random(); });
auto successor = Successor{};
SECTION("Roundtrip")
{
const auto beginBeats = Beats{44.};
const auto tempo = Tempo{120.};
auto sender = Sender{};
auto encoder = TestEncoder(util::injectRef(sender), {});
auto decoder = TestDecoder(util::injectRef(successor), 512);
const AudioBuffer::Chunks chunks = {
AudioBuffer::Chunk{1u, bufferSize, beginBeats, tempo}};
encoder(input.data(), chunks, 1, 48000, Id{});
CHECK(input.size() * sizeof(SampleFormat) == sender.buffer.numBytes);
decoder(sender.buffer);
CHECK(bufferSize == successor.inputFrames);
CHECK(input == successor.cache);
CHECK(beginBeats == successor.beginBeats);
CHECK(tempo == successor.tempo);
}
}
} }