Alright, I hummed and hawed too much about this. I wrote a trivial sndfile ecl lisp snippet. It's just one screen of lisp that's mostly one of the sndfile examples. My dream is that someone else could also try playing with it (as trivial sound making goes). So I will talk about dependencies, download the lisp files, building it, and an example synth program which I will also inline here. I'm on openbsd, so please divine this into your own package manager: pkg_add ecl libsndfile mpv lynx I am just using system calls to mpv to play the notes, and lynx to download the lisp. Ecl is the compiler, and libsndfile is libsndfile. Now I'm going to use shell to download some text files (ecl lisp source) using lynx. ```ksh mkdir conspiracy # it's named conspiracy. cd conspiracy lynx gopher://gopher.club/0/users/screwtape/conspiracy/build.ecl -dump \ > build.ecl lynx gopher://gopher.club/0/users/screwtape/conspiracy/conspiracy.ecl \ -dump > conspiracy.ecl lynx gopher://gopher.club/0/users/screwtape/conspiracy/foo.syn \ -dump > foo.syn # example mkdir notes # note wavs will go into here. ``` At this juncture, you should probably lay eyes on what's in each of those files so you know I'm not virusing you ;p. They're not very big. For portability there's no pledge or unveil. ```ksh ecl --load build.ecl ## This builds an executable named sine ./sine --load foo.syn ``` foo.syn is actually just another lisp file that uses the conspiracy.ecl built into ./sine. The mechanism, which sucks and is slow but is extremely general is to redefun the functions #'left-fun and #'right-fun (float) -> float then call (my-get-note "note-file-name" float-duration) -> lambda that makes a system call to mpv to play the note. So a "syn" lisp (or just in ./sine's repl) is like ```foo.syn (defun left-fun (float) (values (apply (make-sine 440) `(,float)))) (defun right-fun (float) (values (apply (make-sine 660) `(,float)))) (setq *lambda-1* (my-get-note "test-note-1" 1.2)) (funcall *lambda-1*) (defun left-fun (float) (values (apply (make-sine 110) `(,float)))) (defun right-fun (float) (values (apply (make-sine 55) `(,float)))) (setq *lambda-2* (my-get-note "test-note-2" 3.6)) (funcall *lambda-2*) (funcall *lambda-1*) (funcall *lambda-2*) ``` (ecl) async repeating can be like (setq *process* (mp:process-run-function 'example (lambda () (loop for x below 10 do (sleep 1) do (funcall *lambda-2*))))) (mp:process-join *process*) But I don't want to complicate things more here.