#include "remotebuffer.h" #include #include struct RemoteAudioBufferWrapper : public emscripten::wrapper { EMSCRIPTEN_WRAPPER(RemoteAudioBufferWrapper); void read(int frameOffset, BufferF32 output) override { return call("read", frameOffset, output); } }; EMSCRIPTEN_BINDINGS(remotebuffer) { using namespace emscripten; class_>( "RemoteAudioBuffer") .smart_ptr>("RemoteAudioBuffer") .function("read", select_overload(&RemoteAudioBuffer::read), pure_virtual()) .function("readZeroPadded", &RemoteAudioBuffer::readZeroPadded) .property("sampleRate", &RemoteAudioBuffer::getSampleRate) .property("channelCount", &RemoteAudioBuffer::getChannelCount) .property("frameCount", &RemoteAudioBuffer::getFrameCount) .allow_subclass>( "RemoteAudioBufferWrapper", "RemoteAudioBufferWrapperSharedPtr", constructor()); class_>( "BufferAsRemoteAudioBuffer") .smart_ptr_constructor, int &&, std::shared_ptr &&>( "BufferAsRemoteAudioBuffer", &std::make_shared); }; TEST_CASE("RAAR zero padded read", "[randomaccessaudioreadable]") { auto buf = std::make_shared(2, 100); buf->noise(); auto raa = std::make_shared(44100, buf); REQUIRE(raa->getSampleRate() == 44100); REQUIRE(raa->getChannelCount() == 2); REQUIRE(raa->getFrameCount() == 100); BufferF32 out(2, 10), bigout(2, 500); out.fill(1.f); raa->readZeroPadded(0, out); for (int channel = 0; channel < 2; channel++) { REQUIRE(std::equal(out[channel], out[channel] + out.getFrameCount(), buf->getChannelData(channel))); } out.fill(1.f); raa->readZeroPadded(-1, out); for (int channel = 0; channel < 2; channel++) { REQUIRE(std::equal(out[channel] + 1, out[channel] + out.getFrameCount(), buf->getChannelData(channel))); REQUIRE(out[channel][0] == 0.f); } out.fill(1.f); raa->readZeroPadded(95, out); for (int channel = 0; channel < 2; channel++) { REQUIRE(std::equal(out[channel], out[channel] + 5, buf->getChannelData(channel) + 95)); REQUIRE(std::all_of(out[channel] + 5, out[channel] + out.getFrameCount(), [](float v) { return v == 0.f; })); } bigout.fill(1.f); raa->readZeroPadded(-5, bigout); for (int channel = 0; channel < 2; channel++) { REQUIRE(std::equal(bigout[channel] + 5, bigout[channel] + 105, buf->getChannelData(channel))); REQUIRE(std::all_of(bigout[channel], bigout[channel] + 5, [](float v) { return v == 0.f; })); REQUIRE(std::all_of(bigout[channel] + 105, bigout[channel] + 500, [](float v) { return v == 0.f; })); } } TEST_CASE("RAAR stereo muxing", "[randomaccessaudioreadable]") { auto buf = std::make_shared(2, 100); buf->noise(); auto bufMono = std::make_shared(1, 100); for (int i = 0; i < buf->getFrameCount(); i++) { (*bufMono)[0][i] = ((*buf)[0][i] + (*buf)[1][i]) / 2.f; } auto raa = std::make_shared(44100, buf); auto raaMono = std::make_shared(44100, bufMono); REQUIRE(raa->getChannelCount() == 2); REQUIRE(raaMono->getChannelCount() == 1); BufferF32 out(2, 10), outMono(1, 10); out.fill(0.f); raa->readWithMuxing(10, out); // no muxing for (int channel = 0; channel < 2; channel++) { REQUIRE(std::equal(out[channel], out[channel] + 10, buf->getChannelData(channel) + 10)); } outMono.fill(0.f); raaMono->readWithMuxing(10, outMono); // no muxing REQUIRE( std::equal(outMono[0], outMono[0] + 10, bufMono->getChannelData(0) + 10)); outMono.fill(0.f); raa->readWithMuxing(10, outMono); // down REQUIRE( std::equal(outMono[0], outMono[0] + 10, bufMono->getChannelData(0) + 10)); out.fill(0.f); raaMono->readWithMuxing(10, out); // up for (int channel = 0; channel < 2; channel++) { REQUIRE(std::equal(out[channel], out[channel] + 10, bufMono->getChannelData(0) + 10)); } }