1
0
mirror of https://github.com/TomHarte/CLK.git synced 2026-01-23 16:16:16 +00:00

Use common box filter.

This commit is contained in:
Thomas Harte
2026-01-13 17:29:02 -05:00
parent fd73b408a3
commit a3ef460334
2 changed files with 35 additions and 41 deletions

View File

@@ -151,38 +151,6 @@ constexpr MTLResourceOptions SharedResourceOptionsTexture =
} \
} \
}
/// @returns the proper 1d kernel to apply a box filter around a certain point a pixel density of @c radiansPerPixel and applying an
/// angular limit of @c cutoff. The values returned will be the first eight of a fifteen-point filter that is symmetrical around its centre.
std::array<float, 8> boxCoefficients(float radiansPerPixel, float cutoff) {
std::array<float, 8> filter;
float total = 0.0f;
for(size_t c = 0; c < 8; ++c) {
// This coefficient occupies the angular window [6.5-c, 7.5-c]*radiansPerPixel.
const float startAngle = (6.5f - float(c)) * radiansPerPixel;
const float endAngle = (7.5f - float(c)) * radiansPerPixel;
float coefficient = 0.0f;
if(endAngle < cutoff) {
coefficient = 1.0f;
} else if(startAngle >= cutoff) {
coefficient = 0.0f;
} else {
coefficient = (cutoff - startAngle) / radiansPerPixel;
}
total += 2.0f * coefficient; // All but the centre coefficient will be used twice.
filter[c] = coefficient;
}
total = total - filter[7]; // As per above; ensure the centre coefficient is counted only once.
for(size_t c = 0; c < 8; ++c) {
filter[c] /= total;
}
return filter;
}
}
using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
@@ -730,9 +698,11 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
simd::float3 firCoefficients[8]{};
// Initial seed: a box filter for the chrominance parts and no filter at all for luminance.
const auto chromaCoefficients = boxCoefficients(radiansPerPixel, 3.141592654f);
const auto testBox = SignalProcessing::Box::filter<SignalProcessing::ScalarType::Float>(radiansPerPixel, 3.141592654f * 2.0f);
(void)testBox;
const auto chromaCoefficients =
SignalProcessing::Box::filter<SignalProcessing::ScalarType::Float>(
radiansPerPixel,
3.141592654f * 2.0f
).resize(15);
_chromaKernelSize = 15;
for(size_t c = 0; c < 8; ++c) {
@@ -765,10 +735,9 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
// actual cutoff frequency is going to be a function of the input clock, which is a bit phoney but the
// best way to stay safe within the PCM sampling limits.
if(!isSVideoOutput) {
const auto sharpenFilter
const auto sharpen
= SignalProcessing::KaiserBessel::filter<SignalProcessing::ScalarType::Float>(
15, 1368, 60.0f, 227.5f);
const auto sharpen = sharpenFilter.coefficients();
const size_t offset = (15 - sharpen.size()) / 2;
for(size_t c = offset; c < 8; ++c) {
@@ -787,7 +756,11 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
// Generate the luminance separation filter and determine its required size.
{
simd::float2 lumaCoefficients[8]{};
const auto coefficients = boxCoefficients(radiansPerPixel, 3.141592654f);
const auto coefficients =
SignalProcessing::Box::filter<SignalProcessing::ScalarType::Float>(
radiansPerPixel,
3.141592654f * 2.0f
).resize(15);
_lumaKernelSize = 15;
for(size_t c = 0; c < 8; ++c) {
lumaCoefficients[c].x = coefficients[c];// * 1.15f;

View File

@@ -17,8 +17,9 @@
#endif
#include <algorithm>
#include <cassert>
#include <cmath>
#include <span>
#include <numeric>
#include <vector>
namespace SignalProcessing {
@@ -116,8 +117,28 @@ public:
}
}
std::span<const CoefficientType> coefficients() const {
return std::span(coefficients_);
CoefficientType operator[](const size_t index) const {
return coefficients_[index];
}
size_t size() const {
return coefficients_.size();
}
FIRFilter &resize(const size_t size) {
assert(size & 1);
if(size >= coefficients_.size()) {
// TODO: find a faster solution than this.
const auto half_difference = (size - coefficients_.size()) / 2;
std::vector<CoefficientType> zeroes(half_difference);
coefficients_.insert(coefficients_.begin(), zeroes.begin(), zeroes.end());
coefficients_.insert(coefficients_.end(), zeroes.begin(), zeroes.end());
return *this;
}
// const auto total = std::accumulate(coefficients_.begin(), coefficients_.end(), CoefficientType{});
return *this;
}
private: