20260622 - making a music video in TempleOS

TempleOS is one of the most beautiful creations I have interacted with. I don't know much about operating system design but I do know that every minute I spend programming in TempleOS heals my soul ever so slightly. It's exactly as useful and powerful as an operating system should be. Give it a try!

This blog post documents the incredibly fried workflow I developed to build a music video in TempleOS for my band Josephine's Next Million Miles. It took about a year and a half from conceptualization to completion (off and on working most of the time but a pretty solid month and a half long grind at the end).

DISCLAIMER! I find great pleasure in time-consuming, tedious processes and I made this music video in a slow, inefficient and bespoke manner. If you are trying to make something similar, it would probably not serve you well to try to exactly recreate my process. The source code is provided with the caveat that it is probably only useful for your curious perusal.

source code

music video


intro

In fall 2024, after years of watching clips of Terry Davis on youtube, and feeling his influence shake through the internet, I decided to give TempleOS a try. I'd read that there was a generative hymn program in the operating system and I wanted to hear it in action. After not being able to get sound out of qemu on my mac, this interest also spurred me to finally install debian (thank god) and emulate TempleOS from there. The hymn program was cool, but it was the graphics that really won me over: the simple colors, shimmery dithering, embedded 3D assets and clever demo programs.

I watched every TempleOS tutorial I could find and started trying to program some basic test programs (rectangles moving around, sprites rotating, etc). I found HolyC to be quite easy to pick up in comparison to other programming paradigms. I'm not an incredibly experienced programmer and I often find that the more abstractions there are, the more my head begins to spin. Looking through a high level API like JUCE is such a miserable experience. In TempleOS, the autocomplete menu can take you to the source code of any function you type, and a quick execution of the Find function will show you every place it is used in the OS. So simple!

Around this time I also got really into watching Commodore 64 demos. I knew Terry had been inspired by C64 and demoscene when building his OS so I wondered if there was any equivalent scene of TempleOS "demos". A slightly underwhelming search on youtube led me to a few videos, but what really caught my eye were a few music video style demos by Alec Murphy and Austin Sierra. Both of their demos combined TempleOS graphics library animations with imported video/image assets. The Commodore 64 has incredibly limited memory which prevents the would-be demo-writer from importing full animations (or even just a few bitmap frames). This has led the demo scene to create tons of genius tricks, going far beyond the initial bounds of the C64 to make some truly transcendent visuals. Limitation breeds creativity of course. But it's not the 80's anymore. Is it so wrong to use the memory at your disposal in TempleOS? Alec and Austin's demos combine the aesthetics of classic demos with the offerings of modern hardware in a fried computational amalgamation that feels so fitting for the 2020s. In our current technological hellscape, pretending there is still a possibility of some pure computational existence like the C64 feels at best idealistic and at worst reactionary.

These demos also gave me the idea that I could make a music video for my band in TempleOS. I'd been thinking about making a demo-style video for us, but we make rock band music so I would want the video to not be 100% programmed; it was important that we include real footage of the band rocking out so that one day a screengrab could be placed on the cover of Rolling Stone magazine. In addition to demoscene I was inspired by music videos from some of my favorite 00's indie bands: The Go Team, Tummy Toast, 17 Colorful Feathers and one particular Yacht fan video. These videos featured bright colors, basic geometries and simple animations. With a 4-bit color pallette, a graphics library of shape primitives and the aforementioned ability to import images, TempleOS would be the perfect system for this; no need to debase myself by using depressing tools like p5.js or TouchDesigner!

At this point, I realized the video I was starting to conceptualize was at the limits of my skill level. I didn't even know how to import files into TempleOS yet, and I had no idea how I was going to structure the code for a full timeline of the video (a big long switch statement??). I identified two main processes I would need in the music video and decided to prototype them as background visuals for a show we were scheduled to play in spring 2025.

  1. the ability to play a sequence of images as a video
  2. a collection of generative visuals to play behind the images

From the TempleOS demos I'd watched on youtube, I hated the way full imported frames looked, but loved when small imported assets were layered with TempleOS graphics, meaning I would need to make heavy use of greenscreen footage. For my tests I found this video of a girl dancing on youtube. It was perfect because she had exaggerated dance moves, an outfit with simple blocky colors that would look good in TempleOS and the greenscreen behind her was evenly lit so I wouldn't need to worry about finetuning greenscreen settings. I wrote a quick script that used ffmpeg to extract frames from the video as bitmaps and ImageMagick to key out the green, leaving a transparent background.

