Pattern
A tracker's pattern editor the music writes, for Resolume

What it does
An FFGL source plugin for Resolume Arena and Avenue. A tracker plays a pattern of 64 rows, and how fast the rows go by comes down to two numbers: Speed, in ticks per row, and BPM, where a tick lasts 2.5 / BPM seconds, so at the default Speed of 6 you get four rows to a beat. Each row holds one note per channel: a note name, a sample number and an effect.
FFGL gives a plugin no audio output, only the spectrum of whatever's playing, so Pattern runs the tracker backwards. The row cursor runs on a proper tracker clock, locked to the host's BPM, and the music writes into the pattern. Each channel owns a band of the host's 64-bin spectrum, and an onset in that band writes a note into that channel on the current row. Its pitch is the band's spectral peak through the bin law, its volume is a Cxx effect from how strong the onset was, and its sample number is the channel's.
What comes out is what a tracker does. The cursor steps on the beat because it runs on a clock rather than an animation. A busy passage fills every row and a sparse one leaves dots, because nothing gets written that wasn't heard. After row 3F the cursor wraps and the next pass writes over the last, clearing each row as the cursor enters it, so a change in the arrangement shows up as the old notes being replaced: rows above the cursor are this pass and rows below it are the last one. Each channel's VU bar drops one step every 20 ms, the way a vblank-driven meter does.
The clock's held in double precision and re-anchored whenever the tempo changes, because Resolume's host clock runs into the hundreds of millions of milliseconds and a float phase would skip rows. When the host's tempo is wrong, a Detected tempo source finds the track's BPM from the audio, and since v0.1.1 it reads the beat rather than the half note, landing within one BPM in four seconds on drum grooves from 80 to 170 BPM. Nobody's measured how Resolume lays out its 64 bins, so the layout and value law are controls (Bin Law and Bin Value) rather than guesses buried in the code. It doesn't play MODs, it draws no logos and no tracker's name, and the themes are named by colour.
- A row cursor on the tracker's own clock: Host, Detected or Manual tempo, Speed 1 to 31 ticks a row, Swing, 64 or 32 rows
- Four or eight channels, each owning a band of the host's 64-bin spectrum, with the split under your control
- An onset per band writes a note on the current row: pitch from the peak, volume as a Cxx effect, sample number from the channel
- The ring: each pass overwrites the last, row by row, or Keep Notes holds them
- Bin Law (Linear or Log) and Bin Value (Magnitude or Power) for the host's unmeasured spectrum, and Fold Octaves for pitches outside C-1 to B-3
- Grey, Blue and Green themes, 3 to 33 rows visible, VU bars and effects columns, whole-pixel scaling
- A detected tempo within one BPM in four seconds, at the beat and not the half note, and a clock that holds its row from a host at 499 million milliseconds
- Tempo Out: Send Tempo sets Resolume's composition tempo from the detected one over OSC, with Default BPM and When Lost for when there's nothing to trust, and Hide Screen for when it should only listen
- Universal macOS bundle and a Windows x64 DLL
Where it stands
v0.2.1, and still early days. v0.2.0 added Tempo Out, which sends the tempo Pattern detects to Resolume's composition tempo over OSC, and Hide Screen, which makes the output transparent so it can sit in a composition and just listen. It only sends a tempo it trusts: three readings a second apart have to agree, so the first send comes about six seconds in, and after that it sends a change of half a BPM or more, at most once a second. Resolume needs OSC Input switched on (it's off by default), and the music clip should stay on Timeline transport rather than BPM Sync. v0.2.1 answers the first report from a real rig, where one user had it setting Resolume's tempo and found it slow to follow: a clear change now reaches Resolume in about four seconds, as one message, and the status says HOLD when it isn't sure and OVERRIDDEN when something else has changed the tempo. On my own machines the plugin itself has never sent a tempo to a Resolume. The message it sends was checked in Arena 7.27.1 by sending the same thing from outside the plugin, and its sending is measured against a fake Resolume and byte for byte on a real socket. It hasn't been loaded into Resolume on macOS. On Windows a build of v0.2.1 loads in Arena 7.27.1 on software rendering (no GPU) with all 28 host controls as declared, but that machine has no sound device, so no real audio has reached it in a host of mine. The layout, value law and sample rate of Resolume's 64 bins are assumed, which is what Bin Law, Bin Value and Sensitivity are for, and the onset thresholds and the tempo detector's level ratio were set on synthetic spectra and synthesised tracks. A breakbeat, and an off-beat bass at 80 to 90 BPM, still read at the wrong level. The tracker is measured offline, by a harness driving the real plugin: the row cursor sits on the right row on every frame of six ten-minute runs from a host clock at 499,000,000 ms, where a float phase gets 2,400 of 36,000 frames wrong; a burst in a band writes exactly one note, in the right channel, on the right row; audio already playing when the clip starts writes no false notes; the next pass clears, keeps or overwrites rows as it should; 45 drum grooves from 80 to 170 BPM are detected within 1 BPM by 4.00 s at the right level, where v0.1.0's detector got 15 of them wrong; and every scaled block and probed glyph matches the font table. It catches eight models broken on purpose and a one-character sabotage of its own shader, and all 20 controls that draw change the picture; Send Tempo and OSC Port are measured on the socket instead. It costs 0.041 ms a frame at 720p on macOS, 0.054 at 1080p and 0.128 at 4K. There's a user guide and a browser demo, which is a port rather than the plugin, but no presets and no OpenFX port. The macOS builds are signed and notarised. Try it in your own rig before you trust it in a show.
Watch it running
Nothing loads from YouTube until you press play.Watch it there instead