-
Notifications
You must be signed in to change notification settings - Fork 696
Add filter_waveform #2928
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Add filter_waveform #2928
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,6 +47,7 @@ DSP | |
:nosignatures: | ||
|
||
adsr_envelope | ||
filter_waveform | ||
extend_pitch | ||
oscillator_bank | ||
sinc_impulse_response | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -486,6 +486,110 @@ def test_freq_ir_reference(self, shape): | |
|
||
self.assertEqual(hyp, ref) | ||
|
||
@parameterized.expand( | ||
[ | ||
# fmt: off | ||
# INPUT: single-dim waveform and 2D filter | ||
# The number of frames is divisible with the number of filters (15 % 3 == 0), | ||
# thus waveform must be split into chunks without padding | ||
((15, ), (3, 3)), # filter size (3) is shorter than chunk size (15 // 3 == 5) | ||
((15, ), (3, 5)), # filter size (5) matches than chunk size | ||
((15, ), (3, 7)), # filter size (7) is longer than chunk size | ||
# INPUT: single-dim waveform and 2D filter | ||
# The number of frames is NOT divisible with the number of filters (15 % 4 != 0), | ||
# thus waveform must be padded before padding | ||
((15, ), (4, 3)), # filter size (3) is shorter than chunk size (16 // 4 == 4) | ||
((15, ), (4, 4)), # filter size (4) is shorter than chunk size | ||
((15, ), (4, 5)), # filter size (5) is longer than chunk size | ||
# INPUT: multi-dim waveform and 2D filter | ||
# The number of frames is divisible with the number of filters (15 % 3 == 0), | ||
# thus waveform must be split into chunks without padding | ||
((7, 2, 15), (3, 3)), | ||
((7, 2, 15), (3, 5)), | ||
((7, 2, 15), (3, 7)), | ||
# INPUT: single-dim waveform and 2D filter | ||
# The number of frames is NOT divisible with the number of filters (15 % 4 != 0), | ||
# thus waveform must be padded before padding | ||
((7, 2, 15), (4, 3)), | ||
((7, 2, 15), (4, 4)), | ||
((7, 2, 15), (4, 5)), | ||
# INPUT: multi-dim waveform and multi-dim filter | ||
# The number of frames is divisible with the number of filters (15 % 3 == 0), | ||
# thus waveform must be split into chunks without padding | ||
((7, 2, 15), (7, 2, 3, 3)), | ||
((7, 2, 15), (7, 2, 3, 5)), | ||
((7, 2, 15), (7, 2, 3, 7)), | ||
# INPUT: multi-dim waveform and multi-dim filter | ||
# The number of frames is NOT divisible with the number of filters (15 % 4 != 0), | ||
# thus waveform must be padded before padding | ||
((7, 2, 15), (7, 2, 4, 3)), | ||
((7, 2, 15), (7, 2, 4, 4)), | ||
((7, 2, 15), (7, 2, 4, 5)), | ||
# INPUT: multi-dim waveform and (broadcast) multi-dim filter | ||
# The number of frames is divisible with the number of filters (15 % 3 == 0), | ||
# thus waveform must be split into chunks without padding | ||
((7, 2, 15), (1, 1, 3, 3)), | ||
((7, 2, 15), (1, 1, 3, 5)), | ||
((7, 2, 15), (1, 1, 3, 7)), | ||
# INPUT: multi-dim waveform and (broadcast) multi-dim filter | ||
# The number of frames is NOT divisible with the number of filters (15 % 4 != 0), | ||
# thus waveform must be padded before padding | ||
((7, 2, 15), (1, 1, 4, 3)), | ||
((7, 2, 15), (1, 1, 4, 4)), | ||
((7, 2, 15), (1, 1, 4, 5)), | ||
# fmt: on | ||
] | ||
) | ||
def test_filter_waveform_shape(self, waveform_shape, filter_shape): | ||
"""filter_waveform returns the waveform with the same number of samples""" | ||
waveform = torch.randn(waveform_shape, dtype=self.dtype, device=self.device) | ||
filters = torch.randn(filter_shape, dtype=self.dtype, device=self.device) | ||
|
||
filtered = F.filter_waveform(waveform, filters) | ||
|
||
assert filtered.shape == waveform.shape | ||
|
||
@nested_params([1, 3, 5], [3, 5, 7, 4, 6, 8]) | ||
def test_filter_waveform_delta(self, num_filters, kernel_size): | ||
"""Applying delta kernel preserves the origianl waveform""" | ||
waveform = torch.arange(-10, 10, dtype=self.dtype, device=self.device) | ||
kernel = torch.zeros((num_filters, kernel_size), dtype=self.dtype, device=self.device) | ||
kernel[:, kernel_size // 2] = 1 | ||
|
||
result = F.filter_waveform(waveform, kernel) | ||
self.assertEqual(waveform, result) | ||
|
||
def test_filter_waveform_same(self, kernel_size=5): | ||
"""Applying the same filter returns the original waveform""" | ||
waveform = torch.arange(-10, 10, dtype=self.dtype, device=self.device) | ||
kernel = torch.randn((1, kernel_size), dtype=self.dtype, device=self.device) | ||
kernels = torch.cat([kernel] * 3) | ||
|
||
out1 = F.filter_waveform(waveform, kernel) | ||
out2 = F.filter_waveform(waveform, kernels) | ||
self.assertEqual(out1, out2) | ||
|
||
def test_filter_waveform_diff(self): | ||
"""Filters are applied from the first to the last""" | ||
kernel_size = 3 | ||
waveform = torch.arange(-10, 10, dtype=self.dtype, device=self.device) | ||
kernels = torch.randn((2, kernel_size), dtype=self.dtype, device=self.device) | ||
|
||
# use both filters. | ||
mix = F.filter_waveform(waveform, kernels) | ||
# use only one of them | ||
ref1 = F.filter_waveform(waveform[:10], kernels[0:1]) | ||
ref2 = F.filter_waveform(waveform[10:], kernels[1:2]) | ||
|
||
print("mix:", mix) | ||
print("ref1:", ref1) | ||
print("ref2:", ref2) | ||
# The first filter is effective in the first half | ||
self.assertEqual(mix[:10], ref1[:10]) | ||
# The second filter is effective in the second half | ||
self.assertEqual(mix[-9:], ref2[-9:]) | ||
# the middle portion is where the two filters affect | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this missing another assert for the middle portion? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no, the middle portion is mixture of two so we can't assert. |
||
|
||
|
||
class Functional64OnlyTestImpl(TestBaseMixin): | ||
@nested_params( | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove print statements
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? It is useful to have the print statements when test fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, I thought it was accidentally leftover from debugging. Can we print only if it's failing to avoid extra print clutter and make it more clear the function that is being tested in the print? Otherwise if we start adding generic print/debug statements in tests it can lead to extra clutter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use
pytest
as runner, and it by default captures and hides the stdout/stderr. So it's shown only when told so or failed.