#!/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