Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/torchaudio/functional/filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -1694,6 +1694,19 @@ def vad(
flushedLen_ns = (measures_len - num_measures_to_flush) * measure_period_ns
break
# end for window
if not has_triggered and not bool(torch.isfinite(waveform).all()):
# Nothing triggered. Either the signal really is silent, or the running trigger
# measure was poisoned: one non-finite sample makes it non-finite for the rest of
# the waveform, so every later comparison against trigger_level is false and the
# whole input is discarded as silence. Only the second case is an error, and the
# scan sits in this branch so a waveform that triggers never pays for it.
raise ValueError(
"waveform must be finite everywhere, but it contains NaN or infinite values. "
"Vad tracks a running measure of the signal, and a single non-finite sample "
"makes every later comparison against trigger_level false, so the whole input "
"would be discarded as silence."
)

if not has_triggered and shape[-1] >= fixed_pre_trigger_len_ns:
return waveform[..., :fixed_pre_trigger_len_ns].view(shape[:-1] + torch.Size([fixed_pre_trigger_len_ns]))

Expand Down
15 changes: 15 additions & 0 deletions test/torchaudio_unittest/transforms/transforms_test_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,3 +498,18 @@ def test_vad_on_zero_audio(self, input_shape, output_shape, sample_rate: int, pr
expected_output = torch.zeros(output_shape, dtype=self.dtype, device=self.device)
result = T.Vad(sample_rate, pre_trigger_time=pre_trigger_time)(inpt)
self.assertEqual(result, expected_output)

@parameterized.expand([(float("nan"),), (float("inf"),), (float("-inf"),)])
def test_vad_rejects_non_finite_audio(self, bad_value: float):
"""VAD should raise on non-finite input rather than report the signal as silence.

The trigger measure is a running mean, so one non-finite sample poisons it and
every later comparison against trigger_level is false. Nothing triggers and the
whole waveform is discarded, returning an empty Tensor. See
https://github.com/pytorch/audio/issues/4216.
"""
sample_rate = 16000
waveform = torch.zeros(sample_rate, dtype=self.dtype, device=self.device)
waveform[100] = bad_value
with self.assertRaisesRegex(ValueError, "finite"):
T.Vad(sample_rate)(waveform)