Skip to content

Commit

Permalink
importance: filter HOA channels/blocks by importance
Browse files Browse the repository at this point in the history
  • Loading branch information
tomjnixon committed Feb 26, 2024
1 parent ca3513f commit 090c4fb
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 0 deletions.
40 changes: 40 additions & 0 deletions ear/core/importance.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def filter_by_importance(rendering_items,
Yields: RenderingItem
"""
f = mute_audioBlockFormat_by_importance(rendering_items, threshold)
f = mute_hoa_channels_by_importance(f, threshold)
f = filter_audioObject_by_importance(f, threshold)
f = filter_audioPackFormat_by_importance(f, threshold)
return f
Expand Down Expand Up @@ -115,3 +116,42 @@ def mute_unimportant_block(type_metadata):
item.metadata_source, mute_unimportant_block
),
)


def mute_hoa_channels_by_importance(rendering_items, threshold):
"""Adapt HOA rendering items to emulate block format importance handling
This installs a `MetadataSourceMap` which sets the gain to zero if the
block importance is less than the given threshold. This operates
independently for each channel, so can reduce the HOA order (or make a mess
if the importances are not structured so that higher orders are discarded
first).
Parameters:
rendering_items (iterable of RenderingItems): RenderingItems to adapt
threshold (int): importance threshold
Yields: RenderingItem
"""
def mute_unimportant_channels(type_metadata):
if min(type_metadata.importances) < threshold:
new_gains = [
0.0 if importance < threshold else gain
for (gain, importance) in zip(
type_metadata.gains, type_metadata.importances
)
]
return evolve(type_metadata, gains=new_gains)
else:
return type_metadata

for item in rendering_items:
if isinstance(item, HOARenderingItem):
yield evolve(
item,
metadata_source=MetadataSourceMap(
item.metadata_source, mute_unimportant_channels
),
)
else:
yield item
48 changes: 48 additions & 0 deletions ear/core/test/test_importance.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
DirectSpeakersRenderingItem,
DirectSpeakersTypeMetadata,
HOARenderingItem,
HOATypeMetadata,
DirectTrackSpec,
ImportanceData,
MetadataSourceIter,
Expand All @@ -20,6 +21,7 @@
filter_audioObject_by_importance,
filter_audioPackFormat_by_importance,
)
from attrs import evolve
from fractions import Fraction
import pytest

Expand Down Expand Up @@ -185,3 +187,49 @@ def test_importance_filter_blocks_single_channel(make_type_metadata, make_render
rendering_items_out = filter_by_importance(rendering_items, 6)
[rendering_item_out] = rendering_items_out
assert get_blocks(rendering_item_out.metadata_source) == expected


@pytest.mark.parametrize(
"gains",
[
[1.0, 1.0, 1.0, 1.0],
[0.5, 0.25, 0.25, 0.25],
],
)
def test_importance_filter_hoa(gains):
type_metadatas = [
HOATypeMetadata( # all but first channel muted
orders=[0, 1, 1, 1],
degrees=[0, -1, 0, 1],
importances=[6, 5, 5, 5],
normalization="SN3D",
gains=gains,
),
HOATypeMetadata( # not modified
orders=[0, 1, 1, 1],
degrees=[0, -1, 0, 1],
importances=[6, 6, 6, 6],
normalization="SN3D",
gains=gains,
),
]
expected = [
evolve(
type_metadatas[0],
gains=[gains[0], 0.0, 0.0, 0.0],
),
evolve(
type_metadatas[1],
gains=gains,
),
]
rendering_items = [
HOARenderingItem(
track_specs=[DirectTrackSpec(i) for i in range(4)],
metadata_source=MetadataSourceIter(type_metadatas),
),
]

rendering_items_out = filter_by_importance(rendering_items, 6)
[rendering_item_out] = rendering_items_out
assert get_blocks(rendering_item_out.metadata_source) == expected

0 comments on commit 090c4fb

Please sign in to comment.