Hello all
;; I did some experimenting in pattern language playing vectors of pairs of real midi
;; notes which differ by small amounts. Like this for example:
; (:> test1 4 0 (play samp1 @1 80 dur) '(#(63.5 64.5) #(61.5 62.5) #(59.5 60.5)))
;; Rather than manually change '(64 62 63) into '(#(63.5 64.5) #(61.5 62.5) #(59.5 60.5))
;; I wanted to be able to do it on the fly.
;; I had to learn quite a lot about deep recursion in Scheme!
;; This is where I landed:
;; Function g_itnote
;; Function g_itnote will replace a midi note, other than notes within a vector,
;; by a vector containing two slightly different real midi notes.
;; One note is a bit lower and the other a bit higher than the original midi.
;; Then new pair of notes has a "beating effect" when played together as a vector.
;; The frequency shift delta can be changed on the fly.
(define g_itnote
(let ((delta 0.4321)) ;; Can redefine g_itnote with a new value of delta
(lambda (note)
(vector (- note delta) (+ note delta)))))
(println (g_itnote 70))
;; Function g_it
;; Apply the g_itnote function to members of list and all levels of sublists ....
;; This function g_it retains vectors, rests '_ and ties '| without modification.
(define (g_it L)
(cond ((null? L) '())
((vector? (car L)) (cons (car L) (g_it (cdr L)))) ;; copy vectors as-is
((symbol? (car L)) (cons (car L) (g_it (cdr L)))) ;; copy '_ and '| as-is
((list? (car L)) (cons (g_it (car L)) (g_it (cdr L))))
(else (cons (g_itnote (car L)) (g_it (cdr L))))))
;; Some tests:
(println (g_it '(40.0 _ #(94 67) | 55)))
(println (g_it '(1 (3 _ 5) 7 #(18 19) 9 | (11 | 13))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Make some sounds and try the function.
;; Set up dsp with some fmsynth output ....
(sys:load "libs/external/instruments_ext.xtm")
(sys:load "libs/core/pattern-language.xtm")
(*metro* 'set-tempo 80)
;; Use the built-in fmsynth instrument.
(make-instrument fmsynth fmsynth)
;; Set up the sound output:
(bind-func dsp:DSP
(lambda (in time chan dat)
(cond ((< chan 2)
(* 1.0 (fmsynth in time chan dat)))
(else 0.0))))
(dsp:set! dsp)
;; To change the delta value you have to redefine g_itnote with a new delta value
;; You can do this 'on the fly'
(define g_itnote
(let ((delta 0.0))
(lambda (note)
(vector (- note delta) (+ note delta)))))
;; Play something which includes sublists, vectors, ties and rests:
(:> g_itC 4 0 (play fmsynth @1 80 dur) (g_it '(60 _ (64 _ (66 | 68)) #(66 68) | | 67 _ 70)))
;; TO CHANGE DELTA NEED TO REDEFINE g_itnote
(define g_itnote
(let ((delta 3.4321))
(lambda (note)
(vector (- note delta) (+ note delta)))))
;; Footnote: I wonder if there is a different way to execute changes to delta?
;; One that would allow you to use cosr to change the delta automatically as the
;; tune plays?
Would be interested in any ideas.