Work-in-progress repo for ambisonics extensions for OM-SoX
Marlon Schumacher
3 days ago 27d7ae0a3f50b5554d4ead0fbb09c2490d62ad07
commit | author | age
92c40d 1 ;*********************************************************************
AN 2 ; OM-SoX, (c) 2011-2014 Marlon Schumacher (CIRMMT/McGill University) *
3 ;             http://sourceforge.net/projects/omsox/                 *
4 ;                                                                    *
5 ;  Multichannel Audio Manipulation and Functional Batch Processing.  *
6 ;        DSP based on SoX - (c) C.Bagwell and Contributors           *
7 ;                  http://sox.sourceforge.net/                       *
8 ;*********************************************************************
9 ;
10 ;This program is free software; you can redistribute it and/or
11 ;modify it under the terms of the GNU General Public License
12 ;as published by the Free Software Foundation; either version 2
13 ;of the License, or (at your option) any later version.
14 ;
15 ;See file LICENSE for further informations on licensing terms.
16 ;
17 ;This program is distributed in the hope that it will be useful,
18 ;but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 ;GNU General Public License for more details.
21 ;
22 ;You should have received a copy of the GNU General Public License
23 ;along with this program; if not, write to the Free Software
24 ;Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,10 USA.
25 ;
26 ;Authors: M. Schumacher
27
28 (in-package :om)
29
30 ; sox-reverse ==================================
31
32 (defmethod! sox-reverse ( &key sox-append)
33   :icon 70
34   :initvals '(nil)
35   :indoc (list *sox-append-doc*)
36   :doc "Reverse audio"
37
38   (let* ((thestring (format nil " reverse")))
39     (sox-concat sox-append thestring))
40   )
41
42
43 ; sox-repeat ==================================
44
45 (defmethod! sox-repeat ((repetitions number) &key sox-append)
46   :icon 70
47   :initvals '(nil)
48   :indoc (list "number of repetitions (loops)" *sox-append-doc*)
49   :doc "repeats (loops) a soundfile n (repetition) number of times."
50
51   (let ((thestring (format nil "repeat ~d" repetitions)))
52     (sox-concat sox-append thestring))
53   )
54
55
56 ; sox-pad ==================================
57 ; if float then seconds if int then samples!
58 ; I should use sox-units for any unit (time, amplitude, etc.)
59
60 (defmethod! sox-pad ((duration float) &key position sox-append)
61   :icon 70
62   :initvals '(nil nil nil)
63   :indoc (list "duration of silence/zero-padding (if float in seconds, otherwise in samples)" "position in the soundfile to insert silence" *sox-append-doc*)
64   :doc "Pad the audio with silence. Optionally at beginning, end, or specified points through the audio."
65
66 ; NEEDS TIME UNITS!  
67
68 ;NB: length and position can be specified in secs [float] or samples [integer].
69
70   (let ((thestring (if position 
71                        (setf thestring (format nil " pad ~d@~d" duration position))
72                      (format nil " pad ~d " duration))))
73     (sox-concat sox-append thestring))
74   )
75
76 ;if ints are provided for duration, it is in samples
77 (defmethod! sox-pad ((duration integer) &key position sox-append)
78             (let ((thestring (if position 
79                                  (setf thestring (format nil " pad ~ds@~d" duration position))
80                                (format nil " pad ~ds " duration))))
81               (sox-concat sox-append thestring))
82             )
83
84 (defmethod! sox-pad ((duration list) &key position sox-append)
85   (let* ((thestring (format nil " pad")))
86     (if position
87         (loop for dur in duration
88               for pos in position do
89               (setf thestring (concatenate 'string thestring
90                                            (format nil " ~d@~d" dur pos))))
91       (loop for dur in duration do 
92             (setf thestring (concatenate 'string thestring 
93                                          (format nil " ~d" dur))))
94       )
95     (sox-concat sox-append thestring))
96   )
97
98
99 ; sox trim ==================================
100
101 (defmethod! sox-trim ((start number) &key unit sox-append)
102   :icon 70
103   :initvals '(nil nil nil)
104   :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* )
105   :menuins '((1 (("seconds" "seconds") ("samples" "samples"))))
106   :doc "Trims off unwanted parts from beginning and end of audio"
107
27d7ae 108   (let* ((thestring (format nil " trim ~d" start))
92c40d 109          (thestring (sox-units thestring unit)))
AN 110     (sox-concat sox-append thestring))
111   )
112
113 (defmethod! sox-trim ((start-and-end list) &key unit sox-append)
114   (let* ((thestring (if (equal unit "samples") 
27d7ae 115                         (format nil " trim ~ds ~ds " (first start-and-end) (- (second start-and-end) (first start-and-end)))
MS 116                       (format nil " trim ~d ~d " (first start-and-end) (- (second start-and-end) (first start-and-end))))))         
92c40d 117     (sox-concat sox-append thestring))
AN 118   )
119
120
121 ; sox-crop ==================================
122 ; (allows to crop from the end)
123
124 (defmethod! sox-crop ((start number) &key sox-append)
125   :icon 70
126   :initvals '(nil nil)
127   :indoc (list "start (number in secs), or start and end (list of 'start' and 'end' point (in secs)" *sox-append-doc* )
128   :doc "trims off unwanted audio from beginning and end of audio"
129
130   (let* ((thestring (format nil "crop ~d " start)))
131     (sox-concat sox-append thestring))
132   )
133    
134
135 (defmethod! sox-crop ((start-and-end list) &key sox-append)
136   (let* ((thestring (format nil "crop ~d ~d" (first start-and-end) (- (second start-and-end) (first start-and-end)))))
137     (sox-concat sox-append thestring))
138   )
139
140
141
142 ; sox-autotrim ==================================
143 ; strips-off silence based on a cepstral power measurement to detect a human voice
144
145 (defmethod! sox-voicetrim ((mode string) &key sox-append)
146   :icon 70
147   :initvals '("front" nil nil nil nil nil nil)
148   :menuins '((0 (("front" "front") ("back" "back") ("front+back" "front+back"))))
149   :indoc (list "mode: trim silence from front/back/front+back" *sox-append-doc*)
150   :doc "Automatically trim silence and quiet background sounds from the beginning/end of (voiced) audio. 
151
152 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."
153
154   (let* (
155          (thestring 
156          (cond ((equal mode "front")
157                 "vad")
158                ((equal mode "back")
159                 "reverse vad reverse")
160                ((equal mode "front+back")
161                 "vad reverse vad reverse")
162                 )))
163     (sox-concat sox-append thestring)))
164
165 ; for compatibility
166 #|
167 (defmethod! sox-autotrim ((mode string) &key sox-append)
168             :icon 70
169             (sox-voicetrim mode :sox-append sox-append))
170 |#
171
172 ;; PS these options don't seem to work ... 
173 ;; bug in sox?
174 #|
175 (defmethod! sox-autotrim ((mode string) &key trigger-level ignore-time prior-time gap-time preserve-time commands)
176   :icon 01
177   :initvals '(front nil nil nil nil nil nil)
178   :menuins '((0 (("front" "front") ("back" "back") ("front+back" "front+back"))))
179   :indoc '("mode: trim silence from front/back/front+back" "autotrim-settings" "connect other commands to add to the processing chain")
180   :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."
181   (let* (
182          (thestring 
183          (cond ((equal mode "front")
184                 (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)))
185                ((equal mode "back")
186                 (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)))
187                ((equal mode "front+back")
188                 (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) ))
189                 )))
190     (when commands
191       (setf thestring (concatenate 'string thestring 
192                                    (format nil " ~a" commands))))
193     thestring))
194 |#
195
196 ;; sox-fade ==================================
197 (defmethod! sox-fade ((fadein-length number) (fadeout-length number) (stoptime t) &key (type "l") sox-append)
198   :icon 70
199   :initvals '(1 1 "-0" "l" nil)
200   :menuins '((3 (("logarithmic" "l") ("parabola" "p") ("quarter sinewave" "q") ("half sinewave" "h") ("linear" "t")))) 
201   :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*)
202   :doc "creates fadeins/outs"
203
204   (setf thestring (format nil " fade ~a ~d ~d ~d " type fadein-length stoptime fadeout-length))
205     ;; settings here!
206     (sox-concat sox-append thestring))
207
208
209 (defmethod! sox-fade ((soundfile sound) (fadeout-length number) (stoptime number) &key (type "l") sox-append)
210   (let* ((duration (sound-dur soundfile))
211          (markers (markers soundfile))
212          (fadein-length (first markers))
213          (fadeout-length (- duration (second markers)))
214          (stoptime duration))
215   (setf thestring (format nil " fade ~a ~d ~d ~d " type fadein-length stoptime fadeout-length)))
216   (sox-concat sox-append thestring))
217
218
219
220 ;; sox-silence ==================================
221 ; remove (cut) silence from a recording
222 (defmethod! sox-trimsilence  ((above-periods number) (duration number) (threshold number) &key below-periods (below-duration 1) (below-threshold -50) leave-beginning sox-append)
223   :icon 70
224   :initvals '(1 2 -60 1 1 -50 nil nil)
225   :indoc (list "How many periods of non-silence should be retained" 
226                "Amount of time that non-silence must be detected before it stops trimming audio" 
227                "Silence-threshold (in dB)" 
228                "How many periods of silence should be retained"
229                "Amount of time that silence must be detected before it trims audio"
230                "Below-threshold (in dB)"
231                "Leave the beginning of audio untouched"
232                *sox-append-doc*)
233   :doc "Removes (trims off) silence from the audo. 'Silence' is determined via duration (in secs) and threshold (in dB)."
234
235   (let ((thestring (format nil " silence ")))
236     (when leave-beginning (setf thestring (concatenate 'string thestring " -l")))
237     (setf thestring (if (equal above-periods 0)
238                         (string+ thestring (format nil " ~d" above-periods))
239                       (string+ thestring (format nil " ~d ~f ~d" above-periods duration (db->lin threshold))))) ; if it's in percent I should multiply by 100, no?
240     (when below-periods (setf thestring (string+ thestring (format nil " ~d ~f ~d" below-periods below-duration (db->lin below-threshold)))))
241     (sox-concat sox-append thestring)
242     ))
243