;;; -*- syntax: common-lisp; package: clm; base: 10; mode: lisp -*- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; File: trim-silence.ins ;;; ;;; Purpose: Writes a new sound file with the silence at the beginning ;;; of the input file cut off. Silence threshold is ;;; configurable. ;;; ;;; Author: Michael Edwards - m@michael-edwards.org ;;; ;;; $$ Last modified: 11:42:56 Tue Jul 5 2011 BST ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defmacro db2amp (db) `(expt 10.0 (/ ,db 20))) (defmacro end-silence () `(loop for i from 0 below num-samps do (setf inAval (readin inA)) (when stereo-input (setf inBval (readin inB))) (unless (and (< inAval minamp) (< inBval minamp)) (return i)))) ;;; no final / on dirs (defun dir-trim-silence (indir outdir &key (minDB -100) (extension ".wav")) (let ((files (directory (format nil "~a/*~a" indir extension)))) (setf files (loop for f in files collect (namestring f))) (loop for f in files for outf = (format nil "~a/~a~a" outdir (pathname-name f) extension) do (with-sound (:output outf :channels (sound-chans f) :statistics nil :play nil :srate (sound-srate f)) (trim-silence f minDB))))) (definstrument get-samples (file start stop &optional (channel 0)) (let* ((nd (floor (* *srate* (- stop start)))) (samples (make-double-float-array nd)) (rd (make-readin :file file :channel channel :start (floor (* *srate* start))))) (run* (samples) (loop for i below nd do (setf (aref samples i) (readin rd)))) samples)) (definstrument trim-silence (file &optional (minDB -100)) (let* ((stereo-input (= 2 (sound-chans file))) (inA (make-readin :file file)) (inB (when stereo-input (make-readin :file file :channel 1))) (num-samps (sound-frames file)) (inAval 0.0) (inBval 0.0) (start 0) (stop 0) (minamp (db2amp minDB)) (num-samps (sound-frames file))) (run* (start stop) (progn (setf start (end-silence) (mus-location inA) (1- num-samps) (mus-increment inA) -1) (when stereo-input (setf (mus-location inB) (1- num-samps) (mus-increment inB) -1)) (setf stop (- num-samps (end-silence)) (mus-location inA) start (mus-increment inA) 1) (when stereo-input (setf (mus-location inB) start (mus-increment inB) 1)) (unless (and start stop) (error "couldn't detect end/start of silence: start = ~a stop = ~a" start stop)) (loop for i from start to stop and j from 0 do (outa j (readin inA)) (when stereo-input (outb j (readin inB)))))) (format t "~&Trimmed silence from 0 to ~a (~,3f secs) ~ ~%and from ~a to ~a (~,3f secs)~%" start (/ start *srate*) stop num-samps (/ (- num-samps stop) *srate*)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; #| (dir-trim-silence "/projects/mpc/snd" "/projects/mpc/snd/trim" -90) (with-sound (:srate 48000) (trim-silence "/projects/mpc/snd/big-nails-spinning-barns.wav")) (get-samples "/projects/mpc/snd/platter-b4-fall-princey-window.wav" 39.8 41.2) |# ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; EOF trim-silence.ins