;*********************************************************************
|
; OM-SoX, (c) 2011-2014 Marlon Schumacher (CIRMMT/McGill University) *
|
; http://sourceforge.net/projects/omsox/ *
|
; *
|
; Multichannel Audio Manipulation and Functional Batch Processing. *
|
; DSP based on SoX - (c) C.Bagwell and Contributors *
|
; http://sox.sourceforge.net/ *
|
;*********************************************************************
|
;
|
;This program is free software; you can redistribute it and/or
|
;modify it under the terms of the GNU General Public License
|
;as published by the Free Software Foundation; either version 2
|
;of the License, or (at your option) any later version.
|
;
|
;See file LICENSE for further informations on licensing terms.
|
;
|
;This program is distributed in the hope that it will be useful,
|
;but WITHOUT ANY WARRANTY; without even the implied warranty of
|
;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
;GNU General Public License for more details.
|
;
|
;You should have received a copy of the GNU General Public License
|
;along with this program; if not, write to the Free Software
|
;Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,10 USA.
|
;
|
;Authors: M. Schumacher
|
|
(in-package :om)
|
|
; sox-reverse ==================================
|
|
(defmethod! sox-reverse ( &key sox-append)
|
:icon 70
|
:initvals '(nil)
|
:indoc (list *sox-append-doc*)
|
:doc "Reverse audio"
|
|
(let* ((thestring (format nil " reverse")))
|
(sox-concat sox-append thestring))
|
)
|
|
|
; sox-repeat ==================================
|
|
(defmethod! sox-repeat ((repetitions number) &key sox-append)
|
:icon 70
|
:initvals '(nil)
|
:indoc (list "number of repetitions (loops)" *sox-append-doc*)
|
:doc "repeats (loops) a soundfile n (repetition) number of times."
|
|
(let ((thestring (format nil "repeat ~d" repetitions)))
|
(sox-concat sox-append thestring))
|
)
|
|
|
; sox-pad ==================================
|
; if float then seconds if int then samples!
|
; I should use sox-units for any unit (time, amplitude, etc.)
|
|
(defmethod! sox-pad ((duration float) &key position sox-append)
|
:icon 70
|
:initvals '(nil nil nil)
|
:indoc (list "duration of silence/zero-padding (if float in seconds, otherwise in samples)" "position in the soundfile to insert silence" *sox-append-doc*)
|
:doc "Pad the audio with silence. Optionally at beginning, end, or specified points through the audio."
|
|
; NEEDS TIME UNITS!
|
|
;NB: length and position can be specified in secs [float] or samples [integer].
|
|
(let ((thestring (if position
|
(setf thestring (format nil " pad ~d@~d" duration position))
|
(format nil " pad ~d " duration))))
|
(sox-concat sox-append thestring))
|
)
|
|
;if ints are provided for duration, it is in samples
|
(defmethod! sox-pad ((duration integer) &key position sox-append)
|
(let ((thestring (if position
|
(setf thestring (format nil " pad ~ds@~d" duration position))
|
(format nil " pad ~ds " duration))))
|
(sox-concat sox-append thestring))
|
)
|
|
(defmethod! sox-pad ((duration list) &key position sox-append)
|
(let* ((thestring (format nil " pad")))
|
(if position
|
(loop for dur in duration
|
for pos in position do
|
(setf thestring (concatenate 'string thestring
|
(format nil " ~d@~d" dur pos))))
|
(loop for dur in duration do
|
(setf thestring (concatenate 'string thestring
|
(format nil " ~d" dur))))
|
)
|
(sox-concat sox-append thestring))
|
)
|
|
|
; sox trim ==================================
|
|
(defmethod! sox-trim ((start number) &key unit sox-append)
|
:icon 70
|
:initvals '(nil nil nil)
|
:indoc (list "start (number in secs), or start and end (list of 'start' and 'end' point (in secs)" "specify time in seconds or samples" *sox-append-doc* )
|
:menuins '((1 (("seconds" "seconds") ("samples" "samples"))))
|
:doc "Trims off unwanted parts from beginning and end of audio"
|
|
(let* ((thestring (format nil " trim ~d" start))
|
(thestring (sox-units thestring unit)))
|
(sox-concat sox-append thestring))
|
)
|
|
(defmethod! sox-trim ((start-and-end list) &key unit sox-append)
|
(let* ((thestring (if (equal unit "samples")
|
(format nil " trim ~ds ~ds " (first start-and-end) (- (second start-and-end) (first start-and-end)))
|
(format nil " trim ~d ~d " (first start-and-end) (- (second start-and-end) (first start-and-end))))))
|
(sox-concat sox-append thestring))
|
)
|
|
|
; sox-crop ==================================
|
; (allows to crop from the end)
|
|
(defmethod! sox-crop ((start number) &key sox-append)
|
:icon 70
|
:initvals '(nil nil)
|
:indoc (list "start (number in secs), or start and end (list of 'start' and 'end' point (in secs)" *sox-append-doc* )
|
:doc "trims off unwanted audio from beginning and end of audio"
|
|
(let* ((thestring (format nil "crop ~d " start)))
|
(sox-concat sox-append thestring))
|
)
|
|
|
(defmethod! sox-crop ((start-and-end list) &key sox-append)
|
(let* ((thestring (format nil "crop ~d ~d" (first start-and-end) (- (second start-and-end) (first start-and-end)))))
|
(sox-concat sox-append thestring))
|
)
|
|
|
|
; sox-autotrim ==================================
|
; strips-off silence based on a cepstral power measurement to detect a human voice
|
|
(defmethod! sox-voicetrim ((mode string) &key sox-append)
|
:icon 70
|
:initvals '("front" nil nil nil nil nil nil)
|
:menuins '((0 (("front" "front") ("back" "back") ("front+back" "front+back"))))
|
:indoc (list "mode: trim silence from front/back/front+back" *sox-append-doc*)
|
:doc "Automatically trim silence and quiet background sounds from the beginning/end of (voiced) audio.
|
|
Sox-voicetrim attempts to automatically trim silence and quiet background sounds from the beginning/end of (fairly high resolution i.e. 16-bit, 44.1kHz) speech based on cepstral power measurement."
|
|
(let* (
|
(thestring
|
(cond ((equal mode "front")
|
"vad")
|
((equal mode "back")
|
"reverse vad reverse")
|
((equal mode "front+back")
|
"vad reverse vad reverse")
|
)))
|
(sox-concat sox-append thestring)))
|
|
; for compatibility
|
#|
|
(defmethod! sox-autotrim ((mode string) &key sox-append)
|
:icon 70
|
(sox-voicetrim mode :sox-append sox-append))
|
|#
|
|
;; PS these options don't seem to work ...
|
;; bug in sox?
|
#|
|
(defmethod! sox-autotrim ((mode string) &key trigger-level ignore-time prior-time gap-time preserve-time commands)
|
:icon 01
|
:initvals '(front nil nil nil nil nil nil)
|
:menuins '((0 (("front" "front") ("back" "back") ("front+back" "front+back"))))
|
:indoc '("mode: trim silence from front/back/front+back" "autotrim-settings" "connect other commands to add to the processing chain")
|
:doc "Attempts to trim silence and quiet background sounds from the ends of (fairly high resolution i.e. 16-bit, 44-48kHz) recordings of speech based on cepstral power measurement."
|
(let* (
|
(thestring
|
(cond ((equal mode "front")
|
(format nil "vad t ~d T ~d s ~d g ~d p ~d" (or trigger-level 7) (or ignore-time 0.25) (or prior-time 1) (or gap-time 0.25) (or preserve-time 0)))
|
((equal mode "back")
|
(format nil "reverse vad t ~d T ~d s ~d g ~d p ~d reverse" (or trigger-level 7) (or ignore-time 0.25) (or prior-time 1) (or gap-time 0.25) (or preserve-time 0)))
|
((equal mode "front+back")
|
(format nil "vad t ~d T ~d s ~d g ~d p ~d reverse vad t ~d T ~d s ~d g ~d p ~d reverse" (or trigger-level 7) (or ignore-time 0.25) (or prior-time 1) (or gap-time 0.25) (or preserve-time 0) (or trigger-level 7) (or ignore-time 0.25) (or prior-time 1) (or gap-time 0.25) (or preserve-time 0) ))
|
)))
|
(when commands
|
(setf thestring (concatenate 'string thestring
|
(format nil " ~a" commands))))
|
thestring))
|
|#
|
|
;; sox-fade ==================================
|
(defmethod! sox-fade ((fadein-length number) (fadeout-length number) (stoptime t) &key (type "l") sox-append)
|
:icon 70
|
:initvals '(1 1 "-0" "l" nil)
|
:menuins '((3 (("logarithmic" "l") ("parabola" "p") ("quarter sinewave" "q") ("half sinewave" "h") ("linear" "t"))))
|
:indoc (list "fadein-length (in secs). Optionally <sound> object." "fadeout-length (in secs)" "stoptime (in secs). if 0 = duration of soundfile)" "fade-type (logarithmic/parabola/quarter-sine/half-sine/linear)" *sox-append-doc*)
|
:doc "creates fadeins/outs"
|
|
(setf thestring (format nil " fade ~a ~d ~d ~d " type fadein-length stoptime fadeout-length))
|
;; settings here!
|
(sox-concat sox-append thestring))
|
|
|
(defmethod! sox-fade ((soundfile sound) (fadeout-length number) (stoptime number) &key (type "l") sox-append)
|
(let* ((duration (sound-dur soundfile))
|
(markers (markers soundfile))
|
(fadein-length (first markers))
|
(fadeout-length (- duration (second markers)))
|
(stoptime duration))
|
(setf thestring (format nil " fade ~a ~d ~d ~d " type fadein-length stoptime fadeout-length)))
|
(sox-concat sox-append thestring))
|
|
|
|
;; sox-silence ==================================
|
; remove (cut) silence from a recording
|
(defmethod! sox-trimsilence ((above-periods number) (duration number) (threshold number) &key below-periods (below-duration 1) (below-threshold -50) leave-beginning sox-append)
|
:icon 70
|
:initvals '(1 2 -60 1 1 -50 nil nil)
|
:indoc (list "How many periods of non-silence should be retained"
|
"Amount of time that non-silence must be detected before it stops trimming audio"
|
"Silence-threshold (in dB)"
|
"How many periods of silence should be retained"
|
"Amount of time that silence must be detected before it trims audio"
|
"Below-threshold (in dB)"
|
"Leave the beginning of audio untouched"
|
*sox-append-doc*)
|
:doc "Removes (trims off) silence from the audo. 'Silence' is determined via duration (in secs) and threshold (in dB)."
|
|
(let ((thestring (format nil " silence ")))
|
(when leave-beginning (setf thestring (concatenate 'string thestring " -l")))
|
(setf thestring (if (equal above-periods 0)
|
(string+ thestring (format nil " ~d" above-periods))
|
(string+ thestring (format nil " ~d ~f ~d" above-periods duration (db->lin threshold))))) ; if it's in percent I should multiply by 100, no?
|
(when below-periods (setf thestring (string+ thestring (format nil " ~d ~f ~d" below-periods below-duration (db->lin below-threshold)))))
|
(sox-concat sox-append thestring)
|
))
|