After a brief perusal of Austin Sierra's Moses Staff program, I thought there must be a better way to get files into TempleOS. I joined a TempleOS discord server (which I was subsequently kicked from twice for inactivity, sorry!) and gathered that Aiwnios was the way to go. I really don't understand what Aiwnios is, but for my purposes, it was just an alternate version of TempleOS that had access to the parent OS's filesystem so I could easily pack a folder of .bmps as a TempleOS compatible ISO, which I could then mount when I booted the vm. It worked perfectly! This workflow combined with Terry's FileBMP.HC script (if i remember correctly, I had to modify this script to properly import transparency) located in TOS_Supplemental1.ISO.C meant I was able to import BMPs, convert them to device contexts (DCs are essentially the TempleOS graphics library's canvas element) and draw them to the screen! Combine this with a few simple background graphic programs I wrote and I had some exciting visuals coming together. For the show, I had this short video play on loop randomizing its framerate and frameskip every few seconds and also randomly swapping between a few generative backgrounds.

I did run into my first problem here though, which was that importing BMPs to TempleOS is really slow. If I exported 20 frames per second from this 27 second video, I ended up with over 500 frames which took several minutes to import. I was importing the frames every time I ran the program which gave me a sizeable slowdown every time I wanted to change, test, or debug it. A smart person may have found some way to optimize FileBMP.HC or store the CDCs on disk after importing them once, but I am no smart person. Instead, I wrote a script to import the images and store them in kernel memory (by pressing shift+f5 to run the script on the Adam task), which would allow any program to access these variables until I rebooted the system. This meant I would need to run the import script just once per work session and I had the flexibility to change the assets I was working with by simply mounting a different ISO rather than copying/deleting files from my TempleOS disk. This is a process I stuck with through the entire music video process (though I quickly abandoned 20fps video assets, downsampling instead to 6 or 8). By the end of the video it would take about 15 minutes to load all of my assets which became a nice forced break to think and ponder my life decisions whenever I crashed the system.

With the success of these initial explorations, I could start thinking about piecing together a full music video. A really important thing was for the video to have structure. Random video frames and swapping backgrounds was fine for live show visuals but wouldn't cut it for a video. I needed a timeline. The other thing I needed was a workflow for editing the video that wouldn't make me miserable. Up until now I had done everything with simple code structures. I typed the filepaths to the images I wanted to import and organized everything in one script with a lot of conditionals. When I started working with dozens of video clips and backgrounds, this would become untenable. But first...


filming

In December 2025, we were close to finishing our album. Next Million Miles was one of the few tracks that wasn't finished yet. Despite this, I really wanted to film footage for the video. We made some vague plans for the video. Each of us was to wear a blocky single color focused outfit, driven by a fashion moodboard Cathryn created referencing mod fashion, Trainspotting, etc. I had a few things I wanted to record (powershots of us playing instruments, dancing), but for the most part we would just feel it out. In my living room I set up a cloth greenscreen I had ordered from ebay and taped printer paper cones in front of two lightbulbs to act as diffusers, unsuccessfully trying to get a somewhat even luminance across the greenscreen. We played the demo on loop and filmed whatever we could think of all day.

Even while filming the footage, I knew it was going to be difficult to work with. Dark spots on the greenscreen, an unfortunately teal-colored guitar and plenty of shots where the frame turned outside of the greenscreen entirely meant it was going to be difficult to key the backgrounds out. I also didn't know what any of this footage would look like when imported into TempleOS.

The greenscreen script I had used before worked fine for uniform backgrounds but it was going to be hard to finetune for every video clip (each had slightly different hues and luminances in the background as the sun shining in through my living room's window shifted). A brief exploration of Fred's ImageMagick Scripts proved a bit more promising, but even his genius scripting wasn't enough to overcome my poor lighting. The workflow I wound up using was:

  1. key out the background in Final Cut Pro (this allowed me to customize the keying for each individual clip, covering as much of the background as possible)
  2. place a solid green background on the video and export it
  3. split video into individual frames with ffmpeg (sample at 6 or 8 fps)
  4. key out this solid green background with Fred's greenscreen script

The final result was a fairly well keyed clip with just a few issues.

  1. Fred's script is a little aggressive with feathering the edges of the image, which I probably could have fixed by messing with its settings but I never got around to doing this.
  2. Some clips were so poorly lit that even final cut's keying couldn't solve it, and additionally there were still some clips where the frame went past the greenscreen's edges. For these clips (probably 25% of the total frames used in the MV), I had to go through and manually cut the backgrounds frame-by-frame.


petscii converter

Looking at the converted video frames, I realized a lot of them looked pretty bad. The lighting was poor and the borders had been made blobby and inconsistent by the keying. None of the simple beauty of the C64 demos I loved was in sight. I decided to take a page out of the C64 handbook and convert the images to a PETSCII (C64's characterset) representation. I found a tool to handle this conversion and modified it to match the TempleOS color palette, screen dimensions and also allow for transparency. The converter would output the converted an image as a png and also as a binary representation of the PETSCII characters needed to represent the image, both of which I used at different points in the video. By importing the png directly, I was able to simplify my code a bit and also easily apply TempleOS's dithering to the PETSCII images, which made them feel more at home in TempleOS.


timeline workflow

The time had come to start assembling the video. Having recently written a Standard MIDI File parser I hoped to create a similar format: a discrete list of events with some number of parameters describing the event and time information for placing it on a timeline. Another thing I liked about MIDI was the MIDI clock, which describes the timing of events in terms of some number of pulses per quarter note rather than in minutes or seconds. Working with seconds was off the table for me. TempleOS doesn't have audio file playing capabilities. Rather than spending time building a WAV player, I would just load up the song on a second laptop and press play on the video and audio file at the same time. This meant that scrubbing through audio to arbitrary places in the video wasn't possible. I planned on plotting and programming the video by referencing time codes in the ableton project for the song. Ableton lists events in terms of measure number, beat number (1-4) and sixteenth number (1-4). I would place events according to these numbers and at the beginning of my video player script I would prompt myself to enter the starting time to jump to, allowing me to edit/watch/listen anywhere along the timeline.

The timeline format I decided on was a CSV file where each row represented an event. Each field described something about the event. This format was nice because it allowed me to easily add or modify events with scripts but also manually edit the timeline with a text editor when needed. As the complexity of the progress increased, I wound up having three CSV timelines running in parallel:

  1. images/videos
  2. text
  3. "custom processes", which were backgrounds or effects that had some amount of custom code needed
In addition to the CSVs themselves I had scripts for parsing them for the main music video program, sorting events based on start time (my first time actually needing to write a sorting algorithm!), and adding events.

As an example, the fields of the text timeline script looked like this:

start measure start beat start sixteenth end measure end beat end sixteenth x position y position layer text color string text size

The image/video script had significantly more fields, which meant that entering events into the csv manually was very time consuming. I created a script that would allow me to add events to the csv using the most enlightened UX paradigm: the questionnaire.

I made separate questionnaire scripts for adding images, videos, text and custom events. My main workflow for assembling the timeline would be to plot out the video on paper by referencing the ableton project's timestamp's and writing down which clips/backgrounds/etc I wanted to appear at certain times. Then I would add these events to the CSV using the scripts and by manually editing the CSV, whichever would be faster for the events I was adding. Periodically I would run a quicksort script to keep the events of the CSV in order so I wouldn't get lost while editing.


Custom Events

Beyond the placement of images/videos, I wanted some of the graphics in the video to be more computational. The custom events CSV timeline file would sequence out a series of calls to external scripts that would draw something onto one of the layers of the music video.

The scripts can be seen throughout the video, handling the intro, outro (which is just a modified version of one of Terry's games), background visuals and the pixelation and circle overlay effects. One of the more interesting visuals was one I called flaps_bg. I wanted to create the visual of pieces of paper tied to a clothesline flapping up and down in the wind. To do this, I just had to draw a grid of rectangles and apply a different rotation matrix to each of them (TempleOS has a great collection of functions built in for projecting 3D rotation onto a 2D plane, essentially allowing you to create 3D graphics without needing to be bogged down by a full 3D engine). I ended up making it a little crazier by cycling colors and rectangle sizes and set the rotations to be controlled by a few sine wave functions.


animation

There was one sequence in the video that I couldn't think of any way to achieve programmatically, and so I decided to do it the old fashioned way and animate it frame by frame! Not knowing how to use any animation software, I ended up adopting a workflow in Krita where I created a layer group for each frame and enabled each group sequentially as I drew, leaving the previous frame's group enabled with 20% opacity. The images were drawn with the TempleOS color palette and I scribbled white onto most solid sections so that they would look more textured when I converted the results to petscii. I have immense respect for real animators now. This fairly simple sequence of ~100 frames took me an entire weekend to finish.

Ultimately I captured the video by screenrecording it in realtime. The video ran just fine on its own but screenrecording with ffmpeg was too much for my i5 processor so I ended up recording it on my friend Matthew's computer which ran it just fine! The default encoding on CachyOS's screen recorder wasn't perfect, it definitely makes the video less crisp but given most people are watching the video on youtube or instagram there's really no getting around that. It would have been cool to figure out a way to export the video as a sequence of BMPs so I would have more control over encoder settings.


thoughts

This post doesn't go too deep into the software development as it wouldn't be terribly interesting to the average reader (if you are interested, check out the source code or shoot me an email!), however I found the process both incredibly interesting and joyful. Tasks like parsing through TempleOS's source to try to figure out how to navigate the filesystem, or editing Terry's BMP importer script feel like dipping your feet into a clear mountain stream in comparison to the bleak overstimulating world of stackoverflow and claude that many people find themselves inhabiting. I'm pretty confident in saying this is the first proper TempleOS music video made by a musician for their own music (ie not a cover etc, shoutout Austin Sierra's sick videos though!!) and I'm hopeful it won't be the last!


Rest In Peace Terry A Davis (1969-2018)