mi@0
|
1 #!/usr/bin/env python
|
mi@0
|
2 # encoding: utf-8
|
mi@0
|
3 """
|
mi@0
|
4 GmmFeature.py
|
mi@0
|
5
|
mi@0
|
6 Created by George Fazekas on 2014-05-30.
|
mi@0
|
7 Copyright (c) 2014 . All rights reserved.
|
mi@0
|
8 """
|
mi@0
|
9
|
mi@0
|
10 import sys, os, math, wave, struct, cPickle
|
mi@0
|
11 from pprint import pprint
|
mi@0
|
12 from os.path import join, isdir, isfile, abspath, dirname, basename, split, splitext
|
mi@0
|
13 from itertools import *
|
mi@0
|
14 import matplotlib.pyplot as plt
|
mi@0
|
15 from numpy import sum,isnan, log, power, pi, exp, transpose
|
mi@0
|
16 from numpy.random import rand
|
mi@0
|
17 import numpy as np
|
mi@0
|
18 from sklearn.mixture import GMM
|
mi@0
|
19 from sklearn.metrics.pairwise import pairwise_distances
|
mi@0
|
20 from scipy.linalg import *
|
mi@0
|
21 from scipy.io.wavfile import read
|
mi@0
|
22 # from wavebender import *
|
mi@0
|
23 from gmmdist import skl_models
|
mi@0
|
24
|
mi@0
|
25 outFile = '/Users/mitian/Documents/hg/seg/test/distance.txt'
|
mi@0
|
26 audioDir = '/Users/mitian/Documents/hg/seg/audio'
|
mi@0
|
27
|
mi@0
|
28
|
mi@0
|
29 class GaussianComponent(object):
|
mi@0
|
30 '''GMM representations of data.'''
|
mi@0
|
31 __slots__ = ['weight','means','covars']
|
mi@0
|
32
|
mi@0
|
33 def __getstate__(self):
|
mi@0
|
34 d = {}
|
mi@0
|
35 for obj in GaussianComponent.__slots__ :
|
mi@0
|
36 d.update({obj:getattr(self,obj)})
|
mi@0
|
37 return d
|
mi@0
|
38
|
mi@0
|
39 def __setstate__(self,d):
|
mi@0
|
40 for k,v in d.iteritems() :
|
mi@0
|
41 setattr(self,k,v)
|
mi@0
|
42
|
mi@0
|
43 class AudioObj(object):
|
mi@0
|
44 '''A class to store generated audio samples.'''
|
mi@0
|
45 __slots__ = ['name', 'data']
|
mi@0
|
46
|
mi@0
|
47 class FeatureObj(object):
|
mi@0
|
48 '''A class to store extracted features for audio samples.'''
|
mi@0
|
49 __slots__ = ['audio', 'mean', 'std', 'sc', 'sl']
|
mi@0
|
50
|
mi@0
|
51 class DistanceObj(object):
|
mi@0
|
52 '''A class to store calculated GMM distances.'''
|
mi@0
|
53 __slots__ = ['audio1', 'audio2', 'nComponents', 'skl_diag', 'skl_full', 'c2', 'euclidean', 'bhattacharyya']
|
mi@0
|
54
|
mi@0
|
55 def save(self, filename=None):
|
mi@0
|
56 '''Save distance objects.'''
|
mi@0
|
57 if filename == None:
|
mi@0
|
58 filenmae = outFile
|
mi@0
|
59 f = open(filenmae,'a+')
|
mi@0
|
60 f.write(cPickle.dumps(self.__dict__))
|
mi@0
|
61 f.close()
|
mi@0
|
62
|
mi@0
|
63 class GmmDistance(object):
|
mi@0
|
64 '''Calculating distances between two pdfs using different distance metrics.'''
|
mi@0
|
65
|
mi@0
|
66 def __init__(self, feature_array, components = 1, save_data=False):
|
mi@0
|
67 self.n_components = components
|
mi@0
|
68 self.gmm = GMM(n_components = components, covariance_type='full')
|
mi@0
|
69 feature_array = np.nan_to_num(feature_array)
|
mi@0
|
70 feature_array[np.isinf(feature_array)] = 0.0
|
mi@0
|
71 feature_array[np.isnan(feature_array)] = 0.0
|
mi@0
|
72 self.model = self.gmm.fit(feature_array)
|
mi@0
|
73 if save_data :
|
mi@0
|
74 self.data = feature_array
|
mi@0
|
75 else :
|
mi@0
|
76 self.data = None
|
mi@0
|
77 if not self.model.converged_ :
|
mi@0
|
78 print "Warning: model fitting did not converge."
|
mi@0
|
79 self.means = self.model.means_
|
mi@0
|
80 self.covars = self.model.covars_
|
mi@0
|
81 self.weights = self.model.weights_
|
mi@0
|
82 self.label = -1 # used only for clustering
|
mi@0
|
83 self.components = []
|
mi@0
|
84 for c in range(self.n_components) :
|
mi@0
|
85 g = GaussianComponent()
|
mi@0
|
86 g.weight = self.weights[c]
|
mi@0
|
87 g.means = self.means[c]
|
mi@0
|
88 g.covars = self.covars[c]
|
mi@0
|
89 self.components.append(g)
|
mi@0
|
90
|
mi@0
|
91 def update(self):
|
mi@0
|
92 for c in range(self.n_components) :
|
mi@0
|
93 self.weights[c] = self.components[c].weight
|
mi@0
|
94 self.means[c] = self.components[c].means
|
mi@0
|
95 self.covars[c] = self.components[c].covars
|
mi@0
|
96
|
mi@0
|
97 def __str__(self):
|
mi@0
|
98 self.update()
|
mi@0
|
99 return "GMM object:\nmeans:%(means)s\ncovariances:%(covars)s\nweights%(weights)s" %vars(self)
|
mi@0
|
100
|
mi@0
|
101 def kl_div(self, p1, p2):
|
mi@0
|
102 '''Compute KL divergence between p1 and p2 with diagonal covariances.'''
|
mi@0
|
103 if p1.means is None or p2.means is None:
|
mi@0
|
104 return np.finfo(np.float64).max
|
mi@0
|
105 # d = ((0.5 * log(p2.covars**2/p1.covars**2)) - 0.5 + p1.covars**2/(2*p2.covars**2) + (abs(p2.means - p1.means)**2) / (2*p2.covars**2))
|
mi@0
|
106 d = -2.0 * p1.means.shape[0]
|
mi@0
|
107 d += sum( (p1.covars / p2.covars) + (p2.covars / p1.covars) + ((p1.means - p2.means) * ((1.0 / p1.covars) + (1.0 / p2.covars)) * (p1.means - p2.means)), dtype = np.float64 )
|
mi@0
|
108 if isnan(d) :
|
mi@0
|
109 return np.finfo(np.float64).max
|
mi@0
|
110 return d
|
mi@0
|
111
|
mi@0
|
112 def skl_distance_diag(self,other):
|
mi@0
|
113 '''Estimate the symmetrised Kullback–Leibler divergence between this and an other model.'''
|
mi@0
|
114 # TODO: the components are sorted so this works but still theoretically not quite correct to do this...
|
mi@0
|
115 assert (self.n_components == other.n_components), "Number of components must be equal."
|
mi@0
|
116 kl12 = kl21 = 0.0
|
mi@0
|
117 for i in range(self.n_components) :
|
mi@0
|
118 kl12 += self.weights[i] * self.kl_div(self.components[i],other.components[i])
|
mi@0
|
119 kl21 += other.weights[i] * self.kl_div(other.components[i],self.components[i])
|
mi@0
|
120 return (kl12 + kl21 ) / 2.0
|
mi@0
|
121
|
mi@0
|
122 def skl_distance_full(self,other):
|
mi@0
|
123 return skl_models(self,other)
|
mi@0
|
124
|
mi@0
|
125 def skl_distance_full_orig(self,other):
|
mi@0
|
126 '''Estimate the symmetrised Kullback–Leibler divergence between this and an other model.'''
|
mi@0
|
127 n = len(self.components) # number of components
|
mi@0
|
128 d = len(self.components[0].means) # number of dimensions
|
mi@0
|
129
|
mi@0
|
130 ixm = np.ones((n,1),dtype=int).T # selector of mean matrix components
|
mi@0
|
131 ixd = range(0,d*d,d+1) # indices of diagonal elements of DxD matrix
|
mi@0
|
132 t1 = self.covars.swapaxes(1,2).reshape(d,n*d) # concatenate gmm1 covariance matrices
|
mi@0
|
133 t2 = other.covars.swapaxes(1,2).reshape(d,n*d) # concatenate gmm2 covariance matrices
|
mi@0
|
134 loopn = xrange(n)
|
mi@0
|
135
|
mi@0
|
136 logdet1 = np.zeros((n,1))
|
mi@0
|
137 kl11 = np.zeros((n,n))
|
mi@0
|
138 for i in loopn :
|
mi@0
|
139 # step 1) precompute log(determinant()) of covariance matrices of gmm1
|
mi@0
|
140 logdet1[i] = log(det(self.covars.swapaxes(0,2)[:,:,i]))
|
mi@0
|
141
|
mi@0
|
142 # step 2) compute reference kldiv between individual components of gmm1
|
mi@0
|
143 inv1 = inv(self.covars.swapaxes(0,2)[:,:,i])
|
mi@0
|
144 mm1 = self.means - self.means[i*ixm,:][0]
|
mi@0
|
145 b1 = np.dot(inv1,t1).swapaxes(0,1).reshape(n,power(d,2)).T
|
mi@0
|
146 kl11[:,i] = 0.5 * ( (logdet1[i]-d-logdet1)[:,0] + sum(b1[ixd,:],0).T + sum(np.dot(mm1,inv1) * mm1,1))
|
mi@0
|
147 # print kl11
|
mi@0
|
148
|
mi@0
|
149 logdet2 = np.zeros((n,1))
|
mi@0
|
150 kl22 = np.zeros((n,n))
|
mi@0
|
151 for i in loopn :
|
mi@0
|
152 # step 3) precompute log(determinant()) of covariance matrices of gmm2
|
mi@0
|
153 logdet2[i] = log(det(other.covars.swapaxes(0,2)[:,:,i]))
|
mi@0
|
154 inv2 = inv(other.covars.swapaxes(0,2)[:,:,i])
|
mi@0
|
155 mm2 = other.means - other.means[i*ixm,:][0]
|
mi@0
|
156 b2 = np.dot(inv2,t2).swapaxes(0,1).reshape(n,power(d,2)).T
|
mi@0
|
157 kl22[:,i] = 0.5 * ( (logdet2[i]-d-logdet2)[:,0] + sum(b2[ixd,:],0).T + sum(np.dot(mm2,inv2) * mm2,1))
|
mi@0
|
158
|
mi@0
|
159 # step 4) compute pair-wise kldiv between components of gmm1 and gmm2
|
mi@0
|
160 kl12 = np.zeros((n,n))
|
mi@0
|
161 kl21 = np.zeros((n,n))
|
mi@0
|
162 for i in loopn :
|
mi@0
|
163 inv1 = inv(self.covars.swapaxes(0,2)[:,:,i])
|
mi@0
|
164 inv2 = inv(other.covars.swapaxes(0,2)[:,:,i])
|
mi@0
|
165 m12 = self.means - other.means[i*ixm,:][0]
|
mi@0
|
166 m21 = other.means - self.means[i*ixm,:][0]
|
mi@0
|
167 b1 = np.dot(inv1,t1).swapaxes(0,1).reshape(n,power(d,2)).T
|
mi@0
|
168 b2 = np.dot(inv2,t2).swapaxes(0,1).reshape(n,power(d,2)).T
|
mi@0
|
169 kl12[:,i] = 0.5 * ( (logdet2[i]-d-logdet1)[:,0] + sum(b2[ixd,:],0).T + sum(np.dot(m12,inv2) * m12,1))
|
mi@0
|
170 kl21[:,i] = 0.5 * ( (logdet1[i]-d-logdet2)[:,0] + sum(b1[ixd,:],0).T + sum(np.dot(m21,inv1) * m21,1))
|
mi@0
|
171
|
mi@0
|
172 # step 5) compute the final variational distance between gmm1 and gmm2
|
mi@0
|
173 kl_full_12 = np.dot(self.weights.T, (log(sum(exp(-kl11)*self.weights,1))) - log(sum(exp(-kl12)*other.weights,1)))
|
mi@0
|
174 kl_full_21 = np.dot(other.weights.T, (log(sum(exp(-kl22)*other.weights,1))) - log(sum(exp(-kl21)*self.weights,1)))
|
mi@0
|
175 return (kl_full_12 + kl_full_21 ) / 2.0
|
mi@0
|
176
|
mi@0
|
177 def emd(self, p1, p2):
|
mi@0
|
178 '''Compute earth movers distance between component p1 and p2'''
|
mi@0
|
179
|
mi@0
|
180 pass
|
mi@0
|
181
|
mi@0
|
182 def c2(self, p1, p2):
|
mi@0
|
183 d = power(det(p1.covars), -0.5) * power(det(p2.covars), -0.5)
|
mi@0
|
184 return d
|
mi@0
|
185
|
mi@0
|
186 def c2_distance(self, other):
|
mi@0
|
187 '''Compute the c2 pdf distance metric
|
mi@0
|
188 G. Sfikas etc. An analytic distance metric for Gaussian Mixture Models with application in image retrieval. ICANN 2005.
|
mi@0
|
189 '''
|
mi@0
|
190 d12 = d11 = d22 = 0.0
|
mi@0
|
191 for i in xrange(self.n_components) :
|
mi@0
|
192 for j in xrange(self.n_components) :
|
mi@0
|
193 V = inv(inv(self.covars[i]) + inv(other.covars[j]))
|
mi@0
|
194 K = self.means[i].T.dot(inv(self.covars[i])) * (self.means[i] - other.means[j]) + other.means[j].T.dot(inv(other.covars[j])) * (other.means[j] - self.means[i])
|
mi@0
|
195
|
mi@0
|
196 d12 += sum(self.weights[i] * other.weights[j] * power((det(V) / (exp(K) * self.c2(self.components[i], other.components[j]))), 0.5))
|
mi@0
|
197 d11 += sum(self.weights[i] * other.weights[j] * power((det(V) / (exp(K) * self.c2(self.components[i], self.components[j]))), 0.5))
|
mi@0
|
198 d22 += sum(self.weights[i] * other.weights[j] * power((det(V) / (exp(K) * self.c2(other.components[i], other.components[j]))), 0.5))
|
mi@0
|
199
|
mi@0
|
200 dist = -log(2 * d12 / (d11 + d22))
|
mi@0
|
201
|
mi@0
|
202 if isnan(dist) :
|
mi@0
|
203 return np.finfo(np.float64).max
|
mi@0
|
204 return dist
|
mi@0
|
205
|
mi@0
|
206 def euclidean(self, p1, p2):
|
mi@0
|
207 '''Compute euclidean distance between p1 and p2'''
|
mi@0
|
208 if p1.means is None or p2.means is None:
|
mi@0
|
209 return np.finfo(np.float64).max
|
mi@0
|
210 d = sum(power(2 * pi * (power(p1.covars, 2) + power(p2.covars, 2)), -0.5) * exp(-0.5 * power(p1.means - p2.means, 2) / (power(p1.covars, 2) + power(p2.covars, 2))))
|
mi@0
|
211
|
mi@0
|
212 if isnan(d) :
|
mi@0
|
213 return np.finfo(np.float64).max
|
mi@0
|
214 return d
|
mi@0
|
215
|
mi@0
|
216 def euclidean_distance(self, other):
|
mi@0
|
217 '''Compute the pdf distance metric'''
|
mi@0
|
218 e11 = e22 = e12 = 0.0
|
mi@0
|
219 for i in range(self.n_components) :
|
mi@0
|
220 e11 += self.weights[i] * self.weights[i] * self.euclidean(self.components[i],self.components[i])
|
mi@0
|
221 e22 += other.weights[i] * other.weights[i] * self.euclidean(other.components[i],other.components[i])
|
mi@0
|
222 e12 += self.weights[i] * other.weights[i] * self.euclidean(self.components[i],other.components[i])
|
mi@0
|
223
|
mi@0
|
224 dist = e11 + e22 - 2 * e12
|
mi@0
|
225
|
mi@0
|
226 if isnan(dist) :
|
mi@0
|
227 return np.finfo(np.float64).max
|
mi@0
|
228 return dist
|
mi@0
|
229
|
mi@0
|
230 def bhattacharyya(self, p1, p2):
|
mi@0
|
231 '''Compute the Bhattacharyya based distance following:
|
mi@0
|
232 K. Fukunaga. Introduction to statistical pattern recognition. Academic Press 1990
|
mi@0
|
233 '''
|
mi@0
|
234 B_dev = 0.125 * ((p1.means - p2.means).T.dot( inv((p1.covars + p2.covars) / 2))).dot(p1.means - p2.means)\
|
mi@0
|
235 + 0.5 * log( abs(inv((p1.covars + p2.covars) / 2)) / power(abs(inv(p1.covars) * inv(p2.covars)), 0.5) )
|
mi@0
|
236
|
mi@0
|
237 d = sum(B_dev)
|
mi@0
|
238 if isnan(d) :
|
mi@0
|
239 return np.finfo(np.float64).max
|
mi@0
|
240 return d
|
mi@0
|
241
|
mi@0
|
242 def bhattacharyya_distance(self, other):
|
mi@0
|
243 '''Compute the pdf distance metric'''
|
mi@0
|
244 dist = 0.0
|
mi@0
|
245 for i in xrange(self.n_components) :
|
mi@0
|
246 dist += self.weights[i] * other.weights[i] *self.bhattacharyya(self.components[i], other.components[i])
|
mi@0
|
247 return dist
|
mi@0
|
248
|
mi@0
|
249
|
mi@0
|
250 class AudioGenerator(object):
|
mi@0
|
251 '''Generate simple audio data (sinusoidal etc. and noise and their combinations).'''
|
mi@0
|
252
|
mi@0
|
253 def sine(self, freq=440.0, framerate=44100, amplitude=0.5, length=0.02):
|
mi@0
|
254 n = int(length * framerate)
|
mi@0
|
255 return np.array([amplitude * math.sin(2.0*math.pi * float(freq) * (float(i)/float(framerate))) for i in xrange(n)])
|
mi@0
|
256
|
mi@0
|
257 def noise(self, framerate=44100, amplitude=0.1, length=0.02):
|
mi@0
|
258 n = int(length * framerate)
|
mi@0
|
259 return np.array([float(amplitude) * np.random.uniform(-1, 1) for i in xrange(n)])
|
mi@0
|
260
|
mi@0
|
261 def square(self, freq=440.0, framerate=44100, amplitude=0.5, length=0.02):
|
mi@0
|
262 for s in self.sine(freq, framerate, amplitude, length):
|
mi@0
|
263 if s > 0:
|
mi@0
|
264 yield amplitude
|
mi@0
|
265 elif s < 0:
|
mi@0
|
266 yield -amplitude
|
mi@0
|
267 else:
|
mi@0
|
268 yield 0.0
|
mi@0
|
269
|
mi@0
|
270 def damped(self, freq=440.0, framerate=44100, amplitude=0.5, length=0.02):
|
mi@0
|
271 n = int(length*framerate)
|
mi@0
|
272 return (exp(-(float(i%n)/float(framerate))) * s for i, s in enumerate(self.sine(frequency, framerate, amplitude, length)))
|
mi@0
|
273
|
mi@0
|
274 def write_wav_file(self, samples,filename) :
|
mi@0
|
275 '''Create a wav file and write it to disk.'''
|
mi@0
|
276 nchannels, sampwidth, framerate, nframes = 1, 2, 44100, len(samples)
|
mi@0
|
277 max_amplitude = 32767.0
|
mi@0
|
278 w = wave.open(filename, 'w')
|
mi@0
|
279 w.setparams((nchannels, sampwidth, framerate, nframes, 'NONE', 'not compressed'))
|
mi@0
|
280 frames = str().join(struct.pack('h', int(max_amplitude * s)) for s in samples)
|
mi@0
|
281 w.writeframesraw(frames)
|
mi@0
|
282 w.close()
|
mi@0
|
283 print "wav file: %s written." %filename
|
mi@0
|
284
|
mi@0
|
285 class FeatureExtractor(object):
|
mi@0
|
286 '''Extract low level features of input audio samples for compare distance computation.'''
|
mi@0
|
287 def main():
|
mi@0
|
288
|
mi@0
|
289 # ag = AudioGenerator()
|
mi@0
|
290 # fe = FeatureExtractor()
|
mi@0
|
291 #
|
mi@0
|
292 # # Create a "test1.wav" file which is 10s length and contains two sinusoids + noise
|
mi@0
|
293 # length = 10.0 # unit = sG
|
mi@0
|
294 # samples = ag.sine(440.0,length=length) + ag.sine(240.0,length=length) + ag.noise(length=length)
|
mi@0
|
295 # samples = samples / (max(samples) + 0.05)
|
mi@0
|
296 # ag.write_wav_file(samples, "audio/test1.wav")
|
mi@0
|
297 # # Create a file indentical to 'test1.wav
|
mi@0
|
298 # ag.write_wav_file(samples,"audio/test1a.wav")
|
mi@0
|
299 # # Create a file with the same componentes as "test1.wav" but the freq of one sinusouid different
|
mi@0
|
300 # samples = ag.sine(440.0,length=length) + ag.sine(480.0,length=length) + ag.noise(length=length)
|
mi@0
|
301 # samples = samples / (max(samples) + 0.05)
|
mi@0
|
302 # ag.write_wav_file(samples, "audio/test1b.wav")
|
mi@0
|
303 # # Create a file with the same componentes as "test1.wav" but the freq of both sinusouids different
|
mi@0
|
304 # samples = ag.sine(880.0,length=length) + ag.sine(480.0,length=length) + ag.noise(length=length)
|
mi@0
|
305 # samples = samples / (max(samples) + 0.05)
|
mi@0
|
306 # ag.write_wav_file(samples, "audio/test1c.wav")
|
mi@0
|
307 #
|
mi@0
|
308 # # Create a file with one more sinusouid componentes as "test1.wav"
|
mi@0
|
309 # samples = ag.sine(440.0,length=length) + ag.sine(240.0,length=length) + ag.sine(880.0,length=length) + ag.noise(length=length)
|
mi@0
|
310 # samples = samples / (max(samples)+0.05)
|
mi@0
|
311 # ag.write_wav_file(samples, "audio/test2a.wav")
|
mi@0
|
312 # # Create a file with changed freq and one more sinusouid componentes as "test1.wav"
|
mi@0
|
313 # samples = ag.sine(440.0,length=length) + ag.sine(240.0,length=length) + ag.sine(1320.0,length=length) + ag.noise(length=length)
|
mi@0
|
314 # samples = samples / (max(samples)+0.05)
|
mi@0
|
315 # ag.write_wav_file(samples, "audio/test2b.wav")
|
mi@0
|
316 #
|
mi@0
|
317 # # Create a file with longer length than "test1.wav"
|
mi@0
|
318 # samples = ag.sine(440.0,length=15) + ag.sine(240.0,length=15) + ag.noise(length=15)
|
mi@0
|
319 # samples = samples / (max(samples)+0.05)
|
mi@0
|
320 # ag.write_wav_file(samples, "audio/test3a.wav")
|
mi@0
|
321 # # Create a file with longer length and one more sinusoid than "test1.wav"
|
mi@0
|
322 # samples = ag.sine(440.0,length=15) + ag.sine(240.0,length=15) + ag.sine(880.0,length=15) + ag.noise(length=15)
|
mi@0
|
323 # samples = samples / (max(samples)+0.05)
|
mi@0
|
324 # ag.write_wav_file(samples, "audio/test3b.wav")
|
mi@0
|
325
|
mi@0
|
326
|
mi@0
|
327 # plt.plot(samples[:1000])
|
mi@0
|
328 # plt.show()
|
mi@0
|
329
|
mi@0
|
330
|
mi@0
|
331 # print "Testing Gaussian Feature: Generating random features."
|
mi@0
|
332 feature_array_1 = np.zeros((20,100),dtype=np.float64)
|
mi@0
|
333 feature_array_2 = np.zeros((20,100),dtype=np.float64)
|
mi@0
|
334
|
mi@0
|
335 r = rand(2)
|
mi@0
|
336
|
mi@0
|
337 for x in xrange(100) :
|
mi@0
|
338 feature_array_1[:,x] = rand(20) + r[0]
|
mi@0
|
339 feature_array_2[:,x] = rand(20) + r[1]
|
mi@0
|
340
|
mi@0
|
341 f1 = GmmDistance(feature_array_1)
|
mi@0
|
342 f2 = GmmDistance(feature_array_2)
|
mi@0
|
343
|
mi@0
|
344 print f1,f2,"\n"
|
mi@0
|
345
|
mi@0
|
346 print "KL2 distance between f1-f2 using diag covariance:", f1.skl_distance_diag(f2)
|
mi@0
|
347 print "KL2 distance between f1-f1 using diag covariance:", f1.skl_distance_diag(f1)
|
mi@0
|
348 print "KL2 distance between f2-f2 using diag covariance:", f2.skl_distance_diag(f2)
|
mi@0
|
349 print "KL2 distance between f2-f1 using diag covariance:", f2.skl_distance_diag(f1)
|
mi@0
|
350 print '\n'
|
mi@0
|
351 print "KL2 distance between f1-f2 using full covariance:", f1.skl_distance_full(f2)
|
mi@0
|
352 print "KL2 distance between f1-f1 using full covariance:", f1.skl_distance_full(f1)
|
mi@0
|
353 print "KL2 distance between f2-f2 using full covariance:", f2.skl_distance_full(f2)
|
mi@0
|
354 print "KL2 distance between f2-f1 using full covariance:", f2.skl_distance_full(f1)
|
mi@0
|
355 print '\n'
|
mi@0
|
356 print "c2 distance between f1-f2:", f1.c2_distance(f2)
|
mi@0
|
357 print "c2 distance between f1-f1:", f1.c2_distance(f1)
|
mi@0
|
358 print "c2 distance between f2-f2:", f2.c2_distance(f2)
|
mi@0
|
359 print "c2 distance between f2-f1:", f2.c2_distance(f1)
|
mi@0
|
360 print '\n'
|
mi@0
|
361 print "euclidean distance between f1-f2:", f1.euclidean_distance(f2)
|
mi@0
|
362 print "euclidean distance between f1-f1:", f1.euclidean_distance(f1)
|
mi@0
|
363 print "euclidean distance between f2-f2:", f2.euclidean_distance(f2)
|
mi@0
|
364 print "euclidean distance between f2-f1:", f2.euclidean_distance(f1)
|
mi@0
|
365 print '\n'
|
mi@0
|
366 print "bhattacharyya distance between f1-f2:", f1.bhattacharyya_distance(f2)
|
mi@0
|
367 print "bhattacharyya distance between f1-f1:", f1.bhattacharyya_distance(f1)
|
mi@0
|
368 print "bhattacharyya distance between f2-f2:", f2.bhattacharyya_distance(f2)
|
mi@0
|
369 print "bhattacharyya distance between f2-f1:", f2.bhattacharyya_distance(f1)
|
mi@0
|
370
|
mi@0
|
371 # ag = AudioGenerator()
|
mi@0
|
372 # sound = ag.synthesisor(nChannels = 2, framerate=44100, amplitude=0.5, length=0.02)
|
mi@0
|
373 # ag.write_wav_file(samples=sound, nframes=None, length=0.02, filename='audio/test.wav')
|
mi@0
|
374 #
|
mi@0
|
375 # l = dir(__builtins__)
|
mi@0
|
376 # d = __builtins__.__dict__
|
mi@0
|
377 # pprint(l)
|
mi@0
|
378 # pprint(d)
|
mi@0
|
379
|
mi@0
|
380 # # Load audio data
|
mi@0
|
381 # audio_files = [i for i in os.listdir(audioDir) if i.endswith('wav') and not i.startswith('.')]
|
mi@0
|
382 # audio_list = []
|
mi@0
|
383 # for i in audio_files:
|
mi@0
|
384 # ao = AudioObj()
|
mi@0
|
385 # ao.name = splitext(i)[0]
|
mi@0
|
386 # ao.data = np.array(read(join(audioDir, i))[1], dtype=float)
|
mi@0
|
387 # audio_list.append(ao)
|
mi@0
|
388 #
|
mi@0
|
389 # # Calculate pairwise ditances between audio data using listed metrics
|
mi@0
|
390 # res_list = []
|
mi@0
|
391 # for a1, a2 in combinations(audio_list, 2):
|
mi@0
|
392 # # basic info
|
mi@0
|
393 # res = DistanceObj()
|
mi@0
|
394 # f1 = GmmDistance(a1.data)
|
mi@0
|
395 # f2 = GmmDistance(a2.data)
|
mi@0
|
396 # res.audio1 = a1.name
|
mi@0
|
397 # res.audio2 = a2.name
|
mi@0
|
398 # res.nComponents = len(f1.components)
|
mi@0
|
399 #
|
mi@0
|
400 # # distances between two samples should be symmetric
|
mi@0
|
401 # res.skl_full = f1.skl_distance_full(f2)
|
mi@0
|
402 # res.skl_diag = f1.skl_distance_diag(f2)
|
mi@0
|
403 # res.c2 = f1.c2_distance(f2)
|
mi@0
|
404 # res.euclidean = f1.euclidean_distance(f2)
|
mi@0
|
405 # res.bhattacharyya = f1.bhattacharyya_distance(f2)
|
mi@0
|
406 #
|
mi@0
|
407 # res.save()
|
mi@0
|
408 # res_list.append(res)
|
mi@0
|
409
|
mi@0
|
410
|
mi@0
|
411
|
mi@0
|
412 if __name__ == '__main__':
|
mi@0
|
413 main()
|
mi@0
|
414
|
mi@0
|
415
|
mi@0
|
416
|
mi@0
|
417
|