Cover flac since we're at it
This commit is contained in:
parent
8e4e6460d8
commit
121d795559
6 changed files with 93 additions and 73 deletions
|
|
@ -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;
|
||||
|
|
@ -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)) );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#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>
|
||||
|
|
@ -14,20 +15,6 @@
|
|||
#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; };
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -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 = {
|
||||
|
|
|
|||
BIN
tests/TestFiles/kick.flac
Executable file
BIN
tests/TestFiles/kick.flac
Executable file
Binary file not shown.
|
|
@ -12,6 +12,8 @@
|
|||
#include "sfizz/Messaging.h"
|
||||
#include "catch2/catch.hpp"
|
||||
#include "sfizz/modulations/ModKey.h"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
class RegionCCView {
|
||||
public:
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue