Skip to content

Commit

Permalink
Cover flac since we're at it
Browse files Browse the repository at this point in the history
  • Loading branch information
pferrand-soundhound committed May 29, 2023
1 parent 8e4e646 commit 121d795
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 73 deletions.
40 changes: 40 additions & 0 deletions tests/AudioFilesT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,33 @@
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz

#include "AudioSpan.h"
#include "absl/types/span.h"
#include "sfizz/Synth.h"
#include "TestHelpers.h"
#include "catch2/catch.hpp"
#include <algorithm>
#include <vector>
using namespace Catch::literals;

TEST_CASE("[AudioFiles] No leakage on right")
{
sfz::Synth synth;
sfz::AudioBuffer<float> buffer { 2, static_cast<unsigned>(synth.getSamplesPerBlock()) };
std::vector<float> zeros(synth.getSamplesPerBlock(), 0);
sfz::AudioSpan<float> span { buffer };
synth.loadSfzString(fs::current_path() / "tests/TestFiles/wavpack.sfz", R"(
<region> sample=kick.wav key=60 pan=-100
)");
synth.noteOn(0, 60, 127);
synth.renderBlock(buffer);
REQUIRE( numPlayingVoices(synth) == 1 );
REQUIRE( approxEqual(span.getConstSpan(1), absl::MakeConstSpan(zeros), 1e-2f) );
while (numPlayingVoices(synth) > 0) {
synth.renderBlock(buffer);
REQUIRE( approxEqual(span.getConstSpan(1), absl::MakeConstSpan(zeros), 1e-2f) );
}
}

TEST_CASE("[AudioFiles] WavPack file")
{
sfz::Synth synth;
Expand All @@ -29,3 +50,22 @@ TEST_CASE("[AudioFiles] WavPack file")
REQUIRE( approxEqual(span.getConstSpan(0), span.getConstSpan(1)) );
}
}

TEST_CASE("[AudioFiles] Flac file")
{
sfz::Synth synth;
sfz::AudioBuffer<float> buffer { 2, static_cast<unsigned>(synth.getSamplesPerBlock()) };
sfz::AudioSpan<float> span { buffer };
synth.loadSfzString(fs::current_path() / "tests/TestFiles/wavpack.sfz", R"(
<region> sample=kick.wav key=60 pan=-100
<region> sample=kick.flac key=60 pan=100
)");
synth.noteOn(0, 60, 127);
synth.renderBlock(buffer);
REQUIRE( numPlayingVoices(synth) == 2 );
REQUIRE( approxEqual(span.getConstSpan(0), span.getConstSpan(1)) );
while (numPlayingVoices(synth) > 0) {
synth.renderBlock(buffer);
REQUIRE( approxEqual(span.getConstSpan(0), span.getConstSpan(1)) );
}
}
15 changes: 1 addition & 14 deletions tests/EventEnvelopesT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,14 @@
#include "sfizz/ModifierHelpers.h"
#include "sfizz/Buffer.h"
#include "catch2/catch.hpp"
#include "TestHelpers.h"
#include <absl/algorithm/container.h>
#include <absl/types/span.h>
#include <algorithm>
#include <array>
#include <iostream>
using namespace Catch::literals;

template <class Type>
inline bool approxEqual(absl::Span<const Type> lhs, absl::Span<const Type> rhs, Type eps = 1e-3)
{
if (lhs.size() != rhs.size())
return false;

for (size_t i = 0; i < rhs.size(); ++i)
if (rhs[i] != Approx(lhs[i]).epsilon(eps)) {
std::cerr << lhs[i] << " != " << rhs[i] << " at index " << i << '\n';
return false;
}

return true;
}

const auto idModifier = [](float x) { return x; };
const auto twiceModifier = [](float x) { return 2 * x; };
Expand Down
41 changes: 6 additions & 35 deletions tests/SIMDHelpersT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "sfizz/simd/Common.h"
#include "sfizz/SIMDHelpers.h"
#include "sfizz/Panning.h"
#include "TestHelpers.h"
#include "catch2/catch.hpp"
#include <absl/algorithm/container.h>
#include <absl/types/span.h>
Expand All @@ -20,39 +21,9 @@ template <class T, std::size_t A = sfz::config::defaultAlignment>
using aligned_vector = std::vector<T, jsl::aligned_allocator<T, A>>;

constexpr int bigBufferSize { 4095 };
constexpr int medBufferSize { 127 };
constexpr int medBufferSize { 1023 };
constexpr float fillValue { 1.3f };

template <class Type>
inline bool approxEqualMargin(absl::Span<const Type> lhs, absl::Span<const Type> rhs, Type eps = 1e-3)
{
if (lhs.size() != rhs.size())
return false;

for (size_t i = 0; i < rhs.size(); ++i)
if (rhs[i] != Approx(lhs[i]).margin(eps)) {
std::cerr << lhs[i] << " != " << rhs[i] << " at index " << i << '\n';
return false;
}

return true;
}

template <class Type>
inline bool approxEqual(absl::Span<const Type> lhs, absl::Span<const Type> rhs, Type eps = 1e-3)
{
if (lhs.size() != rhs.size())
return false;

for (size_t i = 0; i < rhs.size(); ++i)
if (rhs[i] != Approx(lhs[i]).epsilon(eps)) {
std::cerr << lhs[i] << " != " << rhs[i] << " at index " << i << '\n';
return false;
}

return true;
}

