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