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