92 if (!std::isfinite(windowMs)) windowMs = 300.0;
94 windowMs_ = std::clamp(windowMs, 1.0, 600000.0);
95 alpha_ = 1.0 - std::exp(-1.0 / (windowMs_ * 0.001 * fs));
97 gonioDecim_ = std::max(1,
static_cast<int>(std::llround(std::min(fs / 24000.0, 65536.0))));
98 prepared_.store(
true, std::memory_order_relaxed);
111 lr_ = ll_ = rr_ = 0.0;
113 for (
auto& p : gonio_)
114 p.store(0u, std::memory_order_relaxed);
115 gonioWrite_.store(0, std::memory_order_relaxed);
116 correlation_.store(T(0), std::memory_order_relaxed);
117 balance_.store(T(0), std::memory_order_relaxed);
131 if (!prepared_.load(std::memory_order_relaxed))
return;
133 const int nS = buffer.getNumSamples();
134 const int nCh = buffer.getNumChannels();
135 if (nS <= 0 || nCh <= 0)
return;
137 const T* L = buffer.getChannel(0);
138 const T* R = (nCh >= 2) ? buffer.getChannel(1) : L;
140 const double alpha = alpha_;
141 double lr = lr_, ll = ll_, rr = rr_;
142 int wp = gonioWrite_.load(std::memory_order_relaxed);
144 for (
int i = 0; i < nS; ++i)
146 const double l =
static_cast<double>(L[i]);
147 const double r =
static_cast<double>(R[i]);
148 lr += alpha * (l * r - lr);
149 ll += alpha * (l * l - ll);
150 rr += alpha * (r * r - rr);
152 if (++decimCount_ >= gonioDecim_)
155 if (std::isfinite(l) && std::isfinite(r))
158 p.
mid =
static_cast<float>((l + r) * 0.7071067811865476);
159 p.
side =
static_cast<float>((l - r) * 0.7071067811865476);
160 gonio_[
static_cast<size_t>(wp)].store(std::bit_cast<std::uint64_t>(p),
161 std::memory_order_relaxed);
167 gonioWrite_.store(wp, std::memory_order_release);
175 if (!std::isfinite(lr + ll + rr))
177 lr_ = ll_ = rr_ = 0.0;
184 if (ll < 1e-100) ll = 0.0;
185 if (rr < 1e-100) rr = 0.0;
186 if (std::abs(lr) < 1e-100) lr = 0.0;
192 const double denom = std::sqrt(ll * rr);
193 const double corr = (denom > 1e-12) ? std::clamp(lr / denom, -1.0, 1.0) : 0.0;
194 correlation_.store(
static_cast<T
>(corr), std::memory_order_relaxed);
196 const double total = ll + rr;
197 const double bal = (total > 1e-12) ? (rr - ll) / total : 0.0;
198 balance_.store(
static_cast<T
>(bal), std::memory_order_relaxed);