%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
def ab_delays(beta, d, c=343):
"""Calculate delays for AB stereophony.
beta: angle of incidence in degree, can be a scalar or a sequence
d: distance between microphones in metres
c: speed of sound in m/s
"""
return d / c * np.sin(np.deg2rad(beta))
def plot_ab_delays(max_beta, d, c=343, **kwargs):
"""Plot delays for AB stereophony.
See ab_delays().
"""
betas = np.linspace(-max_beta, max_beta, 100)
delays = ab_delays(betas, d, c);
plt.plot(betas, delays * 1000, **kwargs)
plt.title("d = {} m".format(d))
plt.xlabel("beta (degree)")
plt.ylabel("delay (ms)")
plot_ab_delays(90, 0.4, label="40 cm")
plot_ab_delays(90, 0.6, label="60 cm")
plot_ab_delays(90, 0.8, label="80 cm")
plt.title("Delays for different mic distances")
plt.legend(loc='lower right');
TODO: how to get a smaller recording angle (maximum useful delay: 1.2 ms, see Weinzierl, "Handbuch der Audiotechnik" (in German), p. 573)
def xy_weights(beta, epsilon, a, b):
"""Calculate weighting factors for XY stereophony.
beta: angle of incidence in degree, can be a scalar or a sequence
epsilon: opening angle of microphones in degree
"""
Ax = a + b * np.cos(np.deg2rad(epsilon + beta))
Ay = a + b * np.cos(np.deg2rad(epsilon - beta))
return Ax, Ay
import tools
def plot_xy_weights(epsilon, a, b, pattern):
"""Create 3 plots showing the XY factors."""
betas = np.arange(-180, 181)
weights = np.column_stack(xy_weights(betas, epsilon, a, b))
pos_weights = np.clip(weights, 0, None)
neg_weights = -np.clip(weights, None, 0)
title = "{}, ϵ = {} degree".format(pattern, epsilon)
plt.figure()
plt.polar(np.radians(betas), pos_weights)
plt.gca().set_prop_cycle(None)
plt.polar(np.radians(betas), neg_weights, linewidth=2, linestyle='dashed')
plt.gca().set_theta_zero_location('N')
plt.title(title)
plt.figure()
plt.plot(betas, tools.db(weights))
plt.title(title)
plt.xlim(-180, 180)
plt.ylim(-45, 3)
plt.xlabel("beta / degree")
plt.ylabel("$L_X$ and $L_Y$ / dB")
plt.figure()
differences = np.diff(tools.db(weights), axis=1)
plt.plot(betas, differences)
plt.title(title)
plt.xlim(-180, 180)
plt.ylim(-50, 50)
plt.xlabel("beta / degree")
plt.ylabel("level difference / dB")
Maximum meaningful level difference: between 15 and 18 dB (DIN EN 60268-4, section 12.5.4.1)
plot_xy_weights(45, 0.5, 0.5, "cardioid")
plot_xy_weights(45, 0.366, 0.634, "super-cardioid")
plot_xy_weights(45, 0.25, 0.75, "hyper-cardioid")
plot_xy_weights(45, 0, 1, "figure-of-eight")