13template<
unsigned CHANNELS>
17 , hostClock(hostClock_)
22 narrow<unsigned>(hostPeriod));
28template<
unsigned CHANNELS>
32 auto& emuClk = getEmuClock();
33 unsigned emuNum = emuClk.getTicksTill(time);
38 const unsigned len = emuNum * CHANNELS +
std::max(3u, CHANNELS);
40 EmuTime emu1 = emuClk.getFastAdd(1);
41 assert(emu1 > hostClock.getTime());
42 if (input.generateInput(buf.data(), emuNum)) {
44 hostClock.getTicksTill(emu1, pos1);
45 for (
auto ch :
xrange(CHANNELS)) {
52 buf[CHANNELS * emuNum + ch] =
53 buf[CHANNELS * (emuNum - 1) + ch] + 1.0f;
55 auto last = lastInput[ch];
56 for (
unsigned i = 0; ; ++i) {
57 auto delta = buf[CHANNELS * i + ch] - last;
58 if (delta != 0) [[unlikely]] {
62 last = buf[CHANNELS * i + ch];
74 hostClock.getTicksTill(emu1, pos);
75 for (
auto ch :
xrange(CHANNELS)) {
76 if (lastInput[ch] != 0.0f) {
77 auto delta = -lastInput[ch];
79 blip[ch].addDelta(pos, delta);
86 std::array<bool, CHANNELS> results;
87 for (
auto ch :
xrange(CHANNELS)) {
88 results[ch] = blip[ch].template readSamples<CHANNELS>(dataOut + ch, hostNum);
90 static_assert(CHANNELS ==
one_of(1u, 2u),
"either mono or stereo");
91 if constexpr (CHANNELS == 1) {
94 if (results[0] == results[1]) {
100 unsigned offset = results[0] ? 1 : 0;
101 for (
auto i :
xrange(hostNum)) {
102 dataOut[2 * i + offset] = 0.0f;
Represents a clock with a variable frequency.
EmuDuration getPeriod() const
Returns the length of one clock-cycle.
constexpr uint64_t length() const
static constexpr FixedPoint roundRatioDown(unsigned n, unsigned d)
bool generateOutputImpl(float *dataOut, size_t num, EmuTime::param time) override
ResampleBlip(ResampledSoundDevice &input, const DynamicClock &hostClock)
DynamicClock & getEmuClock()
constexpr vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
This file implemented 3 utility functions:
constexpr void fill(ForwardRange &&range, const T &value)
#define VLA_SSE_ALIGNED(TYPE, NAME, LENGTH)
constexpr auto xrange(T e)