Skip to content

Instantly share code, notes, and snippets.

@paniq
Last active November 5, 2024 18:26
Show Gist options
  • Save paniq/942b4aa2b89b2e312037d06ad44a4115 to your computer and use it in GitHub Desktop.
Save paniq/942b4aa2b89b2e312037d06ad44a4115 to your computer and use it in GitHub Desktop.
printf = dlimport 'printf
printf-type = fntype auto s32 ptr
printf_ = vatype printf-type
printf_ptr = vatype printf-type ptr
printf_s32 = vatype printf-type s32
printf_u32 = vatype printf-type u32
printf_u64 = vatype printf-type u64
printf_s32_s32 = vatype printf-type s32 s32
printf_s32_s32_s32 = vatype printf-type s32 s32 s32
printf_u64_s32 = vatype printf-type u64 s32
printf_s32_u64 = vatype printf-type s32 u64
printf_s32_u16_u8_u16 = vatype printf-type s32 u16 u8 u16
export = proc symbol function-type source :
__replace = SYMINFO
FUNC function-type source 'return
symbol
int = s32
void* = ptr
char* = ptr
float* = ptr
size_t = u64
SDL_AudioDeviceID = u32
#void * memset ( void * ptr, int value, size_t num );
T_memset = fntype auto void* void* int size_t
memset = dlimport 'memset
#void *malloc( size_t size );
T_malloc = fntype auto void* size_t
malloc = dlimport 'malloc
pi = 3.1415927
tau = fmul pi 2.0
smod = proc a b :
__replace = srem (iadd b (srem a b)) b
fmod = proc a b :
__replace = frem (fadd b (frem a b)) b
range = proc N :
i = (case (ine N 0:usize) true) ? loop 0:usize
i1 = iadd i 1:usize
i_last = case (ult i1 N) false
i_repeat = i_last ! repeat i i1
i_last ? repeat i (UNDEF 4)
# sndfile.h
#
struct SF_INFO
{ sf_count_t frames ; /* Used to be called samples. Changed to avoid confusion. */
int samplerate ;
int channels ;
int format ;
int sections ;
int seekable ;
} ;
SF_INFO = 32:usize
SF_INFO.frames = 0:usize # 8
SF_INFO.samplerate = 8:usize # 4
SF_INFO.channels = 12:usize # 4
SF_INFO.format = 16:usize # 4
SF_INFO.sections = 20:usize # 4
SF_INFO.seekable = 24:usize # 4
SNDFILE* = ptr
SF_INFO* = ptr
sf_count_t = s64
SFM_WRITE = 0x20
SF_FORMAT_WAV = 0x010000
SF_FORMAT_PCM_16 = 0x0002
SF_FORMAT_FLOAT = 0x0006
#SNDFILE* sf_open (const char *path, int mode, SF_INFO *sfinfo) ;
T_sf_open = fntype auto SNDFILE* char* int SF_INFO*
sf_open = dlimport 'sf_open
#int sf_close (SNDFILE *sndfile) ;
T_sf_close = fntype auto int SNDFILE*
sf_close = dlimport 'sf_close
#sf_count_t sf_write_float (SNDFILE *sndfile, const float *ptr, sf_count_t items) ;
T_sf_write_float = fntype auto sf_count_t SNDFILE* float* sf_count_t
sf_write_float = dlimport 'sf_write_float
#void sf_write_sync (SNDFILE *sndfile) ;
T_sf_write_sync = fntype auto void SNDFILE*
sf_write_sync = dlimport 'sf_write_sync
#const char* sf_strerror (SNDFILE *sndfile) ;
T_sf_strerror = fntype auto char* SNDFILE*
sf_strerror = dlimport 'sf_strerror
hash = proc x :
x = ixor x (ushr x 16)
x = imul x 0x7feb352d:u32
x = ixor x (ushr x 15)
x = imul x 0x846ca68b:u32
x = ixor x (ushr x 16)
__replace = x
echo = proc s D :
N = imul D 2:usize
SZ = imul N 8:usize
buf = alloc SZ
pcall T_memset memset buf 0 SZ
ppos = alloc 8:usize
store ppos 0:usize
pos = s.l s.r ? load 8 ppos
sofs = imul pos 8:usize
dofs = imul (urem (iadd pos D) N) 8:usize
ldofs = iadd buf dofs
rdofs = iadd ldofs 4:usize
lsofs = iadd buf sofs
rsofs = iadd lsofs 4:usize
l = fmul (load 4 lsofs) 0.9
r = fmul (load 4 rsofs) 0.9
dl = fadd s.l l
dr = fadd s.r r
store ldofs dl
store rdofs dr
store ppos (urem (iadd pos 1:usize) N)
dspmain = proc t :
* = fmul
- = fsub
+ = fadd
% = fmod
/ = fdiv
ntoc = proc x : # 0..1 -> -1..1
__replace = - (* 2.0 x) 1.0
cton = proc x : # -1..1 -> 0..1
__replace = / (+ x 1.0) 2.0
sinosc = proc phase : # -1..1
__replace = sin (* phase tau)
saw = proc phase : # 0..1
__replace = % phase 1.0
sawosc = proc phase : # -1..1
__replace = - (* (% phase 1.0) 2.0) 1.0
octave = proc x :
__replace = exp2 x
bpm = 120.0
beat = / (* t bpm) 60.0
beat = * 4.0 beat
voice = proc idx :
A-4 = 440.0
bar = ftou 4 beat
fidx = utof 4 idx
#beatofs = * fidx (/ 1.0 16.0)
beatofs = * fidx 0.01
beat = + beat beatofs
flip = ntoc (utof 4 (iand idx 1))
freq = fidx
freq = + freq 1.0
bit = ishl 1 idx
#on = case (ieq (iand (hash bar) bit) bit) true
on = case (ieq (iand bar bit) bit) true
nidx = / fidx 7.0
pan = ntoc nidx
pan = * pan flip
pan = * pan nidx
lpan = cton pan
rpan = cton (- 0.0 pan)
vib = + (* (sinosc (* t (+ 7.0 beatofs))) 0.5) 0.5
vib = exp2 (* vib 0.001)
hz = * (+ t vib)
* A-4
freq
s = 0.0
s = + s
sawosc
* hz
octave -2.0
s = + s
sinosc
* hz
octave -1.0
s = * (/ 1.0 16.0)
* s
- 1.0
saw beat
s1 = on ? pass s
s2 = on ! pass 0.0
s = or s1 s2
l = * s lpan
r = * s rpan
silent = proc :
l = 0.0
r = 0.0
mix = proc a b :
l = + a.l b.l
r = + a.r b.r
vmix = proc a b v :
l = + a.l (* b.l v)
r = + a.r (* b.r v)
s = (silent)
s = mix
mix
mix
mix s (voice 0)
mix s (voice 1)
mix
mix s (voice 2)
mix s (voice 3)
mix
mix
mix s (voice 4)
mix s (voice 5)
mix
mix s (voice 6)
mix s (voice 7)
s = vmix s (echo s 400:usize) 0.5
s = vmix s (echo s 6400:usize) 0.5
#old_s = s
#s = echo s
l = s.l
r = s.r
export 'main
fntype auto s32 s32 ptr
proc argc argv :
info = pcall T_malloc malloc SF_INFO
_ = pcall T_memset memset info 0 SF_INFO
info = _ ? pass info
_ = any
store (iadd info SF_INFO.channels) 2
store (iadd info SF_INFO.samplerate) 44100
store (iadd info SF_INFO.format)
ior SF_FORMAT_WAV SF_FORMAT_FLOAT
info = _ ? pass info
handle = pcall T_sf_open sf_open "test.wav" SFM_WRITE info
handle = (case handle 0:u64) ! pass handle
handle ! pcall printf_ptr printf "sf_open() failed: %s\n"
pcall T_sf_strerror sf_strerror null
_ = pcall printf_ptr printf "writing to handle %p\n" handle
# fill buffer
#SAMPLESIZE = 100:usize
SAMPLESIZE = (imul 44100:usize 64:usize)
NUM_SAMPLES = imul SAMPLESIZE 2:usize
SIZEOF_SAMPLES = imul NUM_SAMPLES 4:usize
samples = pcall T_malloc malloc SIZEOF_SAMPLES
r = range SAMPLESIZE
i = _ ? r.i
t = fdiv (utof 4 i) 44100.0
m = dspmain t
ofs = imul i 8:usize
_ = any
store (iadd samples ofs) m.l
store (iadd samples (iadd ofs 4:usize)) m.r
#_ = _ ? pcall printf_u64 printf "i = %llu\n" i
samples = r.i_last ? pass samples
_ = _ r.i_last ? pcall printf_ printf "buffer filled.\n"
_ = _ ? pcall T_sf_write_float sf_write_float handle samples NUM_SAMPLES
res = _
_ = _ ? pcall printf_u64 printf "wrote %llu items\n" res
_ = _ ? pcall T_sf_close sf_close handle
_ = _ ? pcall printf_ printf "handle closed.\n"
return = pass 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment