mirror of
https://github.com/TomHarte/CLK.git
synced 2024-08-30 19:29:37 +00:00
Attempts fully to restore composite video.
Subject to some sort of nasty race condition for the time being.
This commit is contained in:
parent
c36247b609
commit
c7ce65ea4c
@ -98,7 +98,8 @@ struct Uniforms {
|
|||||||
simd::float3x3 fromRGB;
|
simd::float3x3 fromRGB;
|
||||||
float zoom;
|
float zoom;
|
||||||
simd::float2 offset;
|
simd::float2 offset;
|
||||||
simd::float3 firCoefficients[8];
|
simd::float3 chromaCoefficients[8];
|
||||||
|
float lumaCoefficients[8];
|
||||||
float radiansPerPixel;
|
float radiansPerPixel;
|
||||||
float cyclesMultiplier;
|
float cyclesMultiplier;
|
||||||
};
|
};
|
||||||
@ -560,32 +561,30 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
|
|||||||
_compositionRenderPass.colorAttachments[0].clearColor = MTLClearColorMake(0.0, 0.5, 0.5, 1.0);
|
_compositionRenderPass.colorAttachments[0].clearColor = MTLClearColorMake(0.0, 0.5, 0.5, 1.0);
|
||||||
|
|
||||||
// Create suitable FIR filters.
|
// Create suitable FIR filters.
|
||||||
auto *const firCoefficients = uniforms()->firCoefficients;
|
|
||||||
_lineBufferPixelsPerLine = NSUInteger(modals.cycles_per_line) * NSUInteger(uniforms()->cyclesMultiplier);
|
_lineBufferPixelsPerLine = NSUInteger(modals.cycles_per_line) * NSUInteger(uniforms()->cyclesMultiplier);
|
||||||
const float colourCyclesPerLine = float(modals.colour_cycle_numerator) / float(modals.colour_cycle_denominator);
|
const float colourCyclesPerLine = float(modals.colour_cycle_numerator) / float(modals.colour_cycle_denominator);
|
||||||
|
|
||||||
if(isSVideoOutput) {
|
// Generate the chrominance filter.
|
||||||
// In S-Video, don't filter luminance.
|
{
|
||||||
for(size_t c = 0; c < 7; ++c) {
|
auto *const chromaCoefficients = uniforms()->chromaCoefficients;
|
||||||
firCoefficients[c].x = 0.0f;
|
SignalProcessing::FIRFilter chrominancefilter(15, float(_lineBufferPixelsPerLine), 0.0f, colourCyclesPerLine * (isSVideoOutput ? 1.0f : 1.0f));
|
||||||
}
|
|
||||||
firCoefficients[7].x = 1.0f;
|
|
||||||
} else {
|
|
||||||
// In composite, filter luminance gently.
|
|
||||||
SignalProcessing::FIRFilter luminancefilter(15, float(_lineBufferPixelsPerLine), 0.0f, colourCyclesPerLine * 0.5f);
|
|
||||||
const auto calculatedCoefficients = luminancefilter.get_coefficients();
|
|
||||||
for(size_t c = 0; c < 8; ++c) {
|
|
||||||
firCoefficients[c].x = calculatedCoefficients[c];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Whether S-Video or composite, apply the same relatively strong filter to colour channels.
|
|
||||||
SignalProcessing::FIRFilter chrominancefilter(15, float(_lineBufferPixelsPerLine), 0.0f, colourCyclesPerLine * (isSVideoOutput ? 1.0f : 0.25f));
|
|
||||||
const auto calculatedCoefficients = chrominancefilter.get_coefficients();
|
const auto calculatedCoefficients = chrominancefilter.get_coefficients();
|
||||||
for(size_t c = 0; c < 8; ++c) {
|
for(size_t c = 0; c < 8; ++c) {
|
||||||
firCoefficients[c].y = firCoefficients[c].z = calculatedCoefficients[c] * (isSVideoOutput ? 4.0f : 4.0f);
|
chromaCoefficients[c].y = chromaCoefficients[c].z = calculatedCoefficients[c] * (isSVideoOutput ? 4.0f : 8.0f);
|
||||||
|
chromaCoefficients[c].x = 0.0f;
|
||||||
|
}
|
||||||
|
chromaCoefficients[7].x = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate the luminance filter.
|
||||||
|
{
|
||||||
|
auto *const luminanceCoefficients = uniforms()->lumaCoefficients;
|
||||||
|
SignalProcessing::FIRFilter luminancefilter(15, float(_lineBufferPixelsPerLine), 0.0f, colourCyclesPerLine * 0.5f);
|
||||||
|
const auto calculatedCoefficients = luminancefilter.get_coefficients();
|
||||||
|
memcpy(luminanceCoefficients, calculatedCoefficients.data(), sizeof(float)*8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store radians per pixel. TODO: is this now orphaned? Should I keep it anyway?
|
||||||
uniforms()->radiansPerPixel = (colourCyclesPerLine * 3.141592654f * 2.0f) / float(_lineBufferPixelsPerLine);
|
uniforms()->radiansPerPixel = (colourCyclesPerLine * 3.141592654f * 2.0f) / float(_lineBufferPixelsPerLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,9 +32,13 @@ struct Uniforms {
|
|||||||
float zoom;
|
float zoom;
|
||||||
float2 offset;
|
float2 offset;
|
||||||
|
|
||||||
// Describes the FIR filter in use; it'll be 15 coefficients but they're
|
// Describes the FIR filter in use for chroma filtering; it'll be
|
||||||
|
// 15 coefficients but they're symmetrical around the centre.
|
||||||
|
float3 chromaCoefficients[8];
|
||||||
|
|
||||||
|
// Describes the FIR filter in use for luma filtering; also 15 coefficients
|
||||||
// symmetrical around the centre.
|
// symmetrical around the centre.
|
||||||
float3 firCoefficients[8];
|
float lumaCoefficients[8];
|
||||||
|
|
||||||
// Maps from pixel offsets into the composition buffer to angular difference.
|
// Maps from pixel offsets into the composition buffer to angular difference.
|
||||||
float radiansPerPixel;
|
float radiansPerPixel;
|
||||||
@ -386,7 +390,7 @@ kernel void filterChromaKernel( texture2d<float, access::read> inTexture [[textu
|
|||||||
inTexture.read(gid + uint2(14, offset)) - moveToZero,
|
inTexture.read(gid + uint2(14, offset)) - moveToZero,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define Sample(x, y) uniforms.firCoefficients[y] * rawSamples[x].rgb
|
#define Sample(x, y) uniforms.chromaCoefficients[y] * rawSamples[x].rgb
|
||||||
const float3 colour =
|
const float3 colour =
|
||||||
Sample(0, 0) + Sample(1, 1) + Sample(2, 2) + Sample(3, 3) + Sample(4, 4) + Sample(5, 5) + Sample(6, 6) +
|
Sample(0, 0) + Sample(1, 1) + Sample(2, 2) + Sample(3, 3) + Sample(4, 4) + Sample(5, 5) + Sample(6, 6) +
|
||||||
Sample(7, 7) +
|
Sample(7, 7) +
|
||||||
@ -411,32 +415,36 @@ kernel void separateLumaKernel( texture2d<float, access::read> inTexture [[textu
|
|||||||
uint2 gid [[thread_position_in_grid]],
|
uint2 gid [[thread_position_in_grid]],
|
||||||
constant Uniforms &uniforms [[buffer(0)]],
|
constant Uniforms &uniforms [[buffer(0)]],
|
||||||
constant int &offset [[buffer(1)]]) {
|
constant int &offset [[buffer(1)]]) {
|
||||||
// TODO!
|
const float4 centreSample = inTexture.read(gid + uint2(7, offset));
|
||||||
constexpr float4 moveToZero = float4(0.0f, 0.5f, 0.5f, 0.0f);
|
const float rawSamples[] = {
|
||||||
const float4 rawSamples[] = {
|
inTexture.read(gid + uint2(0, offset)).r,
|
||||||
inTexture.read(gid + uint2(0, offset)) - moveToZero,
|
inTexture.read(gid + uint2(1, offset)).r,
|
||||||
inTexture.read(gid + uint2(1, offset)) - moveToZero,
|
inTexture.read(gid + uint2(2, offset)).r,
|
||||||
inTexture.read(gid + uint2(2, offset)) - moveToZero,
|
inTexture.read(gid + uint2(3, offset)).r,
|
||||||
inTexture.read(gid + uint2(3, offset)) - moveToZero,
|
inTexture.read(gid + uint2(4, offset)).r,
|
||||||
inTexture.read(gid + uint2(4, offset)) - moveToZero,
|
inTexture.read(gid + uint2(5, offset)).r,
|
||||||
inTexture.read(gid + uint2(5, offset)) - moveToZero,
|
inTexture.read(gid + uint2(6, offset)).r,
|
||||||
inTexture.read(gid + uint2(6, offset)) - moveToZero,
|
centreSample.r,
|
||||||
inTexture.read(gid + uint2(7, offset)) - moveToZero,
|
inTexture.read(gid + uint2(8, offset)).r,
|
||||||
inTexture.read(gid + uint2(8, offset)) - moveToZero,
|
inTexture.read(gid + uint2(9, offset)).r,
|
||||||
inTexture.read(gid + uint2(9, offset)) - moveToZero,
|
inTexture.read(gid + uint2(10, offset)).r,
|
||||||
inTexture.read(gid + uint2(10, offset)) - moveToZero,
|
inTexture.read(gid + uint2(11, offset)).r,
|
||||||
inTexture.read(gid + uint2(11, offset)) - moveToZero,
|
inTexture.read(gid + uint2(12, offset)).r,
|
||||||
inTexture.read(gid + uint2(12, offset)) - moveToZero,
|
inTexture.read(gid + uint2(13, offset)).r,
|
||||||
inTexture.read(gid + uint2(13, offset)) - moveToZero,
|
inTexture.read(gid + uint2(14, offset)).r,
|
||||||
inTexture.read(gid + uint2(14, offset)) - moveToZero,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define Sample(x, y) uniforms.firCoefficients[y] * rawSamples[x].rgb
|
#define Sample(x, y) uniforms.lumaCoefficients[y] * rawSamples[x]
|
||||||
const float3 colour =
|
const float luminance =
|
||||||
Sample(0, 0) + Sample(1, 1) + Sample(2, 2) + Sample(3, 3) + Sample(4, 4) + Sample(5, 5) + Sample(6, 6) +
|
Sample(0, 0) + Sample(1, 1) + Sample(2, 2) + Sample(3, 3) + Sample(4, 4) + Sample(5, 5) + Sample(6, 6) +
|
||||||
Sample(7, 7) +
|
Sample(7, 7) +
|
||||||
Sample(8, 6) + Sample(9, 5) + Sample(10, 4) + Sample(11, 3) + Sample(12, 2) + Sample(13, 1) + Sample(14, 0);
|
Sample(8, 6) + Sample(9, 5) + Sample(10, 4) + Sample(11, 3) + Sample(12, 2) + Sample(13, 1) + Sample(14, 0);
|
||||||
#undef Sample
|
#undef Sample
|
||||||
|
|
||||||
outTexture.write(float4(uniforms.toRGB * colour, 1.0f), gid + uint2(7, offset));
|
outTexture.write(float4(
|
||||||
|
luminance,
|
||||||
|
(centreSample.gb - float2(0.5f)) * (centreSample.r - luminance) + float2(0.5f),
|
||||||
|
1.0f
|
||||||
|
),
|
||||||
|
gid + uint2(7, offset));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user