Skip to content

Commit 3da5e01

Browse files
committed
sound field extrapolation example for mono-frequency case
1 parent 859c043 commit 3da5e01

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
"""
2+
Modal analysis and extrapolation of a monochromatic sound field
3+
in the cricular harmonics domain using an open circular array
4+
"""
5+
import numpy as np
6+
import micarray
7+
from micarray.util import db
8+
import scipy.special as special
9+
import matplotlib.pyplot as plt
10+
import matplotlib
11+
matplotlib.rcParams['contour.negative_linestyle'] = 'solid'
12+
13+
# Constants
14+
c = 343 # speed of sound [m/s]
15+
16+
# 2-dimensional grid
17+
spacing = 0.01
18+
x = np.expand_dims(np.arange(-1, 1, spacing), axis=0)
19+
y = np.expand_dims(np.arange(-1, 1, spacing), axis=1)
20+
r = np.sqrt(x**2+y**2).astype(complex)
21+
phi = np.arctan2(y, x)
22+
23+
# Incident plane wave
24+
phi_pw = 0.5*np.pi # incoming direction
25+
f = 1500 # temporal frequency
26+
k = micarray.util.asarray_1d(2*np.pi*f/c) # corresponding wave number
27+
s0 = np.exp(1j*k*r*np.cos(phi-phi_pw)) # incident sound field
28+
29+
# Microphone array and modal analysis
30+
N = 15 # maximum order
31+
order = np.roll(np.arange(-N, N+1), -N)
32+
threshold = 1e5 # regulaization parameter
33+
R = 0.5 # radius
34+
Phi, weights = micarray.modal.angular.grid_equal_polar_angle(N) # array
35+
p = np.exp(1j*k*R*np.cos(Phi-phi_pw)) # captured signal
36+
bn = micarray.modal.radial.circ_radial_weights(N, k*R, setup='open')
37+
dn, _ = micarray.modal.radial.regularize(1/bn, threshold, 'softclip')
38+
pm = dn * np.fft.ifft(p)
39+
40+
# Sound field extrapolation
41+
basis = special.jn(order[:, np.newaxis, np.newaxis], k * r[np.newaxis, :, :]) \
42+
* np.exp(-1j*order[:, np.newaxis, np.newaxis] * phi[np.newaxis, :, :])
43+
s = np.tensordot(pm, basis, axes=[0, 0])
44+
45+
46+
# Plots
47+
plt.figure(figsize=(4, 4))
48+
plt.pcolormesh(x, y, np.real(s), cmap='coolwarm')
49+
plt.plot(R*np.cos(Phi), R*np.sin(Phi), 'k.')
50+
plt.axis('scaled')
51+
plt.axis([-1, 1, -1, 1])
52+
cb = plt.colorbar(fraction=0.046, pad=0.04)
53+
plt.clim(-1, 1)
54+
plt.xlabel('$x$ / m')
55+
plt.ylabel('$y$ / m')
56+
plt.title('Extrapolated Sound Field')
57+
plt.savefig('extrapolation_open_circ_mono.png')
58+
59+
plt.figure(figsize=(4, 4))
60+
plt.pcolormesh(x, y, db(s0-s), cmap='Blues', vmin=-60)
61+
plt.plot(R*np.cos(Phi), R*np.sin(Phi), 'k.')
62+
plt.axis('scaled')
63+
plt.axis([-1, 1, -1, 1])
64+
cb = plt.colorbar(fraction=0.046, pad=0.04)
65+
cb.set_label('dB')
66+
plt.clim(-60, 0)
67+
plt.xlabel('$x$ / m')
68+
plt.ylabel('$y$ / m')
69+
xx, yy = np.meshgrid(x, y)
70+
cs = plt.contour(xx, yy, db(s0-s), np.arange(-60, 20, 20), colors='orange')
71+
plt.clabel(cs, fontsize=9, inline=1, fmt='%1.0f')
72+
plt.title('Extrapolation Error')
73+
plt.savefig('extrapolation_error_open_circ_mono.png')

micarray/modal/radial.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ def regularize(dn, a0, method):
176176
else:
177177
raise ValueError('method must be either: none, ' +
178178
'discard, hardclip, softclip, Tikh or wng')
179-
dn[0, 1:] = dn[1, 1:]
179+
# dn[0, 1:] = dn[1, 1:]
180180
dn = dn * hn
181181
if not np.isfinite(dn).all():
182182
raise UserWarning("Filter not finite")

0 commit comments

Comments
 (0)