;;; vfollow.cl ;;; real-time subtractive synthesis ;;; producing vocal like sounds ;;; with vibrato-- rate & range ;;; formant data is stored as a set of presets ;;; add a "mic-in" to change the 2nd frequency formant in real-time ;;; instrument on/off (defparameter vowels-recon 1100) ;;; input level control (defparameter vowels-in-level 1101) ;;; filter frequencies (defparameter vowels-1-frq 1102) (defparameter vowels-2-frq 1103) (defparameter vowels-3-frq 1104) ;;; filter radius (defparameter vowels-1-bw 1105) (defparameter vowels-2-bw 1106) (defparameter vowels-3-bw 1107) ;;; filter gains (defparameter vowels-1-g 1108) (defparameter vowels-2-g 1109) (defparameter vowels-3-g 1110) ;;; input monitor (defparameter vowels-in-frq 1111) (defparameter vowels-in-sel 1112) (defparameter vowels-line-in 1113) ;;; output level (defparameter vowels-out 1114) ;;; presets (defparameter vowels-set-1 1115) (defparameter vowels-set-2 1116) (defparameter vowels-set-3 1117) (defparameter vowels-set-4 1118) (defparameter vowels-set-5 1119) ;;; vibrato control (defparameter vibrato-rate 1120) ;;; add a vibrato control depending on ;;; how fast the oscil per second (defparameter vibrato-range 1121) ;;; add a vibrato control depending on ;;; how deep the oscil by Hz ;;; follower control (defparameter follow-amp 1122) (defparameter follow-out 1123) ;;; macro needed to properly compute filter's radius ;;; from a given bandwidth in Hertz (defmacro compute-radius (bw) `(- 1 (/ (* pi ,bw) ,sampling-rate))) ;;; instrument (defpinstrument vfollow (&key (window-length 100.0) (decay 0.9) (tester nil)) (let* ((window-scale (/ 1.0 window-length));;; modified here (amp-f (make-fcontrol follow-amp)) (counter 0) (output 0.0) (sum 0.0) (input 0.0) ;;;??? (center 1150.0) (noi (make-randh :frequency 5000 :amplitude .1)) ;;; noise generator (pulse (make-sum-of-cosines :cosines 30 ;;; pulse train generator :frequency 5000)) (vibrato (make-oscil :frequency 1.0)) ;;; make an oscil for vibrato ;;; filters (filter-1 (make-formant 0.99 175.0)) (filter-2 (make-formant 0.99 610.0)) (filter-3 (make-formnt 0.99 1600.0)) ;;; input level contol (levelf (make-fcontrol vowels-in-level)) ;;; noise/pulses frequency (frq-inf (make-fcontrol vowels-in-frq)) ;;; output level control (outf (make-fcontrol vowels-out)) ;;; frequency controls (frqf-1 (make-fcontrol vowels-1-frq)) (frqf-2 (make-fcontrol vowels-2-frq)) (frqf-3 (make-fcontrol vowels-3-frq)) ;;; radius controls (rf-1 (make-fcontrol vowels-1-bw)) (rf-2 (make-fcontrol vowels-2-bw)) (rf-3 (make-fcontrol vowels-3-bw)) ;;; gain controls (gf-1 (make-fcontrol vowels-1-g)) (gf-2 (make-fcontrol vowels-2-g)) (gf-3 (make-fcontrol vowels-3-g)) ;;; vibrato controls (vf-rate (make-fcontrol vibrato-rate)) ;;; make the control (vf-range (make-fcontrol vibrato-range))) ;;; make the control (run (loop for i from 0 do (when (= (control vowels-recon) 0.0) (loop-finish)) (let* ((input (* (fcontrol amp-f)(rec-any 0)))) ;;;modified (when (= counter window-length) (setf sum 0.0) (setf counter 0) ;;; print the followed value (setf (control follow-out) output) ) (incf counter) (incf sum (abs input)) (setf sum (* sum decay)) (setf output (* sum window-scale))) ;;; some female soprano formants as presets ;;; A (cond ((= (control vowels-set-1) 1.0) ;;; frq (setf (control vowels-1-frq) 800.0) (setf (control vowels-2-frq) 1150.0) (setf center 1150.0) (setf (control vowels-3-frq) 2900.0) ;;; bw (setf (control vowels-1-bw) 80.0) (setf (control vowels-2-bw) 90.0) (setf (control vowels-3-bw) 120.0) ;;; g (setf (control vowels-1-g) 1.0) (setf (control vowels-2-g) 0.5) (setf (control vowels-3-g) 0.025) ;;; release button (setf (control vowels-set-1) 0.0) ) ;;; E ((= (control vowels-set-2) 1.0) ;;; frq (setf (control vowels-1-frq) 350.0) (setf (control vowels-2-frq) 2000.0) (setf center 2000.0) (setf (control vowels-3-frq) 2800.0) ;;; bw (setf (control vowels-1-bw) 60.0) (setf (control vowels-2-bw) 100.0) (setf (control vowels-3-bw) 120.0) ;;; g (setf (control vowels-1-g) 1.0) (setf (control vowels-2-g) 0.1) (setf (control vowels-3-g) 0.18) ;;; release button (setf (control vowels-set-2) 0.0)) ;;; I ((= (control vowels-set-3) 1.0) ;;; frq (setf (control vowels-1-frq) 270.0) (setf (control vowels-2-frq) 2140.0) (setf center 2140.0) (setf (control vowels-3-frq) 2950.0) ;;; bw (setf (control vowels-1-bw) 60.0) (setf (control vowels-2-bw) 90.0) (setf (control vowels-3-bw) 100.0) ;;; g (setf (control vowels-1-g) 1.0) (setf (control vowels-2-g) 0.25) (setf (control vowels-3-g) 0.05) ;;; release button (setf (control vowels-set-3) 0.0)) ;;; O ((= (control vowels-set-4) 1.0) ;;; frq (setf (control vowels-1-frq) 450.0) (setf (control vowels-2-frq) 800.0) (setf center 800.0) (setf (control vowels-3-frq) 2830.0) ;;; bw (setf (control vowels-1-bw) 70.0) (setf (control vowels-2-bw) 80.0) (setf (control vowels-3-bw) 100.0) ;;; g (setf (control vowels-1-g) 1.0) (setf (control vowels-2-g) 0.28) (setf (control vowels-3-g) 0.08) ;;; release button (setf (control vowels-set-4) 0.0)) ;;; U ((= (control vowels-set-5) 1.0) ;;; frq (setf (control vowels-1-frq) 325.0) (setf (control vowels-2-frq) 700.0) (setf center 700.0) (setf (control vowels-3-frq) 2700.0) ;;; bw (setf (control vowels-1-bw) 50.0) (setf (control vowels-2-bw) 60.0) (setf (control vowels-3-bw) 170.0) ;;; g (setf (control vowels-1-g) 1.0) (setf (control vowels-2-g) 0.16) (setf (control vowels-3-g) 0.02) ;;; release button (setf (control vowels-set-5) 0.0)) (t nil)) ;;; set noise/pulses frq input (if (= (control vowels-in-sel) 1.0) (setf (frequency noi)(fcontrol frq-inf)) (setf (frequency pulse)(fcontrol frq-inf))) (setf (frequency vibrato)(fcontrol vf-rate)) ;;; make vibrato-oscil do with rate-control ;;; set frequencies (setf (frequency filter-1)(fcontrol frqf-1)) (setf (frequency filter-2)(+ center (* output 3000))) (setf (control vowels-2-frq) (+ center (* output 3000))) ;;;modified (setf (frequency filter-3)(fcontrol frqf-3)) ;;; set radius (setf (formant-radius filter-1)(compute-radius (fcontrol rf-1))) (setf (formant-radius filter-2)(compute-radius (fcontrol rf-2))) (setf (formant-radius filter-3)(compute-radius (fcontrol rf-3))) ;;; set gains (setf (frmnt-g filter-1)(/ (fcontrol gf-1) 10.0)) (setf (frmnt-g filter-2)(/ (fcontrol gf-2) 10.0)) (setf (frmnt-g filter-3)(/ (fcontrol gf-3) 10.0)) ;;; select the input we want (let* ((in-val (* (fcontrol levelf) (if (= (control vowels-line-in) 1.0) (rec-any 0) (if (= (control vowels-in-sel) 1.0) (randh noi) (sum-of-cosines pulse (in-hz (* (fcontrol vf-range) (oscil vibrato)))))))) ;;; make range-control into pulse-train ;;; add output of the filters together (out-val (+ (formant filter-1 in-val) (formant filter-2 in-val) (formant filter-3 in-val)))) ;;; send scaled value to the output (outa i (* (fcontrol outf) out-val)) ;;; if tester is on send output to it (if tester (setf (tester-in) out-val))))))) (make-controller "vfollow_lnx" 2048 '(vowels-recon "play" :toggle t) '(vowels-line-in "Line-in on/off" :toggle nil) '(vowels-in-sel "Noise/Pulse-Train" :toggle t) '(vowels-in-level "input" :slider 0.0 1.0) '(vowels-out "output" :slider 0.0 1.0) '(vowels-in-frq "input frequency" :slider 0.0 5000.0) '(vibrato-rate "vib-rate" :slider 0.0 10.0) '(vibrato-range "vib-range" :slider 0.0 8.0) '(0 "" :separator 20) '(vowels-set-1 "A" :push) '(vowels-set-2 "E" :push) '(vowels-set-3 "I" :push) '(vowels-set-4 "O" :push) '(vowels-set-5 "U" :push) '(0 "" :separator 5) ;;; follower sliders '(follow-out "out" :label "ivory2" "red") ;;;modified '(follow-amp "amplitude" :slider 0.0 1.0) ;;; frq sliders '(vowels-1-frq "filter-1-frq" :slider 0.0 11025.0) '(vowels-2-frq "filter-2-frq" :slider 0.0 11025.0) '(vowels-3-frq "filter-3-frq" :slider 0.0 11025.0) ;;; bw sliders '(vowels-1-bw "filter-1-bw" :slider 20.0 200.0) '(vowels-2-bw "filter-2-bw" :slider 20.0 200.0) '(vowels-3-bw "filter-3-bw" :slider 20.0 200.0) ;;; g sliders '(vowels-1-g "filter-1-g" :slider 0.0 1.0) '(vowels-2-g "filter-2-g" :slider 0.0 1.0) '(vowels-3-g "filter-3-g" :slider 0.0 1.0)) #| ;;; calls to the instrument (with-psound (:srate 22050)(vfollow1)) (with-psound (:srate 22050 :rec-line 0 :rec-chans 1) (tester) (vfollow :tester t)) |#