TEST_CASE("[Helpers] willAlign, prevAligned and unaligned tests")
{
aligned_vector<float, 32> array(16);
Expand Down Expand Up @@ -430,8 +401,8 @@ TEST_CASE("[Helpers] Linear Ramp (SIMD)")
TEST_CASE("[Helpers] Linear Ramp (SIMD vs scalar)")
{
const float start { 0.0f };
std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize);
std::vector<float> outputScalar(medBufferSize);
std::vector<float> outputSIMD(medBufferSize);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::linearRamp, false);
sfz::linearRamp<float>(absl::MakeSpan(outputScalar), start, fillValue);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::linearRamp, true);
Expand All @@ -442,8 +413,8 @@ TEST_CASE("[Helpers] Linear Ramp (SIMD vs scalar)")
TEST_CASE("[Helpers] Linear Ramp unaligned (SIMD vs scalar)")
{
const float start { 0.0f };
std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize);
std::vector<float> outputScalar(medBufferSize);
std::vector<float> outputSIMD(medBufferSize);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::linearRamp, false);
sfz::linearRamp<float>(absl::MakeSpan(outputScalar).subspan(1), start, fillValue);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::linearRamp, true);
Expand Down
24 changes: 5 additions & 19 deletions tests/SmoothersT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "sfizz/OnePoleFilter.h"
#include "sfizz/Smoothers.h"
#include "catch2/catch.hpp"
#include "TestHelpers.h"
// #include "cnpy.h"
// #include "ghc/fs_std.hpp"
#include <absl/types/span.h>
Expand All @@ -16,21 +17,6 @@
#include <iostream>
using namespace Catch::literals;

template <class Type, size_t N>
inline bool approxEqual(const std::array<Type, N>& lhs, const std::array<Type, N>& rhs, Type epsilon = 1e-3)
{
if (lhs.size() != rhs.size())
return false;

for (size_t i = 0; i < rhs.size(); ++i)
if (lhs[i] != Approx(rhs[i]).epsilon(epsilon)) {
std::cerr << lhs[i] << " != " << rhs[i] << " at index " << i << '\n';
return false;
}

return true;
}

template <class Type, size_t N>
void testFilter(const std::array<Type, N>& input, const std::array<Type, N>& expectedLow, const std::array<Type, N>& expectedHigh, Type gain)
{
Expand All @@ -43,19 +29,19 @@ void testFilter(const std::array<Type, N>& input, const std::array<Type, N>& exp
sfz::OnePoleFilter<Type> filter;
filter.setGain(gain);
filter.processLowpass(input, outputSpan);
REQUIRE(approxEqual(output, expectedLow));
REQUIRE(approxEqual(absl::MakeConstSpan(output), absl::MakeConstSpan(expectedLow)));

filter.reset();
filter.processLowpass(input, outputSpan, gains);
REQUIRE(approxEqual(output, expectedLow));
REQUIRE(approxEqual(absl::MakeConstSpan(output), absl::MakeConstSpan(expectedLow)));

filter.reset();
filter.processHighpass(input, outputSpan);
REQUIRE(approxEqual(output, expectedHigh));
REQUIRE(approxEqual(absl::MakeConstSpan(output), absl::MakeConstSpan(expectedHigh)));

filter.reset();
filter.processHighpass(input, outputSpan, gains);
REQUIRE(approxEqual(output, expectedHigh));
REQUIRE(approxEqual(absl::MakeConstSpan(output), absl::MakeConstSpan(expectedHigh)));
}

constexpr std::array<float, 64> floatInput01 = {
Expand Down
Binary file added tests/TestFiles/kick.flac
Binary file not shown.
46 changes: 41 additions & 5 deletions tests/TestHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include "sfizz/Messaging.h"
#include "catch2/catch.hpp"
#include "sfizz/modulations/ModKey.h"
#include <iostream>
#include <iomanip>

class RegionCCView {
public:
Expand Down Expand Up @@ -148,18 +150,52 @@ std::string createDefaultGraph(std::vector<std::string> lines, int numRegions =
std::string createModulationDotGraph(std::vector<std::string> lines);

template <class Type>
inline bool approxEqual(absl::Span<const Type> lhs, absl::Span<const Type> rhs, Type eps = 1e-3)
bool approxEqual(absl::Span<const Type> lhs, absl::Span<const Type> rhs, Type eps = 1e-3)
{
if (lhs.size() != rhs.size())
return false;

bool different = false;
for (size_t i = 0; i < rhs.size(); ++i)
if (rhs[i] != Approx(lhs[i]).epsilon(eps)) {
std::cerr << lhs[i] << " != " << rhs[i] << " at index " << i << '\n';
return false;
if (rhs[i] != Approx(lhs[i]).margin(eps)) {
std::cerr << lhs[i] << " != " << rhs[i] << " (delta " << std::abs(rhs[i] - lhs[i]) << ") at index " << i << '\n';
different = true;
break;
}

return true;
auto print_span = [](absl::Span<const Type> span) {
if (span.empty()) {
std::cerr << "{ }" << '\n';
return;
}

std::cerr << "{ ";
if (span.size() < 16) {
for (unsigned i = 0; i < span.size() - 1; ++i) {
std::cerr << span[i] << ", ";
}
} else {
for (unsigned i = 0; i < 8; ++i) {
std::cerr << span[i] << ", ";
}
std::cerr << "..., ";
for (unsigned i = span.size() - 8; i < span.size() - 1; ++i) {
std::cerr << span[i] << ", ";
}
}
std::cerr << span.back() << " }" << '\n';
};

if (different) {
std::cerr << std::setprecision(3) << std::fixed;
std::cerr << "Differences between spans" << '\n';
std::cerr << "lhs: ";
print_span(lhs);
std::cerr << "rhs: ";
print_span(rhs);
}

return !different;
}

/**
Expand Down

0 comments on commit 121d795

Please sign in to comment.