#!/bin/sh mkdir -p ~/common-lisp/ecl-mpv/ ;; apt install -y ecl mpv rlwrap lynx lynx -dump --dont-wrap-pre - > ~/common-lisp/ecl-mpv/ecl-mpv.asd <<EOG gopher://gopher.club/1/users/tfw/ecl-mpv.asd EOG lynx -dump --dont-wrap-pre - > ~/common-lisp/ecl-mpv/ecl-mpv.lisp <<EOG gopher://gopher.club/1/users/tfw/ecl-mpv.lisp EOG ## The gist here is to use ## mpv --demuxer=rawaudio - ## as a portable virtual (in this case u8) raw device. ## (out) gets the stream to that mpv (exec'd by (getout)) ## *io* is a :direction :io stream backed by your disk ; ## I would just put it on a ramdisk instead if you wanted ## fast speeds. sequential u8s are smol anyhow. rlwrap ecl <<EOG (require 'asdf) (require 'ecl-mpv) (in-package :mpv) (enbuff) ;; setqs *io* (getout) ;; setf symbol-function (out) to mpv virt. dev. (setq *sin* (getsin 44100 300)) ;;; 44100-looping frequency=300Hz sine (for fs=44100) ;;; The meaning of the counter loop limit is debatable (setq *win* (getsin 44100 1)) ;;; 44100-looping frequence=1Hz as above. LFO ;;; Obviously subsonic. ;;; Oh, getsin makes max. '(unsigned-byte 8) outputs. (setq *tyn* (compose *win* *sin*)) ;;;Utility for hadamarding sinusoidal closures into ;;;new closures. ;;;Sound at last (loop repeat (* 6 44100) for byte = (Funcall *tyn*) do (write-byte byte *io*)) ;;;We're using a single bivalent stream *io* ;;goto position 0 and then go along ;;writing bytes to (out) (file-position *io* 0) (loop repeat (1- (file-length *io*)) for byte = (read-byte *io*) do (write-byte byte (out))) ;;;Now we're at the end of the stream, ;; (Check (file-position *io*)) ;;let's add an upward slide. (loop for f from 50 to 350 do (setq *sin* (getsin 4410 f)) do (loop repeat 4410 for byte = (funcall *tyn*) do (write-byte byte *io*))) ;;; Let's play that (defun play () (loop initially (file-position *io* 0) repeat (1- (file-length *io*)) for byte = (read-byte *io*) do (write-byte byte (out)))) (play) (sleep 1) (loop for r = (random (+ -44100 (file-length *io*))) for n from 0 below 300 for d = (random 44100) for m = (* 0.01 (random 100)) do (file-position *io* r) do (loop repeat d for byte = (truncate (* (read-byte *io*) m)) do (write-byte byte (out))) finally (play)) (sleep 1) (loop repeat 20 for m = (* 0.01 (random 50)) for dur = (+ 44100 (random 44100)) do (file-position *io* (- (* 6 44100) 20000)) do (loop repeat dur for byte = (read-byte *io*) do (write-byte (truncate (* m byte)) (out))) finally (play)) EOG