;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Funciones para entrar y procesar sonidos en Snd
;;;
;;;
;;; juanig\_at\_ccrma
;;;
;;; (c) 2005
;;;
;;; -1- Cargar un canal del archivo
;;; -2- Volver el sonido en reversa
;;; -3- Cargar dos canales
;;; -4- Cambio de velocidad del sonido
;;; -5- Filtrar el sonido
;;; -6- Panear (panoramico)
;;; -7- Estiramiento del sonido en dos canales
;;;
;;;**********************
;;;
;;; -1- Cargar un canal de un archivo de audio arbitrario
;;;
(define getson1
(lambda* (archivo comienzo #:key
(direcc 1)
(amp 1.0)
(amp-env '(0 1 100 1))
)
(let* ((inicio (floor (* comienzo (srate))))
(duracion (mus-sound-duration archivo))
(leera (make-readin archivo
:channel 0
:direction direcc))
(ampfunc (make-env amp-env amp duracion))
(final (+ inicio (floor (* (srate) duracion))))
(salida (make-vct final))
)
(do ((i inicio (1+ i)))
((= i final))
(vct-set! salida i (* (env ampfunc) (readin leera))) )
(mix-vct salida inicio #f 0 #f))))
;;
;;; (new-sound "nuevo.snd")
;;; (getson1 "/zap/caneca.snd" 0)
;;; (getson1 "/zap/caneca.snd" 0 :direcc -1.0) ;; este debe leer al revés
(define seq1
(lambda ()
(getson1 "/zap/caneca.snd" 0)
(getson1 "/zap/caneca.snd" 1.5)
(getson1 "/zap/caneca.snd" 3.0)))
;;;
;;; CUIDADO:
;;; Al ejecutar getson1 el nombre del archivo que se quiere cargar debe
;;; o estar en el directorio de donde corre Snd o sino hay que
;;; escribir el path completo
;;;
;;; -2- Volver el sonido en reversa
;;;
;;; NOTA:
;;; Para cambiar la dirección del sonido en forma directa se
;;; selecciona el pedazo, la región o (select-all) y en el listener
;;; (guile) se utiliza el siguiente comando:
;;;
;;; (reverse-selection)
;;;
;;;
;;;
;;; -3- Para cargar dos canales de un archivo stereo mínimo
;;;
;;;
(define getson2
(lambda* (archivo comienzo #:key
(amp 1.0)
(amp-env '(0 1 100 1))
)
(let* ((inicio (floor (* comienzo (srate))))
(duracion (mus-sound-duration archivo))
(leera (make-readin archivo :channel 0))
(leerb (make-readin archivo :channel 1))
(ampfunc1 (make-env amp-env amp duracion))
(ampfunc2 (make-env amp-env amp duracion))
(final (+ inicio (floor (* (srate) duracion))))
(salida1 (make-vct final))
(salida2 (make-vct final))
)
(do ((i inicio (1+ i)))
((= i final))
(vct-set! salida1 i (* (env ampfunc1) (readin leera)))
(vct-set! salida2 i (* (env ampfunc2) (readin leerb)))
)
(vct->channel salida1 inicio final #f 0)
(vct->channel salida2 inicio final #f 1)
)))
;;; (new-sound "/zap/test.snd" :channels 2)
;;; (getson2 "/zap/caneca.snd" 0)
;;; CUIDADO:
;;; Al ejecutar getson2 el nombre del archivo que se quiere cargar debe
;;; o estar en el directorio de donde corre Snd o sino hay que
;;; escribir el path completo
;;;
;;; -4- Cambio de velocidad del sonido
;;;
;;; este cambio de velocidad se realiza al cambiar el
;;; valor de la tasa de frecuencia de muestreo.
;;; radio-fm es la división entre la frecuencia de muestreo
;;; original y la nueva. Si es uno no hay cambio, si es 0.5
;;; es la mitad.
;;;
;;;
(define simsrc
(lambda* (archivo comienzo #:key
(ancho 5.0)
(radio-fm 0.5)
(src-env '(0 1.0 100 1.0))
)
(let* ((infsr (mus-sound-srate archivo))
(duracion (/ (mus-sound-frames archivo) infsr))
(entrada (make-readin archivo :channel 0))
(srcenv (make-env :envelope src-env
:duration duracion))
(inicio (* comienzo infsr))
(final (+ inicio (floor (* duracion infsr))))
(salida (make-vct final))
(generador (make-src :input (lambda (dir) (readin entrada))
:srate radio-fm
:width ancho )) )
(do ((i inicio (1+ i)))
((= i final))
(vct-set! salida i (src generador (env srcenv))) )
(vct->channel salida inicio final ))))
;;; (new-sound "/zap/test.snd")
;;; (simsrc "/zap/why.snd" 0)
;;; (simsrc "/zap/why.snd" 0 :src-env ´(0 0.25 1 1.5))
;;;
;;;
;;; -5- Filtrar el sonido
;;;
;;;
;;; Funciones para sacar los coeficientes de los filtros
;;; resonantes.
;;;
;;;
(define b1-de-frec-rad
(lambda (r freq)
(- (* 2.0 r (cos (hz->radians freq))))))
(define b2-de-radianes
(lambda (r)
(* r r)))
(define formantes
(lambda* (archivo comienzo #:key
(frecuencias '(0 20 1 10000))
(radianes '(0 0.707 1 0.707))
)
(let* ((infsr (mus-sound-srate archivo))
(duracion (/ (mus-sound-frames archivo) infsr))
(entrada (make-readin archivo :channel 0))
(inicio (* comienzo infsr))
(longitud (+ inicio (floor (* duracion infsr))))
(env-frecu (make-env :envelope frecuencias
:duration duracion))
(env-rad (make-env :envelope radianes
:duration duracion))
(filtro (make-formant :frequency 440
:radius 0.25))
(salida (make-vct longitud)))
;;
(vct-map! salida
(lambda ()
(let ((rd (env env-rad))
(fr (env env-frecu)))
(set! (mus-xcoeff filtro 2) (- rd ))
(set! (mus-ycoeff filtro 1)
(b1-de-frec-rad rd fr))
(set! (mus-ycoeff filtro 2) (b2-de-radianes rd))
(formant filtro (readin entrada)))))
(vct->channel salida inicio longitud ))))
;;;(formantes "/zap/caneca.snd" 0)
;;;
;;;
;;;
;;; -6- Panear (panoramico)
;;;
;;;
;;;
(define pansoni
(lambda* (archivo comienzo #:key
(inbeg 0)
(grados 45)
(amp 1.0)
(amp-env '(0 1 100 1))
)
(let* ((inicio (inexact->exact (floor (* comienzo (mus-srate)))))
(duracion (mus-sound-duration archivo))
(inloc (inexact->exact (floor (* (or inbeg 0)
(mus-sound-srate archivo)))))
(ampfunc1 (make-env amp-env amp duracion))
(ampfunc2 (make-env amp-env amp duracion))
(final (+ inicio (inexact->exact (floor (* (mus-srate) duracion)))))
(leera (make-readin archivo
:channel 0
:start inloc
) )
(loc (make-locsig
:channels (channels)
:degree (or grados (random 90))
))
(salida1 (make-vct final))
(salida2 (make-vct final)))
;;
(do ((i inicio (1+ i)))
((= i final))
(vct-set! salida1 i (* (locsig-ref loc 0) (env ampfunc1) (readin leera)))
(vct-set! salida2 i (* (locsig-ref loc 1) (env ampfunc2) (readin leera))))
(mix-vct salida1 inicio #f 0 #f)
(mix-vct salida2 inicio #f 1 #f) )))
;;; (new-sound "/zap/test.snd" :channels 2 :srate 44100)
;;;(pansoni "/zap/caneca.snd" 0)
;;;(pansoni "/zap/caneca.snd" 0 :grados 22.5)
;;; (load "entrada.scm")
(define secuencia
(lambda ()
(pansoni "/zap/caneca.snd" 0 :grados 0.0 :amp-env '(0 0 20 1 80 1 100 0))
(pansoni "/zap/caneca.snd" 1.5 :grados 22.5 :amp-env '(0 0 20 1 80 1 100 0))
(pansoni "/zap/caneca.snd" 3.0 :grados 45.0 :amp-env '(0 0 20 1 80 1 100 0))
(pansoni "/zap/caneca.snd" 4.5 :grados 67.5 :amp-env '(0 0 20 1 80 1 100 0))
(pansoni "/zap/caneca.snd" 6.0 :grados 90.0 :amp-env '(0 0 20 1 80 1 100 0))
(pansoni "/zap/caneca.snd" 7.5 :grados 90.0 :amp-env '(0 0 20 1 80 1 100 0))
(pansoni "/zap/caneca.snd" 9.0 :grados 67.5 :amp-env '(0 0 20 1 80 1 100 0))
(pansoni "/zap/caneca.snd" 10.5 :grados 45.0 :amp-env '(0 0 20 1 80 1 100 0))
(pansoni "/zap/caneca.snd" 12 :grados 22.5 :amp-env '(0 0 20 1 80 1 100 0))
(pansoni "/zap/caneca.snd" 13.5 :grados 0.0 :amp-env '(0 0 20 1 80 1 100 0))
))
;;;
;;;
;;;
;;; -7- Estiramiento del sonido en dos canales
;;;
;;;
;;; La envolvente de paneo 'pan-env' da los valores para mover
;;; el sonido entre 0 y 90 grados.
(define esparsoni
(lambda* (archivo comienzo
#:key
(amp-env '(0 0.20 1 0.95))
(pan-env '(0 0.0 0.5 90.0 1 0.00))
(angulo 0.00) (distancia 1.0) )
(let* ((inicio (floor (* comienzo (srate))))
(longitud (mus-sound-duration archivo))
(leera (make-readin archivo
:channel 0
) )
(final (+ inicio (floor (* (srate) longitud))))
(env-a0 (make-env :envelope amp-env
:duration longitud))
(env-a1 (make-env :envelope amp-env
:duration longitud))
(l-env (make-env :envelope pan-env
:scaler (/ 1.0 90.0)
:duration longitud ))
(r-env (make-env :envelope pan-env
:scaler (/ 1.0 90.0)
:duration longitud ))
(loc (make-locsig :channels (channels)
:degree angulo
:distance distancia))
(out-a (make-vct final))
(out-b (make-vct final)))
(vct-map! out-a (lambda ()
(let ((p-val (env l-env)))
(locsig-set! loc 0 (- 1.0 p-val))
(* (locsig-ref loc 0) (env env-a0) (readin leera))
)))
(vct-map! out-b (lambda ()
(locsig-set! loc 1 (env r-env))
(* (locsig-ref loc 1 ) (env env-a1) (readin leera))
))
(vct->channel out-a inicio final #f 0)
(vct->channel out-b inicio final #f 1))))
;;;(esparsoni "/zap/caneca.snd" 0)
;;; (new-sound "/zap/test.snd" :channels 2)
;; (load "entrada.scm")
|