diff experiment-reverb/code/ui.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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/experiment-reverb/code/ui.py	Wed Dec 14 13:15:48 2016 +0000
@@ -0,0 +1,1035 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Thu Jun 11 11:03:04 2015
+
+@author: mmxgn
+"""
+
+
+import matplotlib
+matplotlib.use("TkAgg")
+from matplotlib.figure import Figure
+from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
+
+import pyaudio
+from sys import argv, exit
+from essentia.standard import YamlInput, YamlOutput, AudioLoader, AudioWriter
+from essentia import Pool
+from pca import *
+
+from numpy import *
+from sklearn import cluster
+from sklearn.metrics import pairwise_distances
+from sklearn.cluster import KMeans, MiniBatchKMeans
+from matplotlib.pyplot import *
+#from sklearn.mixture import GMM
+from sklearn.naive_bayes import GaussianNB, MultinomialNB
+from scipy.signal import decimate
+from sklearn import cross_validation
+from Tkinter import *
+import tkMessageBox
+import thread
+from numpy.core._internal import _gcd as gcd
+import time
+import os
+import subprocess
+from scikits.audiolab import Format, Sndfile
+from scipy.signal import fftconvolve
+from glob import glob
+
+def zafar(lx, rx, d1, g1, da, G, gc, m):
+    """ Rafii & Pardo Reverberator (2009) controlled by High Level parameters 
+        Inputs:
+            lx : left channel input
+            rx : right channel input
+            d1 : delay of first comb filter in samples
+            g1 : gain of first comb filters
+            da : delay of allpass filter in samples
+            G  : dry/wet mix gain
+            gc : lowpass filter gain
+            m  : difference between left and right channel phases
+            
+        Outputs:
+            ly: left channel output
+            ry: right channel output
+            """
+        
+    def calculate_parameters(d1,g1):
+        
+        d2 = int(round((1.5)**(-1)*d1))
+
+        while gcd(d2,d1) != 1:
+            d2 += 1
+        
+        d3 = int(round((1.5)**(-2)*d1))
+        
+        while gcd(d3, d2) != 1 or gcd(d3, d1) != 1:
+            d3 += 1
+            
+        d4 = int(round((1.5)**(-3)*d1))
+        
+        while gcd(d4, d3) != 1 or gcd(d4, d2) != 1  or gcd(d4, d1) != 1:
+            d4 += 1
+
+            
+        d5 = int(round((1.5)**(-4)*d1))
+
+        while gcd(d5, d4) != 1 or gcd(d5, d3) != 1  or gcd(d5, d2) != 1 or gcd(d5, d1) != 1:
+            d5 += 1        
+        
+        d6 = int(round((1.5)**(-5)*d1))
+        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:
+            d6 += 1          
+        g2 = g1**(1.5)**(-1)*g1
+        g3 = g1**(1.5)**(-2)*g1
+        g4 = g1**(1.5)**(-3)*g1     
+        g5 = g1**(1.5)**(-4)*g1 
+        g6 = g1**(1.5)**(-5)*g1        
+        
+        return (d1, d2, d3, d4, d5, d6, g1, g2, g3, g4, g5, g6)       
+    def comb_array(x, g1, d1):
+
+        (d1,d2,d3,d4,d5,d6,g1,g2,g3,g4,g5,g6) = calculate_parameters(d1,g1)
+
+
+        
+        c1out = comb(x, g1, d1)
+        c2out = comb(x, g2, d2)
+        c3out = comb(x, g3, d3)
+        c4out = comb(x, g4, d4)
+        c5out = comb(x, g5, d5)
+        c6out = comb(x, g6, d6)
+        
+        
+        Lc1 = len(c1out)
+        Lc2 = len(c2out)
+        Lc3 = len(c3out)
+        Lc4 = len(c4out)
+        Lc5 = len(c5out)
+        Lc6 = len(c6out)
+        
+        Lc = max(Lc1, Lc2, Lc3, Lc4, Lc5, Lc6)
+        
+        y = zeros((Lc, ))
+        
+        y[0:Lc1] = c1out
+        y[0:Lc2] += c2out
+        y[0:Lc3] += c3out
+        y[0:Lc4] += c4out
+        y[0:Lc5] += c5out
+        y[0:Lc6] += c6out
+        
+        return y        
+        
+    def comb(x, g, d):
+        LEN = len(x)+d
+        print d
+        y = zeros((LEN,))
+        for n in range(0, LEN):
+            if n - d < 0:
+                y[n] = 0
+            else:
+                y[n] =  x[n-d] + g*y[n-d]
+                
+        return y     
+        
+    def allpass(x, g, d):
+        LENx = len(x)
+        LENy = LENx+d
+        y = zeros((LENy,))
+        for n in range(0, LENy):
+            if n-d < 0:
+                y[n] = -g*x[n]
+            elif n >= LENx:
+                y[n] = x[n-d] + g*y[n-d]
+            else:
+                y[n] = x[n-d] - g*x[n] + g*y[n-d]
+                
+        return y
+        
+    def lowpass(x, g):
+        LEN = len(x)
+        y = zeros((LEN,))
+        
+        for n in range(0, LEN):
+            if n-1 < 0:
+                y[n] = (1-g)*x[n]
+            else:
+                y[n] = (1-g)*x[n] + g*y[n-1]
+        
+        return y    
+        
+    ga = 1./sqrt(2.)
+    
+    cin = 0.5*lx + 0.5*rx
+    cout = comb_array(cin, g1, d1)     
+    
+            
+    ra = allpass(cout,  ga, da+m/2)
+    la = allpass(cout,  ga, da-m/2)
+    
+    ral = lowpass(ra, gc)
+    lal = lowpass(la, gc)
+
+    ralg = G*ral
+    lalg = G*lal
+
+    ry = ralg[0:len(rx)] + (1-G)*rx
+    ly = lalg[0:len(lx)] + (1-G)*lx
+
+  #     ry = cout
+  #      ly = cout
+            
+    
+    
+    return (ry, ly)
+
+class UI:
+    
+    def __init__(self, master, directory):
+        self.master = master
+        
+        self.directory = directory
+        
+
+
+        yamlinput = YamlInput(filename="session.yaml")
+        
+        try:
+            self.sessionpool = yamlinput()
+            try:
+                self.files_to_visit = self.sessionpool['files_to_visit']
+            except:
+                self.files_to_visit = []
+                
+            try:
+                self.visited_files = self.sessionpool['visited_files']
+            except:
+                self.visited_files = []
+            
+            
+
+        except:
+            print "[II] Could not open sessionpool file, creating a new one"
+            self.sessionpool = Pool()
+            self.files_to_visit = glob("%s/*.wav" % directory)
+            for i in self.files_to_visit:
+                self.sessionpool.add('files_to_visit', i)
+            self.visited_files = []            
+            
+        if len(self.files_to_visit) == 0:
+            tkMessageBox.showinfo("","No files to visit")
+            master.destroy()
+            return
+            
+        filename = self.files_to_visit[-1]
+        self.filename = filename
+       # visited_files.append(filename)
+        self.label_top = Label(master, text="")
+        self.label_top.grid(row=0, column=0, columnspan=6)
+        
+        self.load_song(filename)
+
+        
+        # Top Label
+
+        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))
+
+        # Sliders
+        
+        self.scale_d1 = Scale(master, to_=0.01, from_=0.1, resolution=0.01, label="d1", showvalue=True)#, command=self.callback_update_parameters)
+        self.scale_d1.bind("<ButtonRelease-1>",self.callback_update_parameters)        
+        self.scale_d1.grid(row=1,column=0,rowspan=17,sticky=N+S+E+W)
+        self.scale_g1 = Scale(master,to_=0.01, from_=0.99, resolution=0.01, label="g1", showvalue=True)#, command=self.callback_update_parameters)
+        self.scale_g1.bind("<ButtonRelease-1>",self.callback_update_parameters)        
+        
+        self.scale_g1.grid(row=1,column=1,rowspan=17,sticky=N+S+E+W)        
+        self.scale_da = Scale(master, to_=0.006, from_=0.012, resolution=0.001, label="da", showvalue=True)#, command=self.callback_update_parameters)
+        self.scale_da.bind("<ButtonRelease-1>",self.callback_update_parameters)        
+        
+        self.scale_da.grid(row=1,column=2,rowspan=17,sticky=N+S+E+W)      
+        self.scale_G = Scale(master,to_=0.01, from_=0.99, resolution=0.01, label="G", showvalue=True)#, command=self.callback_update_parameters)
+        self.scale_G.bind("<ButtonRelease-1>",self.callback_update_parameters)        
+        
+        self.scale_G.grid(row=1,column=3,rowspan=17,sticky=N+S+E+W)    
+        self.scale_gc = Scale(master, to_=0.01, from_=0.99, resolution=0.01, label="gc", showvalue=True)#, command=self.callback_update_parameters)
+        self.scale_gc.bind("<ButtonRelease-1>",self.callback_update_parameters)        
+        
+        self.scale_gc.grid(row=1,column=4,rowspan=17,sticky=N+S+E+W)        
+        
+        
+        # Labels
+        
+        self.label_T60 = Label(master, text="Reverberation Time: ")
+        self.label_T60.grid(row=2,column=6,sticky=N+S+E+W)
+        self.label_D = Label(master, text="Echo Density: ")
+        self.label_D.grid(row=3,column=6,sticky=N+S+E+W)
+        self.label_C = Label(master, text="Clarity: ")
+        self.label_C.grid(row=4,column=6,sticky=N+S+E+W)
+        self.label_Tc = Label(master, text="Central Time: ")
+        self.label_Tc.grid(row=5,column=6,sticky=N+S+E+W)
+        self.label_SC = Label(master, text="Spectral Centroid: ")
+        self.label_SC.grid(row=6,column=6,sticky=N+S+E+W)
+        
+        
+        # Buttons
+        
+        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)
+        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)
+        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) 
+        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)           
+        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)         
+        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)   
+        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)         
+        self.button_reset = Button(master, text="Undo", width=15, command=self.callback_reset).grid(row=14, column=6,sticky=N+S+E+W)                 
+        self.button_next = Button(master, text="Next >>", width=15, command=self.callback_next).grid(row=15, column=6,sticky=N+S+E+W)                 
+        
+        
+        
+        # Figure
+        
+        self.figure = Figure( dpi=50)
+        self.figure.text(0.5,0.5,'No plot selected', weight = "bold", horizontalalignment='center')
+        
+        
+        # a tk.DrawingArea
+        self.canvas = FigureCanvasTkAgg(self.figure, master=root)
+        #self.canvas.get_tk_widget().config(height=500, width=640)
+        self.canvas.show()
+        self.canvas.get_tk_widget().grid(row=0, column=7, rowspan=17, padx=20,sticky=E+W+N+S)
+        
+   #     toolbar = NavigationToolbar2TkAgg( master, master )
+   #     toolbar.update()
+        self.canvas._tkcanvas.grid(row=0, column=7, rowspan=17)
+     #   self.scale_d1.pack()
+        
+        # Toolbar for canvas
+        
+        self.toolbar_frame = Frame(master)
+        self.toolbar_frame.grid(row=17,column=7,sticky=E+W+N+S, padx=19)
+        self.toolbar = NavigationToolbar2TkAgg(self.canvas, self.toolbar_frame)
+        
+
+        
+        Grid.columnconfigure(master, 7, weight=1)
+        Grid.rowconfigure(master, 1, weight=1)
+        
+        # Status bar
+
+        self.status_bar_text = Label(text="Ready.")
+        self.status_bar_text.grid(row=18, column=0, columnspan = 8, sticky=N+S+E, padx=10)
+        
+        self.lastplot = ''
+        self.parameterschanged_render = True
+        self.pendingactions = []
+        
+        # Initial values
+        
+        d1t = 0.05
+        self.d1 = d1t*self.SR
+        dat = 0.006
+        self.da = dat*self.SR
+        g1 = 0.5
+        self.g1 = g1
+        G = 0.5
+        self.G = G
+        gc = 0.5
+        self.gc = gc
+        
+        self.scale_d1.set(d1t)
+        self.scale_da.set(dat)
+        self.scale_g1.set(g1)
+        self.scale_gc.set(gc)
+        self.scale_G.set(G)
+        
+        t = zeros((self.SR*120,))
+        t[0] = 1  
+        
+        self.impulse = t
+        
+      #  self.callback_plot_impulse()
+        
+        
+        # Pyaudio object
+        
+   #     self.player = pyaudio.PyAudio()
+        
+   #     self.player_idx = 0
+   #     
+    #    self.playerprocess = None
+        
+        
+        # Pool
+        
+        self.pool = Pool()
+        self.pool.set('filename', self.filename)
+        self.pool.set('sampleRate', self.SR)
+        self.pool.set('nChannels', self.numChannels)
+        
+
+        # Finally        
+        self.callback_update_parameters(None)
+
+
+        
+        
+        
+    def pyaudio_callback_raw(self, in_data, frame_count, time_info, status):
+        if self.player_command == 'Stop':
+            return (0, pyaudio.paAbort)
+        
+        data = self.audio[self.player_idx:self.player_idx+frame_count, :]
+        
+        data = reshape(data, (data.shape[0]*data.shape[1], 1))
+        
+      #  print data
+        self.player_idx += frame_count
+        
+        
+        return (data, pyaudio.paContinue)
+        
+    
+    def play_reverb(self):
+            
+            self.calculate_impulse_response()
+            ly, ry = self.impulse_response_left_channel, self.impulse_response_right_channel
+            
+            lx = self.audio[:,0]
+            rx = self.audio[:,1]
+            
+            print "Convolving left channel"
+            l_out = fftconvolve(ly, lx)
+
+            print "Convolving right channel"
+            r_out = fftconvolve(ry, rx)
+            
+            
+            
+            lim = min(len(l_out), len(r_out))
+            
+            
+            
+            if self.numChannels == 1:
+                audio_out = l_out[0:lim]
+            else:
+                audio_out = concatenate((matrix(l_out[0:lim]).T,
+                                    matrix(r_out[0:lim]).T                                    
+                                    ),
+                                    axis=1)
+            
+            reverb_filename = "%s_reverb_%s" % (self.filename.split('.')[0], self.filename.split('.')[1])
+                        
+            audio_file = Sndfile(reverb_filename, 'w', Format(self.filename.split('.')[1]), self.numChannels, self.SR)
+            audio_file.write_frames(audio_out)
+            audio_file.close()
+            
+            self.reverberated_audio = audio_out
+      #                              
+       #     audiowriter(audio_out)
+            
+            self.reverb_filename = reverb_filename
+            
+            self.playerprocess = subprocess.Popen("mplayer %s" % reverb_filename, 
+                                                  stdout = subprocess.PIPE,
+                                                  shell=True,
+                                                  preexec_fn=os.setsid)
+        
+    def play_raw(self):
+        self.playerprocess = subprocess.Popen("mplayer %s" % self.filename,
+                                              stdout = subprocess.PIPE,
+                                              shell=True,
+                                              preexec_fn=os.setsid)
+        
+        
+        
+        
+        
+    def remove_action_from_status(self, text):
+        
+        self.pendingactions.remove(text)
+        
+        if len(self.pendingactions) == 0:
+            self.status_bar_text.config(text='Ready.')
+        elif len(self.pendingactions) == 1:
+            self.status_bar_text.config(text=self.pendingactions[0]+'.') 
+        else:
+            self.status_bar_text.config(text=reduce(lambda h,t: h+','+t, self.pendingactions)+'.')        
+        
+        
+    def add_action_to_status(self, text):
+        
+        self.pendingactions.append(text)
+        
+        if len(self.pendingactions) == 0:
+            self.status_bar_text.config(text='Ready.')
+        elif len(self.pendingactions) == 1:
+            self.status_bar_text.config(text=text+'.')             
+        else:
+            self.status_bar_text.config(text=reduce(lambda h,t: h+', '+t, self.pendingactions)+'.')
+            
+        print self.pendingactions, len(self.pendingactions)
+        
+        
+    def load_song(self, filename):
+  #      self.label_top.config(text="Training '%s'" % filename)
+       # print filename
+        #self.audio, self.SR, self.numChannels = AudioLoader(filename=filename)()
+        tup = AudioLoader(filename=filename)()
+        self.audio = tup[0]
+        self.SR = tup[1]
+        self.numChannels = tup[2]
+        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))
+        self.saved = False
+        
+        
+        
+  
+    def estimate_T60(self, d1, g1, gc, G, SR):
+        ga = 1/sqrt(2)
+        return d1/SR/log(g1)*log(10**-3/ga/(1-gc)/G) 
+        
+    def calculate_parameters(self,d1,g1):
+        
+        d2 = int(round((1.5)**(-1)*d1))
+
+        while gcd(d2,d1) != 1:
+            d2 += 1
+        
+        d3 = int(round((1.5)**(-2)*d1))
+        
+        while gcd(d3, d2) != 1 or gcd(d3, d1) != 1:
+            d3 += 1
+            
+        d4 = int(round((1.5)**(-3)*d1))
+        
+        while gcd(d4, d3) != 1 or gcd(d4, d2) != 1  or gcd(d4, d1) != 1:
+            d4 += 1
+
+            
+        d5 = int(round((1.5)**(-4)*d1))
+
+        while gcd(d5, d4) != 1 or gcd(d5, d3) != 1  or gcd(d5, d2) != 1 or gcd(d5, d1) != 1:
+            d5 += 1        
+        
+        d6 = int(round((1.5)**(-5)*d1))
+        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:
+            d6 += 1          
+        g2 = g1**(1.5)**(-1)*g1
+        g3 = g1**(1.5)**(-2)*g1
+        g4 = g1**(1.5)**(-3)*g1     
+        g5 = g1**(1.5)**(-4)*g1 
+        g6 = g1**(1.5)**(-5)*g1        
+        
+        return (d1, d2, d3, d4, d5, d6, g1, g2, g3, g4, g5, g6)     
+    def estimate_C(self, g1, G, gc):
+        g2 = g1**(1.5)**(-1)*g1
+        g3 = g1**(1.5)**(-2)*g1
+        g4 = g1**(1.5)**(-3)*g1     
+        g5 = g1**(1.5)**(-4)*g1 
+        g6 = g1**(1.5)**(-5)*g1         
+        gains = zeros((6,1))
+        gains[0] = g1
+        gains[1] = g2
+        gains[2] = g3
+        gains[3] = g4
+        gains[4] = g5
+        gains[5] = g6
+        
+        return -10*log10(G**2*(1-gc)/(1+gc)*sum(1/(1-gains**2)))    
+    
+    def estimate_D(self, d1, g1, da, SR):
+        Dm = zeros((6,10))
+        delays = zeros((6,))
+        gains = zeros((6,1))        
+        (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)    
+        for k in range(1, 7):
+            for m in range(1, 11):
+                Dm[k-1,m-1] = max(0.1-m*delays[k-1]/SR,0)        
+        
+        return 10/da*self.SR*sum(Dm)
+        
+    def estimate_Tc(self, d1, g1, da, SR):
+        delays = zeros((6,))
+        gains = zeros((6,1))        
+        (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) 
+        return sum(delays/SR*gains**2/(1-gains**2)**2)/sum(gains**2/(1-gains**2)) + da/SR           
+        
+        
+    def callback_update_parameters(self,_):
+        SR = self.SR
+        d1t = self.scale_d1.get()
+        print d1t
+        
+        d1 = round(d1t*SR)
+        g1 = self.scale_g1.get()
+        dat = self.scale_da.get()
+        da = round(dat*SR)
+        G = self.scale_G.get()
+        gc = self.scale_gc.get()
+   
+        
+        T60 = self.estimate_T60(d1,g1,gc,G,SR)
+        D = self.estimate_D(d1, g1, da, SR)/10
+        C = self.estimate_C(g1, G, gc)
+        Tc = self.estimate_Tc(d1,g1,da,SR)
+        SC = self.estimate_SC(gc, SR)
+        
+        self.d1_old = self.d1
+        self.G_old = self.G
+        self.gc_old = self.gc
+        self.g1_old = self.g1
+        self.da_old = self.da
+        
+        self.d1 = d1
+        self.G = G
+        self.gc = gc
+        self.g1 = g1
+        self.da = da
+        
+        
+        
+        self.pool.set('parameters.d1', d1t)
+        self.pool.set('parameters.G', G)
+        self.pool.set('parameters.gc', gc)
+        self.pool.set('parameters.g1', g1)
+        self.pool.set('parameters.da', dat)
+        
+        
+        
+        self.T60 = T60
+        self.D = D
+        self.Tc = Tc
+        self.SC = SC
+        self.C = C
+        
+        self.pool.set('parameters.T60', T60)
+        self.pool.set('parameters.D', D)
+        self.pool.set('parameters.C', C)
+        self.pool.set('parameters.Tc', Tc)
+        self.pool.set('parameters.SC', SC)
+        
+        self.label_T60.config(text="Reverberation Time: %.3fs" % T60)
+        self.label_D.config(text="Echo Density: %.3f at 0.1s" % D)
+        self.label_C.config(text="Clarity: %.3f dB" % C)   
+        self.label_Tc.config(text="Central Time: %.3fs" % Tc)    
+        self.label_SC.config(text="Spectral Centroid: %.3f Hz" % SC)        
+        
+        self.lastplot = ''
+        self.parameterschanged_render = True
+#        self.callback_plot_impulse()
+        
+        
+    def estimate_SC(self, gc, SR):
+        n = arange(0, SR/2+1)
+        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)))        
+       
+        
+        
+        
+    def say_hi(self):
+        print "Hi, there"
+
+    def callback_plot_impulse(self):
+        try:
+            thread.start_new_thread(self.plot_impulse, ())
+        except:
+            print "[EE] Could not start new thread"
+    
+    
+    
+    def calculate_impulse_response(self):
+            self.add_action_to_status('Calculating impulse response')     
+            N = self.numChannels
+            SR = self.SR
+            T = 1.0/self.SR
+            
+            delta = self.impulse[0:int(self.T60*self.SR)]
+            print "delta:"
+            print delta
+            
+            d1 = int(self.d1)
+            g1 = self.g1
+            da = int(self.da)
+            G = self.G
+            gc = self.gc
+            
+            mt = 0.002
+            m = int(mt*SR)
+                   
+            (ly, ry) = zafar(delta,delta,d1,g1,da,G,gc,m)
+            
+            limt = self.T60
+            
+            lim = int(limt*SR)            
+            t = arange(0, lim)*T
+
+            padded_y = zeros(shape(t))
+            padded_y[0:len(ly)] = ly
+            
+            
+            padded_y = zeros(shape(t))
+            padded_y[0:len(ry)] = ry
+            
+            ry = padded_y                        
+            
+            self.impulse_response_left_channel = ly
+            self.impulse_response_right_channel = ry
+            
+            
+            self.remove_action_from_status('Calculating impulse response')
+            
+        
+    
+    def plot_impulse(self):
+        if self.lastplot != 'impulse':
+            self.add_action_to_status('Plotting impulse response')
+            N = self.numChannels
+            SR = self.SR
+            T = 1.0/self.SR
+            
+            delta = self.impulse[0:int(self.T60*self.SR)]
+            print "delta:"
+            print delta
+            
+            d1 = int(self.d1)
+            g1 = self.g1
+            da = int(self.da)
+            G = self.G
+            gc = self.gc
+            
+            mt = 0.002
+            m = int(mt*SR)
+                   
+            print "Calculating zafar"
+            (ly, ry) = zafar(delta,delta,d1,g1,da,G,gc,m)
+            
+            print "Stopped calculating zafar"#ly.shape
+            limt = self.T60
+            
+            lim = int(limt*SR)
+            print "lim:", lim
+            
+            t = arange(0, lim)*T
+           # print t
+            
+            # Pad ly to t
+            print "Shape ly"
+            print ly
+            print len(ly)
+            padded_y = zeros(shape(t))
+            padded_y[0:len(ly)] = ly
+            
+            print "Padded y"
+            #print padded_y
+            
+           # ly = padded_y
+            
+            # Pad ry to t
+            
+            padded_y = zeros(shape(t))
+            padded_y[0:len(ry)] = ry
+            
+            ry = padded_y            
+            
+            
+            
+            self.figure.clear()
+            
+            print "Passed A"
+            subplt0 =  self.figure.add_subplot(2,1,1)
+
+            subplt0.plot(t,abs(ly[0:lim]))
+            subplt0.set_title('Left Channel')
+            subplt0.set_xlabel('time (s)')
+            subplt0.set_ylabel('amplitude')   
+            subplt0.axvspan(0,0.1, alpha=0.1,color='cyan')
+            subplt0.axvline(self.Tc, color='red', linestyle='--')
+            subplt0.axvline(0.1, color='cyan', linestyle='--')
+            subplt0.annotate('Central Time (Tc)', xy=(self.Tc, 0.5), xytext=(self.Tc+0.01, 0.52), arrowprops=dict(facecolor='black',width=1))
+            subplt0.annotate('Echo Density (D) Measurement Point ', xy=(0.1, 0.6), xytext=(.11, 0.62), arrowprops=dict(facecolor='black',width=1))
+            
+#            
+            
+            subplt1 = self.figure.add_subplot(2,1,2,sharex=subplt0)
+            subplt1.set_title('Right Channel')
+            
+            subplt1.plot(t,abs(ry[0:lim]))
+            subplt1.set_xlabel('time (s)')
+            subplt1.set_ylabel('amplitude')
+            subplt1.axvspan(0,0.1, alpha=0.1,color='cyan')
+            subplt1.axvline(self.Tc, color='red', linestyle='--')
+            subplt1.axvline(0.1, color='cyan', linestyle='--')
+            
+            
+            self.figure.suptitle("Reverberation Impulse Response")
+            
+#            print "Passed B"
+#            
+            self.remove_action_from_status('Plotting impulse response')
+            self.canvas.draw()
+            
+            self.lastplot = 'impulse'
+#            
+            thread.exit_thread()
+
+                
+    
+    def plot_raw(self):
+        if self.lastplot != 'raw':
+            self.add_action_to_status('Plotting raw')
+            N = self.numChannels
+            print "Channels: %d" % N
+            L = len(self.audio[:,0])
+            
+            
+            
+            
+            self.figure.clear()
+            
+            T = 1.0/self.SR
+            t = arange(0, L)*T
+            
+            oldsubplt = None
+            for n in range(0, N):
+                if oldsubplt is not None:
+                    subplt =  self.figure.add_subplot(N,1,n+1,sharex=oldsubplt)
+                else:
+                    subplt = self.figure.add_subplot(N,1,n+1)
+                subplt.plot(t,self.audio[:,n])
+                subplt.set_title('Channel %d' % n)
+                subplt.set_xlabel('time (s)')
+                subplt.set_ylabel('amplitude')
+                
+                oldsubplt = subplt
+    
+                
+            self.figure.suptitle('Raw Signal')
+            self.canvas.draw()
+            
+            self.lastplot = 'raw'
+            self.remove_action_from_status('Plotting raw')    
+            thread.exit_thread()
+    def callback_plot_raw(self):
+        try:
+            thread.start_new_thread(self.plot_raw, ())
+        except:
+            print "[EE] Could not start new thread"
+            
+
+
+       # show()
+    
+    def plot_reverb(self):       
+        if self.lastplot != 'reverb':
+            self.add_action_to_status('Plotting reverberated signal')
+            
+            self.calculate_impulse_response()
+            ly, ry = self.impulse_response_left_channel, self.impulse_response_right_channel
+            
+            lx = self.audio[:,0]
+            rx = self.audio[:,1]
+            
+            print "Concolving left channel"
+            l_out = fftconvolve(ly, lx)
+
+            print "Convolving right channel"
+            r_out = fftconvolve(ry, rx)
+            
+            
+            
+            lim = min(len(l_out), len(r_out))            
+#            N = self.numChannels
+#            SR = self.SR
+#            T = 1.0/self.SR
+#            
+#            
+#            d1 = int(self.d1)
+#            g1 = self.g1
+#            da = int(self.da)
+#            G = self.G
+#            gc = self.gc
+#            
+#            mt = 0.002
+#            m = int(mt*SR)
+#            
+#            lchannel = ravel(self.audio[:,0])
+#            rchannel = ravel(self.audio[:,1])
+#                   
+#            print "Calculating zafar"
+#            
+#            if self.parameterschanged_render == True:
+#                (ly, ry) = zafar(lchannel,rchannel,d1,g1,da,G,gc,m)
+#                
+#                self.reverberated_signal_left_channel = ly
+#                self.reverberated_signal_right_channel = ry
+#                
+#                self.parameterschanged_render = 0
+#            else:
+#                ly = self.reverberated_signal_left_channel
+#                ry = self.reverberated_signal_right_channel
+#            
+#            print "Stopped calculating zafar"#ly.shape
+#           # limt = self.T60
+#            
+         #   lim = int(limt*SR)
+            
+    #        lim = len(lchannel)
+     #       print "lim:", lim
+            T = 1/self.SR
+            t = arange(0, lim)*T
+           # print t
+            
+            # Pad ly to t
+       #     print "Shape ly"
+         ##   print ly
+         #   print len(ly)
+           # padded_y = zeros(shape(t))
+           # padded_y[0:len(ly)] = ly
+            
+   #         print "Padded y"
+            #print padded_y
+            
+           # ly = padded_y
+            
+            # Pad ry to t
+            
+          #  padded_y = zeros(shape(t))
+          #  padded_y[0:len(ry)] = ry
+            
+        #    ry = padded_y            
+      #      
+            
+            
+            self.figure.clear()
+            
+            print "Passed A"
+            subplt0 =  self.figure.add_subplot(2,1,1)
+
+            subplt0.plot(t,l_out[0:lim])
+            subplt0.set_title('Left Channel')
+            subplt0.set_xlabel('time (s)')
+            subplt0.set_ylabel('amplitude')   
+      #      subplt0.axvspan(0,0.1, alpha=0.1,color='cyan')
+        #    subplt0.axvline(self.Tc, color='red', linestyle='--')
+       #     subplt0.axvline(0.1, color='cyan', linestyle='--')
+      #      subplt0.annotate('Central Time (Tc)', xy=(self.Tc, 0.5), xytext=(self.Tc+0.01, 0.52), arrowprops=dict(facecolor='black',width=1))
+      #     subplt0.annotate('Echo Density (D) Measurement Point ', xy=(0.1, 0.6), xytext=(.11, 0.62), arrowprops=dict(facecolor='black',width=1))
+            
+#            
+            
+            subplt1 = self.figure.add_subplot(2,1,2,sharex=subplt0)
+            subplt1.set_title('Right Channel')
+            
+            subplt1.plot(t,r_out[0:lim])
+            subplt1.set_xlabel('time (s)')
+            subplt1.set_ylabel('amplitude')
+        #    subplt1.axvspan(0,0.1, alpha=0.1,color='cyan')
+    #        subplt1.axvline(self.Tc, color='red', linestyle='--')
+     #       subplt1.axvline(0.1, color='cyan', linestyle='--')
+            
+            
+            self.figure.suptitle("Reverberated Signal")
+            
+#            print "Passed B"
+#            
+            self.remove_action_from_status('Plotting reverberated signal')
+            self.canvas.draw()
+            
+            self.lastplot = 'reverb'
+#            
+            thread.exit_thread()        
+    def callback_plot_reverb(self):
+        try:
+            thread.start_new_thread(self.plot_reverb, ())
+        except:
+            print "[EE] Could not start new thread"
+            
+    
+    def callback_play_raw(self):
+        print "[II] Called callback_play_raw"        
+        try:
+            self.playerprocess.terminate()
+        except:
+            pass
+        self.play_raw()
+        
+    def callback_play_reverb(self):
+        
+        print "[II] Called callback_play_reverb"
+        try:
+            self.playerprocess.terminate()
+        except:
+            pass
+            
+        self.play_reverb()
+    
+    def callback_stop(self):
+        self.playerprocess.terminate()
+    
+    def callback_save(self):
+        outf = "%s_parameters.yaml" % self.filename.split('.')[0]
+        out = YamlOutput(filename=outf)
+        out(self.pool)
+        print "[II] Parameters Saved"
+        self.saved = True
+    
+    def callback_reset(self):
+        d1 = self.d1
+        g1 = self.g1
+        da = self.da
+        G = self.G
+        gc = self.gc
+        
+        self.d1 = self.d1_old
+        self.g1 = self.g1_old
+        self.G = self.G_old
+        self.gc = self.gc_old
+        self.da = self.da_old
+        
+        self.scale_d1.set(self.d1/self.SR)
+        self.scale_g1.set(self.g1)
+        self.scale_da.set(self.da/self.SR)
+        self.scale_G.set(self.G)
+        self.scale_gc.set(self.gc)
+        
+    
+    def callback_next(self):
+        if self.saved == False:
+            tkMessageBox.showerror("File not saved", "You need to save your changes first")
+            return
+            
+            
+        self.visited_files.append(self.filename)
+        self.sessionpool.add('visited_files', self.filename)
+        self.files_to_visit.pop()
+        self.sessionpool.remove('files_to_visit')
+        for i in self.files_to_visit:
+            self.sessionpool.add('files_to_visit', i)
+        outp = YamlOutput(filename="session.yaml")(self.sessionpool)
+            
+        if len(self.files_to_visit) == 0:
+            tkMessageBox.showinfo("Congratulations!", "You finished the training session!")
+            self.master.destroy()
+            return            
+        self.filename = self.files_to_visit[-1]
+        self.load_song(self.filename)
+        
+        
+        
+    
+if __name__ == "__main__":
+    if len(argv) != 2:
+        print "[EE] Wrong number of arguments"
+        print "[II] Correct syntax is:"
+        print "[II] \t%s <trainingdir>"
+        print "[II] where <trainingdir> contains the segments in .wav format and their corresponding .yaml files"
+
+        exit(-1)    
+        
+    print "[II] Using directory: %s" % argv[1]
+    root = Tk()
+    app = UI(root, argv[1])
+    root.mainloop()
+    
+  #  app.player.terminate()
+   # root.destroy()
\ No newline at end of file