;;;;This file is a simple port of the libsndfile regaining example. ;;;;ie sfprocess.c (defpackage warm (:export transform *left* *right*) ) ;;;;BUFFER_LEN = 8192 ;;;;CHANNELS = 2 ;;;;So the transforms each act upon an 4096 length list. (in-package warm) (defvar *left* (list)) (defvar *right* (list)) (defvar *left-transformation* (lambda (list) (nreverse list))) (defvar *right-transformation* (lambda (list) (nreverse list))) ;;;These middleman callbacks aren't actually so slow. (defvar pusher* (ffi:defcallback push-channels nil ((left :float) (right :float)) (push left *left*) (push right *right*))) (defvar popleft* (ffi:defcallback pop-left :float () (pop *left*))) (defvar popright* (ffi:defcallback pop-right :float () (pop *right*))) (defvar transformer* (ffi:defcallback transformer nil () (setf *left* (funcall *left-transformation* *left*) *right* (funcall *right-transformation* *right*)))) ;;;headers (ffi:clines " #include #include #include #define BUFFER_LEN 8192 #define MAX_CHANNELS 2 ") (defun transformin (infilename outfilename) " Internal use: Applies the above lambdas. " (ffi:with-cstrings ((cinfilename infilename) (coutfilename outfilename)) (ffi:c-inline (cinfilename coutfilename pusher* transformer* popleft* popright*) (:cstring :cstring :pointer-void :pointer-void :pointer-void :pointer-void) :int " //callbacks // float (* right)(float) = (float (*)(float))#3; void (* pusher)(float, float) = (void (*)(float, float))#2; void (* transformer)() = (void (*)())#3; float (* popleft)() = (float (*)())#4; float (* popright)() = (float (*)())#5; ///callbacks static float data[BUFFER_LEN]; SNDFILE *infile, *outfile; SF_INFO sfinfo; int readcount; const char *infilename = #0; const char *outfilename = #1; memset(&sfinfo, 0, sizeof(sfinfo)); if (! (infile = sf_open(infilename, SFM_READ, &sfinfo))) { printf(\"Not able to open input file %s.\\n\", infilename); puts(sf_strerror(NULL)); @(return)=1; } if (sfinfo.channels > MAX_CHANNELS) { printf(\"Too many channels\\n\"); @(return)=1; } if (! (outfile = sf_open(outfilename, SFM_WRITE, &sfinfo))) { printf(\"Not able to open output file %s.\\n\", outfilename); puts(sf_strerror(NULL)); @(return)=1; } int i; while ((readcount = sf_read_float(infile, data, BUFFER_LEN))) { //Send both channels to lisp-land for (i=0;i