def optimfuncLDFB(x, N): '''function for optimizing an MDCT type filter bank. x: unknown matrix coefficients, N: Number of subbands. ''' #Analysis folding matrix: Fa = symFmatrix(x[0:int(1.5 * N)]) Faz = polmatmult(Fa, Dmatrix(N)) Faz = polmatmult(Faz, Gmatrix(x[int(1.5 * N):(2 * N)])) #baseband prototype function h: h = Fa2h(Faz) #'Fa2h is returning 2D array. Squeeze to make it 1D' #h= np.squeeze(h) #Frequency response of the the baseband prototype function at 1024 frequency sampling points #between 0 and Nyquist: w, H = sig.freqz(h, 1, 1024) #desired frequency response #Limit of desired pass band (passband is between -pb and +pb, hence ../2) pb = int(1024 / N / 2.0) #Ideal desired frequency response: Hdes = np.concatenate((np.ones(pb), np.zeros(1024 - pb))) #transition band width to allow filter transition from pass band to stop band: tb = int(np.round(1.0 * pb)) #Weights for differently weighting errors in pass band, transition band and stop band: weights = np.concatenate( (1.0 * np.ones(pb), np.zeros(tb), 1000 * np.ones(1024 - pb - tb))) #Resulting total error number as the sum of all weighted errors: err = np.sum(np.abs(H - Hdes) * weights) return err
def optimfuncMDCT(x, N): """Computes the error function for the filter bank optimization for coefficients x, a 1-d array, N: Number of subbands""" import numpy as np import scipy.signal as sig from polmatmult import polmatmult from Dmatrix import Dmatrix from symFmatrix import symFmatrix from Fa2h import Fa2h #x = np.transpose(x) Fa = symFmatrix(x) D = Dmatrix(N) Faz = polmatmult(Fa, D) h = Fa2h(Faz) h = np.hstack(h) w, H = sig.freqz(h, 1, 1024) pb = int(1024 / N / 2) Hdes = np.concatenate((np.ones((pb, 1)), np.zeros(((1024 - pb, 1)))), axis=0) tb = np.round(pb) weights = np.concatenate((np.ones((pb, 1)), np.zeros( (tb, 1)), 1000 * np.ones((1024 - pb - tb, 1))), axis=0) err = np.sum(np.abs(H - Hdes) * weights) return err
def MDCTanafb(x, N, fb): #MDCT analysis filter bank. #Arguments: x: input signal, e.g. audio signal, a 1-dim. array #N: number of subbands #fb: coefficients for the MDCT filter bank, for the F matrix, np.array with 1.5*N coefficients. #returns y, consisting of blocks of subband in in a 2-d array of shape (N,# of blocks) Fa = symFmatrix(fb) D = Dmatrix(N) y = x2polyphase(x, N) y = polmatmult(y, Fa) y = polmatmult(y, D) y = DCT4(y) #strip first dimension: y = y[0, :, :] return y
def LDFBana(x, N, fb): #Low Delay analysis filter bank. #Arguments: x: input signal, e.g. audio signal, a 1-dim. array #N: number of subbands #fb: coefficients for the MDCT filter bank, for the F matrix, np.array with 1.5*N coefficients. #returns y, consisting of blocks of subband in in a 2-d array of shape (N,# of blocks) Fa = symFmatrix(fb[0:int(1.5 * N)]) print("Fa.shape=", Fa.shape) D = Dmatrix(N) G = Gmatrix(fb[int(1.5 * N):(2 * N)]) y = x2polyphase(x, N) print("y[:,:,0]=", y[:, :, 0]) y = polmatmult(y, Fa) y = polmatmult(y, D) y = polmatmult(y, G) y = DCT4(y) #strip first dimension: y = y[0, :, :] return y
def MDCTsynfb(y, fb): #MDCT synthesis filter bank. #Arguments: y: 2-d array of blocks of subbands, of shape (N, # of blokcs) #returns xr, the reconstructed signal, a 1-d array. N = y.shape[0] Fa = symFmatrix(fb) #invert Fa matrix for synthesis after removing last dim: Fs = np.linalg.inv(Fa[:, :, 0]) #add again last dimension for function polmatmult: Fs = np.expand_dims(Fs, axis=-1) Dinv = Dinvmatrix(N) #add first dimension to y for polmatmult: y = np.expand_dims(y, axis=0) xp = DCT4(y) xp = polmatmult(xp, Dinv) xp = polmatmult(xp, Fs) xr = polyphase2x(xp) return xr
def LDFBsyn(y, fb): #Low Delay synthesis filter bank. #Arguments: y: 2-d array of blocks of subbands, of shape (N, # of blokcs) #returns xr, the reconstructed signal, a 1-d array. Fa = symFmatrix(fb[0:int(1.5 * N)]) #invert Fa matrix for synthesis after removing last dim: Fs = np.linalg.inv(Fa[:, :, 0]) #add again last dimension for function polmatmult: Fs = np.expand_dims(Fs, axis=-1) Ginv = Ginvmatrix(fb[int(1.5 * N):(2 * N)]) Dinv = Dinvmatrix(N) #Display the synthesis folding matrix Fs(z): Fsz = polmatmult(polmatmult(Ginv, Dinv), Fs) #add first dimension to y for polmatmult: y = np.expand_dims(y, axis=0) xp = DCT4(y) xp = polmatmult(xp, Ginv) xp = polmatmult(xp, Dinv) xp = polmatmult(xp, Fs) xr = polyphase2x(xp) return xr
import scipy.signal import matplotlib.pyplot as plt N = 4 #number of subbands s = 2 * N bounds = [(-14, 14)] * s xmin = sp.optimize.differential_evolution(optimfuncLDFB, bounds, args=(N, ), disp=True) print("error after optim.=", xmin.fun) print("optimized coefficients=", xmin.x) np.savetxt("LDFBcoeff.txt", xmin.x) x = xmin.x #Baseband Impulse Response: Fa = symFmatrix(x[0:int(1.5 * N)]) #print("Fa=", Fa[:,:,0]) Faz = polmatmult(Fa, Dmatrix(N)) Faz = polmatmult(Faz, Gmatrix(x[int(1.5 * N):(2 * N)])) h = Fa2h(Faz) plt.plot(h) plt.xlabel('Sample') plt.ylabel('Value') plt.title('Baseband Impulse Response of the Low Delay Filter Bank') #Magnitude Response: w, H = sp.signal.freqz(h) plt.figure() plt.plot(w, 20 * np.log10(abs(H))) plt.axis([0, 3.14, -60, 20]) plt.xlabel('Normalized Frequency') plt.ylabel('Magnitude (dB)')
from Dmatrix import Dmatrix from Fa2h import Fa2h N = 4 #Start optimization with some starting point: x0 = -np.random.rand(int(1.5 * N)) print("starting error=", optimfuncMDCT(x0, N)) #test optim. function xmin = sp.optimize.minimize(optimfuncMDCT, x0, args=(N, ), options={'disp': True}) print("optimized coefficients=", xmin.x) np.savetxt("MDCTcoeff.txt", xmin.x) print("error after optim.=", optimfuncMDCT(xmin.x, N)) #Baseband Impulse Response: Fa = symFmatrix(xmin.x) Faz = polmatmult(Fa, Dmatrix(N)) h = Fa2h(Faz) print("h=", h) plt.plot(h) plt.xlabel('Sample') plt.ylabel('Value') plt.title('Baseband Impulse Response of our Optimized MDCT Filter Bank') plt.figure() #Magnitude Response: w, H = sp.signal.freqz(h) plt.plot(w, 20 * np.log10(abs(H))) plt.axis([0, 3.14, -60, 20]) plt.xlabel('Normalized Frequency') plt.ylabel('Magnitude (dB)') plt.title('Mag. Frequency Response of the MDCT Filter Bank')
import numpy as np #import scipy as sp import matplotlib.pyplot as plt from scipy.optimize import minimize from optimfuncLDFB import optimfuncLDFB x0 = np.random.random(8) xmin = minimize(optimfuncLDFB, x0) x = xmin.x print(x) from symFmatrix import symFmatrix from polmatmult import polmatmult from Dmatrix import Dmatrix from Fa2h import Fa2h from Gmatrix import Gmatrix N = 4 Fa = symFmatrix(x[0:(3 * N / 2)]) #print("Fa=", Fa[:,:,0]) Faz = polmatmult(Fa, Dmatrix(4)) Faz = polmatmult(Faz, Gmatrix(x[3 * N / 2:(2 * N)])) #baseband prototype function h: h = Fa2h(Faz) print(h) plt.plot(h) plt.show()
import numpy as np #import scipy as sp import matplotlib.pyplot as plt from scipy.optimize import minimize from optimfuncMDCT import optimfuncMDCT x0 = np.random.random(6) xmin = minimize(optimfuncMDCT, x0) x=xmin.x print (x) from symFmatrix import symFmatrix from polmatmult import polmatmult from Dmatrix import Dmatrix from Fa2h import Fa2h Fa = symFmatrix(x) #print("Fa=", Fa[:,:,0]) Faz = polmatmult(Fa, Dmatrix(4)) h = Fa2h(Faz) print(h) plt.plot(h) plt.show()