e@0
|
1 # -*- coding: utf-8 -*-
|
e@0
|
2 """
|
e@0
|
3 Created on Thu Jun 11 11:03:04 2015
|
e@0
|
4
|
e@0
|
5 @author: mmxgn
|
e@0
|
6 """
|
e@0
|
7
|
e@0
|
8
|
e@0
|
9 import matplotlib
|
e@0
|
10 matplotlib.use("TkAgg")
|
e@0
|
11 from matplotlib.figure import Figure
|
e@0
|
12 from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
|
e@0
|
13
|
e@0
|
14 import pyaudio
|
e@0
|
15 from sys import argv, exit
|
e@0
|
16 from essentia.standard import YamlInput, YamlOutput, AudioLoader, AudioWriter
|
e@0
|
17 from essentia import Pool
|
e@0
|
18 from pca import *
|
e@0
|
19
|
e@0
|
20 from numpy import *
|
e@0
|
21 from sklearn import cluster
|
e@0
|
22 from sklearn.metrics import pairwise_distances
|
e@0
|
23 from sklearn.cluster import KMeans, MiniBatchKMeans
|
e@0
|
24 from matplotlib.pyplot import *
|
e@0
|
25 #from sklearn.mixture import GMM
|
e@0
|
26 from sklearn.naive_bayes import GaussianNB, MultinomialNB
|
e@0
|
27 from scipy.signal import decimate
|
e@0
|
28 from sklearn import cross_validation
|
e@0
|
29 from Tkinter import *
|
e@0
|
30 import tkMessageBox
|
e@0
|
31 import thread
|
e@0
|
32 from numpy.core._internal import _gcd as gcd
|
e@0
|
33 import time
|
e@0
|
34 import os
|
e@0
|
35 import subprocess
|
e@0
|
36 from scikits.audiolab import Format, Sndfile
|
e@0
|
37 from scipy.signal import fftconvolve
|
e@0
|
38 from glob import glob
|
e@0
|
39
|
e@0
|
40 def zafar(lx, rx, d1, g1, da, G, gc, m):
|
e@0
|
41 """ Rafii & Pardo Reverberator (2009) controlled by High Level parameters
|
e@0
|
42 Inputs:
|
e@0
|
43 lx : left channel input
|
e@0
|
44 rx : right channel input
|
e@0
|
45 d1 : delay of first comb filter in samples
|
e@0
|
46 g1 : gain of first comb filters
|
e@0
|
47 da : delay of allpass filter in samples
|
e@0
|
48 G : dry/wet mix gain
|
e@0
|
49 gc : lowpass filter gain
|
e@0
|
50 m : difference between left and right channel phases
|
e@0
|
51
|
e@0
|
52 Outputs:
|
e@0
|
53 ly: left channel output
|
e@0
|
54 ry: right channel output
|
e@0
|
55 """
|
e@0
|
56
|
e@0
|
57 def calculate_parameters(d1,g1):
|
e@0
|
58
|
e@0
|
59 d2 = int(round((1.5)**(-1)*d1))
|
e@0
|
60
|
e@0
|
61 while gcd(d2,d1) != 1:
|
e@0
|
62 d2 += 1
|
e@0
|
63
|
e@0
|
64 d3 = int(round((1.5)**(-2)*d1))
|
e@0
|
65
|
e@0
|
66 while gcd(d3, d2) != 1 or gcd(d3, d1) != 1:
|
e@0
|
67 d3 += 1
|
e@0
|
68
|
e@0
|
69 d4 = int(round((1.5)**(-3)*d1))
|
e@0
|
70
|
e@0
|
71 while gcd(d4, d3) != 1 or gcd(d4, d2) != 1 or gcd(d4, d1) != 1:
|
e@0
|
72 d4 += 1
|
e@0
|
73
|
e@0
|
74
|
e@0
|
75 d5 = int(round((1.5)**(-4)*d1))
|
e@0
|
76
|
e@0
|
77 while gcd(d5, d4) != 1 or gcd(d5, d3) != 1 or gcd(d5, d2) != 1 or gcd(d5, d1) != 1:
|
e@0
|
78 d5 += 1
|
e@0
|
79
|
e@0
|
80 d6 = int(round((1.5)**(-5)*d1))
|
e@0
|
81 while gcd(d6, d5) != 1 or gcd(d6, d4) != 1 or gcd(d6, d3) != 1 or gcd(d6, d2) != 1 or gcd(d6, d1) != 1:
|
e@0
|
82 d6 += 1
|
e@0
|
83 g2 = g1**(1.5)**(-1)*g1
|
e@0
|
84 g3 = g1**(1.5)**(-2)*g1
|
e@0
|
85 g4 = g1**(1.5)**(-3)*g1
|
e@0
|
86 g5 = g1**(1.5)**(-4)*g1
|
e@0
|
87 g6 = g1**(1.5)**(-5)*g1
|
e@0
|
88
|
e@0
|
89 return (d1, d2, d3, d4, d5, d6, g1, g2, g3, g4, g5, g6)
|
e@0
|
90 def comb_array(x, g1, d1):
|
e@0
|
91
|
e@0
|
92 (d1,d2,d3,d4,d5,d6,g1,g2,g3,g4,g5,g6) = calculate_parameters(d1,g1)
|
e@0
|
93
|
e@0
|
94
|
e@0
|
95
|
e@0
|
96 c1out = comb(x, g1, d1)
|
e@0
|
97 c2out = comb(x, g2, d2)
|
e@0
|
98 c3out = comb(x, g3, d3)
|
e@0
|
99 c4out = comb(x, g4, d4)
|
e@0
|
100 c5out = comb(x, g5, d5)
|
e@0
|
101 c6out = comb(x, g6, d6)
|
e@0
|
102
|
e@0
|
103
|
e@0
|
104 Lc1 = len(c1out)
|
e@0
|
105 Lc2 = len(c2out)
|
e@0
|
106 Lc3 = len(c3out)
|
e@0
|
107 Lc4 = len(c4out)
|
e@0
|
108 Lc5 = len(c5out)
|
e@0
|
109 Lc6 = len(c6out)
|
e@0
|
110
|
e@0
|
111 Lc = max(Lc1, Lc2, Lc3, Lc4, Lc5, Lc6)
|
e@0
|
112
|
e@0
|
113 y = zeros((Lc, ))
|
e@0
|
114
|
e@0
|
115 y[0:Lc1] = c1out
|
e@0
|
116 y[0:Lc2] += c2out
|
e@0
|
117 y[0:Lc3] += c3out
|
e@0
|
118 y[0:Lc4] += c4out
|
e@0
|
119 y[0:Lc5] += c5out
|
e@0
|
120 y[0:Lc6] += c6out
|
e@0
|
121
|
e@0
|
122 return y
|
e@0
|
123
|
e@0
|
124 def comb(x, g, d):
|
e@0
|
125 LEN = len(x)+d
|
e@0
|
126 print d
|
e@0
|
127 y = zeros((LEN,))
|
e@0
|
128 for n in range(0, LEN):
|
e@0
|
129 if n - d < 0:
|
e@0
|
130 y[n] = 0
|
e@0
|
131 else:
|
e@0
|
132 y[n] = x[n-d] + g*y[n-d]
|
e@0
|
133
|
e@0
|
134 return y
|
e@0
|
135
|
e@0
|
136 def allpass(x, g, d):
|
e@0
|
137 LENx = len(x)
|
e@0
|
138 LENy = LENx+d
|
e@0
|
139 y = zeros((LENy,))
|
e@0
|
140 for n in range(0, LENy):
|
e@0
|
141 if n-d < 0:
|
e@0
|
142 y[n] = -g*x[n]
|
e@0
|
143 elif n >= LENx:
|
e@0
|
144 y[n] = x[n-d] + g*y[n-d]
|
e@0
|
145 else:
|
e@0
|
146 y[n] = x[n-d] - g*x[n] + g*y[n-d]
|
e@0
|
147
|
e@0
|
148 return y
|
e@0
|
149
|
e@0
|
150 def lowpass(x, g):
|
e@0
|
151 LEN = len(x)
|
e@0
|
152 y = zeros((LEN,))
|
e@0
|
153
|
e@0
|
154 for n in range(0, LEN):
|
e@0
|
155 if n-1 < 0:
|
e@0
|
156 y[n] = (1-g)*x[n]
|
e@0
|
157 else:
|
e@0
|
158 y[n] = (1-g)*x[n] + g*y[n-1]
|
e@0
|
159
|
e@0
|
160 return y
|
e@0
|
161
|
e@0
|
162 ga = 1./sqrt(2.)
|
e@0
|
163
|
e@0
|
164 cin = 0.5*lx + 0.5*rx
|
e@0
|
165 cout = comb_array(cin, g1, d1)
|
e@0
|
166
|
e@0
|
167
|
e@0
|
168 ra = allpass(cout, ga, da+m/2)
|
e@0
|
169 la = allpass(cout, ga, da-m/2)
|
e@0
|
170
|
e@0
|
171 ral = lowpass(ra, gc)
|
e@0
|
172 lal = lowpass(la, gc)
|
e@0
|
173
|
e@0
|
174 ralg = G*ral
|
e@0
|
175 lalg = G*lal
|
e@0
|
176
|
e@0
|
177 ry = ralg[0:len(rx)] + (1-G)*rx
|
e@0
|
178 ly = lalg[0:len(lx)] + (1-G)*lx
|
e@0
|
179
|
e@0
|
180 # ry = cout
|
e@0
|
181 # ly = cout
|
e@0
|
182
|
e@0
|
183
|
e@0
|
184
|
e@0
|
185 return (ry, ly)
|
e@0
|
186
|
e@0
|
187 class UI:
|
e@0
|
188
|
e@0
|
189 def __init__(self, master, directory):
|
e@0
|
190 self.master = master
|
e@0
|
191
|
e@0
|
192 self.directory = directory
|
e@0
|
193
|
e@0
|
194
|
e@0
|
195
|
e@0
|
196 yamlinput = YamlInput(filename="session.yaml")
|
e@0
|
197
|
e@0
|
198 try:
|
e@0
|
199 self.sessionpool = yamlinput()
|
e@0
|
200 try:
|
e@0
|
201 self.files_to_visit = self.sessionpool['files_to_visit']
|
e@0
|
202 except:
|
e@0
|
203 self.files_to_visit = []
|
e@0
|
204
|
e@0
|
205 try:
|
e@0
|
206 self.visited_files = self.sessionpool['visited_files']
|
e@0
|
207 except:
|
e@0
|
208 self.visited_files = []
|
e@0
|
209
|
e@0
|
210
|
e@0
|
211
|
e@0
|
212 except:
|
e@0
|
213 print "[II] Could not open sessionpool file, creating a new one"
|
e@0
|
214 self.sessionpool = Pool()
|
e@0
|
215 self.files_to_visit = glob("%s/*.wav" % directory)
|
e@0
|
216 for i in self.files_to_visit:
|
e@0
|
217 self.sessionpool.add('files_to_visit', i)
|
e@0
|
218 self.visited_files = []
|
e@0
|
219
|
e@0
|
220 if len(self.files_to_visit) == 0:
|
e@0
|
221 tkMessageBox.showinfo("","No files to visit")
|
e@0
|
222 master.destroy()
|
e@0
|
223 return
|
e@0
|
224
|
e@0
|
225 filename = self.files_to_visit[-1]
|
e@0
|
226 self.filename = filename
|
e@0
|
227 # visited_files.append(filename)
|
e@0
|
228 self.label_top = Label(master, text="")
|
e@0
|
229 self.label_top.grid(row=0, column=0, columnspan=6)
|
e@0
|
230
|
e@0
|
231 self.load_song(filename)
|
e@0
|
232
|
e@0
|
233
|
e@0
|
234 # Top Label
|
e@0
|
235
|
e@0
|
236 self.label_top.config( text="Training song: %s (sampleRate: %.0f, nChannels: %d) - %d songs left" % (filename, self.SR, self.numChannels, len(self.files_to_visit)-1))
|
e@0
|
237
|
e@0
|
238 # Sliders
|
e@0
|
239
|
e@0
|
240 self.scale_d1 = Scale(master, to_=0.01, from_=0.1, resolution=0.01, label="d1", showvalue=True)#, command=self.callback_update_parameters)
|
e@0
|
241 self.scale_d1.bind("<ButtonRelease-1>",self.callback_update_parameters)
|
e@0
|
242 self.scale_d1.grid(row=1,column=0,rowspan=17,sticky=N+S+E+W)
|
e@0
|
243 self.scale_g1 = Scale(master,to_=0.01, from_=0.99, resolution=0.01, label="g1", showvalue=True)#, command=self.callback_update_parameters)
|
e@0
|
244 self.scale_g1.bind("<ButtonRelease-1>",self.callback_update_parameters)
|
e@0
|
245
|
e@0
|
246 self.scale_g1.grid(row=1,column=1,rowspan=17,sticky=N+S+E+W)
|
e@0
|
247 self.scale_da = Scale(master, to_=0.006, from_=0.012, resolution=0.001, label="da", showvalue=True)#, command=self.callback_update_parameters)
|
e@0
|
248 self.scale_da.bind("<ButtonRelease-1>",self.callback_update_parameters)
|
e@0
|
249
|
e@0
|
250 self.scale_da.grid(row=1,column=2,rowspan=17,sticky=N+S+E+W)
|
e@0
|
251 self.scale_G = Scale(master,to_=0.01, from_=0.99, resolution=0.01, label="G", showvalue=True)#, command=self.callback_update_parameters)
|
e@0
|
252 self.scale_G.bind("<ButtonRelease-1>",self.callback_update_parameters)
|
e@0
|
253
|
e@0
|
254 self.scale_G.grid(row=1,column=3,rowspan=17,sticky=N+S+E+W)
|
e@0
|
255 self.scale_gc = Scale(master, to_=0.01, from_=0.99, resolution=0.01, label="gc", showvalue=True)#, command=self.callback_update_parameters)
|
e@0
|
256 self.scale_gc.bind("<ButtonRelease-1>",self.callback_update_parameters)
|
e@0
|
257
|
e@0
|
258 self.scale_gc.grid(row=1,column=4,rowspan=17,sticky=N+S+E+W)
|
e@0
|
259
|
e@0
|
260
|
e@0
|
261 # Labels
|
e@0
|
262
|
e@0
|
263 self.label_T60 = Label(master, text="Reverberation Time: ")
|
e@0
|
264 self.label_T60.grid(row=2,column=6,sticky=N+S+E+W)
|
e@0
|
265 self.label_D = Label(master, text="Echo Density: ")
|
e@0
|
266 self.label_D.grid(row=3,column=6,sticky=N+S+E+W)
|
e@0
|
267 self.label_C = Label(master, text="Clarity: ")
|
e@0
|
268 self.label_C.grid(row=4,column=6,sticky=N+S+E+W)
|
e@0
|
269 self.label_Tc = Label(master, text="Central Time: ")
|
e@0
|
270 self.label_Tc.grid(row=5,column=6,sticky=N+S+E+W)
|
e@0
|
271 self.label_SC = Label(master, text="Spectral Centroid: ")
|
e@0
|
272 self.label_SC.grid(row=6,column=6,sticky=N+S+E+W)
|
e@0
|
273
|
e@0
|
274
|
e@0
|
275 # Buttons
|
e@0
|
276
|
e@0
|
277 self.button_plot_impulse = Button(master, text="Plot Impulse",command=self.callback_plot_impulse, width=15).grid(row=7,column=6,sticky=N+S+E+W)
|
e@0
|
278 self.button_plot_raw = Button(master, text="Plot Raw", width=15,command=self.callback_plot_raw).grid(row=8,column=6,sticky=N+S+E+W)
|
e@0
|
279 self.button_plot_reverb = Button(master, text="Plot Reverb", width=15, command=self.callback_plot_reverb).grid(row=9, column=6,sticky=N+S+E+W)
|
e@0
|
280 self.button_play_raw = Button(master, text="Play Raw", bg="green", fg="white", width=15, command=self.callback_play_raw).grid(row=10, column=6,sticky=N+S+E+W)
|
e@0
|
281 self.button_play_reverb = Button(master, text="Play Reverb", bg="green", fg="white", width=15, command=self.callback_play_reverb).grid(row=11, column=6,sticky=N+S+E+W)
|
e@0
|
282 self.button_stop = Button(master, text="Stop Playing", bg="red", fg="white", width=15, command=self.callback_stop).grid(row=12, column=6,sticky=N+S+E+W)
|
e@0
|
283 self.button_save = Button(master, text="Save", fg="white", bg="orange", width=15, command=self.callback_save).grid(row=13, column=6,sticky=N+S+E+W)
|
e@0
|
284 self.button_reset = Button(master, text="Undo", width=15, command=self.callback_reset).grid(row=14, column=6,sticky=N+S+E+W)
|
e@0
|
285 self.button_next = Button(master, text="Next >>", width=15, command=self.callback_next).grid(row=15, column=6,sticky=N+S+E+W)
|
e@0
|
286
|
e@0
|
287
|
e@0
|
288
|
e@0
|
289 # Figure
|
e@0
|
290
|
e@0
|
291 self.figure = Figure( dpi=50)
|
e@0
|
292 self.figure.text(0.5,0.5,'No plot selected', weight = "bold", horizontalalignment='center')
|
e@0
|
293
|
e@0
|
294
|
e@0
|
295 # a tk.DrawingArea
|
e@0
|
296 self.canvas = FigureCanvasTkAgg(self.figure, master=root)
|
e@0
|
297 #self.canvas.get_tk_widget().config(height=500, width=640)
|
e@0
|
298 self.canvas.show()
|
e@0
|
299 self.canvas.get_tk_widget().grid(row=0, column=7, rowspan=17, padx=20,sticky=E+W+N+S)
|
e@0
|
300
|
e@0
|
301 # toolbar = NavigationToolbar2TkAgg( master, master )
|
e@0
|
302 # toolbar.update()
|
e@0
|
303 self.canvas._tkcanvas.grid(row=0, column=7, rowspan=17)
|
e@0
|
304 # self.scale_d1.pack()
|
e@0
|
305
|
e@0
|
306 # Toolbar for canvas
|
e@0
|
307
|
e@0
|
308 self.toolbar_frame = Frame(master)
|
e@0
|
309 self.toolbar_frame.grid(row=17,column=7,sticky=E+W+N+S, padx=19)
|
e@0
|
310 self.toolbar = NavigationToolbar2TkAgg(self.canvas, self.toolbar_frame)
|
e@0
|
311
|
e@0
|
312
|
e@0
|
313
|
e@0
|
314 Grid.columnconfigure(master, 7, weight=1)
|
e@0
|
315 Grid.rowconfigure(master, 1, weight=1)
|
e@0
|
316
|
e@0
|
317 # Status bar
|
e@0
|
318
|
e@0
|
319 self.status_bar_text = Label(text="Ready.")
|
e@0
|
320 self.status_bar_text.grid(row=18, column=0, columnspan = 8, sticky=N+S+E, padx=10)
|
e@0
|
321
|
e@0
|
322 self.lastplot = ''
|
e@0
|
323 self.parameterschanged_render = True
|
e@0
|
324 self.pendingactions = []
|
e@0
|
325
|
e@0
|
326 # Initial values
|
e@0
|
327
|
e@0
|
328 d1t = 0.05
|
e@0
|
329 self.d1 = d1t*self.SR
|
e@0
|
330 dat = 0.006
|
e@0
|
331 self.da = dat*self.SR
|
e@0
|
332 g1 = 0.5
|
e@0
|
333 self.g1 = g1
|
e@0
|
334 G = 0.5
|
e@0
|
335 self.G = G
|
e@0
|
336 gc = 0.5
|
e@0
|
337 self.gc = gc
|
e@0
|
338
|
e@0
|
339 self.scale_d1.set(d1t)
|
e@0
|
340 self.scale_da.set(dat)
|
e@0
|
341 self.scale_g1.set(g1)
|
e@0
|
342 self.scale_gc.set(gc)
|
e@0
|
343 self.scale_G.set(G)
|
e@0
|
344
|
e@0
|
345 t = zeros((self.SR*120,))
|
e@0
|
346 t[0] = 1
|
e@0
|
347
|
e@0
|
348 self.impulse = t
|
e@0
|
349
|
e@0
|
350 # self.callback_plot_impulse()
|
e@0
|
351
|
e@0
|
352
|
e@0
|
353 # Pyaudio object
|
e@0
|
354
|
e@0
|
355 # self.player = pyaudio.PyAudio()
|
e@0
|
356
|
e@0
|
357 # self.player_idx = 0
|
e@0
|
358 #
|
e@0
|
359 # self.playerprocess = None
|
e@0
|
360
|
e@0
|
361
|
e@0
|
362 # Pool
|
e@0
|
363
|
e@0
|
364 self.pool = Pool()
|
e@0
|
365 self.pool.set('filename', self.filename)
|
e@0
|
366 self.pool.set('sampleRate', self.SR)
|
e@0
|
367 self.pool.set('nChannels', self.numChannels)
|
e@0
|
368
|
e@0
|
369
|
e@0
|
370 # Finally
|
e@0
|
371 self.callback_update_parameters(None)
|
e@0
|
372
|
e@0
|
373
|
e@0
|
374
|
e@0
|
375
|
e@0
|
376
|
e@0
|
377 def pyaudio_callback_raw(self, in_data, frame_count, time_info, status):
|
e@0
|
378 if self.player_command == 'Stop':
|
e@0
|
379 return (0, pyaudio.paAbort)
|
e@0
|
380
|
e@0
|
381 data = self.audio[self.player_idx:self.player_idx+frame_count, :]
|
e@0
|
382
|
e@0
|
383 data = reshape(data, (data.shape[0]*data.shape[1], 1))
|
e@0
|
384
|
e@0
|
385 # print data
|
e@0
|
386 self.player_idx += frame_count
|
e@0
|
387
|
e@0
|
388
|
e@0
|
389 return (data, pyaudio.paContinue)
|
e@0
|
390
|
e@0
|
391
|
e@0
|
392 def play_reverb(self):
|
e@0
|
393
|
e@0
|
394 self.calculate_impulse_response()
|
e@0
|
395 ly, ry = self.impulse_response_left_channel, self.impulse_response_right_channel
|
e@0
|
396
|
e@0
|
397 lx = self.audio[:,0]
|
e@0
|
398 rx = self.audio[:,1]
|
e@0
|
399
|
e@0
|
400 print "Convolving left channel"
|
e@0
|
401 l_out = fftconvolve(ly, lx)
|
e@0
|
402
|
e@0
|
403 print "Convolving right channel"
|
e@0
|
404 r_out = fftconvolve(ry, rx)
|
e@0
|
405
|
e@0
|
406
|
e@0
|
407
|
e@0
|
408 lim = min(len(l_out), len(r_out))
|
e@0
|
409
|
e@0
|
410
|
e@0
|
411
|
e@0
|
412 if self.numChannels == 1:
|
e@0
|
413 audio_out = l_out[0:lim]
|
e@0
|
414 else:
|
e@0
|
415 audio_out = concatenate((matrix(l_out[0:lim]).T,
|
e@0
|
416 matrix(r_out[0:lim]).T
|
e@0
|
417 ),
|
e@0
|
418 axis=1)
|
e@0
|
419
|
e@0
|
420 reverb_filename = "%s_reverb_%s" % (self.filename.split('.')[0], self.filename.split('.')[1])
|
e@0
|
421
|
e@0
|
422 audio_file = Sndfile(reverb_filename, 'w', Format(self.filename.split('.')[1]), self.numChannels, self.SR)
|
e@0
|
423 audio_file.write_frames(audio_out)
|
e@0
|
424 audio_file.close()
|
e@0
|
425
|
e@0
|
426 self.reverberated_audio = audio_out
|
e@0
|
427 #
|
e@0
|
428 # audiowriter(audio_out)
|
e@0
|
429
|
e@0
|
430 self.reverb_filename = reverb_filename
|
e@0
|
431
|
e@0
|
432 self.playerprocess = subprocess.Popen("mplayer %s" % reverb_filename,
|
e@0
|
433 stdout = subprocess.PIPE,
|
e@0
|
434 shell=True,
|
e@0
|
435 preexec_fn=os.setsid)
|
e@0
|
436
|
e@0
|
437 def play_raw(self):
|
e@0
|
438 self.playerprocess = subprocess.Popen("mplayer %s" % self.filename,
|
e@0
|
439 stdout = subprocess.PIPE,
|
e@0
|
440 shell=True,
|
e@0
|
441 preexec_fn=os.setsid)
|
e@0
|
442
|
e@0
|
443
|
e@0
|
444
|
e@0
|
445
|
e@0
|
446
|
e@0
|
447 def remove_action_from_status(self, text):
|
e@0
|
448
|
e@0
|
449 self.pendingactions.remove(text)
|
e@0
|
450
|
e@0
|
451 if len(self.pendingactions) == 0:
|
e@0
|
452 self.status_bar_text.config(text='Ready.')
|
e@0
|
453 elif len(self.pendingactions) == 1:
|
e@0
|
454 self.status_bar_text.config(text=self.pendingactions[0]+'.')
|
e@0
|
455 else:
|
e@0
|
456 self.status_bar_text.config(text=reduce(lambda h,t: h+','+t, self.pendingactions)+'.')
|
e@0
|
457
|
e@0
|
458
|
e@0
|
459 def add_action_to_status(self, text):
|
e@0
|
460
|
e@0
|
461 self.pendingactions.append(text)
|
e@0
|
462
|
e@0
|
463 if len(self.pendingactions) == 0:
|
e@0
|
464 self.status_bar_text.config(text='Ready.')
|
e@0
|
465 elif len(self.pendingactions) == 1:
|
e@0
|
466 self.status_bar_text.config(text=text+'.')
|
e@0
|
467 else:
|
e@0
|
468 self.status_bar_text.config(text=reduce(lambda h,t: h+', '+t, self.pendingactions)+'.')
|
e@0
|
469
|
e@0
|
470 print self.pendingactions, len(self.pendingactions)
|
e@0
|
471
|
e@0
|
472
|
e@0
|
473 def load_song(self, filename):
|
e@0
|
474 # self.label_top.config(text="Training '%s'" % filename)
|
e@0
|
475 # print filename
|
e@0
|
476 #self.audio, self.SR, self.numChannels = AudioLoader(filename=filename)()
|
e@0
|
477 tup = AudioLoader(filename=filename)()
|
e@0
|
478 self.audio = tup[0]
|
e@0
|
479 self.SR = tup[1]
|
e@0
|
480 self.numChannels = tup[2]
|
e@0
|
481 self.label_top.config(text="Training song: %s (sampleRate: %.0f, nChannels: %d) - %d songs left" % (filename, self.SR, self.numChannels, len(self.files_to_visit)-1))
|
e@0
|
482 self.saved = False
|
e@0
|
483
|
e@0
|
484
|
e@0
|
485
|
e@0
|
486
|
e@0
|
487 def estimate_T60(self, d1, g1, gc, G, SR):
|
e@0
|
488 ga = 1/sqrt(2)
|
e@0
|
489 return d1/SR/log(g1)*log(10**-3/ga/(1-gc)/G)
|
e@0
|
490
|
e@0
|
491 def calculate_parameters(self,d1,g1):
|
e@0
|
492
|
e@0
|
493 d2 = int(round((1.5)**(-1)*d1))
|
e@0
|
494
|
e@0
|
495 while gcd(d2,d1) != 1:
|
e@0
|
496 d2 += 1
|
e@0
|
497
|
e@0
|
498 d3 = int(round((1.5)**(-2)*d1))
|
e@0
|
499
|
e@0
|
500 while gcd(d3, d2) != 1 or gcd(d3, d1) != 1:
|
e@0
|
501 d3 += 1
|
e@0
|
502
|
e@0
|
503 d4 = int(round((1.5)**(-3)*d1))
|
e@0
|
504
|
e@0
|
505 while gcd(d4, d3) != 1 or gcd(d4, d2) != 1 or gcd(d4, d1) != 1:
|
e@0
|
506 d4 += 1
|
e@0
|
507
|
e@0
|
508
|
e@0
|
509 d5 = int(round((1.5)**(-4)*d1))
|
e@0
|
510
|
e@0
|
511 while gcd(d5, d4) != 1 or gcd(d5, d3) != 1 or gcd(d5, d2) != 1 or gcd(d5, d1) != 1:
|
e@0
|
512 d5 += 1
|
e@0
|
513
|
e@0
|
514 d6 = int(round((1.5)**(-5)*d1))
|
e@0
|
515 while gcd(d6, d5) != 1 or gcd(d6, d4) != 1 or gcd(d6, d3) != 1 or gcd(d6, d2) != 1 or gcd(d6, d1) != 1:
|
e@0
|
516 d6 += 1
|
e@0
|
517 g2 = g1**(1.5)**(-1)*g1
|
e@0
|
518 g3 = g1**(1.5)**(-2)*g1
|
e@0
|
519 g4 = g1**(1.5)**(-3)*g1
|
e@0
|
520 g5 = g1**(1.5)**(-4)*g1
|
e@0
|
521 g6 = g1**(1.5)**(-5)*g1
|
e@0
|
522
|
e@0
|
523 return (d1, d2, d3, d4, d5, d6, g1, g2, g3, g4, g5, g6)
|
e@0
|
524 def estimate_C(self, g1, G, gc):
|
e@0
|
525 g2 = g1**(1.5)**(-1)*g1
|
e@0
|
526 g3 = g1**(1.5)**(-2)*g1
|
e@0
|
527 g4 = g1**(1.5)**(-3)*g1
|
e@0
|
528 g5 = g1**(1.5)**(-4)*g1
|
e@0
|
529 g6 = g1**(1.5)**(-5)*g1
|
e@0
|
530 gains = zeros((6,1))
|
e@0
|
531 gains[0] = g1
|
e@0
|
532 gains[1] = g2
|
e@0
|
533 gains[2] = g3
|
e@0
|
534 gains[3] = g4
|
e@0
|
535 gains[4] = g5
|
e@0
|
536 gains[5] = g6
|
e@0
|
537
|
e@0
|
538 return -10*log10(G**2*(1-gc)/(1+gc)*sum(1/(1-gains**2)))
|
e@0
|
539
|
e@0
|
540 def estimate_D(self, d1, g1, da, SR):
|
e@0
|
541 Dm = zeros((6,10))
|
e@0
|
542 delays = zeros((6,))
|
e@0
|
543 gains = zeros((6,1))
|
e@0
|
544 (delays[0],delays[1],delays[2],delays[3],delays[4],delays[5],gains[0],gains[1],gains[2],gains[3],gains[4],gains[5]) = self.calculate_parameters(d1,g1)
|
e@0
|
545 for k in range(1, 7):
|
e@0
|
546 for m in range(1, 11):
|
e@0
|
547 Dm[k-1,m-1] = max(0.1-m*delays[k-1]/SR,0)
|
e@0
|
548
|
e@0
|
549 return 10/da*self.SR*sum(Dm)
|
e@0
|
550
|
e@0
|
551 def estimate_Tc(self, d1, g1, da, SR):
|
e@0
|
552 delays = zeros((6,))
|
e@0
|
553 gains = zeros((6,1))
|
e@0
|
554 (delays[0],delays[1],delays[2],delays[3],delays[4],delays[5],gains[0],gains[1],gains[2],gains[3],gains[4],gains[5]) = self.calculate_parameters(d1,g1)
|
e@0
|
555 return sum(delays/SR*gains**2/(1-gains**2)**2)/sum(gains**2/(1-gains**2)) + da/SR
|
e@0
|
556
|
e@0
|
557
|
e@0
|
558 def callback_update_parameters(self,_):
|
e@0
|
559 SR = self.SR
|
e@0
|
560 d1t = self.scale_d1.get()
|
e@0
|
561 print d1t
|
e@0
|
562
|
e@0
|
563 d1 = round(d1t*SR)
|
e@0
|
564 g1 = self.scale_g1.get()
|
e@0
|
565 dat = self.scale_da.get()
|
e@0
|
566 da = round(dat*SR)
|
e@0
|
567 G = self.scale_G.get()
|
e@0
|
568 gc = self.scale_gc.get()
|
e@0
|
569
|
e@0
|
570
|
e@0
|
571 T60 = self.estimate_T60(d1,g1,gc,G,SR)
|
e@0
|
572 D = self.estimate_D(d1, g1, da, SR)/10
|
e@0
|
573 C = self.estimate_C(g1, G, gc)
|
e@0
|
574 Tc = self.estimate_Tc(d1,g1,da,SR)
|
e@0
|
575 SC = self.estimate_SC(gc, SR)
|
e@0
|
576
|
e@0
|
577 self.d1_old = self.d1
|
e@0
|
578 self.G_old = self.G
|
e@0
|
579 self.gc_old = self.gc
|
e@0
|
580 self.g1_old = self.g1
|
e@0
|
581 self.da_old = self.da
|
e@0
|
582
|
e@0
|
583 self.d1 = d1
|
e@0
|
584 self.G = G
|
e@0
|
585 self.gc = gc
|
e@0
|
586 self.g1 = g1
|
e@0
|
587 self.da = da
|
e@0
|
588
|
e@0
|
589
|
e@0
|
590
|
e@0
|
591 self.pool.set('parameters.d1', d1t)
|
e@0
|
592 self.pool.set('parameters.G', G)
|
e@0
|
593 self.pool.set('parameters.gc', gc)
|
e@0
|
594 self.pool.set('parameters.g1', g1)
|
e@0
|
595 self.pool.set('parameters.da', dat)
|
e@0
|
596
|
e@0
|
597
|
e@0
|
598
|
e@0
|
599 self.T60 = T60
|
e@0
|
600 self.D = D
|
e@0
|
601 self.Tc = Tc
|
e@0
|
602 self.SC = SC
|
e@0
|
603 self.C = C
|
e@0
|
604
|
e@0
|
605 self.pool.set('parameters.T60', T60)
|
e@0
|
606 self.pool.set('parameters.D', D)
|
e@0
|
607 self.pool.set('parameters.C', C)
|
e@0
|
608 self.pool.set('parameters.Tc', Tc)
|
e@0
|
609 self.pool.set('parameters.SC', SC)
|
e@0
|
610
|
e@0
|
611 self.label_T60.config(text="Reverberation Time: %.3fs" % T60)
|
e@0
|
612 self.label_D.config(text="Echo Density: %.3f at 0.1s" % D)
|
e@0
|
613 self.label_C.config(text="Clarity: %.3f dB" % C)
|
e@0
|
614 self.label_Tc.config(text="Central Time: %.3fs" % Tc)
|
e@0
|
615 self.label_SC.config(text="Spectral Centroid: %.3f Hz" % SC)
|
e@0
|
616
|
e@0
|
617 self.lastplot = ''
|
e@0
|
618 self.parameterschanged_render = True
|
e@0
|
619 # self.callback_plot_impulse()
|
e@0
|
620
|
e@0
|
621
|
e@0
|
622 def estimate_SC(self, gc, SR):
|
e@0
|
623 n = arange(0, SR/2+1)
|
e@0
|
624 return sum(n/(1+gc**2-2*gc*cos(2*pi*n/SR)))/sum(1/(1+gc**2-2*gc*cos(2*pi*n/SR)))
|
e@0
|
625
|
e@0
|
626
|
e@0
|
627
|
e@0
|
628
|
e@0
|
629 def say_hi(self):
|
e@0
|
630 print "Hi, there"
|
e@0
|
631
|
e@0
|
632 def callback_plot_impulse(self):
|
e@0
|
633 try:
|
e@0
|
634 thread.start_new_thread(self.plot_impulse, ())
|
e@0
|
635 except:
|
e@0
|
636 print "[EE] Could not start new thread"
|
e@0
|
637
|
e@0
|
638
|
e@0
|
639
|
e@0
|
640 def calculate_impulse_response(self):
|
e@0
|
641 self.add_action_to_status('Calculating impulse response')
|
e@0
|
642 N = self.numChannels
|
e@0
|
643 SR = self.SR
|
e@0
|
644 T = 1.0/self.SR
|
e@0
|
645
|
e@0
|
646 delta = self.impulse[0:int(self.T60*self.SR)]
|
e@0
|
647 print "delta:"
|
e@0
|
648 print delta
|
e@0
|
649
|
e@0
|
650 d1 = int(self.d1)
|
e@0
|
651 g1 = self.g1
|
e@0
|
652 da = int(self.da)
|
e@0
|
653 G = self.G
|
e@0
|
654 gc = self.gc
|
e@0
|
655
|
e@0
|
656 mt = 0.002
|
e@0
|
657 m = int(mt*SR)
|
e@0
|
658
|
e@0
|
659 (ly, ry) = zafar(delta,delta,d1,g1,da,G,gc,m)
|
e@0
|
660
|
e@0
|
661 limt = self.T60
|
e@0
|
662
|
e@0
|
663 lim = int(limt*SR)
|
e@0
|
664 t = arange(0, lim)*T
|
e@0
|
665
|
e@0
|
666 padded_y = zeros(shape(t))
|
e@0
|
667 padded_y[0:len(ly)] = ly
|
e@0
|
668
|
e@0
|
669
|
e@0
|
670 padded_y = zeros(shape(t))
|
e@0
|
671 padded_y[0:len(ry)] = ry
|
e@0
|
672
|
e@0
|
673 ry = padded_y
|
e@0
|
674
|
e@0
|
675 self.impulse_response_left_channel = ly
|
e@0
|
676 self.impulse_response_right_channel = ry
|
e@0
|
677
|
e@0
|
678
|
e@0
|
679 self.remove_action_from_status('Calculating impulse response')
|
e@0
|
680
|
e@0
|
681
|
e@0
|
682
|
e@0
|
683 def plot_impulse(self):
|
e@0
|
684 if self.lastplot != 'impulse':
|
e@0
|
685 self.add_action_to_status('Plotting impulse response')
|
e@0
|
686 N = self.numChannels
|
e@0
|
687 SR = self.SR
|
e@0
|
688 T = 1.0/self.SR
|
e@0
|
689
|
e@0
|
690 delta = self.impulse[0:int(self.T60*self.SR)]
|
e@0
|
691 print "delta:"
|
e@0
|
692 print delta
|
e@0
|
693
|
e@0
|
694 d1 = int(self.d1)
|
e@0
|
695 g1 = self.g1
|
e@0
|
696 da = int(self.da)
|
e@0
|
697 G = self.G
|
e@0
|
698 gc = self.gc
|
e@0
|
699
|
e@0
|
700 mt = 0.002
|
e@0
|
701 m = int(mt*SR)
|
e@0
|
702
|
e@0
|
703 print "Calculating zafar"
|
e@0
|
704 (ly, ry) = zafar(delta,delta,d1,g1,da,G,gc,m)
|
e@0
|
705
|
e@0
|
706 print "Stopped calculating zafar"#ly.shape
|
e@0
|
707 limt = self.T60
|
e@0
|
708
|
e@0
|
709 lim = int(limt*SR)
|
e@0
|
710 print "lim:", lim
|
e@0
|
711
|
e@0
|
712 t = arange(0, lim)*T
|
e@0
|
713 # print t
|
e@0
|
714
|
e@0
|
715 # Pad ly to t
|
e@0
|
716 print "Shape ly"
|
e@0
|
717 print ly
|
e@0
|
718 print len(ly)
|
e@0
|
719 padded_y = zeros(shape(t))
|
e@0
|
720 padded_y[0:len(ly)] = ly
|
e@0
|
721
|
e@0
|
722 print "Padded y"
|
e@0
|
723 #print padded_y
|
e@0
|
724
|
e@0
|
725 # ly = padded_y
|
e@0
|
726
|
e@0
|
727 # Pad ry to t
|
e@0
|
728
|
e@0
|
729 padded_y = zeros(shape(t))
|
e@0
|
730 padded_y[0:len(ry)] = ry
|
e@0
|
731
|
e@0
|
732 ry = padded_y
|
e@0
|
733
|
e@0
|
734
|
e@0
|
735
|
e@0
|
736 self.figure.clear()
|
e@0
|
737
|
e@0
|
738 print "Passed A"
|
e@0
|
739 subplt0 = self.figure.add_subplot(2,1,1)
|
e@0
|
740
|
e@0
|
741 subplt0.plot(t,abs(ly[0:lim]))
|
e@0
|
742 subplt0.set_title('Left Channel')
|
e@0
|
743 subplt0.set_xlabel('time (s)')
|
e@0
|
744 subplt0.set_ylabel('amplitude')
|
e@0
|
745 subplt0.axvspan(0,0.1, alpha=0.1,color='cyan')
|
e@0
|
746 subplt0.axvline(self.Tc, color='red', linestyle='--')
|
e@0
|
747 subplt0.axvline(0.1, color='cyan', linestyle='--')
|
e@0
|
748 subplt0.annotate('Central Time (Tc)', xy=(self.Tc, 0.5), xytext=(self.Tc+0.01, 0.52), arrowprops=dict(facecolor='black',width=1))
|
e@0
|
749 subplt0.annotate('Echo Density (D) Measurement Point ', xy=(0.1, 0.6), xytext=(.11, 0.62), arrowprops=dict(facecolor='black',width=1))
|
e@0
|
750
|
e@0
|
751 #
|
e@0
|
752
|
e@0
|
753 subplt1 = self.figure.add_subplot(2,1,2,sharex=subplt0)
|
e@0
|
754 subplt1.set_title('Right Channel')
|
e@0
|
755
|
e@0
|
756 subplt1.plot(t,abs(ry[0:lim]))
|
e@0
|
757 subplt1.set_xlabel('time (s)')
|
e@0
|
758 subplt1.set_ylabel('amplitude')
|
e@0
|
759 subplt1.axvspan(0,0.1, alpha=0.1,color='cyan')
|
e@0
|
760 subplt1.axvline(self.Tc, color='red', linestyle='--')
|
e@0
|
761 subplt1.axvline(0.1, color='cyan', linestyle='--')
|
e@0
|
762
|
e@0
|
763
|
e@0
|
764 self.figure.suptitle("Reverberation Impulse Response")
|
e@0
|
765
|
e@0
|
766 # print "Passed B"
|
e@0
|
767 #
|
e@0
|
768 self.remove_action_from_status('Plotting impulse response')
|
e@0
|
769 self.canvas.draw()
|
e@0
|
770
|
e@0
|
771 self.lastplot = 'impulse'
|
e@0
|
772 #
|
e@0
|
773 thread.exit_thread()
|
e@0
|
774
|
e@0
|
775
|
e@0
|
776
|
e@0
|
777 def plot_raw(self):
|
e@0
|
778 if self.lastplot != 'raw':
|
e@0
|
779 self.add_action_to_status('Plotting raw')
|
e@0
|
780 N = self.numChannels
|
e@0
|
781 print "Channels: %d" % N
|
e@0
|
782 L = len(self.audio[:,0])
|
e@0
|
783
|
e@0
|
784
|
e@0
|
785
|
e@0
|
786
|
e@0
|
787 self.figure.clear()
|
e@0
|
788
|
e@0
|
789 T = 1.0/self.SR
|
e@0
|
790 t = arange(0, L)*T
|
e@0
|
791
|
e@0
|
792 oldsubplt = None
|
e@0
|
793 for n in range(0, N):
|
e@0
|
794 if oldsubplt is not None:
|
e@0
|
795 subplt = self.figure.add_subplot(N,1,n+1,sharex=oldsubplt)
|
e@0
|
796 else:
|
e@0
|
797 subplt = self.figure.add_subplot(N,1,n+1)
|
e@0
|
798 subplt.plot(t,self.audio[:,n])
|
e@0
|
799 subplt.set_title('Channel %d' % n)
|
e@0
|
800 subplt.set_xlabel('time (s)')
|
e@0
|
801 subplt.set_ylabel('amplitude')
|
e@0
|
802
|
e@0
|
803 oldsubplt = subplt
|
e@0
|
804
|
e@0
|
805
|
e@0
|
806 self.figure.suptitle('Raw Signal')
|
e@0
|
807 self.canvas.draw()
|
e@0
|
808
|
e@0
|
809 self.lastplot = 'raw'
|
e@0
|
810 self.remove_action_from_status('Plotting raw')
|
e@0
|
811 thread.exit_thread()
|
e@0
|
812 def callback_plot_raw(self):
|
e@0
|
813 try:
|
e@0
|
814 thread.start_new_thread(self.plot_raw, ())
|
e@0
|
815 except:
|
e@0
|
816 print "[EE] Could not start new thread"
|
e@0
|
817
|
e@0
|
818
|
e@0
|
819
|
e@0
|
820 # show()
|
e@0
|
821
|
e@0
|
822 def plot_reverb(self):
|
e@0
|
823 if self.lastplot != 'reverb':
|
e@0
|
824 self.add_action_to_status('Plotting reverberated signal')
|
e@0
|
825
|
e@0
|
826 self.calculate_impulse_response()
|
e@0
|
827 ly, ry = self.impulse_response_left_channel, self.impulse_response_right_channel
|
e@0
|
828
|
e@0
|
829 lx = self.audio[:,0]
|
e@0
|
830 rx = self.audio[:,1]
|
e@0
|
831
|
e@0
|
832 print "Concolving left channel"
|
e@0
|
833 l_out = fftconvolve(ly, lx)
|
e@0
|
834
|
e@0
|
835 print "Convolving right channel"
|
e@0
|
836 r_out = fftconvolve(ry, rx)
|
e@0
|
837
|
e@0
|
838
|
e@0
|
839
|
e@0
|
840 lim = min(len(l_out), len(r_out))
|
e@0
|
841 # N = self.numChannels
|
e@0
|
842 # SR = self.SR
|
e@0
|
843 # T = 1.0/self.SR
|
e@0
|
844 #
|
e@0
|
845 #
|
e@0
|
846 # d1 = int(self.d1)
|
e@0
|
847 # g1 = self.g1
|
e@0
|
848 # da = int(self.da)
|
e@0
|
849 # G = self.G
|
e@0
|
850 # gc = self.gc
|
e@0
|
851 #
|
e@0
|
852 # mt = 0.002
|
e@0
|
853 # m = int(mt*SR)
|
e@0
|
854 #
|
e@0
|
855 # lchannel = ravel(self.audio[:,0])
|
e@0
|
856 # rchannel = ravel(self.audio[:,1])
|
e@0
|
857 #
|
e@0
|
858 # print "Calculating zafar"
|
e@0
|
859 #
|
e@0
|
860 # if self.parameterschanged_render == True:
|
e@0
|
861 # (ly, ry) = zafar(lchannel,rchannel,d1,g1,da,G,gc,m)
|
e@0
|
862 #
|
e@0
|
863 # self.reverberated_signal_left_channel = ly
|
e@0
|
864 # self.reverberated_signal_right_channel = ry
|
e@0
|
865 #
|
e@0
|
866 # self.parameterschanged_render = 0
|
e@0
|
867 # else:
|
e@0
|
868 # ly = self.reverberated_signal_left_channel
|
e@0
|
869 # ry = self.reverberated_signal_right_channel
|
e@0
|
870 #
|
e@0
|
871 # print "Stopped calculating zafar"#ly.shape
|
e@0
|
872 # # limt = self.T60
|
e@0
|
873 #
|
e@0
|
874 # lim = int(limt*SR)
|
e@0
|
875
|
e@0
|
876 # lim = len(lchannel)
|
e@0
|
877 # print "lim:", lim
|
e@0
|
878 T = 1/self.SR
|
e@0
|
879 t = arange(0, lim)*T
|
e@0
|
880 # print t
|
e@0
|
881
|
e@0
|
882 # Pad ly to t
|
e@0
|
883 # print "Shape ly"
|
e@0
|
884 ## print ly
|
e@0
|
885 # print len(ly)
|
e@0
|
886 # padded_y = zeros(shape(t))
|
e@0
|
887 # padded_y[0:len(ly)] = ly
|
e@0
|
888
|
e@0
|
889 # print "Padded y"
|
e@0
|
890 #print padded_y
|
e@0
|
891
|
e@0
|
892 # ly = padded_y
|
e@0
|
893
|
e@0
|
894 # Pad ry to t
|
e@0
|
895
|
e@0
|
896 # padded_y = zeros(shape(t))
|
e@0
|
897 # padded_y[0:len(ry)] = ry
|
e@0
|
898
|
e@0
|
899 # ry = padded_y
|
e@0
|
900 #
|
e@0
|
901
|
e@0
|
902
|
e@0
|
903 self.figure.clear()
|
e@0
|
904
|
e@0
|
905 print "Passed A"
|
e@0
|
906 subplt0 = self.figure.add_subplot(2,1,1)
|
e@0
|
907
|
e@0
|
908 subplt0.plot(t,l_out[0:lim])
|
e@0
|
909 subplt0.set_title('Left Channel')
|
e@0
|
910 subplt0.set_xlabel('time (s)')
|
e@0
|
911 subplt0.set_ylabel('amplitude')
|
e@0
|
912 # subplt0.axvspan(0,0.1, alpha=0.1,color='cyan')
|
e@0
|
913 # subplt0.axvline(self.Tc, color='red', linestyle='--')
|
e@0
|
914 # subplt0.axvline(0.1, color='cyan', linestyle='--')
|
e@0
|
915 # subplt0.annotate('Central Time (Tc)', xy=(self.Tc, 0.5), xytext=(self.Tc+0.01, 0.52), arrowprops=dict(facecolor='black',width=1))
|
e@0
|
916 # subplt0.annotate('Echo Density (D) Measurement Point ', xy=(0.1, 0.6), xytext=(.11, 0.62), arrowprops=dict(facecolor='black',width=1))
|
e@0
|
917
|
e@0
|
918 #
|
e@0
|
919
|
e@0
|
920 subplt1 = self.figure.add_subplot(2,1,2,sharex=subplt0)
|
e@0
|
921 subplt1.set_title('Right Channel')
|
e@0
|
922
|
e@0
|
923 subplt1.plot(t,r_out[0:lim])
|
e@0
|
924 subplt1.set_xlabel('time (s)')
|
e@0
|
925 subplt1.set_ylabel('amplitude')
|
e@0
|
926 # subplt1.axvspan(0,0.1, alpha=0.1,color='cyan')
|
e@0
|
927 # subplt1.axvline(self.Tc, color='red', linestyle='--')
|
e@0
|
928 # subplt1.axvline(0.1, color='cyan', linestyle='--')
|
e@0
|
929
|
e@0
|
930
|
e@0
|
931 self.figure.suptitle("Reverberated Signal")
|
e@0
|
932
|
e@0
|
933 # print "Passed B"
|
e@0
|
934 #
|
e@0
|
935 self.remove_action_from_status('Plotting reverberated signal')
|
e@0
|
936 self.canvas.draw()
|
e@0
|
937
|
e@0
|
938 self.lastplot = 'reverb'
|
e@0
|
939 #
|
e@0
|
940 thread.exit_thread()
|
e@0
|
941 def callback_plot_reverb(self):
|
e@0
|
942 try:
|
e@0
|
943 thread.start_new_thread(self.plot_reverb, ())
|
e@0
|
944 except:
|
e@0
|
945 print "[EE] Could not start new thread"
|
e@0
|
946
|
e@0
|
947
|
e@0
|
948 def callback_play_raw(self):
|
e@0
|
949 print "[II] Called callback_play_raw"
|
e@0
|
950 try:
|
e@0
|
951 self.playerprocess.terminate()
|
e@0
|
952 except:
|
e@0
|
953 pass
|
e@0
|
954 self.play_raw()
|
e@0
|
955
|
e@0
|
956 def callback_play_reverb(self):
|
e@0
|
957
|
e@0
|
958 print "[II] Called callback_play_reverb"
|
e@0
|
959 try:
|
e@0
|
960 self.playerprocess.terminate()
|
e@0
|
961 except:
|
e@0
|
962 pass
|
e@0
|
963
|
e@0
|
964 self.play_reverb()
|
e@0
|
965
|
e@0
|
966 def callback_stop(self):
|
e@0
|
967 self.playerprocess.terminate()
|
e@0
|
968
|
e@0
|
969 def callback_save(self):
|
e@0
|
970 outf = "%s_parameters.yaml" % self.filename.split('.')[0]
|
e@0
|
971 out = YamlOutput(filename=outf)
|
e@0
|
972 out(self.pool)
|
e@0
|
973 print "[II] Parameters Saved"
|
e@0
|
974 self.saved = True
|
e@0
|
975
|
e@0
|
976 def callback_reset(self):
|
e@0
|
977 d1 = self.d1
|
e@0
|
978 g1 = self.g1
|
e@0
|
979 da = self.da
|
e@0
|
980 G = self.G
|
e@0
|
981 gc = self.gc
|
e@0
|
982
|
e@0
|
983 self.d1 = self.d1_old
|
e@0
|
984 self.g1 = self.g1_old
|
e@0
|
985 self.G = self.G_old
|
e@0
|
986 self.gc = self.gc_old
|
e@0
|
987 self.da = self.da_old
|
e@0
|
988
|
e@0
|
989 self.scale_d1.set(self.d1/self.SR)
|
e@0
|
990 self.scale_g1.set(self.g1)
|
e@0
|
991 self.scale_da.set(self.da/self.SR)
|
e@0
|
992 self.scale_G.set(self.G)
|
e@0
|
993 self.scale_gc.set(self.gc)
|
e@0
|
994
|
e@0
|
995
|
e@0
|
996 def callback_next(self):
|
e@0
|
997 if self.saved == False:
|
e@0
|
998 tkMessageBox.showerror("File not saved", "You need to save your changes first")
|
e@0
|
999 return
|
e@0
|
1000
|
e@0
|
1001
|
e@0
|
1002 self.visited_files.append(self.filename)
|
e@0
|
1003 self.sessionpool.add('visited_files', self.filename)
|
e@0
|
1004 self.files_to_visit.pop()
|
e@0
|
1005 self.sessionpool.remove('files_to_visit')
|
e@0
|
1006 for i in self.files_to_visit:
|
e@0
|
1007 self.sessionpool.add('files_to_visit', i)
|
e@0
|
1008 outp = YamlOutput(filename="session.yaml")(self.sessionpool)
|
e@0
|
1009
|
e@0
|
1010 if len(self.files_to_visit) == 0:
|
e@0
|
1011 tkMessageBox.showinfo("Congratulations!", "You finished the training session!")
|
e@0
|
1012 self.master.destroy()
|
e@0
|
1013 return
|
e@0
|
1014 self.filename = self.files_to_visit[-1]
|
e@0
|
1015 self.load_song(self.filename)
|
e@0
|
1016
|
e@0
|
1017
|
e@0
|
1018
|
e@0
|
1019
|
e@0
|
1020 if __name__ == "__main__":
|
e@0
|
1021 if len(argv) != 2:
|
e@0
|
1022 print "[EE] Wrong number of arguments"
|
e@0
|
1023 print "[II] Correct syntax is:"
|
e@0
|
1024 print "[II] \t%s <trainingdir>"
|
e@0
|
1025 print "[II] where <trainingdir> contains the segments in .wav format and their corresponding .yaml files"
|
e@0
|
1026
|
e@0
|
1027 exit(-1)
|
e@0
|
1028
|
e@0
|
1029 print "[II] Using directory: %s" % argv[1]
|
e@0
|
1030 root = Tk()
|
e@0
|
1031 app = UI(root, argv[1])
|
e@0
|
1032 root.mainloop()
|
e@0
|
1033
|
e@0
|
1034 # app.player.terminate()
|
e@0
|
1035 # root.destroy() |