Add methods to get oversampler factor given in/out rates

This commit is contained in:
Jean Pierre Cimalando 2021-02-24 03:27:46 +01:00
parent 7d885bd297
commit 1818f2e927
6 changed files with 75 additions and 2 deletions

View file

@ -152,6 +152,7 @@ static void generate_cpp_prologue(int argc, char *argv[])
printf(
"#pragma once\n"
"#include \"OversamplerHelpers.h\"\n"
"#include \"MathHelpers\"\n"
"\n"
"namespace sfz {\n"
);
@ -209,6 +210,14 @@ static void generate_cpp_upsampler(const Stage *stages, int num_stages)
printf("\t\t" "}\n");
printf("\t" "}\n");
printf("\t" "static unsigned conversionFactor(double sourceRate, double targetRate)\n");
printf("\t" "{\n");
printf("\t\t" "int factor = static_cast<int>(std::ceil(targetRate / sourceRate));\n");
printf("\t\t" "factor = (factor > 1) ? factor : 1;\n");
printf("\t\t" "factor = (factor < 128) ? factor : 128;\n");
printf("\t\t" "return nextPow2(factor);\n");
printf("\t" "}\n");
printf("\t" "static bool canProcess(int factor)\n");
printf("\t" "{\n");
printf("\t\t" "switch (factor) {\n");
@ -322,6 +331,14 @@ static void generate_cpp_downsampler(const Stage *stages, int num_stages)
printf("\t\t" "}\n");
printf("\t" "}\n");
printf("\t" "static unsigned conversionFactor(double sourceRate, double targetRate)\n");
printf("\t" "{\n");
printf("\t\t" "int factor = static_cast<int>(std::ceil(targetRate / sourceRate));\n");
printf("\t\t" "factor = (factor > 1) ? factor : 1;\n");
printf("\t\t" "factor = (factor < 128) ? factor : 128;\n");
printf("\t\t" "return nextPow2(factor);\n");
printf("\t" "}\n");
printf("\t" "static bool canProcess(int factor)\n");
printf("\t" "{\n");
printf("\t\t" "switch (factor) {\n");

View file

@ -263,8 +263,8 @@ add_library(sfizz::internal ALIAS sfizz_internal)
target_sources(sfizz_internal PRIVATE ${SFIZZ_HEADERS} ${SFIZZ_SOURCES} ${FAUST_FILES})
target_include_directories(sfizz_internal PUBLIC "." "sfizz")
target_link_libraries(sfizz_internal
PUBLIC absl::strings absl::span sfizz::filesystem sfizz::atomic_queue sfizz::spin_mutex sfizz::bit_array sfizz::simde
PRIVATE sfizz::parser sfizz::messaging absl::flat_hash_map Threads::Threads st_audiofile sfizz::pugixml sfizz::spline sfizz::tunings sfizz::hiir sfizz::kissfft sfizz::cephes sfizz::cpuid sfizz::threadpool sfizz::jsl sfizz::atomic)
PUBLIC absl::strings absl::span sfizz::filesystem sfizz::atomic_queue sfizz::spin_mutex sfizz::bit_array sfizz::simde sfizz::hiir
PRIVATE sfizz::parser sfizz::messaging absl::flat_hash_map Threads::Threads st_audiofile sfizz::pugixml sfizz::spline sfizz::tunings sfizz::kissfft sfizz::cephes sfizz::cpuid sfizz::threadpool sfizz::jsl sfizz::atomic)
if(SFIZZ_USE_SNDFILE)
target_compile_definitions(sfizz_internal PUBLIC "SFIZZ_USE_SNDFILE=1")
target_link_libraries(sfizz_internal PUBLIC st_audiofile)

View file

@ -296,6 +296,25 @@ constexpr long int lroundPositive(T value)
return static_cast<int>(0.5f + value); // NOLINT
}
/**
* @brief Compute the next power of 2
*
* @param v An integer
* @return The next power of 2, inclusive from @p v
*/
inline uint32_t nextPow2(uint32_t v)
{
// Bit Twiddling Hacks
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
return v;
}
/**
@brief Wrap a normalized phase into the domain [0;1[
*/

View file

@ -11,6 +11,7 @@
#pragma once
#include "OversamplerHelpers.h"
#include "MathHelpers.h"
namespace sfz {
@ -94,6 +95,13 @@ public:
return factor * spl;
}
}
static unsigned conversionFactor(double sourceRate, double targetRate)
{
int factor = static_cast<int>(std::ceil(targetRate / sourceRate));
factor = (factor > 1) ? factor : 1;
factor = (factor < 128) ? factor : 128;
return nextPow2(factor);
}
static bool canProcess(int factor)
{
switch (factor) {
@ -293,6 +301,13 @@ public:
return factor * spl;
}
}
static unsigned conversionFactor(double sourceRate, double targetRate)
{
int factor = static_cast<int>(std::ceil(targetRate / sourceRate));
factor = (factor > 1) ? factor : 1;
factor = (factor < 128) ? factor : 128;
return nextPow2(factor);
}
static bool canProcess(int factor)
{
switch (factor) {

View file

@ -41,6 +41,7 @@ set(SFIZZ_TEST_SOURCES
ModulationsT.cpp
LFOT.cpp
MessagingT.cpp
OversamplerT.cpp
DataHelpers.h
DataHelpers.cpp
)

21
tests/OversamplerT.cpp Normal file
View file

@ -0,0 +1,21 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#include "sfizz/OversamplerHelpers.h"
#include "catch2/catch.hpp"
TEST_CASE("[Oversampler] Conversion factor")
{
REQUIRE(sfz::Upsampler::conversionFactor(44100.0, 44100.0) == 1);
REQUIRE(sfz::Upsampler::conversionFactor(44100.0, 44101.0) == 2);
REQUIRE(sfz::Upsampler::conversionFactor(44100.0, 88200.0) == 2);
REQUIRE(sfz::Upsampler::conversionFactor(44100.0, 88201.0) == 4);
REQUIRE(sfz::Upsampler::conversionFactor(44100.0, 176400.0) == 4);
REQUIRE(sfz::Upsampler::conversionFactor(44100.0, 176401.0) == 8);
// low and high limits
REQUIRE(sfz::Upsampler::conversionFactor(44100.0, 1.0) == 1);
REQUIRE(sfz::Upsampler::conversionFactor(44100.0, 1e10) == 128);
}