|
6 | 6 | import numpy as np
|
7 | 7 | import matplotlib.pyplot as plt
|
8 | 8 | import micarray
|
| 9 | +from micarray.util import db |
9 | 10 |
|
10 |
| -N = 90 # order of modal beamformer/microphone array |
| 11 | +Nsf = 50 # order of the incident sound field |
| 12 | +N = 30 # order of modal beamformer/microphone array |
11 | 13 | pw_angle = 1.23 * np.pi # incidence angle of plane wave
|
12 |
| -pol_pwd = np.linspace(0, 2*np.pi, 91, endpoint=False) # angles for plane wave decomposition |
| 14 | +pol_pwd = np.linspace(0, 2*np.pi, 180, endpoint=False) # angles for plane wave decomposition |
13 | 15 | k = np.linspace(0.1, 20, 100) # wavenumber vector
|
14 | 16 | r = 1 # radius of array
|
15 | 17 |
|
16 | 18 | # get uniform grid (microphone positions) of order N
|
17 | 19 | pol, weights = micarray.modal.angular.grid_equal_polar_angle(N)
|
18 |
| -# get circular harmonics matrix for sensors |
19 |
| -Psi_p = micarray.modal.angular.cht_matrix(N, pol, weights) |
20 |
| -# get circular harmonics matrix for a source ensemble of azimuthal plane wave |
21 |
| -Psi_q = micarray.modal.angular.cht_matrix(N, pol_pwd) |
22 |
| -# get radial filters |
| 20 | + |
| 21 | +# pressure on the surface of a rigid cylinder for an incident plane wave |
| 22 | +Bn = micarray.modal.radial.circular_pw(Nsf, k, r, setup='open') |
| 23 | +D = micarray.modal.radial.circ_diagonal_mode_mat(Bn) |
| 24 | +Psi_p = micarray.modal.angular.cht_matrix(Nsf, pol) |
| 25 | +Psi_pw = micarray.modal.angular.cht_matrix(Nsf, pw_angle) |
| 26 | +p = np.matmul(np.matmul(np.conj(Psi_p.T), D), Psi_pw) |
| 27 | +p = np.squeeze(p) |
| 28 | + |
| 29 | +# incident plane wave exhibiting infinite spatial bandwidth |
| 30 | +# p = np.exp(1j * k[:, np.newaxis]*r * np.cos(pol - pw_angle)) |
| 31 | + |
| 32 | +# plane wave decomposition using modal beamforming |
23 | 33 | Bn = micarray.modal.radial.circular_pw(N, k, r, setup='open')
|
24 |
| -Dn, _ = micarray.modal.radial.regularize(1/Bn, 100, 'softclip') |
| 34 | +Dn, _ = micarray.modal.radial.regularize(1/Bn, 3000, 'softclip') |
25 | 35 | D = micarray.modal.radial.circ_diagonal_mode_mat(Dn)
|
26 |
| - |
27 |
| -# compute microphone signals for an incident broad-band plane wave |
28 |
| -p = np.exp(1j * k[:, np.newaxis]*r * np.cos(pol - pw_angle)) |
29 |
| -# compute plane wave decomposition |
| 36 | +Psi_p = micarray.modal.angular.cht_matrix(N, pol, weights) |
| 37 | +Psi_q = micarray.modal.angular.cht_matrix(N, pol_pwd) |
30 | 38 | A_pwd = np.matmul(np.matmul(np.conj(Psi_q.T), D), Psi_p)
|
31 | 39 | q_pwd = np.squeeze(np.matmul(A_pwd, np.expand_dims(p, 2)))
|
32 | 40 | q_pwd_t = np.fft.fftshift(np.fft.irfft(q_pwd, axis=0), axes=0)
|
33 | 41 |
|
34 | 42 | # visualize plane wave decomposition (aka beampattern)
|
35 | 43 | plt.figure()
|
36 |
| -plt.pcolormesh(k, pol_pwd/np.pi, micarray.util.db(q_pwd.T), vmin=-40) |
| 44 | +plt.pcolormesh(k, pol_pwd/np.pi, db(q_pwd.T), vmin=-40) |
37 | 45 | plt.colorbar()
|
38 | 46 | plt.xlabel(r'$kr$')
|
39 | 47 | plt.ylabel(r'$\phi / \pi$')
|
40 | 48 | plt.title('Plane wave docomposition by modal beamformer (frequency domain)')
|
41 |
| -plt.savefig('modal_open_beamformer_pwd_fd.png') |
| 49 | +plt.savefig('modal_circ_open_beamformer_pwd_fd.png') |
42 | 50 |
|
43 | 51 | plt.figure()
|
44 |
| -plt.pcolormesh(range(2*len(k)-2), pol_pwd/np.pi, micarray.util.db(q_pwd_t.T), vmin=-40) |
| 52 | +plt.pcolormesh(range(2*len(k)-2), pol_pwd/np.pi, db(q_pwd_t.T), vmin=-40) |
45 | 53 | plt.colorbar()
|
46 | 54 | plt.ylabel(r'$\phi / \pi$')
|
47 | 55 | plt.title('Plane wave docomposition by modal beamformer (time domain)')
|
48 |
| -plt.savefig('modal_open_beamformer_pwd_td.png') |
| 56 | +plt.savefig('modal_circ_open_beamformer_pwd_td.png') |
0 commit comments