;;; ;;; Spatialization ;;; Using locsig... ;;; #| ;;; first a test instrument (a framework which we will incrementally improve) ;;; one oscillator, amplitude control, output to first channel only (definstrument moveit (start duration freq amp) (let* ((beg (floor (* start *srate*))) (end (+ beg (floor (* duration *srate*)))) (s (make-oscil :frequency freq))) (run (loop for i from beg to end do (outa i (* (oscil s) amp)))))) ;;; add an enevelope for amplitude, use locsig for multichannel output (definstrument moveit (start duration freq amp &key (amp-env '(0 0 0.01 1 0.1 0.1 1 0)) (degree 0)(distance 1)) (let* ((beg (floor (* start *srate*))) (end (+ beg (floor (* duration *srate*)))) (loc (make-locsig :degree degree :distance distance)) (e (make-env :envelope amp-env :duration duration)) (s (make-oscil :frequency freq))) (run (loop for i from beg to end do (locsig loc i (* (env e)(oscil s) amp)))))) ;;; "moving" a sound by calling moveit in a loop (with-sound(:srate 44100 :channels 2) (loop for time from 0 by 0.1 for degree from 0 by 5 below 90 do (moveit time 0.2 440.0 0.1 :degree degree))) ;;; add a bit of noise (50% sine, 50% noise) to the instrument (definstrument moveit (start duration freq amp &key (amp-env '(0 0 0.01 1 0.1 0.1 1 0)) (degree 0)(distance 1)) (let* ((beg (floor (* start *srate*))) (end (+ beg (floor (* duration *srate*)))) (loc (make-locsig :degree degree :distance distance)) (e (make-env :envelope amp-env :duration duration)) (s (make-oscil :frequency freq)) (n (make-rand :frequency (/ *srate* 2)))) (run (loop for i from beg to end do (locsig loc i (* (+ (oscil s)(rand n)) (env e) amp)))))) ;;; now add degree and distance envelopes, use move-locsig ;;; to move a sound dynamically ;;; (we don't change the parameters for degree and distance, ;;; if we don't get a list - envelope - we create a constant one) (definstrument moveit (start duration freq amp &key (amp-env '(0 0 0.01 1 0.1 0.1 1 0)) (degree 0)(distance 1)) (let* ((beg (floor (* start *srate*))) (end (+ beg (floor (* duration *srate*)))) (loc (make-locsig)) (e (make-env :envelope amp-env :duration duration)) (s (make-oscil :frequency freq)) (n (make-rand :frequency (/ *srate* 2))) (dg (make-env :duration duration :envelope (if (listp degree) degree (list 0 degree 1 degree)))) (ds (make-env :duration duration :envelope (if (listp distance) distance (list 0 distance 1 distance))))) (run (loop for i from beg to end do (move-locsig loc (env dg)(env ds)) (locsig loc i (* (+ (oscil s)(rand n)) (env e) amp)))))) (definstrument moveit (start duration freq amp &key (amp-env '(0 0 0.01 1 0.1 0.1 1 0)) (degree 0)(distance 1) (reverb-amount 0.01)) (let* ((beg (floor (* start *srate*))) (end (+ beg (floor (* duration *srate*)))) (loc (make-locsig :reverb reverb-amount :channels (mus-channels *output*))) (e (make-env :envelope amp-env :duration duration)) (s (make-oscil :frequency freq)) (n (make-rand :frequency (/ *srate* 2))) (dg (make-env :duration duration :envelope (if (listp degree) degree (list 0 degree 1 degree)))) (ds (make-env :duration duration :envelope (if (listp distance) distance (list 0 distance 1 distance))))) (run (loop for i from beg to end do ;; bypasses clm problem... (locsig-set! loc 0 0.0) ;; now "move" the sound by setting the speaker coeffs (move-locsig loc (env dg)(env ds)) (locsig loc i (* (+ (oscil s)(rand n)) (env e) amp)))))) |# ;;; this one includes a workaround for the "first channel always ;;; on" problem we noticed in class today (definstrument moveit (start duration freq amp &key (amp-env '(0 0 0.01 1 0.1 0.1 1 0)) (degree 0)(distance 1) (reverb-amount 0.01)) (let* ((beg (floor (* start *srate*))) (end (+ beg (floor (* duration *srate*)))) (loc (make-locsig :reverb reverb-amount :channels (mus-channels *output*))) (e (make-env :envelope amp-env :duration duration)) (s (make-oscil :frequency freq)) (n (make-rand :frequency (/ *srate* 2))) (max-dist 100) (del (make-delay 0 :max-size (* (/ max-dist 343.0) *srate*))) (dg (make-env :duration duration :envelope (if (listp degree) degree (list 0 degree 1 degree)))) (ds (make-env :duration duration :envelope (if (listp distance) distance (list 0 distance 1 distance))))) (run (loop for i from beg to end do (let* ((dist (env ds))) ;; bypasses clm problem... (locsig-set! loc 0 0.0) ;; now "move" the sound by setting the speaker coeffs (move-locsig loc (env dg) dist) (delay-tick del (* (+ (oscil s)(rand n)) (env e) amp)) (locsig loc i (tap del (* (/ dist 343.0) *srate*)))))))) #| (with-sound(:srate 44100 :channels 2) (loop for time from 0 by 0.1 for degree from 0 by 5 below 90 do (moveit time 0.2 440.0 0.1 :degree degree))) ;;; to use non-linear interpolation between speakers do this: ;;; (the default is linear interp) (setf *clm-locsig-type* mus-interp-sinusoidal) (with-sound(:srate 44100 :channels 8 :play nil) (loop for time from 0 by 0.1 for degree from 0 by 5 below 360 do (moveit time 0.2 440.0 0.1 :degree degree :amp-env '(0 0 0.01 1 0.1 0.1 1 0)))) ;;; smooth movement of one note... (with-sound(:srate 44100 :channels 8) (moveit 0 10 440.0 0.1 :degree '(0 0 1 360) :amp-env '(0 1 1 1))) ;;; both combined (warning: something's wrong in the first channel) (with-sound(:srate 44100 :channels 8) (loop for time from 0 by 0.4 for degree from 0 by 20 below 560 do (moveit time 0.6 440.0 0.1 :degree (list 0 degree 1 (+ degree 30)) :amp-env '(0 1 1 1)))) |#