Mercurial > hg > chourdakisreiss2016
comparison training-sessions/jacob.harrison/mapping.py @ 0:246d5546657c
initial commit, needs cleanup
author | Emmanouil Theofanis Chourdakis <e.t.chourdakis@qmul.ac.uk> |
---|---|
date | Wed, 14 Dec 2016 13:15:48 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:246d5546657c |
---|---|
1 # -*- coding: utf-8 -*- | |
2 """ | |
3 Created on Mon Mar 7 13:03:01 2016 | |
4 | |
5 @author: Emmanouil Theofanis Chourdakis | |
6 """ | |
7 | |
8 #from numpy import * | |
9 from scipy.optimize import * | |
10 from numpy import sqrt,array,polyval,exp,log,log10,mean,sum,var,loadtxt | |
11 | |
12 ga = sqrt(2) | |
13 g1_min = 0.001 | |
14 g1_max = 0.999 | |
15 | |
16 d1_min = 0.010 | |
17 d1_max = 0.900 | |
18 | |
19 da_min = 0.006 | |
20 da_max = 0.012 | |
21 | |
22 gc_min = 0.001 | |
23 gc_max = 0.999 | |
24 | |
25 G_min = 0.001 | |
26 G_max = 0.999 | |
27 | |
28 # Limits are defined by the variables minima and maxima | |
29 | |
30 T60_min = 0.2 | |
31 T60_max = 4 | |
32 # | |
33 D_min = 1000 | |
34 D_max = 10000 | |
35 # | |
36 C_min = -20 | |
37 C_max = 10 | |
38 # | |
39 Tc_min = 0.01 | |
40 Tc_max = 2.0 | |
41 # | |
42 SC_min = 200 | |
43 SC_max = 11025 | |
44 def normalize(f,fmin,fmax): | |
45 return (f - fmin)/(fmax - fmin) | |
46 | |
47 def normalize_param(p): | |
48 return array([ | |
49 normalize(p[0],T60_min,T60_max), | |
50 normalize(p[1],D_min,D_max), | |
51 normalize(p[2],C_min,C_max), | |
52 normalize(p[3],Tc_min,Tc_max) | |
53 ]) | |
54 | |
55 def get_high_param_norm(x): | |
56 return array([ | |
57 normalize(T60(x),T60_min,T60_max), | |
58 normalize(D(x),D_min,D_max), | |
59 normalize(C(x),C_min,C_max), | |
60 normalize(Tc(x),Tc_min,Tc_max) | |
61 ]) | |
62 def T601d(d1,g1,gc,G): | |
63 g1 = abs(g1) | |
64 return -d1/log(g1)*(log(G)+log(1-gc)+log(ga)+3*log(10)) | |
65 | |
66 | |
67 | |
68 def D1d(d1,da,t=0.1): | |
69 kS = 20.78125 | |
70 | |
71 return kS*t/d1/da | |
72 | |
73 | |
74 def C1d(g1,gc, G): | |
75 s_ = 0 | |
76 for k in range(1, 7): | |
77 s_ += g1**(2*1.5**(1-k))/(1-g1**(2*1.5**(1-k))) | |
78 | |
79 return -10 * log10(G**2*(1-gc)/(1+gc)*s_) | |
80 | |
81 def Tc1d(d1,da,g1): | |
82 gk = lambda k: g1**(1.5)**(1-k) | |
83 dk = lambda k: d1*1.5**(1-k) | |
84 | |
85 sum1 = 0 | |
86 sum2 = 0 | |
87 | |
88 for k in range(1, 7): | |
89 s1 = gk(k)**2/(1-gk(k)**2) | |
90 sum2 += s1 | |
91 sum1 += dk(k)*s1/(1-gk(k)**2) | |
92 | |
93 return sum1/sum2 + da | |
94 | |
95 def Tc_g1_d1_D(d1,g1,D, t=0.1): | |
96 S1 = sum([1.5**(-k + 1)*d1*g1**(2*1.5**(-k + 1))/(-g1**(2*1.5**(-k + 1)) + 1)**2 for k in range(1, 7)]) | |
97 S2 = sum([g1**(2*1.5**(-k + 1))/(-g1**(2*1.5**(-k + 1)) + 1) for k in range(1, 7)]) | |
98 Tc = S1/S2 + 20.78125*t/(D*d1) | |
99 return Tc | |
100 | |
101 def T60_d1_g1_C(d1,g1,gc,C): | |
102 # S1 = sum([g1**(2*1.5**(-k + 1))/(-g1**(2*1.5**(-k + 1)) + 1) for k in range(1, 7)]) | |
103 g1 = abs(g1) | |
104 s_ = 0 | |
105 for k in range(1, 7): | |
106 s_ += g1**(2*1.5**(1-k))/(1-g1**(2*1.5**(1-k))) | |
107 | |
108 T60 = d1*log(0.001/ga*exp(C*log(10)/20)/(sqrt((gc + 1)/((-gc + 1)*s_))*(-gc + 1)))/log(g1) | |
109 | |
110 return T60 | |
111 | |
112 def d1_g1_T60_C(g1,gc,T60,C): | |
113 g1 = abs(g1) | |
114 s_ = 0 | |
115 for k in range(1, 7): | |
116 s_ += g1**(2*1.5**(1-k))/(1-g1**(2*1.5**(1-k))) | |
117 #S1 = sum([g1**(2*1.5**(-k + 1))/(-g1**(2*1.5**(-k + 1)) + 1) for k in range(1, 7)]) | |
118 | |
119 | |
120 d1 = T60*log(g1)/log(0.001/ga*exp(C*log(10)/20)/(sqrt((gc + 1)/((-gc + 1)*s_))*(-gc + 1))) | |
121 return d1 | |
122 | |
123 def G_g1_C(g1,gc, C): | |
124 | |
125 s_ = 0 | |
126 for k in range(1, 7): | |
127 s_ += g1**(2*1.5**(1-k))/(1-g1**(2*1.5**(1-k))) | |
128 | |
129 G = sqrt(exp(-C/10*log(10))/(1-gc)*(1+gc)/s_) | |
130 return G | |
131 | |
132 def da_d1_D(d1,gc, D,t=0.1): | |
133 return 20.78125*t/d1/D | |
134 | |
135 | |
136 def Tc_g1_T60_D_C(g1,gc, T60, D, C,SR=44100.0): | |
137 S1 = sum([g1**(2*1.5**(-k + 1))/(-g1**(2*1.5**(-k + 1)) + 1) for k in range(1, 7)]) | |
138 L1 = log(0.001*exp(C*log(10)/20)/(ga*sqrt((gc + 1)/((-gc + 1)*S1))*(-gc + 1))) | |
139 S2 = sum([1.5**(-k + 1)*T60*g1**(2*1.5**(-k + 1))*log(g1)/((-g1**(2*1.5**(-k + 1)) + 1)**2*L1) for k in range(1, 7)]) | |
140 Tc = S2/S1 + 20.78125*t*log(0.001*exp(C*log(10)/20)/(ga*sqrt((gc + 1)/((-gc + 1)*S1))*(-gc + 1)))/(D*T60*log(g1)) | |
141 | |
142 return Tc | |
143 | |
144 def f_gc(sc,SR=44100): | |
145 T = loadtxt('scmapping.csv') | |
146 SampleRates = T[:,0] | |
147 P = T[:,1:] | |
148 p = P[SampleRates == SR][0] | |
149 return polyval(p, sc) | |
150 | |
151 | |
152 def errorfunc(g1, Target, gc, weights=(1.0, 1.0, 1.0, 1.0),SR=44100.0): | |
153 | |
154 (kT60, kD, kC, kTc) = Target | |
155 G = G_g1_C(g1, gc, kC) | |
156 | |
157 | |
158 # Check bounds | |
159 | |
160 if G>G_max: | |
161 G = G_max | |
162 if G<G_min: | |
163 G = G_min | |
164 | |
165 | |
166 d1 = d1_g1_T60_C(g1,gc, kT60, kC) | |
167 | |
168 if d1>d1_max: | |
169 d1 = d1_max | |
170 if d1<d1_min: | |
171 d1 = d1_min | |
172 | |
173 da = da_d1_D(d1, gc, kD) | |
174 | |
175 if da>da_max: | |
176 da = da_max | |
177 if da<da_min: | |
178 da = da_min | |
179 | |
180 T_60_est = T601d(d1,g1,gc,G) | |
181 D_est = D1d(d1,da) | |
182 C_est = C1d(g1,gc,G) | |
183 Tc_est = Tc1d(d1,da,g1) | |
184 | |
185 est_vect = normalize_param(array([T_60_est, D_est, C_est, Tc_est])) | |
186 orig_vect = normalize_param([kT60, kD, kC, kTc]) | |
187 | |
188 errvec = abs(est_vect-orig_vect) | |
189 w1 = weights[0] | |
190 w2 = weights[1] | |
191 w3 = weights[2] | |
192 w4 = weights[3] | |
193 | |
194 errvec = array([w1*errvec[0],w2*errvec[1],w3*errvec[2],w4*errvec[3]]) | |
195 | |
196 return mean(errvec**2) + var(errvec**2)**2 #+ skew(abs(est_vect-orig_vect)**2) | |
197 | |
198 def SC1d(gc,SR=44100): | |
199 | |
200 lut = 1-2*gc*cos(2*pi*arange(0,int(SR/2)+1)/SR)+gc**2 | |
201 | |
202 fgcn = lambda n: 1/lut[n] | |
203 | |
204 sum1 = 0 | |
205 sum2 = 0 | |
206 | |
207 for n in range(0, int(SR/2)): | |
208 fgcn_ = fgcn(n) | |
209 sum1 += n*fgcn_ | |
210 sum2 += fgcn_ | |
211 | |
212 return sum1/sum2 | |
213 | |
214 | |
215 def forward_mapping(d1, da, g1, gc, G): | |
216 SC = SC1d(gc) | |
217 T60 = T601d(d1,g1,gc,G) | |
218 D = D1d(d1,da) | |
219 C = C1d(g1,gc,G) | |
220 Tc = Tc1d(d1,da,g1) | |
221 | |
222 return (T60, D, C, Tc, SC) | |
223 | |
224 def inverse_mapping(T60, D, C, Tc, SC, SR=44100): | |
225 """ returns a vector (d1, da, g1, gc, G) of filter coefficients """ | |
226 | |
227 #1. Estimate gc from spectral centroid | |
228 gc = f_gc(SC, SR) | |
229 print gc | |
230 | |
231 #2. Estimate g1 | |
232 g1 = minimize_scalar(lambda x: errorfunc(x, (T60,D,C,Tc), gc), bounds=(g1_min,g1_max), method='bounded').x | |
233 | |
234 #4. a. Estimate G from G_g1_C | |
235 G = G_g1_C(g1, gc, C) | |
236 if G > G_max: | |
237 G = G_max | |
238 elif G < G_min: | |
239 G = G_min | |
240 | |
241 #4. b. Estimate d1 from d1_g1_T60_C | |
242 d1 = d1_g1_T60_C(g1,gc,T60,C) | |
243 if d1 > d1_max: | |
244 d1 = d1_max | |
245 elif d1 < d1_min: | |
246 d1 = d1_min | |
247 | |
248 #4. c. Estimate da from da_d1_D | |
249 da = da_d1_D(d1,gc, D) | |
250 if da > da_max: | |
251 da = da_max | |
252 elif da < da_min: | |
253 da = da_min | |
254 | |
255 return (d1, da, g1, gc, G) | |
256 |