Skip to content

Commit c2b3a55

Browse files
committed
test objectbased hoa
1 parent 2389e86 commit c2b3a55

File tree

1 file changed

+170
-0
lines changed

1 file changed

+170
-0
lines changed
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
import numpy as np
2+
import pytest
3+
4+
from ....fileio.adm.elements import (
5+
AudioBlockFormatObjects,
6+
ObjectDivergence,
7+
ObjectPolarPosition,
8+
)
9+
from ...hoa import sph_harm
10+
from ...hoa_adapter import HOAFormat
11+
from ...metadata_input import ExtraData, ObjectTypeMetadata
12+
from ..gain_calc_hoa import GainCalcHOA
13+
14+
15+
@pytest.fixture(scope="module")
16+
def fmt():
17+
return HOAFormat(max_order=1, normalization="SN3D", channel_order="ACN")
18+
19+
20+
@pytest.fixture(scope="module")
21+
def gain_calc(fmt):
22+
return GainCalcHOA(fmt)
23+
24+
25+
@pytest.fixture(scope="module")
26+
def pan(fmt):
27+
def f(az, el):
28+
n, m = fmt.orders_degrees
29+
return sph_harm(n, m, np.radians(az), np.radians(el), fmt.norm_fn)
30+
31+
return f
32+
33+
34+
@pytest.fixture(scope="module")
35+
def run_test(fmt, gain_calc, pan):
36+
def f(
37+
block_format,
38+
extra_data=ExtraData(),
39+
direct_gains=None,
40+
diffuse_gains=None,
41+
direct_position=None,
42+
diffuse_position=None,
43+
atol=1e-10,
44+
rtol=1e-6,
45+
):
46+
block_format = AudioBlockFormatObjects(**block_format)
47+
48+
actual = gain_calc.render(
49+
ObjectTypeMetadata(block_format=block_format, extra_data=extra_data)
50+
)
51+
52+
if direct_position is not None:
53+
direct_gains = pan(*direct_position)
54+
if diffuse_position is not None:
55+
diffuse_gains = pan(*diffuse_position)
56+
57+
if direct_gains is None:
58+
direct_gains = np.zeros(fmt.num_channels)
59+
if diffuse_gains is None:
60+
diffuse_gains = np.zeros(fmt.num_channels)
61+
62+
np.testing.assert_allclose(actual.direct, direct_gains, atol=atol, rtol=rtol)
63+
np.testing.assert_allclose(actual.diffuse, diffuse_gains, atol=atol, rtol=rtol)
64+
65+
return f
66+
67+
68+
@pytest.mark.parametrize(
69+
"az,el",
70+
[
71+
(0.0, 0.0),
72+
(90.0, 0.0),
73+
(-90.0, 0.0),
74+
(180.0, 0.0),
75+
(0.0, 90.0),
76+
(0.0, -90.0),
77+
],
78+
)
79+
def test_direct_pos(run_test, az, el):
80+
run_test(
81+
dict(position=ObjectPolarPosition(azimuth=az, elevation=el)),
82+
direct_position=(az, el),
83+
)
84+
85+
86+
def test_gain(run_test, pan):
87+
run_test(
88+
dict(position=ObjectPolarPosition(azimuth=0.0, elevation=0.0), gain=0.5),
89+
direct_gains=pan(0.0, 0.0) * 0.5,
90+
)
91+
92+
93+
def test_full_diffuse(run_test, pan):
94+
run_test(
95+
dict(position=ObjectPolarPosition(azimuth=0.0, elevation=0.0), diffuse=1.0),
96+
diffuse_position=(0.0, 0.0),
97+
)
98+
99+
100+
def test_half_diffuse(run_test, pan):
101+
run_test(
102+
dict(position=ObjectPolarPosition(azimuth=0.0, elevation=0.0), diffuse=0.5),
103+
direct_gains=pan(0.0, 0.0) * np.sqrt(0.5),
104+
diffuse_gains=pan(0.0, 0.0) * np.sqrt(0.5),
105+
)
106+
107+
108+
def test_spread_small(run_test, pan):
109+
run_test(
110+
dict(
111+
position=ObjectPolarPosition(azimuth=0.0, elevation=0.0),
112+
width=10.0,
113+
height=10.0,
114+
),
115+
direct_gains=[1, 0, 0, 0.99],
116+
atol=1e-2,
117+
)
118+
119+
run_test(
120+
dict(
121+
position=ObjectPolarPosition(azimuth=180.0, elevation=0.0),
122+
width=10.0,
123+
height=10.0,
124+
),
125+
direct_gains=[1, 0, 0, -0.99],
126+
atol=1e-2,
127+
)
128+
129+
run_test(
130+
dict(
131+
position=ObjectPolarPosition(azimuth=90.0, elevation=0.0),
132+
width=10.0,
133+
height=10.0,
134+
),
135+
direct_gains=[1, 0.99, 0, 0],
136+
atol=1e-2,
137+
)
138+
139+
140+
def test_spread_large(run_test, pan):
141+
run_test(
142+
dict(
143+
position=ObjectPolarPosition(azimuth=0.0, elevation=0.0),
144+
width=360.0,
145+
height=360.0,
146+
),
147+
direct_gains=[1, 0, 0, 0],
148+
atol=1e-2,
149+
)
150+
151+
# for FOA, full width is equivalent to full extent
152+
run_test(
153+
dict(
154+
position=ObjectPolarPosition(azimuth=0.0, elevation=0.0),
155+
width=360.0,
156+
height=0.0,
157+
),
158+
direct_gains=[1, 0, 0, 0],
159+
atol=1e-2,
160+
)
161+
162+
163+
def test_diverge(run_test, pan):
164+
run_test(
165+
dict(
166+
position=ObjectPolarPosition(azimuth=0.0, elevation=0.0),
167+
objectDivergence=ObjectDivergence(0.5, azimuthRange=360 / 3),
168+
),
169+
direct_gains=[1, 0, 0, 0],
170+
)

0 commit comments

Comments
 (0)