Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
;; This file: ;; http://anggtwu.net/elisp/2024-piano-roll-macros.el.html ;; http://anggtwu.net/elisp/2024-piano-roll-macros.el ;; (find-angg "elisp/2024-piano-roll-macros.el") ;; Author: Eduardo Ochs <eduardoochs@gmail.com> ;; ;; `eeks': like `eek', but the keys are "spaced (in time)". ;; `eeks' plays "notes" "spaced in time", like a pianola. ;; Compare: (eek "RET Hello") ;; with: (eeks 0.5 0.25 "RET Hello") ;; ;; «.macro» (to "macro") ;; «.eeks» (to "eeks") ;; «.test-eepitch» (to "test-eepitch") ;; «macro» (to ".macro") ;; Tests: (ee-let*-macro-eeks 0.25 0.5 "RET Hello" tevents) ;; (ee-let*-macro-eeks 0.25 0.5 "RET Hello" ppushs) ;; (ee-let*-macro-eeks 0.25 0.5 "RET Hello" prats) ;; (ee-let*-macro-eeks 0.25 0.5 "RET Hello" (length tevents)) ;; (ee-let*-macro-eeks 0.25 0.5 "RET Hello" (find-eppp ppushs :end)) ;; (ee-let*-macro-eeks 0.25 0.5 "RET Hello" (find-eppp prats :end)) ;; (ee-let*-macro-eeks 0.25 0.5 "RET Hello" (eval prats)) ;; (ee-let*-macro-eeks 0.25 0.5 nil (list dist nf8s f8s)) ;; See: (find-templates-intro "7. let* macros") ;; (find-kla-intro "8. `cl-loop'") ;; Skel: (find-let*-macro-links "eeks" "t0 dt str" "tevents pushs ppushs rats prats") (defmacro ee-let*-macro-eeks (t0 dt str &rest code) (declare (indent 3)) `(let* ((t0 ,t0) (dt ,dt) (str ,str) (dist (if (not str) (- (save-excursion (move-end-of-line 1) (search-forward "*") (line-number-at-pos)) (line-number-at-pos)))) (nf8s (if dist (1- dist))) (f8s (if dist (cl-loop for i from 1 to nf8s concat " <f8>"))) (tevents (ee-eek2 (or str f8s))) (pushs (cl-loop for tevent in tevents collect `(eek2 '(,tevent)))) (rats (cl-loop for push in pushs collect `(run-at-time ,t0 nil 'eval ',push) do (setq t0 (+ t0 dt)))) (ppushs (cons 'progn pushs)) (prats (cons 'progn rats))) ,@code)) ;; «eeks» (to ".eeks") ;; Test: (eeks 1.5 0.5 "RET Hello") (defun eeks (&optional t0 dt str) "Like `eek' and `eek2', but play the events spaced in time. T0 is the time of the first event; DT is T1-T0, T2-T1, etc. If STR is nil, play a series of <f8>s; this is meant to be used in eepitch blocks.\n See the tests before the definition of `ee-let*-macro-eeks' to understand how this works." (ee-let*-macro-eeks (or t0 0.25) (or dt 0.125) str (eval prats) (list (length tevents) 'events))) ;; «test-eepitch» (to ".test-eepitch") '("This is a test block: * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) ** Type <f8> on the line below and wait: * (eeks 0.5 0.5) echo a echo b echo c * --") ;; Local Variables: ;; coding: utf-8-unix ;; End: