Blog

Some GLSL-Fun

The visualizer video for Moonchild’s “The Other Side” caught me the first time I saw it: calm music, and a scene just as calm, a boat on a night sea under an aurora. I was deep into Shadertoy back then, so I tried to rebuild that scene from techniques I picked up in other shaders. It got somewhere, but never to a state I wanted to publish.

AI-assisted development got me past the point where I had given up, and I could finally finish what I had in mind for that shader. The workflow was fun enough that I went straight on to a second one: an animated version of “imperfection”, an image I once made with generative AI.

Continue reading “Some GLSL-Fun”

go-whistle: Whistle speech-to-text in pure Go, rebuilt from the weights

Whistle is a speech-to-text model from Cactus Compute: 55 million parameters and 16.9 MB on disk, covering seven languages (English, German, French, Spanish, Italian, Dutch and Polish). The weights are published under Apache-2.0, but the code that runs them is not. Upstream, in cactus-compute/needle, Whistle is a thin Python wrapper around a prebuilt, closed-source C++ engine. go-whistle is my pure-Go port: no cgo, no Python, no ONNX. It does transcription with language detection, keyword biasing, word timestamps, live streaming and embeddings, from a CLI, an HTTP/WebSocket server, a Go library, or a WebAssembly page in the browser.

Continue reading “go-whistle: Whistle speech-to-text in pure Go, rebuilt from the weights”

kolibri-llama-cpp: Aleph Alpha’s Kolibri-1 in llama.cpp

Aleph Alpha has released Kolibri-1, a mixture-of-experts language model with 78 billion parameters, of which only about 3.5 billion are active per token. That ratio makes it a candidate for a laptop, yet Aleph Alpha’s own way to run it is a plugin for vLLM, an inference server built for data-centre GPUs. kolibri-llama-cpp brings Kolibri to llama.cpp instead. The goal is a quantized build that runs on a Mac with 48 GB of unified memory and gives the same answers as Aleph Alpha’s reference. Quantized builds already run there, at up to 64 tokens per second.

Continue reading “kolibri-llama-cpp: Aleph Alpha’s Kolibri-1 in llama.cpp”

Pocket-sized speech, in Go

Kyutai’s PocketTTS is a text-to-speech model small enough to run on a CPU. Its reference implementation is Python and PyTorch. go-pocket-tts runs the same model as a single Go binary: it reads the safetensors weights directly and needs neither Python nor ONNX Runtime.

It got one sentence in Audio on Linux, in Go. It deserves more than that, because upstream has moved on since then: a September model, German, a 24-layer variant and a new kind of sampler. This weekend I brought the port up to upstream v3.3.0. That came to 25 pull requests and 116 commits in two days, and German is part of it.

Continue reading “Pocket-sized speech, in Go”

PixelParade: a music video, computed

PixelParade is an 86-second chiptune instrumental generated with Suno: a bright pulse arpeggio in G major at 105 BPM, with a band that comes and goes around it. On Saturday I wanted a music video for it. I left the work to Codex and Claude and tried to give them as few instructions as possible. By the evening there were three. Every frame is computed from the song itself, and nothing in the picture is improvised by a browser FFT at playback time.

Continue reading “PixelParade: a music video, computed”

go-signal: Signal on the command line, in pure Go

I wanted to send and read Signal messages from a script, and let an AI agent do the same, without running a Java runtime next to it. signal-cli is the established tool, but it needs a JVM. So on 25 September I started go-signal, a Signal client for the command line written in Go. It ships as a single static binary for Linux, macOS and Windows, and since the second release it contains no Rust or C either.

Continue reading “go-signal: Signal on the command line, in pure Go”

qmc: evenly spread points for Go

Many programs need random points: to estimate an integral, to sample a parameter space, or to send rays through a room. Random points are easy to make, but they clump and leave gaps. Quasi-Monte Carlo sequences such as Sobol and Halton place points so that they fill the space evenly, and for many problems that gives the same accuracy with far fewer points. qmc is a small Go library for these sequences, with no dependencies. I started it in August and have just given it a thorough review.

Continue reading “qmc: evenly spread points for Go”

go-sofa and go-hdf5: how a head hears, in pure Go

A SOFA file describes how a head hears. SOFA (Spatially Oriented Format for Acoustics, standardised as AES69) stores head-related transfer functions: for hundreds or thousands of directions, the impulse response from a loudspeaker at that direction to a microphone in each ear. With such a set you can place any sound anywhere around a listener on headphones. I wrote my first SOFA reader, PasSofa, in Object Pascal in 2017, and ported it to JavaScript as WebSofa. Now there is go-sofa, which reads and writes SOFA files in pure Go, on top of my fork of a pure-Go HDF5 library, go-hdf5. Both started in February. On the last weekend of September they got about 230 commits and 39,000 added lines. Every figure in this post was made by a Go program that reads the files with go-sofa or go-hdf5.

Continue reading “go-sofa and go-hdf5: how a head hears, in pure Go”

goodix-5120-linux: a fingerprint reader behind the keyboard controller

My Huawei MateBook has a fingerprint reader, a Goodix 27c6:5120. No Linux distribution supports it, so on Ubuntu it was just a button. Now it unlocks sudo and the login screen with a finger, through a libfprint driver I wrote for it: goodix-5120-linux. Getting there involved a dead keyboard, a key hidden in Windows, and a sensor too small for ordinary fingerprint matching.

Continue reading “goodix-5120-linux: a fingerprint reader behind the keyboard controller”