|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
;; -*- lexical-binding: nil; -*-
;; 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")
;;
;; See: (find-1stclassvideo-links "2024pianoroll")
;;
;; «.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: