Recently I've been playing about doing NTSC decoding in software, trying to build an software TV/monitor for emulation purposes. I originally wanted to do the decoding of sampled composite signals to RGB and the horizontal scaling in a single step (precomputing a finite impulse response filter which does it all). However, I have come to realize that while this would yield the fastest code, it's not sufficiently flexible for what I want to do.
Specifically, in the signals I want to decode, the horizontal sync pulses can happen at any point (within a certain range) which means that the relationship between samples and horizontal pixel positions is not fixed in advance. This means that it's better to do the decoding (at least composite to YIQ if not all the way to RGB) at a fixed frequency and then rescale the result to pixels in real time (possibly using linear or cubic rescaling).
Having determined this, I looked to see what other NTSC software implementations do. Blargg's NES filter rescales at a ratio of 3:7 at the same time as it decodes, then it's up to the calling code to rescale this to the right width. xanalogtv converts composite to YIQ at 4 samples per color carrier cycle, uses linear rescaling on the YIQ samples and then converts the result to RGB. The resulting pixels may be doubled or tripled to get to the right width. This also allows for nice effects such as "blooming" (widening brighter lines).
My current simulator is here and the source is here (Windows only for now - sorry). This uses similar techniques to xanalogtv, but the rescaling is done by the GPU, in RGB space. The scanline effects are a bit more accurate (all the scanlines appear to be the same width, no matter what size the window is), and a phosphor mask is displayed. Most reasonably modern machines should be able to display the images at full speed (60Hz). If your machine is too slow or your monitor doesn't run at 60Hz there may be some odd effects (most LCD panels run at 60Hz). I believe this is the only software CRT simulator that correctly renders both interlaced and non-interlaced signals, and has physically correct phase-locked-loop line frequency behavior. If I can figure out how to add a pixel shader for light bloom, I should be able to get images as good as these (except with arbitrary scaling in real time).
One other rough edge in this version is that the horizontal sync pulse is currently only found to the nearest sample. This means that the phase locked loop isn't very tunable, and will cause problems for PAL signals (where the horizontal sync position is at a different subsample offset on every line). That should be quite easy to fix, though.
This simulator is going to form the basis for my demo machine emulator. The emulator itself is trivial - in fact I have already written it. But I haven't tried it out yet because I have no program to run on it. First I have to write an assembler for it. I might tweak the instruction set a bit somewhat in doing so, so I don't want to release the emulator just yet. Watch this space!
Well, that looks very promising!! I have to say though that there's more horizontal jitter than I remember from nearly all crappy CRTs I've ever worked with. The vertical roll was very cute :) I also loved watching the luma/chroma dot crawl :-D
Thought you'd like it! Yeah, the horizontal sync needs a little work. It's fine with a composite signal but it's overly sensitive to the noise I'm adding to simulate an RF-modulated signal. Maybe if I filter out frequencies over 1MHz or so and then do some interpolation to find the sync position, that would work better. I may also need to use a higher order differential equation to model the PLL. I was pleasantly surprised to find out that one can do some fairly sophisticated processing there because one only needs to look at a small section of the signal.
I should credit you for the vertical roll - I looked at some video you sent me a while back to determine the appropriate roll velocity for an IBM 5153 monitor!
[...] Reenigne blog Stuff I think about « NTSC hacking [...]
I think I'd be the first person ever credited for "roll velocity" ;-)
[...] my TV emulation, I wanted to render scanlines nicely and at any resolution. xanalogtv does vertical rescaling by [...]