43 : source_(source), spec_(spec), expected_(fingerprint), inputPeak_(inputPeak), job_(job),
44 input_(job, spec, std::min(256, blockFrames)),
45 aligned_(job, spec, std::min(256, blockFrames))
56 generator_->setWidth(1);
57 if (!generator_->prepare(environment, options))
59 latency_ = generator_->getLatency();
61 ringSize_ = latency_ + input_.
frames();
62 original_ = job.template allocate<T>(
static_cast<std::uint64_t
>(ringSize_) * spec.
channels);
73 generator_->resetAtFrame(
static_cast<std::uint64_t
>(spec_.
timelineOrigin));
75 int write = 0, read = 0, skip = latency_;
76 std::int64_t written = 0;
77 const auto block = [&](std::int64_t first,
int count,
bool flush) {
78 auto input = input_.
view(count);
81 std::array<std::array<double, 256>, 2> work{};
82 std::array<double, 256> delta{};
83 for (
int i = 0; i < count; ++i)
85 for (
int c = 0; c < spec_.
channels; ++c)
87 const T sample = flush ? T(0) : input.getChannel(c)[i];
88 if (!std::isfinite(sample))
93 if (std::abs(
static_cast<double>(sample)) > inputPeak_)
96 original_[
static_cast<std::size_t
>(c) * ringSize_ + write] = sample;
97 work[c][i] =
static_cast<double>(sample);
100 work[1][i] = work[0][i];
101 write = (write + 1) % ringSize_;
105 double *channels[]{work[0].data(), work[1].data()};
106 if (!generator_->processBlock({channels, 2, count},
107 {delta.data(),
static_cast<std::size_t
>(count)}))
110 const int start = std::min(skip, count);
112 const int produced = count - start;
113 auto original = aligned_.
view(produced);
114 for (
int i = 0; i < produced; ++i)
116 for (
int c = 0; c < spec_.
channels; ++c)
117 original.getChannel(c)[i] =
118 original_[
static_cast<std::size_t
>(c) * ringSize_ + read];
119 read = (read + 1) % ringSize_;
122 consume(written, original,
123 std::span<const double>(delta.data() + start,
124 static_cast<std::size_t
>(produced)));
127 for (std::int64_t first = 0; first < spec_.
frames;)
130 static_cast<int>(std::min<std::int64_t>(input_.
frames(), spec_.
frames - first));
131 block(first, count,
false);
136 for (
int remaining = latency_; remaining > 0;)
138 const int count = std::min(input_.
frames(), remaining);
139 block(spec_.
frames, count,
true);
143 if (written != spec_.
frames || fingerprint != expected_ || source_.getSpec() != spec_)