Work-in-progress repo for ambisonics extensions for OM-SoX
Marlon Schumacher
9 days ago 124c935cf1e7d639506bf1fca048646ef1a4bf2f
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 ;%%%%%%%%%%%% Time/Frequency %%%%%%%%%%%%%%%%%%%%%%%%
31
32 ;; Sox-Transpose ==================================
33
34 (defmethod! sox-transpose ((transposition number) &key segment search overlap sox-append)
35   :icon 50
36   :initvals '(nil 82 14.68 12 nil)
37   :indoc (list "transposition in midicents" "segment-size (ms)" "search-size (ms)" "overlap (ms)" *sox-append-doc*)
38   :doc "Transposes a sound (without changing the speed/length).
39
40 This effect uses the WSOLA algorithm. The audio is chopped up into segments which are then shifted in the time domain and overlapped (cross-faded) at points where their waveforms are most similar as determined by measurement of 'least squares'."
41
42   (let* ((thestring (format nil " pitch ~a ~d ~d ~d" transposition (or segment 82) (or search 14.68) (or overlap 12))))
43     (sox-concat sox-append thestring))
44   )
45
46 ;; Sox-Multitranspose
47
48 ;; keep the delta-times in the list-based function, but use start-times and 0 bend (or vice versa) for th BPF case
49
50 (defmethod! sox-multi-transpose ((midicents list) (delta-times list) (durations list) &key (framerate 25) (oversampling 16) sox-append) 
51   :icon 50
52   :initvals '(nil nil nil 25 16 nil)
53   :indoc (list "transposition in midicents (list) or pitch-profile (bpf)" "Delta-times between transpositions (in secs) or pitch-profile (bpf)" "duration of 'portamento'" "framerate of DFTs" "oversampling factor" *sox-append-doc*)
54   :doc "Changes pitch by specified amounts at specified times (without changing the speed). 
55
56 The pitch-bending algorithm utilises the Discrete Fourier Transform (DFT) at a particular frame rate and over-sampling rate. 
57 The <framerate> (default: 25, max: 64) and <oversampling> (default: 16, max: 32) parameters may be used to adjust these parameters and thus control the smoothness of the changes in pitch.
58 "  
59
60 ;delay is the amount of time after the start of the audio stream, or the end of the previous bend, at which to start bending the pitch
61 ;cents is the number of cents
62 ;duration the length of time over which the pitch will be bent.
63
64 ;(delta-times should be 'start times' absolute not, deltas
65
66   (let* (
67          (thestring (format nil "bend -f ~d -o ~d" (clip (or framerate 25) 1 64) (clip (or oversampling) 1 32))))
68          ;(delta-times (x-append (first start-times) (x->dx start-times))))
69     (unless (listp midicents)
70       (setf midicents
71             (make-list (length delta-times) :initial-element midicents)))
72     (unless (listp durations)
73       (setf durations
74             (make-list (length delta-times) :initial-element (clip durations 0.001 9999))))
75     (loop for time in delta-times
76           for cents in midicents
77           for durs in durations do
78           (setf thestring (concatenate 'string thestring
79                                         (format nil " ~d,~d,~d" time cents durs))))
80               (sox-concat sox-append thestring))
81   )
82
83
84 (defmethod! sox-multi-transpose ((midicents bpf) (delta-times list) (durations list) &key (framerate 25) (oversampling 16) sox-append)
85   (let* ((thepoints (mat-trans (point-pairs midicents)))
86          ;(thedxpoints (mat-trans (list (x-append (first (first thepoints)) (x->dx (first thepoints))) (x->dx (second thepoints)))))
87          (thexpoints (loop for item in (x->dx (first thepoints)) collect
88                            (if (= 0 item) 0.001 item)))
89                       
90          (theypoints (loop for item in (x->dx (second thepoints)) collect
91                            (if (= 0 item)  0.01 item)))
92                              
93          (thedxpoints (mat-trans (list thexpoints theypoints)))
94         
95          (thestring (format nil " bend -f ~a -o ~a" framerate oversampling)))
96
97     (loop for pair in thedxpoints collect
98           (setf thestring (concatenate 'string thestring         
99                                        (format nil " 0,~d,~d" (second pair) (first pair))))
100           )
101     (sox-concat sox-append thestring)
102     ))
103
104 ;; Sox-Stretch ==================================
105
106 (defmethod! sox-stretch ((factor number) &key preset segment (search 14.68) (overlap 12) sox-append)
107   :icon 50
108   :initvals '(nil nil nil nil nil nil)
109   :menuins '((1 (("music" "-m") ("speech" "-s") ("linear" "-l"))))
110   :indoc (list "stretch-factor" "preset (default = linear)" "segment-size (ms)" "search-size (ms)" "overlap (ms)" *sox-append-doc*)
111   :doc "Stretch/compress a sound temporally (without changing the pitch).
112
113 This effect uses the WSOLA algorithm. The audio is chopped up into segments which are then shifted in the time domain and overlapped (cross-faded) at points where their waveforms are most similar as determined bymeasurement of 'least squares'."
114
115   (let* (
116         (thestring (format nil "tempo"))
117         (factor (float (/ 1 factor))))
118     (if preset     
119         (setf thestring (concatenate 'string thestring 
120                                      (format nil " ~a ~a" preset factor)))
121       (setf thestring (concatenate 'string thestring 
122                                    (format nil " ~a ~d ~d ~d" factor (or segment 82) (or search 14.68) (or (clip overlap 0 search) 12)))))
123     (sox-concat sox-append thestring))
124   )
125
126 ;; Sox-Speed ==================================
127
128 (defmethod! sox-speed ((speed number) &key mode sox-append)
129   :icon 50
130   :initvals '(nil "ratio" nil)
131   :menuins '((1 (("ratio" "ratio") ("midicent" "midicent"))))
132   :indoc (list "speed-factor / midicents (depending on mode)" 
133                "ratio or midicent to control change in speed (default = ratio)" 
134                *sox-append-doc*)
135   :doc "Adjust the audio speed (pitch and tempo together). 
136
137 Speed is either the ratio of the new speed to the old speed: greater than 1 speeds up, less than 1 slows down, or, depending on 'mode' the number of cents by which the pitch (and tempo) should be adjusted: greater than 0 increases, less than 0 decreases."
138
139   (let* ((thestring (format nil "speed ~d" speed)))
140     (when (equal mode "midicent")
141       (setf thestring (concatenate 'string thestring 
142                                    (format nil "c" sox-append))))
143    (sox-concat sox-append thestring))
144   )
145