[CM] Finding the duration of a time-varying resampled sound.

Bill Schottstaedt bil@ccrma.Stanford.EDU
Tue, 28 Oct 2003 08:16:45 -0800


Ok, here's my final entry!

;;; find new duration of sound after using env as srate (src-sound)
;;; the envelope gives the per-sample increment, so the "tempo"
;;;   is the inverse of that. To get the total new duration,
;;;   we need to integrate the inverse envelope, but a straight
;;;   line in the increment envelope becomes a 1/x curve in the
;;;   tempo curve, so we use log(x) as integral of 1/x and
;;;   take into account the local notion of "x".

(define (src-duration e)
   (let* ((len (length e))
	 (ex0 (car e))
	 (ex1 (list-ref e (- len 2)))
	 (all-x (- ex1 ex0))
	 (dur 0.0))
     (do ((i 0 (+ i 2)))
	((>= i (- len 2)) dur)
       (let* ((x0 (list-ref e i))
	     (x1 (list-ref e (+ i 2)))
	     (xy0 (list-ref e (+ i 1))) ; 1/x x points
	     (y0 (/ 1.0 xy0))           ; related y value
	     (xy1 (list-ref e (+ i 3)))
	     (y1 (/ 1.0 xy1))
	     (area (if (< (abs (- xy0 xy1)) .0001) ; don't divide by 0
		       (* y0 (/ (- x1 x0) all-x))
		       (* (/ (- (log y1) (log y0))
			     (- xy0 xy1))
			  (/ (- x1 x0) all-x)))))
	(set! dur (+ dur (abs area)))))))

(define (new-dur orig-dur src-env)
   (* orig-dur (src-duration src-env)))

:(src-duration '(0 1 .5 1))
1.0
:(src-duration '(0 1 1 2))
0.693147180559945
:(src-duration '(0 1 1 .5))
1.38629436111989
:(src-duration '(0 2 1 1))
0.693147180559945
:(src-duration '(0 1 1 .5 2 1))
1.38629436111989
:(src-duration '(0 .5 .5 3 .6 1 .7 .1 .8 1.5 1 1))
1.02474349685432