echolevel
banner
echolevel.co.uk
echolevel
@echolevel.co.uk
Brendan O'Callaghan Ratliff - Audio Director/Coder, Sound Designer & Composer at Cardboard Sword Games • Film Sound • BBC radio drama • Irish traditional music • chiptune/demoscene stuff as Syphus^UpRough

https://echolevel.co.uk
Yeah, it's been a wild ride! I think the people who care most about them are audio programmers and high frequency trading algo programmers, and at least my trial-and-error worst case is "music go weird" rather than "I just lost $12m whoops"
November 4, 2025 at 11:26 AM
Honestly, I still couldn't explain every memory_order option if my life depended on it, but at least I've learnt that if my writer uses release and my reader uses acquire, I'll probably be ok on ARM. And I'll still be ok on x86, which doesn't seem to give a fuck.

I told you it was boring.
November 2, 2025 at 8:31 PM
to a) hold an atomic state struct per buffer reader that was trivially copyable and b) use the *correct* std::memory_order args when updating its PCM pointer or ready flag. Ptrs/flags/vars in the reader now can't be touched out of sequence and can't become stale. All my stolen notes, returned.
November 2, 2025 at 8:31 PM
code is very defensively written. Basically the state of a voice's buffer reader was subject to tearing which could (safely!) invalidate a note right after it was triggered (hence the dropped notes) and/or load a stale start-offset position to the note (hence the wonky breakbeats). The solution was
November 2, 2025 at 8:31 PM
arguments implied on my atomic load()s and store()s, I was...sloppy. ARM, however, is not interested in giving you a safety net. Poorly thought-out atomic operations by idiots like me result in values not being what you expect, when you expect, and no errors will be thrown - especially if your
November 2, 2025 at 8:31 PM
...has probably worked it out. x86 doesn't give much of a fuck about atomic read/write order because it can always see entire state across all cores, and knows which order things should be done in - it lets you get away with being sloppy. And because I didn't *truly* understand what the memory order
November 2, 2025 at 8:31 PM
One notable waste of time was my trying to demand at init time that the audio thread be constrained to a single core, or just two, because I could see that my buffer callbacks were alternating between 3, 4 and 5. But that isn't respected on this platform, so nope. Anyone who's stuck this far...
November 2, 2025 at 8:31 PM
Now, I'm not a *complete* idiot so of course I'd been thinking about thread/core migration, but UE does plenty of this on x86 to the 'audio thread' as far as I can tell - the audio thread isn't really a sacrosanct thing in terms of absolute thread ID, and can jump around. But this worked fine on x86
November 2, 2025 at 8:31 PM
for months and *could not* work out why it only happened on ARM. All of my songs in our current game average 3% of my audio CPU budget on Windows/x86, and on the target platform they never went above 4%. FPS dips are rare on this game, but they didn't coincide. So it's not resource pressure.
November 2, 2025 at 8:31 PM
THIS bug tho... An instrument might go silent 1 note in 16, or maybe once every 30secs it starts at the wrong sample offset. Forgivable with a looping pad, but a disaster with a breakbeat chop. The note played, no error there. And the buffer was producing PCM, fine. I came back to this over and over
November 2, 2025 at 8:31 PM
it's easy to use all the oldschool tracker tricks to do wild stuff efficiently without CPU ballooning out of control. So when a buffer pointer is wrong, or dies, or the channel stack goes out of sync or w/e, it's really easy to know why. Asserts are fired, logs blow up, klaxons wail etc.
November 2, 2025 at 8:31 PM
I now have my own from-scratch SampleVoice instrument with its own buffer reader, which is fundamental to Metron and how I manage perf + poly with an iron fist. Each tracker channel has a voice, and new notes swap in the buffer ptr of their assigned instrument on the fly, so polyphony is global and
November 2, 2025 at 8:31 PM
The UE5 version of Metron is currently self-contained within a SynthComponent; it does all its DSP in the SC's buffer callback and also processes music data on the audio thread so it can segment the buffer for extremely tight timing (similar to Quartz, but PPQN-accurate rather than sample-accurate).
November 2, 2025 at 8:31 PM
Really profoundly dull. I'm split between "maybe it'll help someone else" and "anyone interested enough to read the explanation will probably guess it straight off anyway, and I'm just proving what an idiot I spent 6 months being". Maybe you've already guessed, just from me saying "only on ARM".
November 2, 2025 at 8:31 PM
*Battle* bongos, though. Battle bongos.
October 31, 2025 at 1:08 PM
If it was good enough for Mr. Preset, it's good enough for me
October 24, 2025 at 3:25 PM
I feel it. Y/day I pushed a build with a mix that I can't change, then today I wrote a new soft-clip algo, and now my compression sounds nicer and the build sounds worse, and nobody will ever know except me. And they'll listen to it on yoghurt pots. But god damn it, I have standards (j/k, I don't)
October 24, 2025 at 3:19 PM
Wait til you hear what some people are listening to your mixes through - fuckin bluetooth speakers, yoghurt pots on bits of string, Beats by Dre. If you can make your mix sound anything other than shite, it'll be the best thing they've ever heard.
October 24, 2025 at 3:00 PM
Genderless address in this house: lads; boys; boysohboys; good man; man
Gendered address in this house: lad; boy; bad man
October 24, 2025 at 1:41 PM
At this point I'm like "if it wasn't plugged in already, did I even need it?" and then I sell it and it's someone else's problem.
October 1, 2025 at 1:13 PM
Ideally you'd turn up in a balaclava, Jacquard loom-woven with a QR code pattern that audience members can scan to listen to your Strudel jam, or not scan if they'd rather imagine it in contemplative silence, while you stand there as an impassive receptacle for their projected emotions.
September 26, 2025 at 12:53 PM
Thanks!

Strudel - I've seen a few vids floating around, yeah! Not had time to try it, but it did remind me of the time I wrote a livecoding language so I could play an algorave set and then never touched it again. It was fairly shit, and in Java! Doing one in the browser (and properly) is very wise
September 26, 2025 at 12:45 PM