anyone know of any audio sizecoding tricks/blogs about the topic

curious if there are any microscopic formulas for generating a kick, snare, etc

@SuricrasiaOnline Hmm, just looking at it, you may be able to do pretty well by just adjusting the amplitude of a sine waveform by an exponential dropoff over time, if you were to add a bit of noise, you could probably start getting fairly close 🤔

Though the one complication depends on if it has multiple frequencies it vibrates at: even then we imagine you can probably sizecode it to something reasonable.

@SuricrasiaOnline the music-dsp mailing list has a website of algorithms and code snippets which might qualify?

Clever stuff I've seen in the audio domain is usually about efficiency, not necessarily terse code size. Like the magic circle algorithm, for producing a sine wave signal using only 2 adds and 2 multiplies:

@SuricrasiaOnline I was just making some kicks/snares/hihats from scratch for this synthwave track. Could be fun to try and build terse versions of them in C at some point.

@SuricrasiaOnline I got no idea what will actually save space coding-wise, but if I was doing an extremely minimal kick sample, I'd start witth the sine wave at peak amplitude and then decreasing the amplitude so there's a very noticable "klick" at the start.

@SuricrasiaOnline karplus-strong can be implemented in a relatively small amount of space I think? it still needs a lowpass filter and an RNG though.

also a periodic sin(1/x) for x>0 (I think??) can be used as a lazy way to make a kick

line noise 

@SuricrasiaOnline I couldn't resist:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define SR 44100
#define FLT float
FLT ph(FLT p,FLT f){p+=f/SR;while (p >= 1.0) p--;return p;}FLT sn(FLT p){return sin(p * 2 * M_PI);}FLT cb(FLT x){return x*x*x;}FLT sc(FLT x,FLT mn,FLT mx){return x*(mx-mn)+mn;}FLT dv(FLT x,FLT d){if(x > d)return 1;else return x/d;}FLT ns(void){return rand() / (FLT)RAND_MAX;}FLT cd(FLT x, int d){return fmod(x * d, 1.0);}FLT gt(FLT x, int s, int m){int p;p = floor(x * s);return((1<<p)&m)>0;}FLT hp(FLT x, FLT *y, FLT c){FLT o;*y=o=c*((*y) + x);*y=o-x;return o;}int main(int argc, char *argv[]){unsigned long n;FLT i;FLT t;FLT m;FLT p;FLT f;FLT y;t=0;i=1.0/SR;n=0;p=0;m=0;f=2.0-cos(8000*2*M_PI*i);f=f-sqrt(f*f-1.0);y=0;while(t<10){FLT o,c,d;t=n * i;m=ph(m, 0.5);c=cd(m, 4);d=cd(m, 16);p=ph(p, sc(cb(1-dv(c,0.1)),60,500));o=sn(p)*cb(1-c)*gt(m,4,0xF);o+= sc(ns(),-1,1)*cb(1-dv(c, 0.9))*gt(m,4,0xa);o+= hp(sc(ns(),-1,1)*cb(1-dv(d, 0.3)), &y, f);o*= 0.3;n++;fwrite(&o,sizeof(FLT),1,stdout);}return 0;}

use with SoX:

./a.out | sox -t raw -r 44100 -c 1 -e floating-point -b 32 - out.wav

@SuricrasiaOnline i think probably max flexibility with smallest code/data size would be a directed graph of a few extremely basic nodes that implement functions like filtering/delay (allpass), mixing etc. then you could define the structures of these graphs as some small constant strings with a 'grammar' which is parsed to find out which sequence of very basic DSP operations to call


@SuricrasiaOnline also possibly relevant, Faust is a very succinct audio DSL which compiles to just about anything

Sign in to participate in the conversation

cybrespace: the social hub of the information superhighway jack in to the mastodon fediverse today and surf the dataflow through our cybrepunk, slightly glitchy web portal support us on patreon or liberapay!