; creates a meter where metre is a list of numerators
; and base is a shared denominator (relative to impromptu beats. i.e. 1 = crotchet, 0.5 = eighth etc.)
;
; e.g. (define *metre* (make-metre '(2 3 2) 0.5)) = 2/8 3/8 2/8 rotating cycle.
;
; then call meter with time and beat
; if beat matches time then #t else #f
;
; e.g. give the above define
; (*metre* 2.5 1.0) => #t because 0.0 = 1, 0.5 = 2, 1.0 = 1, 1.5 = 2, 2.0 = 3, 2.5 = 1, 3.0 = 2 and repeat.
(define make-metre
(lambda (metre base)
(let ((metre-length (apply + metre)))
(lambda (time . beat)
(let ((b (let loop ((qtime (modulo (/ time base) metre-length))
(lst metre)
(valuea (car metre))
(valueb 0))
(if (< qtime valuea)
(+ 1.0 (- qtime valueb))
(loop qtime (cdr lst) (+ valuea (cadr lst)) (+ valueb (car lst)))))))
(if (null? beat)
b
(if (= (car beat) b) #t #f)))))))