sfs.td.nfchoa¶
Compute NFC-HOA driving functions.
import matplotlib.pyplot as plt
import numpy as np
import sfs
from scipy.signal import unit_impulse
# Plane wave
npw = sfs.util.direction_vector(np.radians(-45))
# Point source
xs = -1.5, 1.5, 0
rs = np.linalg.norm(xs) # distance from origin
ts = rs / sfs.default.c # time-of-arrival at origin
# Impulsive excitation
fs = 44100
signal = unit_impulse(512), fs
# Circular loudspeaker array
N = 32 # number of loudspeakers
R = 1.5 # radius
array = sfs.array.circular(N, R)
grid = sfs.util.xyz_grid([-2, 2], [-2, 2], 0, spacing=0.02)
def plot(d, selection, secondary_source, t=0):
p = sfs.td.synthesize(d, selection, array, secondary_source, grid=grid,
observation_time=t)
sfs.plot2d.level(p, grid)
sfs.plot2d.loudspeakers(array.x, array.n, selection * array.a, size=0.15)
Functions
driving_signals_25d (delay, weight, sos, …) |
Get 2.5-dimensional NFC-HOA driving signals. |
driving_signals_3d (delay, weight, sos, …) |
Get 3-dimensional NFC-HOA driving signals. |
matchedz_zpk (s_zeros, s_poles, s_gain, fs) |
Matched-z transform of poles and zeros. |
plane_25d (x0, r0, npw, fs[, max_order, c, s2z]) |
Virtual plane wave by 2.5-dimensional NFC-HOA. |
plane_3d (x0, r0, npw, fs[, max_order, c, s2z]) |
Virtual plane wave by 3-dimensional NFC-HOA. |
point_25d (x0, r0, xs, fs[, max_order, c, s2z]) |
Virtual Point source by 2.5-dimensional NFC-HOA. |
point_3d (x0, r0, xs, fs[, max_order, c, s2z]) |
Virtual point source by 3-dimensional NFC-HOA. |
-
sfs.td.nfchoa.
matchedz_zpk
(s_zeros, s_poles, s_gain, fs)[source]¶ Matched-z transform of poles and zeros.
Parameters: - s_zeros (array_like) – Zeros in the Laplace domain.
- s_poles (array_like) – Poles in the Laplace domain.
- s_gain (float) – System gain in the Laplace domain.
- fs (int) – Sampling frequency in Hertz.
Returns: - z_zeros (numpy.ndarray) – Zeros in the z-domain.
- z_poles (numpy.ndarray) – Poles in the z-domain.
- z_gain (float) – System gain in the z-domain.
See also
-
sfs.td.nfchoa.
plane_25d
(x0, r0, npw, fs, max_order=None, c=None, s2z=<function matchedz_zpk>)[source]¶ Virtual plane wave by 2.5-dimensional NFC-HOA.
\[D(\phi_0, s) = 2\e{\frac{s}{c}r_0} \sum_{m=-M}^{M} (-1)^m \Big(\frac{s}{s-\frac{c}{r_0}\sigma_0}\Big)^\mu \prod_{l=1}^{\nu} \frac{s^2}{(s-\frac{c}{r_0}\sigma_l)^2+(\frac{c}{r_0}\omega_l)^2} \e{\i m(\phi_0 - \phi_\text{pw})}\]The driving function is represented in the Laplace domain, from which the recursive filters are designed. \(\sigma_l + \i\omega_l\) denotes the complex roots of the reverse Bessel polynomial. The number of second-order sections is \(\nu = \big\lfloor\tfrac{|m|}{2}\big\rfloor\), whereas the number of first-order section \(\mu\) is either 0 or 1 for even and odd \(|m|\), respectively.
Parameters: - x0 ((N, 3) array_like) – Sequence of secondary source positions.
- r0 (float) – Radius of the circular secondary source distribution.
- npw ((3,) array_like) – Unit vector (propagation direction) of plane wave.
- fs (int) – Sampling frequency in Hertz.
- max_order (int, optional) – Ambisonics order.
- c (float, optional) – Speed of sound in m/s.
- s2z (callable, optional) – Function transforming s-domain poles and zeros into z-domain,
e.g.
matchedz_zpk()
,scipy.signal.bilinear_zpk()
.
Returns: - delay (float) – Overall delay in seconds.
- weight (float) – Overall weight.
- sos (list of numpy.ndarray) – Second-order section filters
scipy.signal.sosfilt()
. - phaseshift ((N,) numpy.ndarray) – Phase shift in radians.
- selection ((N,) numpy.ndarray) – Boolean array containing only
True
indicating that all secondary source are “active” for NFC-HOA. - secondary_source_function (callable) – A function that can be used to create the sound field of a
single secondary source. See
sfs.td.synthesize()
.
Examples
delay, weight, sos, phaseshift, selection, secondary_source = \ sfs.td.nfchoa.plane_25d(array.x, R, npw, fs) d = sfs.td.nfchoa.driving_signals_25d( delay, weight, sos, phaseshift, signal) plot(d, selection, secondary_source)
-
sfs.td.nfchoa.
point_25d
(x0, r0, xs, fs, max_order=None, c=None, s2z=<function matchedz_zpk>)[source]¶ Virtual Point source by 2.5-dimensional NFC-HOA.
\[D(\phi_0, s) = \frac{1}{2\pi r_\text{s}} \e{\frac{s}{c}(r_0-r_\text{s})} \sum_{m=-M}^{M} \Big(\frac{s-\frac{c}{r_\text{s}}\sigma_0}{s-\frac{c}{r_0}\sigma_0}\Big)^\mu \prod_{l=1}^{\nu} \frac{(s-\frac{c}{r_\text{s}}\sigma_l)^2-(\frac{c}{r_\text{s}}\omega_l)^2} {(s-\frac{c}{r_0}\sigma_l)^2+(\frac{c}{r_0}\omega_l)^2} \e{\i m(\phi_0 - \phi_\text{s})}\]The driving function is represented in the Laplace domain, from which the recursive filters are designed. \(\sigma_l + \i\omega_l\) denotes the complex roots of the reverse Bessel polynomial. The number of second-order sections is \(\nu = \big\lfloor\tfrac{|m|}{2}\big\rfloor\), whereas the number of first-order section \(\mu\) is either 0 or 1 for even and odd \(|m|\), respectively.
Parameters: - x0 ((N, 3) array_like) – Sequence of secondary source positions.
- r0 (float) – Radius of the circular secondary source distribution.
- xs ((3,) array_like) – Virtual source position.
- fs (int) – Sampling frequency in Hertz.
- max_order (int, optional) – Ambisonics order.
- c (float, optional) – Speed of sound in m/s.
- s2z (callable, optional) – Function transforming s-domain poles and zeros into z-domain,
e.g.
matchedz_zpk()
,scipy.signal.bilinear_zpk()
.
Returns: - delay (float) – Overall delay in seconds.
- weight (float) – Overall weight.
- sos (list of numpy.ndarray) – Second-order section filters
scipy.signal.sosfilt()
. - phaseshift ((N,) numpy.ndarray) – Phase shift in radians.
- selection ((N,) numpy.ndarray) – Boolean array containing only
True
indicating that all secondary source are “active” for NFC-HOA. - secondary_source_function (callable) – A function that can be used to create the sound field of a
single secondary source. See
sfs.td.synthesize()
.
Examples
delay, weight, sos, phaseshift, selection, secondary_source = \ sfs.td.nfchoa.point_25d(array.x, R, xs, fs) d = sfs.td.nfchoa.driving_signals_25d( delay, weight, sos, phaseshift, signal) plot(d, selection, secondary_source, t=ts)
-
sfs.td.nfchoa.
plane_3d
(x0, r0, npw, fs, max_order=None, c=None, s2z=<function matchedz_zpk>)[source]¶ Virtual plane wave by 3-dimensional NFC-HOA.
\[D(\phi_0, s) = \frac{\e{\frac{s}{c}r_0}}{r_0} \sum_{n=0}^{N} (-1)^n (2n+1) P_{n}(\cos\Theta) \Big(\frac{s}{s-\frac{c}{r_0}\sigma_0}\Big)^\mu \prod_{l=1}^{\nu} \frac{s^2}{(s-\frac{c}{r_0}\sigma_l)^2+(\frac{c}{r_0}\omega_l)^2}\]The driving function is represented in the Laplace domain, from which the recursive filters are designed. \(\sigma_l + \i\omega_l\) denotes the complex roots of the reverse Bessel polynomial. The number of second-order sections is \(\nu = \big\lfloor\tfrac{|m|}{2}\big\rfloor\), whereas the number of first-order section \(\mu\) is either 0 or 1 for even and odd \(|m|\), respectively. \(P_{n}(\cdot)\) denotes the Legendre polynomial of degree \(n\), and \(\Theta\) the angle between \((\theta, \phi)\) and \((\theta_\text{pw}, \phi_\text{pw})\).
Parameters: - x0 ((N, 3) array_like) – Sequence of secondary source positions.
- r0 (float) – Radius of the spherical secondary source distribution.
- npw ((3,) array_like) – Unit vector (propagation direction) of plane wave.
- fs (int) – Sampling frequency in Hertz.
- max_order (int, optional) – Ambisonics order.
- c (float, optional) – Speed of sound in m/s.
- s2z (callable, optional) – Function transforming s-domain poles and zeros into z-domain,
e.g.
matchedz_zpk()
,scipy.signal.bilinear_zpk()
.
Returns: - delay (float) – Overall delay in seconds.
- weight (float) – Overall weight.
- sos (list of numpy.ndarray) – Second-order section filters
scipy.signal.sosfilt()
. - phaseshift ((N,) numpy.ndarray) – Phase shift in radians.
- selection ((N,) numpy.ndarray) – Boolean array containing only
True
indicating that all secondary source are “active” for NFC-HOA. - secondary_source_function (callable) – A function that can be used to create the sound field of a
single secondary source. See
sfs.td.synthesize()
.
-
sfs.td.nfchoa.
point_3d
(x0, r0, xs, fs, max_order=None, c=None, s2z=<function matchedz_zpk>)[source]¶ Virtual point source by 3-dimensional NFC-HOA.
\[D(\phi_0, s) = \frac{\e{\frac{s}{c}(r_0-r_\text{s})}}{4 \pi r_0 r_\text{s}} \sum_{n=0}^{N} (2n+1) P_{n}(\cos\Theta) \Big(\frac{s-\frac{c}{r_\text{s}}\sigma_0}{s-\frac{c}{r_0}\sigma_0}\Big)^\mu \prod_{l=1}^{\nu} \frac{(s-\frac{c}{r_\text{s}}\sigma_l)^2-(\frac{c}{r_\text{s}}\omega_l)^2} {(s-\frac{c}{r_0}\sigma_l)^2+(\frac{c}{r_0}\omega_l)^2}\]The driving function is represented in the Laplace domain, from which the recursive filters are designed. \(\sigma_l + \i\omega_l\) denotes the complex roots of the reverse Bessel polynomial. The number of second-order sections is \(\nu = \big\lfloor\tfrac{|m|}{2}\big\rfloor\), whereas the number of first-order section \(\mu\) is either 0 or 1 for even and odd \(|m|\), respectively. \(P_{n}(\cdot)\) denotes the Legendre polynomial of degree \(n\), and \(\Theta\) the angle between \((\theta, \phi)\) and \((\theta_\text{s}, \phi_\text{s})\).
Parameters: - x0 ((N, 3) array_like) – Sequence of secondary source positions.
- r0 (float) – Radius of the spherial secondary source distribution.
- xs ((3,) array_like) – Virtual source position.
- fs (int) – Sampling frequency in Hertz.
- max_order (int, optional) – Ambisonics order.
- c (float, optional) – Speed of sound in m/s.
- s2z (callable, optional) – Function transforming s-domain poles and zeros into z-domain,
e.g.
matchedz_zpk()
,scipy.signal.bilinear_zpk()
.
Returns: - delay (float) – Overall delay in seconds.
- weight (float) – Overall weight.
- sos (list of numpy.ndarray) – Second-order section filters
scipy.signal.sosfilt()
. - phaseshift ((N,) numpy.ndarray) – Phase shift in radians.
- selection ((N,) numpy.ndarray) – Boolean array containing only
True
indicating that all secondary source are “active” for NFC-HOA. - secondary_source_function (callable) – A function that can be used to create the sound field of a
single secondary source. See
sfs.td.synthesize()
.
-
sfs.td.nfchoa.
driving_signals_25d
(delay, weight, sos, phaseshift, signal)[source]¶ Get 2.5-dimensional NFC-HOA driving signals.
Parameters: - delay (float) – Overall delay in seconds.
- weight (float) – Overall weight.
- sos (list of array_like) – Second-order section filters
scipy.signal.sosfilt()
. - phaseshift ((N,) array_like) – Phase shift in radians.
- signal ((L,) array_like + float) – Excitation signal consisting of (mono) audio data and a sampling
rate (in Hertz). A
DelayedSignal
object can also be used.
Returns: DelayedSignal
– A tuple containing the delayed signals (in anumpy.ndarray
with shape(L, N)
), followed by the sampling rate (in Hertz) and a (possibly negative) time offset (in seconds).
-
sfs.td.nfchoa.
driving_signals_3d
(delay, weight, sos, phaseshift, signal)[source]¶ Get 3-dimensional NFC-HOA driving signals.
Parameters: - delay (float) – Overall delay in seconds.
- weight (float) – Overall weight.
- sos (list of array_like) – Second-order section filters
scipy.signal.sosfilt()
. - phaseshift ((N,) array_like) – Phase shift in radians.
- signal ((L,) array_like + float) – Excitation signal consisting of (mono) audio data and a sampling
rate (in Hertz). A
DelayedSignal
object can also be used.
Returns: DelayedSignal
– A tuple containing the delayed signals (in anumpy.ndarray
with shape(L, N)
), followed by the sampling rate (in Hertz) and a (possibly negative) time offset (in seconds).