1
0
mirror of https://github.com/TomHarte/CLK.git synced 2026-01-22 08:26:48 +00:00

Experiment with but discover that 'real' FIRs remain out of reach.

This commit is contained in:
Thomas Harte
2026-01-17 22:50:35 -05:00
parent a11dba682b
commit c93dfd7db7
3 changed files with 40 additions and 30 deletions

View File

@@ -286,7 +286,8 @@ private:
const AddressT graphic_location = base->sprite_generator_table_address_ & bits<11>(AddressT((name << 3) | sprite.row));
sprite.image[0] = base->ram_[graphic_location];
sprite.image[1] = base->ram_[graphic_location+16];
sprite.image[1] = base->ram_[graphic_location+16]; // TODO: occasional out-of-bounds accesses here. Check
// uninitialised Master System.
if constexpr (SpriteBuffer::test_is_filling) {
if(slot == ((mode == SpriteMode::Mode2) ? 7 : 3)) {

View File

@@ -173,7 +173,7 @@ kernel void separateLumaKernel15(
return setSeparatedLumaChroma(
luminanceChrominance,
centreSample.gb - half2(0.5),
centreSample.gb - half2(0.5f),
centreSample.a,
outTexture,
gid,

View File

@@ -30,32 +30,35 @@ float FilterGenerator::radians_per_sample() const {
FilterGenerator::FilterPair FilterGenerator::separation_filter() {
FilterPair result{};
// Luminance: box.
// Luminance.
result.luma =
// SignalProcessing::KaiserBessel::filter<SignalProcessing::ScalarType::Float>(
// max_kernel_size_,
// samples_per_line_,
// 0.0f,
// subcarrier_frequency_ * 0.25f
// );
SignalProcessing::Box::filter<SignalProcessing::ScalarType::Float>(
radians_per_sample(),
std::numbers::pi_v<float> * 2.0f
);
// Chrominance: compute as subcarrier - luminance.
// TODO: attempting a notch as below seems to introduce a phase shift or time delay.
// I'm not smart enough currently to understand why.
// I need to fix or, at the minimum, predict it for correction later.
// Usually provides a better luminance filter, but has issues with in-phase NTSC colour:
//
// SignalProcessing::KaiserBessel::filter<SignalProcessing::ScalarType::Float>(
// max_kernel_size_,
// samples_per_line_,
// 0.0f,
// subcarrier_frequency_ * 0.5f
// );
// Chrominance.
result.chroma = SignalProcessing::KaiserBessel::filter<SignalProcessing::ScalarType::Float>(
max_kernel_size_,
samples_per_line_,
subcarrier_frequency_,
samples_per_line_
);
result.luma.copy_to<SignalProcessing::FIRFilter<SignalProcessing::ScalarType::Float>::iterator>(
SignalProcessing::KaiserBessel::filter<SignalProcessing::ScalarType::Float>(
max_kernel_size_,
samples_per_line_,
0.0f,
subcarrier_frequency_
).copy_to<SignalProcessing::FIRFilter<SignalProcessing::ScalarType::Float>::iterator>(
result.chroma.begin(),
result.chroma.end(),
[](const auto iterator, const float value) {
@@ -69,30 +72,36 @@ FilterGenerator::FilterPair FilterGenerator::separation_filter() {
FilterGenerator::FilterPair FilterGenerator::demouldation_filter() {
FilterPair result{};
result.chroma =
SignalProcessing::KaiserBessel::filter<SignalProcessing::ScalarType::Float>(
max_kernel_size_,
samples_per_line_,
40.0f,
subcarrier_frequency_ * 0.5f
)
* (decoding_path_ == DecodingPath::SVideo ? 2.0f : 0.5f);
// S-Video: don't filter luminance at all.
if(decoding_path_ == DecodingPath::SVideo) {
// S-Video: don't filter luminance at all.
const float identity[] = { 1.0f };
result.luma =
SignalProcessing::FIRFilter<SignalProcessing::ScalarType::Float>(
std::begin(identity),
std::end(identity)
);
return result;
} else {
// Composite: sharpen the luminance a touch.
result.luma =
SignalProcessing::KaiserBessel::filter<SignalProcessing::ScalarType::Float>(
max_kernel_size_, samples_per_line_, 100.0f, subcarrier_frequency_);
}
// Composite: sharpen the luminance a touch.
result.luma =
SignalProcessing::KaiserBessel::filter<SignalProcessing::ScalarType::Float>(
max_kernel_size_, samples_per_line_, 10.0f, subcarrier_frequency_);
result.chroma =
SignalProcessing::Box::filter<SignalProcessing::ScalarType::Float>(
radians_per_sample(),
std::numbers::pi_v<float> * 2.0f
)
* (decoding_path_ == DecodingPath::SVideo ? 2.0f : 0.5f);
// Usually provides a better chroma filter, but has issues with in-phase NTSC colour:
//
// SignalProcessing::KaiserBessel::filter<SignalProcessing::ScalarType::Float>(
// max_kernel_size_,
// samples_per_line_,
// 0.0f,
// subcarrier_frequency_ * 0.5f
// )
return result;
}