Aber der c0pperdragon schafft es ja auch irgendwie, die Signale zu erkennen.
https://github.com/c0pperdragon/C64-Video-Enhancement
Im Grunde ist das Ziel hier ja sehr ähnlich. Ein "externer" c0pperdragon ohne Modifiaktionen am C64, mit HDMI Ausgabe.
Wie schon gesagt, wird hier ja nicht das analoge Signal eingelesen, sondern das
Digitale am VIC-Eingang. Dann wird mittels VIC-II-Emulator (in HDL für FPGAs)
ein Bild synchron nachgebaut und per Wandler für HDMI aufbereitet und ausgegeben.
Wenn man die HDL-Files überfliegt, dann hat man sehr schnell die Vermutung,
dass eine, gelinde gesagt, spärliche Version verwendet wird. D.h. es wird nicht
alles so angezeigt, wie es zu erwarten ist. (und auch hier: ob HDMI oder VGA
oder was auch immer als Ausgabe gewählt wird, ist eigentlich egal)
Was wir halt nicht vergessen dürfen ist, dass es sich um analoge Signale eines Chips handelt, der Ende der 70er entwickelt wurde.
Ja, genau: die Signale sind nicht nur werteanalog, sondern auch zeitanalog. D.h., je
Zeile hat man einen kontinuierlichen Signalverlauf, der auch zeitanalog gewandelt
und auf dem Bildschirm angezeigt wird. Damit sind z.B. auf horz. Ebene Sampling
und entsprechende Skalierungsoperationen, wie sie für höhere Auflösungen von
TFTs notwendig sind, überflüssig (naja, gilt für SW-Monitore, für Farbe hat man
ein Raster und damit eine Art Zeitdiskretisierung). Ausnahme ist aber der vertikale
Verlauf, hier muss die Anzahl der Zeilen gleich der des Bildschirms sein, oder z.B.
per Wiederholung mehrfach angezeigt werden.
Von Pixel zu Pixel springen die Signale nicht unendlich schnell an, sondern haben Ansprech- und Abschwellzeiten, Unter- und Überschwinger. Das düfte mit ein Teil der Herausforderung sein, solche Signale dennoch richtig zu erkennen.
Wenn man z.B. regelmäßige Farbmuster hat, kommt es nicht selten vor, dass sich daraus ein Störmuster ergibt.
Genau deshalb ahme ich ja auch das nach, was in einem Videochip so vorsich geht:
Per hoher Samplingrate nicht nur das LUMA-Signal, sondern auch das CHROMA-Signal
zu samplen, den darin enthaltenen Burst abzufangen, auszuwerten um damit je
Pixelposition ebenfalls enthaltenen Burst in eine Phasen- und Amplitudeninformation
umzuwandeln.
Der Ablauf ist in etwa wie folgt:
- 1. zuerst wird ein horz. Sync eingelesen
- 2. nach kurzer Zeit folgt ein Burst. Dieser wird hochfrequent gesampelt und in eine
Phaseninfo (Phase 1) umgewandelt (Amplitude interessiert nicht)
- 3. wiederum nach kurzer Zeit beginnt dann der Pixelstrom. Und hier ist es extrem
wichtig, nur in einem kleinen Fenster innerhalb des Pixels den Burst auszulesen
und dessen Phase+Amplitude (Phase2) auszulesen. Ist die Amplitude gleich Null,
dann liegt S/W/Grau vor, andernfalls Farbe. Aus der Differenz der beiden Phasen
(Phase2-Phase1, evtl. Modulo-Op?) ergibt sich dann mittels Tabelle die Farbe
- 4. danach kommt dann wieder ein Sync etc., d.h. weiter mit 1. oder 5.
- 5. Bildende erkennen
Der Burst ist hier ein hochfrequentes Signal mit fester Frequenz (ca. 4.4MHz für PAL).
Aus praktischen Gründen sample ich jetzt mit einem Vielfachen dieser Frequenz
(Videochips samplen hier z.B. mit 27, 50 oder gar 100 MHz).
Wenn ich mich so auf die Schnelle nicht verrechnet habe, ist das Fenster leider
so klein, dass nur ein Bruchteil einer kompletten Schwingung gesamplelt werden
kann (sonst werden nich Übergänge zum nächsten Pixel bzw. Farbe mitgelesen,
was dann das Ergebnis verfälscht). Aber mithilfe numerischer Verfahren (gleich
mehr dazu) kann man notwendig viel Informationen extrahieren, um Amplitude
und Phase zu bestimmen.
Numerisches Verfahren, um Amplitude und Phase zu bestimmen:
- es sind n Werte für Cos- und Sin-Function der Burstfrequenz vorberechnet
- es werden n Werte eingelesen
- mithilfe eines einfachen linearen Approximationsverfahren werden
die Koeffizienten Werte = a*cos + b*sin bestimmt (FT oder FFT gehen hier
nicht, da keine ganze Periode vorhanden ist!), aus a und b dann mittels
einfacher Umwandlung die Amplitude und die Phase (ist vlt. gar nicht
notwendig, da evtl. a und b schon für die Farbauswertung ausreichen,
für die Amplitude tun sie das ganz sicher) berechnet.
Das Approximationsverfahren verstehe ich gut genug, für die konkrete
Aufgabe muss ich aber noch ein kleines Skript schreiben, das mir verrauschte
Burstsignale entsprechender Länge erzeugt und das Verfahren darauf
anwenden. Dann kann ich sehen, wie genau a und b bzw. Aplitude und
Phase bestimmt werden können, und das inkl. Rauschen im Signal. Da sehe
ich ausser einem Zeitaufwand aber keine Probleme, auch die Implementierung
in HDL für FPGAs ist sehr einfach, habe ich schon des öfteren gemacht,
erfordert auch nur wenige Resourcen. (das Ganzer natürlich unter der Annahme,
dass das Fenster im Pixel gross genug ist, um ein Minimum an Periodenanteil
der Burstfrequenz zu fassen, sonst wird die Extraktion von Phase und Amplitude
unmögliche. genaueres rechne ich Morgen Abend aus.)
So, jetzt aber gute Nacht