Skip to content

Instantly share code, notes, and snippets.

tracin' rays

Alex Evans mmalex

tracin' rays
View GitHub Profile
View bbo4lpzw.txt
bbo notes
this is literally just the first time I've got the module compiling, so it's not any way 'done' its just 'a step closer', but at least I can send you a hex file now.
theres gonna be teething trouble coz Ive not tried a lot of this before!
but heres what I think:
to program it, you can use stm32cubeprogrammer, (or the ide), that you can get from
you can either use DFU mode where you disconnect it from euro power, and plug a USB A<->USB A cable in to it. as it powers up, you may need to short JP1 which forces it into ST's DFU bootrom, windows should detect the USB device and stm32cube programmer should let you flash it via DFU mode. (I havent tried this yet, but will).
mmalex / allpasstest.cpp
Created Mar 4, 2020
quick timing test of different ways of writing a chain of serial allpasses
View allpasstest.cpp
#include "stdafx.h"
#include <Windows.h> // for performance counter
// quick test of the theory in
// we try running a simple impulse train (click every 4096 samples) through 6 allpasses with random lengths
// we time how long it takes to process 1 million samples, structuring the loop 3 ways:
// - a sample at a time with self contained allpass structures,
// - a sample at a time with a single big buffer
// - a block at a time using self contained allpass structures, operating in place on a 256 sample buffer.
// using this naive code, on a single core of my AMD threadripper, with default release compile settings on visual studio 2015,
// I see
mmalex /
Last active Mar 17, 2021
optimising allpass reverbs by using a single shared buffer

TLDR: if you've got a bunch of delays in series, for example all-pass filters in a reverb, put them all in a single big buffer and let them crawl over each other for a perf win!

recently I was fiddling around with my hobby reverb code, in preparation for porting it onto a smaller/slower CPU. I'd implemented a loop-of-allpass filters type reverb, just like everybody else, and indeed, I basically had the classic 'OOP'ish abstraction of an 'allpass' struct that was, say, 313 samples long, and... did an allpass. on its own little float buffer[313]. (well, short integer, not float, but thats not relevant) I'll write out the code in a moment.

but then I was browsing the internet one night, as you do, and stumbled on this old post by Sean Costello of Valhalla DSP fame - noting the sad passing of Alesis founder and general all-round DSP legend, Keith Barr.

It's worth a read just for his wonderful anecdote about the birth of the midiverb - which spawned the thou

View midi2osc.cpp
quick midi 2 osc hack by @mmalex, use at your own risk etc
reads midi messages, forward them to osc messages on your network.
barely tested but works for me in windows 7, compiled with msvc 2015 sp2
stick a midi2osc.ini file in the same folder as the exe to configure it, with lines like these:
mmalex / base85_test.cpp
Created Jul 28, 2015
example for @ocornut of encoding groggy clean as a base85 string
View base85_test.cpp
const char *font_85 =
View gist:7917083
the redis feedback thread has been interesting, and I share many of antirez's 'tastes' when it comes to wanting to create pragmatic software that is 'robust enough' for many use cases. OTOH I do think that redis is in an interesting place regarding how its users view (and potentially misinterpret) its data 'promises' , especially in cluster
I just wanted to give an example in case it is a useful datapoint in the spectrum being discussed for redis (pure memory store vs evolving into a disk cluster that might or might not make CP claims...)
TL;DR difference from redis cluster: I basically wanted not to have the distinction of master vs slave, and all the complexity that brings (having to do elections, split brain, etc) and instead build everything around merging between symmetrical peers - ie every node is equal, and they merge their differences on (re)connection. I think it's a really powerful paradigm, and not one that I've seen antirez talk much about with respect to redis. if you're interested in
View gist:7663290
// sillycocg.cpp : disgusting test code. loads a 320x180 rgb image from input.raw
// writes out a (fixed) photoshop-style 3 bytes per index palette file to ycocg.act
// you can load this in photoshop via image/mode/index then image/mode/color-table.../load...
// then it writes out an 8bpp indexed image to output.raw
// its kinda a hindsight is 2020 thing, the old 'fake truecolor' demos that did RGB stripes/
// patterns - I wondered what it would be like to do something like
// but 15 years ago in 256 color mode, so you compute 2 channels per pixel instead of 3,
// and those channels are Y and one of Co or Cg; then you alternate Co/Cg in a checkerboard
// and pack 4 bits y, 3 bits chroma, 1 bit checkerboard switch.
mmalex / gist:2660905
Created May 11, 2012
notes on symmetric 3x3 matrix maths
View gist:2660905
// symmetric matrix stuff
// not heavily tested but should be about right
// hlsl notation
// thanks to @rygorous @m1k3 and mark adami for help
// mostly just a big geek out :)
// multiply e by the 3x3 symmetric 3x3 matrix fromed from d on the diagonal and u in the upper triangle
float3 mul_sym3x3(float3 d, float3 u, float3 e)
return float3(dot(e,float3(d.x,u.z,u.y)), // u=(yz,xz,xy) in the case of covariance matrix
mmalex / gist:1219860
Created Sep 15, 2011
untest implementation of @deplinenoise's amiga checksum
View gist:1219860
#include <stdio.h>
#include <arpa/inet.h> // for htonl
int main(int argc, char **argv){
unsigned int c=0,d,i,block[256]={0};
for (i=0;i<256;++i)
if (c > (d=c+htonl(block[i]))) c=d+1; else c=d;
return 0;
mmalex / pngencode.cpp
Created Apr 7, 2011 — forked from anonymous/pngencode.cpp
bug fix png encoder
View pngencode.cpp
// by alex evans, 2011. released into the public domain.
// based on a first ever reading of the png spec, it occurs to me that a minimal png encoder should be quite simple.
// this is a first stab - may be buggy! the only external dependency is zlib and some basic typedefs (u32, u8)
// VERSION 0.02! now using zlib's crc rather than my own, and avoiding a memcpy and memory scribbler in the old one
// by passing the zero byte at the start of the scanline to zlib first, then the original scanline in place. WIN!
// more context at
// follow me on twitter @mmalex