Very excited for NEC (ugh, web link)

http://anonradio.net/code-battle-zone/

which I believe our underground poet gef is hosting on Christmas, UTC. NEC = Noise, Electronics and Code; three things close to my heart and fingertips.

My travel laptop wasn't intended for much other than browsing gopher and lispy gopher show recordings! I have portable access to a raw audio device through mpv like this:

mpv --demuxer=rawaudio \\
   --demuxer-rawaudio-format=u8 \\
   --demuxer-rawaudio-rate=44100

mpv knows about this linux, and can ask it for sound configuration and then just pass through raw bytes. (on this device pragmatically raw bytes are in fact raw bytes but could be s24le or the default s16le).

I can fork and exec mpv to configure and pass through audio in ecl like this:

(setf
   (symbol-function 'out)
   (multiple-value-bind
         (streams ret process)
       (ext:run-program
        "mpv"
        '("--demuxer=rawaudio"
          "--demuxer-rawaudio-format=u8"
          "--demuxer-rawaudio-rate=44100"
          "-")
        :wait nil)
     (lambda ()
       (two-way-stream-output-stream streams))))

after which a call to the closure (out) returns a useful output stream.

I also need somewhere for data:

(setq *io*
        (open ,file
              :direction
              :io))

Common lisp doesn't provide in-memory bivalent streams, so a buffer is used (in a higher performance context I think that buffer could sit in a ramdisk or something).

I packaged that along with a frequency -> closure and closure composer at

gopher://gopher.club/0/users/tfw/ecl-mpv.lisp

If you don't have access to anything except mpv and ecl like me this is a bare-bones way to drive raw audio from a single (seekable) bivalent stream and raw output stream!

If you are less resource-starved lots of damgud cyberchatters (gef, ldbeth, froggyme, arf, gerbilfat, unimagine, iiogama, mhcat, and many more) can help with puredata, orca, cl-music and lots of things I don't know. zdrmonster knows the retro [lib-] adlib.