Source code for spharpy.beamforming.beamforming

import numpy as np
import numpy.polynomial as poly
from scipy.linalg import eig
from scipy.special import factorial

import spharpy
import spharpy.special as special


[docs]def dolph_chebyshev_weights( n_max, design_parameter, design_criterion='sidelobe'): """Calculate the weights for a spherical Dolph-Chebyshev beamformer. The design criterion can either be a desired side-lobe attenuation or a desired main-lobe width. Once one criterion is chosen, the other will become a dependent property which will be chosen accordingly. Parameters ---------- n_max : int Spherical harmonic order design_parameter : float, double This can either be the desired side-lobe attenuation or the width of the main-lobe in radians. design_criterion : 'sidelobe', 'mainlobe' Whether the design parameter argument is the desired side-lobe attenuation or the desired main-lobe width. Returns ------- weigths : ndarray, double An array containing the weight coefficients $d_nm$. References ---------- .. [1] A. Koretz and B. Rafaely, “Dolph-Chebyshev beampattern design for spherical arrays,” IEEE Transactions on Signal Processing, vol. 57, no. 6, pp. 2417–2420, 2009. """ M = 2*n_max if design_criterion == 'sidelobe': R = design_parameter x0 = np.cosh((1/M) * np.arccosh(R)) elif design_criterion == 'mainlobe': theta0 = design_parameter x0 = np.cos(np.pi/2/M) / np.cos(theta0/2) R = np.cosh(M * np.arccosh(x0)) else: raise ValueError("This design criterion is not available.") t_2N = special.chebyshev_coefficients(2*n_max) P_N = np.zeros((n_max+1, n_max+1)) for n in range(n_max+1): P_N[0:n+1, n] = special.legendre_coefficients(n) d_n = np.zeros(n_max+1) for n in range(n_max+1): temp = 0 for i in range(n+1): for j in range(n_max+1): for m in range(j+1): temp = temp+(1-(-1)**(m+i+1))/(m+i+1) * \ factorial(j)/(factorial(m)*factorial(j-m)) * \ (1/2**j)*t_2N[2*j]*P_N[i, n]*x0**(2*j) d_n[n] = (2*np.pi/R)*temp weights = spharpy.indexing.sph_identity_matrix(n_max, type='n-nm').T @ d_n return weights
[docs]def rE_max_weights(n_max): """Weights that maximize the length of the energy vector. This is most often used in Ambisonics decoding. Parameters ---------- n_max : int Spherical harmonic order Returns ------- weights : ndarray, double An array containing the weight coefficients. References ---------- .. [2] J. Daniel, J.-B. Rault, and J.-D. Polack, “Ambisonics Encoding of Other Audio Formats for Multiple Listening Conditions,” in 105th Convention of the Audio Engineering Society, 1998, vol. 3. """ leg = poly.legendre.Legendre.basis(n_max+1) P_n_root = poly.legendre.legroots(leg.coef) max_root = np.max(np.abs(P_n_root)) g_n = np.zeros(n_max+1) for n in range(0, n_max+1): leg = poly.legendre.Legendre.basis(n) g_n[n] = leg(max_root) weights = spharpy.indexing.sph_identity_matrix(n_max).T @ g_n return weights
[docs]def maximum_front_back_ratio_weights(n_max): """Weights that maximize the front-back ratio of the beam pattern. This is also often referred to as the super-cardioid beam pattern. Parameters ---------- n_max : int The spherical harmonic order Returns ------- weigths : ndarray, double An array containing the weight coefficients Note ---- The weights are calculated from an eigenvalue problem References ---------- [3] B. Rafaely, Fundamentals of Spherical Array Processing, Springer, 2015. """ P_N = np.zeros((n_max+1, n_max+1)) for n in range(n_max+1): P_N[0:n+1, n] = special.legendre_coefficients(n) Ann = np.zeros((n_max+1, n_max+1)) Bnn = np.zeros((n_max+1, n_max+1)) for n in range(n_max+1): for n_dash in range(n_max+1): const = 1/8/np.pi * (2*n+1) * (2*n_dash+1) temp = 0 for q in range(0, n+1): for ll in range(0, n_dash+1): temp += 1/(q+ll+1) * P_N[q, n] * P_N[ll, n_dash] Ann[n, n_dash] = temp * const temp = 0 for q in range(0, n+1): for ll in range(0, n_dash+1): temp += ((-1)**(q+ll))/(q+ll+1) * \ P_N[q, n] * P_N[ll, n_dash] Bnn[n, n_dash] = temp * const eigenvals, eigenvectors = eig(Ann, Bnn) f_n = eigenvectors[:, np.argmax(np.real(eigenvals))] weights = spharpy.indexing.sph_identity_matrix(n_max).T @ f_n return weights