Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def get_rir(self, mic, visibility, Fs, t0=0., t_max=None):
'''
Compute the room impulse response between the source
and the microphone whose position is given as an
argument.
'''
# fractional delay length
fdl = constants.get('frac_delay_length')
fdl2 = (fdl-1) // 2
# compute the distance
dist = self.distance(mic)
time = dist / constants.get('c') + t0
alpha = self.damping / (4.*np.pi*dist)
# the number of samples needed
if t_max is None:
# we give a little bit of time to the sinc to decay anyway
N = np.ceil((1.05*time.max() - t0) * Fs)
else:
N = np.ceil((t_max - t0) * Fs)
N += fdl
def far_field_weights(self, phi):
'''
This method computes weight for a far field at infinity
phi: direction of beam
'''
u = unit_vec2D(phi)
proj = np.dot(u.T, self.R - self.center)[0]
# normalize the first arriving signal to ensure a causal filter
proj -= proj.max()
self.weights = np.exp(2j * np.pi *
self.frequencies[:, np.newaxis] * proj / constants.get('c')).T
def steering_vector_2D(self, frequency, phi, dist, attn=False):
phi = np.array([phi]).reshape(phi.size)
# Assume phi and dist are measured from the array's center
X = dist * np.array([np.cos(phi), np.sin(phi)]) + self.center
D = distance(self.R, X)
omega = 2 * np.pi * frequency
if attn:
# TO DO 1: This will mean slightly different absolute value for
# every entry, even within the same steering vector. Perhaps a
# better paradigm is far-field with phase carrier.
return 1. / (4 * np.pi) / D * np.exp(-1j * omega * D /
constants.get('c'))
else:
return np.exp(-1j * omega * D / constants.get('c'))
def response(self, phi_list, frequency):
i_freq = np.argmin(np.abs(self.frequencies - frequency))
if self.weights is None and self.filters is not None:
self.weights_from_filters()
elif self.weights is None and self.filters is None:
raise NameError('Beamforming weights or filters need to be computed'
' first.')
# For the moment assume that we are in 2D
bfresp = np.dot(H(self.weights[:,i_freq]), self.steering_vector_2D(
self.frequencies[i_freq], phi_list, constants.get('ffdist')))
return self.frequencies[i_freq], bfresp
Returns
-------
numpy array
An ndarray where the ith row contains the fractional delay filter
corresponding to the ith delay. The number of columns of the matrix
is proportional to the maximum delay.
'''
delays = np.array(delays)
# subtract the minimum delay, so that all delays are positive
delays -= delays.min()
# constants and lengths
N = delays.shape[0]
L = constants.get('frac_delay_length')
filter_length = L + int(np.ceil(delays).max())
# allocate a flat array for the filter bank that we'll reshape at the end
bank_flat = np.zeros(N * filter_length)
# separate delays in integer and fractional parts
di = np.floor(delays).astype(np.int)
df = delays - di
# broadcasting tricks to compute at once all the locations
# and sinc times that must be computed
T = np.arange(L)
indices = (T[None,:] + (di[:,None] + filter_length * np.arange(N)[:,None]))
sinc_times = (T - df[:,None] - (L - 1) / 2)
# we'll need to window also all the sincs at once
self,
walls,
fs=8000,
t0=0.,
max_order=1,
sigma2_awgn=None,
sources=None,
mics=None):
self.walls = walls
self.fs = fs
self.max_order = max_order
self.sigma2_awgn = sigma2_awgn
# Compute the filter delay if not provided
if t0 < (constants.get('frac_delay_length')-1)/float(fs)/2:
self.t0 = (constants.get('frac_delay_length')-1)/float(fs)/2
else:
self.t0 = t0
if sources is not None and isinstance(sources, list):
self.sources = sources
else:
self.sources = []
self.mic_array = mics
self.normals = np.array([wall.normal for wall in self.walls]).T
self.corners = np.array([wall.corners[:, 0] for wall in self.walls]).T
self.absorption = np.array([wall.absorption for wall in self.walls])
# in the beginning, nothing has been
def highpass(signal, Fs, fc=None, plot=False):
''' Filter out the really low frequencies, default is below 50Hz '''
if fc is None:
fc = constants.get('fc_hp')
# have some predefined parameters
rp = 5 # minimum ripple in dB in pass-band
rs = 60 # minimum attenuation in dB in stop-band
n = 4 # order of the filter
type = 'butter'
# normalized cut-off frequency
wc = 2. * fc / Fs
# design the filter
from scipy.signal import iirfilter, lfilter, freqz
b, a = iirfilter(n, Wn=wc, rp=rp, rs=rs, btype='highpass', ftype=type)
# plot frequency response of filter if requested
if (plot):
phi = np.array([phi]).reshape(phi.size)
# Assume phi and dist are measured from the array's center
X = dist * np.array([np.cos(phi), np.sin(phi)]) + self.center
D = distance(self.R, X)
omega = 2 * np.pi * frequency
if attn:
# TO DO 1: This will mean slightly different absolute value for
# every entry, even within the same steering vector. Perhaps a
# better paradigm is far-field with phase carrier.
return 1. / (4 * np.pi) / D * np.exp(-1j * omega * D /
constants.get('c'))
else:
return np.exp(-1j * omega * D / constants.get('c'))
def rake_one_forcing_filters(self, sources, interferers, R_n, epsilon=5e-3):
'''
Compute the time-domain filters of a beamformer with unit response
towards multiple sources.
'''
dist_mat = distance(self.R, sources.images)
s_time = dist_mat / constants.get('c')
s_dmp = 1./(4*np.pi*dist_mat)
dist_mat = distance(self.R, interferers.images)
i_time = dist_mat / constants.get('c')
i_dmp = 1./(4*np.pi*dist_mat)
# compute offset needed for decay of sinc by epsilon
offset = np.maximum(s_dmp.max(), i_dmp.max())/(np.pi*self.fs*epsilon)
t_min = np.minimum(s_time.min(), i_time.min())
t_max = np.maximum(s_time.max(), i_time.max())
# adjust timing
s_time -= t_min - offset
i_time -= t_min - offset
Lh = np.ceil((t_max - t_min + 2*offset)*float(self.fs))
if (ff):
# unit vectors pointing towards sources
p = (X - self.center)
p /= np.linalg.norm(p)
# The projected microphone distances on the unit vectors
D = -1 * np.dot(self.R.T, p)
# subtract minimum in each column
D -= np.min(D)
else:
D = distance(self.R, X)
phase = np.exp(-1j * omega * D / constants.get('c'))
if attn:
# TO DO 1: This will mean slightly different absolute value for
# every entry, even within the same steering vector. Perhaps a
# better paradigm is far-field with phase carrier.
return 1. / (4 * np.pi) / D * phase
else:
return phase