Work-in-progress repo for ambisonics extensions for OM-SoX
Marlon Schumacher
4 days ago 27d7ae0a3f50b5554d4ead0fbb09c2490d62ad07
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
; ********************************************************************
; OM-SoX, (c) 2011-2013 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-denoise ===============================
 
(defmethod! sox-denoise ((amount number) (noiseprofile pathname) &key sox-append)                        
            :icon 60
            :initvals '(nil nil nil)
            :indoc (list "Amount of noise-reduction (1=max. 0=no red.)" "Supply noiseprofile file (generated with sox-noiseprofile)" *sox-append-doc*)
            :doc  "Reduce the noisefloor in an audio file. 
 
How much noise should be removed is specified by 'amount'. 
Higher numbers will remove more noise but present a greater likelihood of removing wanted components of the audio signal."
 
            (let ((thestring (format nil "noisered ~s ~d" (namestring noiseprofile) amount)))
              (sox-concat sox-append thestring))
            )
 
(defmethod! sox-denoise ((amount number) (noiseprofile t) &key sox-append)
    (om-beep-msg (format nil "!!! Wrong noiseprofile for sox-denoise: ~A" noiseprofile)))
 
(defmethod! sox-denoise ((amount number) (noiseprofile sound) &key sox-append)
    (sox-denoise amount (sound-path noiseprofile) :sox-append sox-append))
 
(defmethod! sox-denoise ((amount number) (noiseprofile string) &key sox-append)
    (sox-denoise amount (pathname noiseprofile) :sox-append sox-append))
 
;;; Sox-DCRemove ===============================
; DC-removal via highpass-filter
 
(defmethod! sox-dcremove (&key (cutoff-freq 10) sox-append)                        
            :icon 60
            :initvals '(10 nil)
            :indoc (list "cutoff-frequency of high-pass-filter" *sox-append-doc*)
            :doc "remove dc-offset in an audio file"
 
            (let ((thestring (format nil " highpass ~d" cutoff-freq)))
              (sox-concat sox-append thestring)))
 
 
(defmethod! sox-dcshift ((dc number) &key limitergain sox-append)                        
            :icon 60
            :initvals '(nil 0.05)
            :indoc (list "amount to shift signal" *sox-append-doc*)
            :doc "Shift the dc in an audio file"
 
            (let ((thestring (format nil " dcshift ~d " dc)))
              (when limitergain (setf thestring (string+ thestring (number-to-string limitergain))))
              (sox-concat sox-append thestring))
            )
 
 
; Sox-Riaa ===============================
; (Vinyl playback equalisation)
 
(defmethod! sox-riaa ( &key sox-append )                        
            :icon 60
            :indoc (list *sox-append-doc*)
            :doc "Apply RIAA vinyl playback equalisation. NB: The sampling rate must be one of: 44.1, 48, 88.2, 96 kHz."
 
            (let ((thestring (format nil " riaa")))
              (sox-concat sox-append thestring))
            )
              
 
; Sox-deemph ================================
; CD deemphasis filter
 
(defmethod! sox-deemph ( &key sox-append )                        
            :icon 60
            :indoc (list *sox-append-doc*)
            :doc "Apply Compact Disc (IEC 60908) de-emphasis (a treble attenuation shelving filter)."
 
            (let ((thestring (format nil " deemph")))
              (sox-concat sox-append thestring))
            )
 
 
;;; Sox-Dither =================================================
; this should always be at the end of the processing chain, thus no "sox-append" here
 
