(defun write-note (path period repeats &optional (rampinc 1) &aux (half-period (ash period -1)) (vals (list (1+ 127) (1- 127)))) " write-note args: path - suitable for #'open .. :append / :create period - one wavelength in samples repeats - number of periods to write rampinc - ramp on ramp off increment. rampinc is arbitrarily *0.5'ed at rampoff time. aucat doesn't kerchunk at the end, mpv does. ??? " (with-open-file (out path :direction :output :if-exists :append :if-does-not-exist :create) (loop initially (loop for len below half-period by rampinc do (loop for val in vals do (loop repeat len do (write-byte val out)))) repeat repeats do (loop for val in vals do (loop repeat half-period do (write-byte val out))) finally (loop for len downfrom half-period by (* 0.5 rampinc) to 0 do ;_; (loop for val in vals do (loop repeat len do (write-byte val out))))))) (defparameter *day* 1) (defun %d (&optional (no *day*) (pad 3)) " %d Hypothetical day to string thing. " (format nil "~v,'0d" pad no)) (defun mpvit (&optional (path nil)) " raw mpv from lisp util. raw, 1c, u8, 44.1k args: path - suitable for ~a as mpv's target. " (uiop:Run-program (format nil "mpv --demuxer=rawaudio ~ --demuxer-rawaudio-channels=1 ~ --demuxer-rawaudio-format=u8 ~ --demuxer-rawaudio-rate=44100 ~ ~a" path) :output t :error t)) (defun eg () (loop for n downfrom 100 to 70 by 5 for times = (+ 50 (random 100)) do (write-note "a.raw" n times 0.5)) (mpvit "a.raw"))