40 lines
1.4 KiB
C++
40 lines
1.4 KiB
C++
#pragma once
|
|
|
|
#include <cmath>
|
|
#include <cstddef>
|
|
#include <array>
|
|
|
|
#include "data/audioframe.h"
|
|
#include "data/sample.h"
|
|
|
|
namespace Xybrid::NodeLib {
|
|
const constexpr size_t LUT_LEVELS = 16;
|
|
const constexpr size_t LUT_TAPS = 8;
|
|
const constexpr ptrdiff_t LUT_HTAPS = LUT_TAPS/2-1;//static_cast<ptrdiff_t>(LUT_TAPS - (LUT_TAPS+0.5)/2);
|
|
const constexpr size_t LUT_STEPS = 1024;
|
|
extern const std::array<std::array<std::array<double, LUT_TAPS>, LUT_LEVELS>, LUT_STEPS> resamplerLUT;
|
|
|
|
inline Data::AudioFrame resamp(Data::Sample* smp, double pos, double rate [[maybe_unused]]) {
|
|
auto loop = smp->loopStart >= 0;
|
|
auto len = static_cast<ptrdiff_t>(smp->length());
|
|
auto ls = static_cast<ptrdiff_t>(smp->loopStart);
|
|
auto le = static_cast<ptrdiff_t>(smp->loopEnd);
|
|
auto ll = le - ls;
|
|
|
|
double ip = std::floor(pos);
|
|
auto& pt = NodeLib::resamplerLUT[static_cast<size_t>((pos - ip)*NodeLib::LUT_STEPS) % NodeLib::LUT_STEPS][static_cast<size_t>(std::clamp(std::floor(rate - 0.00001), 0.0, (LUT_LEVELS-1)*1.0))];
|
|
|
|
Data::AudioFrame out(0.0);
|
|
|
|
auto ii = static_cast<ptrdiff_t>(ip) - LUT_HTAPS;
|
|
for (size_t i = 0; i < 8; i++) {
|
|
if (loop && ii >= le) ii = ((ii - ls) % ll) + ls;
|
|
else if (ii >= len) return out; // we can early-out here
|
|
if (ii >= 0) out += (*smp)[static_cast<size_t>(ii)] * pt[i];
|
|
ii++;
|
|
}
|
|
|
|
return out;
|
|
}
|
|
}
|