(defmethod! sox-dither ((noiseshape string) &key auto-mode)
                :icon 90
                :initvals '("triangular" t)
                :indoc '("Select a noise-shaping filter from the menu." "Enables a mode where dithering (and noise-shaping if applicable) are automatically enabled only when needed.")
                :menuins '((0 (("triangular" "triangular") ("sloped-triangular" "sloped-triangular") ("lipshitz" "lipshitz") ("f-weighted" "f-weighted") ("modified-e-weighted" "modified-e-weighted") ("improved-e-weighted" "improved-e-weighted") ("gesemann" "gesemann") ("shibata" "shibata") ("low-shibata" "low-shibata") ("high-shibata" "high-shibata"))))
                :doc "Introduce dithering noise to mask quantization artefacts when reducing bit depth.
 
Adds a small amount of noise to the signal in order to mask audible quantization effects that can occur if the output bit depth is less than 24 bits. 
Note, that most noiseshape types are available only with 44100Hz sample rate.
The most likely use for <auto-mode> is when applying fade in or out to an already dithered file, so that the redithering applies only to the faded portions. 
However, auto dithering is not fool-proof, so the fades should be carefully checked for any noise modulation.
This effect cannot be followed by any other sox-effect."
 
                (let ((thestring (format nil "dither ")))
                  (when auto-mode (setf thestring (concatenate 'string thestring (format nil " -a"))))
                  (when (equal noiseshape "sloped-triangular")
                    (setf thestring (concatenate 'string thestring (format nil " -S"))))
                  (unless (or (equal noiseshape "triangular") (equal noiseshape "sloped-triangular"))
                         (setf thestring (concatenate 'string thestring (format nil " -f ~a" noiseshape))))
                  thestring))
 
 
;;; Sox-resample ==========================
 
(defmethod! sox-resample ((samplerate number) &key quality sox-append)
                :icon 60
                :initvals '(48000 "high" nil)
                :menuins '((0 (("4kHz" 4000) ("8kHz" 8000) ("16kHz" 16000) ("20kHz" 20000) ("30kHz" 30000) ("44.1kHz" 44100) ("48kHz" 48000) ("88.2kHz" 88200) ("96kHz" 96000) ("192kHz" 192000))) 
                           (1 (("quick" "quick") ("low" "low") ("medium" "medium") ("high" "high") ("very high" "very high") ("very high linear phase" "very high linear phase") 
                               ("very high intermediate phase" "very high intermediate phase") ("very high minimum phase" "very high minimum phase"))))
                :indoc (list "samplerate (Hz)" "choose algorithm for samplerate-conversion" *sox-append-doc*)
                :doc "Changes the sampling rate of audio to <samplerate> with choice of algorithm <quality>."
 
                (let ((thestring (format nil "rate ")))     ; this could be done more elegantly with assoc
                  (cond ((equal quality "quick")
                         (setf thestring (concatenate 'string thestring (format nil " -q"))))
                        ((equal quality "low")
                         (setf thestring (concatenate 'string thestring (format nil " -l"))))
                        ((equal quality "medium")
                         (setf thestring (concatenate 'string thestring (format nil " -m"))))
                        ((equal quality "high")
                         (setf thestring (concatenate 'string thestring (format nil " -h"))))
                        ((equal quality "very high")
                         (setf thestring (concatenate 'string thestring (format nil " -v"))))
                        ((equal quality "very high linear phase")
                         (setf thestring (concatenate 'string thestring (format nil " -v -s"))))
                        ((equal quality "very high intermediate phase")
                         (setf thestring (concatenate 'string thestring (format nil " -v -s -I"))))
                        ((equal quality "very high minimum phase")
                         (setf thestring (concatenate 'string thestring (format nil " -v -s -M")))))
                  (setf thestring (concatenate 'string thestring (format nil " ~d" samplerate)))
                  (sox-concat sox-append thestring))
                )
 
;;; SoX-upsample and SoX-downsample are almost mathematical DSP functions (similar to sox-multiply etc.)
;;; SoX-upsample ===============================
 
(defmethod! sox-upsample ((factor integer) &key sox-append)
  :icon 21
  :initvals '(2 nil)
  :indoc (list "Upsamle factor (integer)"  *sox-append-doc*)
  :doc "Upsample the signal by an integer factor. 
 
factor-1 zero-value samples are inserted between each pair of input samples. As a result, the original spectrum is replicated into the new frequency space (aliasing) and attenuated.
This attenuation can be compensated for by amplifying the input signal by <factor> after any further processing. The upsample effect is typically used in combination with filtering effects.
 
See also sox-downsample. For a general resampling effect with anti-aliasing, see sox-resample."
 
 
  (let* ((thestring (format nil " upsample ~d" factor)))
    (sox-concat sox-append thestring))
  )
 
;;; SoX-downsample ===============================
 
(defmethod! sox-downsample ((factor integer) &key sox-append)
  :icon 21
  :initvals '(2 nil)
  :indoc (list "Downsample factor (integer)"  *sox-append-doc*)
  :doc "Downsample the signal by an integer factor. 
 
Downsample the signal by an integer factor: Only the first out of each factor samples is retained, the others are discarded.
No decimation filter is applied. If the input is not a properly bandlimited baseband signal, aliasing will occur. This may be desirable, e.g., for frequency translation.
 
See also sox-upsample. For a general resampling effect with anti-aliasing, see sox-resample."
 
  (let* ((thestring (format nil " downsample ~d" factor)))
    (sox-concat sox-append thestring))
  )
 
; Sox-oops ===============================
; (Out of Phase Stereo (Karaoke) Effect)
 
(defmethod! sox-oops (&key sox-append)
  :icon 60
  :initvals '()
  :indoc (list *sox-append-doc*)
  :doc "Out-Of-Phase-Stereo effect. Mixes stereo to twin-mono where each mono channel contains the difference between the left and right stereo channels. 
 
This is sometimes known as the 'karaoke' effect as it often has the effect of removing most or all of the vocals from a recording."
 
  (let ((thestring (format nil " oops")))
    (setf thestring (sox-concat sox-append thestring))
    thestring)
  )
 
 
;;; +++++++++++ HELPER FUNCTIONS ++++++++++++
 
; sox-monofy ===============================
 
(defmethod! sox-monofy ( &key sox-append )                        
            :icon 60
            :initvals '(nil)
            :indoc (list *sox-append-doc*)
            :doc "Mixes all channels in multichannel audio down to a single channel."
 
            (let* (
                   (thestring (format nil " channels 1")))
              (sox-concat sox-append thestring))
            )
 
 
; Sox-downmix ===============================
 
(defmethod! sox-downmix ( &key (channels 1) sox-append )                        
            :icon 60
            :initvals '(1 nil)
            :indoc (list "number of channels" *sox-append-doc*)
            :doc "Mixes all channels in multichannel audio down to a number of channels specified in <channels>"
            (let ((thestring (format nil " channels ~d" channels)))
              (sox-concat sox-append thestring)
              ))
 
;;; Sox-Invert ==============================
 
(defmethod! sox-invert ( &key sox-append)
            :icon 60
            :initvals '(nil)
            :indoc (list *sox-append-doc*)
            :doc "Inverts the phase of the audio signal"
 
            (let ((thestring (format nil "vol -1")))
              (sox-concat sox-append thestring))
            )
 
 
;;; Sox-Clipguard ==========================
 
(defmethod! sox-clipguard (&key sox-append)                        
            :icon 60
            :initvals ' (nil)
            :indoc (list *sox-append-doc*)
            :doc "Prevents the processing chain from clipping."
 
            (let ((thestring (format nil " gain -nh ")))
              (sox-concat sox-append thestring))
              )