def broadband_performance_dict(self): ''' Compute the preformace value for an adaptive array. Return ------ A dict contains 'array gain', 'noise reduction factor', 'signal reduction facor', 'signal distortion index' values ''' #数字信号宽带计算频率,计算自适应Beamformer的一些性质(宽带的) freq = np.linspace(-0.5, 0.5, num=1000, endpoint=True) * 1 / self.sound_field.Ts freq = freq[1:-1] # 初始化一些矩阵 filter_vec = np.zeros((self.M, len(freq)), dtype=np.complex) #滤波器系数 steer_vec = np.zeros((self.M, len(freq)), dtype=np.complex) #导向矢量 observed_cov_vec = np.zeros((self.M, self.M, len(freq)), dtype=np.complex) #观测矩阵相关系数 noise_cov_vec = np.zeros((self.M, self.M, len(freq)), dtype=np.complex) #噪声的相关系数矩阵 desired_var_vec = np.zeros(len(freq), dtype=np.complex) #期望信号方差 noise_var_vec = self.sound_field.noise_signal_var * np.ones( len(freq)) #第一个阵元噪声的方差 #赋值 for i, f in enumerate(freq): filter_vec[:, i] = self.filter(f).T steer_vec[:, i] = self.steer_vector(f, self.phi).T desired_var_vec[i] = self.sound_field.desired_signal_var(f) observed_cov_vec[:, :, i] = self.sound_field.observed_signal_cov(f) noise_cov_vec[:, :, i] = self.sound_field.noise_signal_cov(f) # 输出的信号和噪声的能量 output_signal_energy = desired_var_vec.dot( np.abs(np.sum(filter_vec.conj() * steer_vec, axis=0))**2) #宽带输出信号能量 output_noise_energy = 0 #equations-8 for i, f in enumerate(freq): output_noise_energy += hermitian(filter_vec[:, i]).dot( noise_cov_vec[:, :, i]).dot(filter_vec[:, i]) #宽带输出噪声能量 # 属性字典 performance_dict = {'array gain' : dB(output_signal_energy / output_noise_energy, power=True) \ - self.sound_field._iSNR.get('dB_value'), 'noise reduction factor' : dB(np.sum(noise_var_vec) / output_noise_energy, power=True), 'signal reduction factor': dB(np.sum(desired_var_vec) / output_signal_energy, power=True), 'signal distortion index': dB((desired_var_vec.dot(np.abs(np.sum(filter_vec.conj() * \ steer_vec, axis=0) - 1) ** 2)) / np.sum(desired_var_vec), power=True) } return performance_dict
def snr_direct_method(self, f): ''' Estimate the single-channel Wiener gain directly ''' hw = hermitian(self.steer_vector(f, self.phi)).dot(self.observed_signal_gamma(f) - \ self.isotropic_noise_coherence(f)).dot(self.steer_vector(f, self.phi)) / \ (self.M ** 2 - hermitian(self.steer_vector(f, self.phi)).dot(self.isotropic_noise_coherence(f)).dot(self.steer_vector(f, self.phi))) return dB(hw)[0][0]
def white_noise_gain(self): ''' return the white noise gain in TDB ''' g = self.steer_vector() h = self.filter white_noise_gain = h.T.dot(g).dot(g.T).dot(h) / h.T.dot(h) white_noise_gain_db = dB(np.abs(white_noise_gain), True) return white_noise_gain_db
def directivity(self): ''' return the directivity in TDB ''' g = self.steer_vector() h = self.filter int_g = self.diffuse_noise_coherence() directivity = (h.T.dot(g.dot(g.T)).dot(h)) / (h.T.dot(int_g).dot(h)) directivity_db = dB(np.abs(directivity), True) return directivity_db
def beam_pattern(self): """ 绘制波束形成的波束图 """ filts = self.filter performace = [] for theta in constants.get('angle_range'): g_tmp = self.steer_vector(theta) performace_theta = filts.T.dot(g_tmp).dot(g_tmp.T).dot(filts) performace.append(performace_theta) return dB(np.array(performace), True)
def white_noise_gain(self, f): ''' For fixed beamforming, the WNG equals to 1 / w.conj().T * w And in delay and sum the w equals to steervector / self.N Parameters ---------- f: float frequency ''' wng = 1 / np.dot(hermitian(self.filter(f)), self.filter(f)) return dB(wng, True)
def front_back_ratio(self): ''' return the front_back_ratio in TDB ''' theta_array_0_90 = np.array_split(constants.get('angle_range'), 2)[0] theta_array_90_180 = np.array_split(constants.get('angle_range'), 2)[1] filts = self.filter gamma_0_half_pi = self.diffuse_noise_coherence(theta_array_0_90) gamma_half_pi_pi = self.diffuse_noise_coherence(theta_array_90_180) front_back_ratio = (filts.T.dot(gamma_0_half_pi).dot(filts)) / ( filts.T.dot(gamma_half_pi_pi).dot(filts)) return dB(front_back_ratio, True)
def beam_pattern(self, f): ''' Compute and Plot beampattern response for microphone array Parameters ---------- f: float frequency ''' omega = self.filter(f) steer_vector = self.steer_vector(f) response = np.squeeze(dB(np.abs(hermitian(steer_vector).dot(omega)))) return response
def performance(self): i = self.i_ell h = self.filter g = self.steer_vector() r_n = self.sound_field.noise_signal_correlation() r_x = self.sound_field.desired_signal_correlation() oSNR = h.T.dot(g).dot(r_x).dot(g.T).dot(h) / h.T.dot(r_n).dot(h) oSNR_dB = np.asscalar(dB(oSNR, True)) nr_factor = r_n[0, 0] / (h.T.dot(r_n).dot(h)) sigr_factor = r_x[0, 0] / (h.T.dot(g).dot(r_x).dot(g.T).dot(h)) sigd_index = ( (g.T.dot(h) - i).T.dot(r_x).dot(g.T.dot(h) - i)) / r_x[0, 0] performance_dict = { 'array gain': (oSNR_dB - self.sound_field._iSNR.get('dB_value')), 'noise reduction factor': np.asscalar(dB(nr_factor, True)), 'signal reduction factor': dB(sigr_factor, True), 'signal distortion index': dB(sigd_index, True) } return performance_dict
def directivity(self, f): ''' Directivity factor of microphone array note: python sinc function is sinc(pi*x) / pi*x Parameters ---------- f: float frequency ''' noise_cov = self.diffuse_noise_coherence(f) di = 1 / hermitian(self.filter(f)).dot(noise_cov).dot(self.filter(f)) return dB(di, True)
def snr_complex_method(self, f): ''' averege method by real and imag decompostion ''' TmpH1 = (np.real(self.observed_signal_gamma(f)) - self.isotropic_noise_coherence(f)) / \ (np.real(np.dot(self.steer_vector(f, self.phi).reshape(self.M, 1), self.steer_vector(f, self.phi).conj().reshape(1,self.M))) - self.isotropic_noise_coherence(f)) TmpH2 = np.imag(self.observed_signal_gamma(f)) / np.imag( np.dot( self.steer_vector(f, self.phi).reshape(self.M, 1), self.steer_vector(f, self.phi).conj().reshape(1, self.M))) [m_mat, n_mat] = np.meshgrid(np.arange(self.M), np.arange(self.M)) idx = np.where((m_mat - n_mat) > 0) return dB( np.complex( np.sum(TmpH1[idx] + TmpH2[idx]) / self.M / (self.M - 1)))