I’ve spent most of last week looking at recording features in SimCoupe, with initial support for sound/video and future support for input recording (more on that one in a future posting):
This was very easy to do as the data is already in PCM format ready to be written to a wave file. I simply write the RIFF/WAV header, append each new frame of PCM data, then seek back and write the final block+data lengths in the header before closing the file.Wave files were the obvious choice for export as they’re universally supported and can always be converted/compressed for other uses. It would also be relatively easy to export through a codec under Windows, to write directly in a different format, but that’s something for a future version.I currently record only the SAA 1099 sound output, as that’s the only readily available source of sound chip data. SimCoupe use hardware mixing (if available), so I don’t have access to the fully mixed stream (SAA, beeper, DACs and tape). The core is being changed to use software mixing instead, and full recording support will be available once that is done.
Sound recordings can optionally have silence trimmed from the start and end, as that’s something users will typically want. Another option allows recordings to be split into separate files, if there’s a enough (user-definable) silence between them.
Here’s a sample recording of the Sophistry music, converted to MP3.
The plan is to write AVI files with a hand-coded MRLE encoder, using Microsoft’s Run-Length Encoding format. It’s a simple format, and seems reasonably well supported on different platforms. MRLE supports up to 256 colours (we need only 128), and the run-length encoding is very well suited to the our simple images.That isstill the plan, but I got side-tracked before I completely finished it! I was inspired by the animated GIF recording in the _SPIN_Spectrum emulator and decided to implement that in SimCoupe before AVI. GIF is ideal for use on web pages, and the LZW compression is again well suited to our clean images.GIF supports sub-image updates, so only the smallest change rectangle needs to be drawn between similar frames. Transparency allows the re-use of colours from the same position in the previous frame, cutting the size down even further. However, care does need to be taken when deciding between transparency and a solid colour, to maximise the run lengths for LZW to compress.
Before each frame image is a block defining how long the frame should remain visible. As well as controlling the overall animation speed, this allows us to store neighbouring identical frames for free. You simply increase the delay by 20ms for each identical display frame.
For smooth animation the recordings should ideally use full (50 fps) or half (25 fps) framerate. Firefox plays these perfectly, but Internet Explorer and Opera limit the animation speed to around 15 fps. Faster animations are simply played in slow motion, rather than skipping frames to maintain full speed. For this reason I’ve included an option to set the framerate, so 16.66 fps (1 in 3 frames) can be used when IE support is needed.
I’ve also included a feature that can help record repeated sections, to be played over and over with the GIF loop feature. Recording starts after the next change of image, and continues until the changed image is seen for a second time. It’s perfect for preserving the flash attribute (see reset screen below), or repeating sections in games or demos (see the SAM Juggler image below).
The output GIF sizes are very respectable, but a decent GIF optimiser should be able to squeeze them down further. The images I create include a full SAM palette of 128 colours, as I’ve no idea which colours will be used during the recording. The palette in optimised images will typically include only used colours, reducing the LZW token count and the final compressed size. However, forcing the optimiser to use the original palette may give a larger file than my original! 🙂
The following GIF animations were recorded by SimCoupe. The first shows a few lines of BASIC being entered, the second is the first 3 levels of Manic Miner, and the final one is a looped section from SAM Juggler. As they are all recorded at 25 fps, I’d recommend viewing them using Firefox or Chrome:
The final sample is what you see when holding in the SAM reset button:
It’s a mode 1 view of RAM page 0, which is where the system variables are stored. The Spectrum-style flashing attributes alternate every 16 frames (320ms), which is perfect for a simple 2-frame looping animation. And at only 3.125 fps even IE can manage to display it at the correct speed!