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:
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user