14 static std::vector<float> bufferStorage;
15 static unsigned bufferSize = 0;
16 static float* aBuffer =
nullptr;
20 template<
unsigned CHANNELS>
24 std::unique_ptr<ResampleLQ<CHANNELS>> result;
26 result = std::make_unique<ResampleLQUp <CHANNELS>>(input, hostClock);
28 result = std::make_unique<ResampleLQDown<CHANNELS>>(input, hostClock);
33 template<
unsigned CHANNELS>
37 , hostClock(hostClock_)
41 assert(
unsigned( emuPeriod) == emuPeriod);
42 assert(
unsigned(hostPeriod) == hostPeriod);
49 [[nodiscard]]
static bool isSilent(
float x)
51 constexpr
float threshold = 1.0f / 32768;
52 return std::abs(
x) < threshold;
55 template<
unsigned CHANNELS>
58 auto& emuClk = getEmuClock();
59 unsigned emuNum = emuClk.getTicksTill(time);
62 unsigned required = emuNum + 4;
63 if (
unlikely(required > bufferSize)) {
65 bufferStorage.resize(required + 3);
67 auto p =
reinterpret_cast<uintptr_t
>(bufferStorage.data());
68 aBuffer =
reinterpret_cast<float*
>((p + 15) & ~15);
70 bufferSize = (bufferStorage.data() + bufferStorage.size()) - aBuffer;
71 assert(bufferSize >= required);
76 auto* buffer = &aBuffer[4 - 2 *
CHANNELS];
77 assert((uintptr_t(&buffer[2 *
CHANNELS]) & 15) == 0);
79 if (!input.generateInput(&buffer[2 *
CHANNELS], emuNum)) {
81 if (
ranges::all_of(lastInput, [](
auto& l) {
return isSilent(l); })) {
89 buffer[j] = lastInput[j];
90 lastInput[j] = buffer[emuNum *
CHANNELS + j];
97 template<
unsigned CHANNELS>
105 template<
unsigned CHANNELS>
107 float* __restrict dataOut,
unsigned hostNum, EmuTime::param time)
109 auto& emuClk = this->getEmuClock();
110 EmuTime host1 = this->hostClock.getFastAdd(1);
111 assert(host1 > emuClk.getTime());
113 emuClk.getTicksTill(host1, pos);
114 assert(pos.toInt() < 2);
117 if (!this->fetchData(time, valid))
return false;
122 auto* buffer = &aBuffer[4 - 2 *
CHANNELS];
123 for (
auto i :
xrange(hostNum)) {
124 unsigned p = pos.toInt();
137 template<
unsigned CHANNELS>
145 template<
unsigned CHANNELS>
147 float* __restrict dataOut,
unsigned hostNum, EmuTime::param time)
149 auto& emuClk = this->getEmuClock();
150 EmuTime host1 = this->hostClock.getFastAdd(1);
151 assert(host1 > emuClk.getTime());
153 emuClk.getTicksTill(host1, pos);
156 if (!this->fetchData(time, valid))
return false;
158 auto* buffer = &aBuffer[4 - 2 *
CHANNELS];
159 for (
auto i :
xrange(hostNum)) {
160 unsigned p = pos.toInt();
161 assert((p + 1) < valid);
162 FP fract = pos.fract();
164 auto s0 = buffer[(p + 0) *
CHANNELS + j];
165 auto s1 = buffer[(p + 1) *
CHANNELS + j];
166 auto out = s0 + (fract.toFloat() * (s1 - s0));
176 template class ResampleLQ<1>;
177 template class ResampleLQ<2>;