Mercurial > hg > chourdakisreiss2016
view cpp/chourdakisreiss2016cpp/mapping.py @ 2:c87a9505f294 tip
Added LICENSE for code, removed .wav files
author | Emmanouil Theofanis Chourdakis <e.t.chourdakis@qmul.ac.uk> |
---|---|
date | Sat, 30 Sep 2017 13:25:50 +0100 |
parents | 144fbd1d29c3 |
children |
line wrap: on
line source
# -*- coding: utf-8 -*- """ Created on Mon Mar 7 13:03:01 2016 @author: Emmanouil Theofanis Chourdakis """ #from numpy import * from scipy.optimize import * from numpy import sqrt,array,polyval,exp,log,log10,mean,sum,cos,pi,arange,var,loadtxt ga = sqrt(2) g1_min = 0.001 g1_max = 0.999 d1_min = 0.010 d1_max = 0.900 da_min = 0.006 da_max = 0.012 gc_min = 0.001 gc_max = 0.999 G_min = 0.001 G_max = 0.999 # Limits are defined by the variables minima and maxima T60_min = 0.2 T60_max = 4 # D_min = 1000 D_max = 10000 # C_min = -20 C_max = 10 # Tc_min = 0.01 Tc_max = 2.0 # SC_min = 200 SC_max = 11025 def normalize(f,fmin,fmax): return (f - fmin)/(fmax - fmin) def normalize_param(p): return array([ normalize(p[0],T60_min,T60_max), normalize(p[1],D_min,D_max), normalize(p[2],C_min,C_max), normalize(p[3],Tc_min,Tc_max) ]) def get_high_param_norm(x): return array([ normalize(T60(x),T60_min,T60_max), normalize(D(x),D_min,D_max), normalize(C(x),C_min,C_max), normalize(Tc(x),Tc_min,Tc_max) ]) def T601d(d1,g1,gc,G): g1 = abs(g1) return -d1/log(g1)*(log(G)+log(1-gc)+log(ga)+3*log(10)) def D1d(d1,da,t=0.1): kS = 20.78125 return kS*t/d1/da def C1d(g1,gc, G): s_ = 0 for k in range(1, 7): s_ += g1**(2*1.5**(1-k))/(1-g1**(2*1.5**(1-k))) return -10 * log10(G**2*(1-gc)/(1+gc)*s_) def Tc1d(d1,da,g1): gk = lambda k: g1**(1.5)**(1-k) dk = lambda k: d1*1.5**(1-k) sum1 = 0 sum2 = 0 for k in range(1, 7): s1 = gk(k)**2/(1-gk(k)**2) sum2 += s1 sum1 += dk(k)*s1/(1-gk(k)**2) return sum1/sum2 + da def Tc_g1_d1_D(d1,g1,D, t=0.1): 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)]) S2 = sum([g1**(2*1.5**(-k + 1))/(-g1**(2*1.5**(-k + 1)) + 1) for k in range(1, 7)]) Tc = S1/S2 + 20.78125*t/(D*d1) return Tc def T60_d1_g1_C(d1,g1,gc,C): # S1 = sum([g1**(2*1.5**(-k + 1))/(-g1**(2*1.5**(-k + 1)) + 1) for k in range(1, 7)]) g1 = abs(g1) s_ = 0 for k in range(1, 7): s_ += g1**(2*1.5**(1-k))/(1-g1**(2*1.5**(1-k))) T60 = d1*log(0.001/ga*exp(C*log(10)/20)/(sqrt((gc + 1)/((-gc + 1)*s_))*(-gc + 1)))/log(g1) return T60 def d1_g1_T60_C(g1,gc,T60,C): g1 = abs(g1) s_ = 0 for k in range(1, 7): s_ += g1**(2*1.5**(1-k))/(1-g1**(2*1.5**(1-k))) #S1 = sum([g1**(2*1.5**(-k + 1))/(-g1**(2*1.5**(-k + 1)) + 1) for k in range(1, 7)]) d1 = T60*log(g1)/log(0.001/ga*exp(C*log(10)/20)/(sqrt((gc + 1)/((-gc + 1)*s_))*(-gc + 1))) return d1 def G_g1_C(g1,gc, C): s_ = 0 for k in range(1, 7): s_ += g1**(2*1.5**(1-k))/(1-g1**(2*1.5**(1-k))) G = sqrt(exp(-C/10*log(10))/(1-gc)*(1+gc)/s_) return G def da_d1_D(d1, D,t=0.1): return 20.78125*t/d1/D def Tc_g1_T60_D_C(g1,gc, T60, D, C,SR=44100.0,t=0.1): S1 = sum([g1**(2*1.5**(-k + 1))/(-g1**(2*1.5**(-k + 1)) + 1) for k in range(1, 7)]) L1 = log(0.001*exp(C*log(10)/20)/(ga*sqrt((gc + 1)/((-gc + 1)*S1))*(-gc + 1))) 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)]) 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)) return Tc def sc_csv_to_c(): T = loadtxt('scmapping.csv') SampleRates = T[:,0] P = T[:,1:] str_ = "" for SR in SampleRates: p = P[SampleRates == SR][0] str_ += "case %d:\n" % SR str_ += "\tp0 = %1.18e;\n\tp1 = %1.18e;\n\tp2 = %1.18e;\n\tp3 = %1.18e;\n\tp4 = %1.18e;\n" % (p[0], p[1], p[2], p[3], p[4]) str_ += "break;\n" return str_ def f_gc(sc,SR=44100): T = loadtxt('scmapping.csv') SampleRates = T[:,0] P = T[:,1:] p = P[SampleRates == SR][0] return polyval(p, sc) def errorfunc(g1, Target, gc, weights=(1.0, 1.0, 1.0, 1.0),SR=44100.0): (kT60, kD, kC, kTc) = Target G = G_g1_C(g1, gc, kC) # print "G1: ", g1 # print "G: ", G # Check bounds if G>G_max: G = G_max if G<G_min: G = G_min d1 = d1_g1_T60_C(g1,gc, kT60, kC) # print "D1: ", d1 if d1>d1_max: d1 = d1_max if d1<d1_min: d1 = d1_min da = da_d1_D(d1, kD) # print "DA: ", da if da>da_max: da = da_max if da<da_min: da = da_min T_60_est = T601d(d1,g1,gc,G) D_est = D1d(d1,da) C_est = C1d(g1,gc,G) Tc_est = Tc1d(d1,da,g1) # print "TCEST:", Tc_est # print "T_60_est", T_60_est # print "D_est", D_est # print "C_est", C_est # print "Tc_est", Tc_est # est_vect = normalize_param([T_60_est, D_est, C_est, Tc_est]) orig_vect = normalize_param([kT60, kD, kC, kTc]) errvec = abs(est_vect-orig_vect) # print "ESTVEC: ", est_vect # print "ORIVEC: ", orig_vect # # print "ERRVEC: ", errvec w1 = weights[0] w2 = weights[1] w3 = weights[2] w4 = weights[3] errvec = array([w1*errvec[0],w2*errvec[1],w3*errvec[2],w4*errvec[3]]) return mean(errvec**2) + var(errvec**2)**2 #+ skew(abs(est_vect-orig_vect)**2) def SC1d(gc,SR=44100): lut = 1-2*gc*cos(2*pi*arange(0,int(SR/2)+1)/SR)+gc**2 fgcn = lambda n: 1/lut[n] sum1 = 0 sum2 = 0 for n in range(0, int(SR/2)): fgcn_ = fgcn(n) sum1 += n*fgcn_ sum2 += fgcn_ return sum1/sum2 def forward_mapping(d1, da, g1, gc, G): SC = SC1d(gc) T60 = T601d(d1,g1,gc,G) D = D1d(d1,da) C = C1d(g1,gc,G) Tc = Tc1d(d1,da,g1) return (T60, D, C, Tc, SC) def inverse_mapping(T60, D, C, Tc, SC, SR=44100): """ returns a vector (d1, da, g1, gc, G) of filter coefficients """ #1. Estimate gc from spectral centroid gc = f_gc(SC, SR) # print "GC: ",gc #2. Estimate g1 g1 = minimize_scalar(lambda x: errorfunc(x, (T60,D,C,Tc), gc), bounds=(g1_min,g1_max), method='bounded').x # print "G1: ", g1 #4. a. Estimate G from G_g1_C G = G_g1_C(g1, gc, C) if G > G_max: G = G_max elif G < G_min: G = G_min # print "G: ", G #4. b. Estimate d1 from d1_g1_T60_C d1 = d1_g1_T60_C(g1,gc,T60,C) if d1 > d1_max: d1 = d1_max elif d1 < d1_min: d1 = d1_min # print "D1: ", d1 #4. c. Estimate da from da_d1_D da = da_d1_D(d1,gc, D) if da > da_max: da = da_max elif da < da_min: da = da_min # print "DA: ", da return (d1, da, g1, gc, G) #print forward_mapping(0.1, 0.006, 0.5, 0.5, 0.5) #print forward_mapping(0.05, 0.006, 0.5, 0.5, 0.5) #print Tc_g1_d1_D(0.1,0.5,1000, t=0.1) #print T60_d1_g1_C(0.01, 0.9, 0.9, -5.0) #print d1_g1_T60_C(0.9, 0.8, 4.2, -10.0) #0.447907 #0.0788184 #0.945694 #print G_g1_C(0.2, 0.4, -2.0) #print da_d1_D(0.05, 0.1, 100) #print f_gc(11025, 44100) #0.415625 #print sc_csv_to_c() #-0.000462180326584 #0.980471 print "--" #print v= inverse_mapping(0.8465784284662089, 3463.5416666666665, -0.10779739192724623, 0.09213541733941949, 6419.2075162127485) #v = inverse_mapping(0.7, 3000, -5, 0.9, 5000) print v print forward_mapping(*v) #print forward_mapping(0.15437302257477994, 0.012, 0.22280866837217597, 0.63966852775153527, 0.999) # EST_VEC: # 0.170152218017423446 # 0.27372685185185186 # 0.663073420269091773 # 0.0412740845527812192 # # ORI_VEC: # 0.17015221801742339 # 0.27372685185185186 # 0.663073420269091773 # 0.0412740790650349201 # # ERR_VEC: # 5.5511151231257827e-17 # 0 # 0 # 5.48774629904880129e-09 # inverse mapping: # 0.100257463495416962 # 0.00299229593030461835 # 0.498999999999999999 # 0.499829818494971656 # 0.500748281620112645 #print "---" #print errorfunc(0.4, (0.8465784284662089, 3463.5416666666665, -0.10779739192724623, 0.09213541733941949), 0.3) #print T601d(0.30876416353,0.1,0.8,1.9511185262)