Esempio n. 1
0
 def test_clamp(self):
     input_signal = torch.ones(1, 44100 * 1, dtype=self.dtype, device=self.device)
     b_coeffs = torch.tensor([1, 0], dtype=self.dtype, device=self.device)
     a_coeffs = torch.tensor([1, -0.95], dtype=self.dtype, device=self.device)
     output_signal = F.lfilter(input_signal, a_coeffs, b_coeffs, clamp=True)
     assert output_signal.max() <= 1
     output_signal = F.lfilter(input_signal, a_coeffs, b_coeffs, clamp=False)
     assert output_signal.max() > 1
Esempio n. 2
0
    def test_lfilter(self):
        signal_length = 2048
        torch.manual_seed(2434)
        x = torch.randn(self.batch_size, signal_length)
        a = torch.rand(self.batch_size, 3)
        b = torch.rand(self.batch_size, 3)

        batchwise_output = F.lfilter(x, a, b, batching=True)
        itemwise_output = torch.stack(
            [F.lfilter(x[i], a[i], b[i]) for i in range(self.batch_size)])

        self.assertEqual(batchwise_output, itemwise_output)
 def func(tensor):
     # Design an IIR lowpass filter using scipy.signal filter design
     # https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.iirdesign.html#scipy.signal.iirdesign
     #
     # Example
     #     >>> from scipy.signal import iirdesign
     #     >>> b, a = iirdesign(0.2, 0.3, 1, 60)
     b_coeffs = torch.tensor(
         [
             0.00299893,
             -0.0051152,
             0.00841964,
             -0.00747802,
             0.00841964,
             -0.0051152,
             0.00299893,
         ],
         device=tensor.device,
         dtype=tensor.dtype,
     )
     a_coeffs = torch.tensor(
         [
             1.0,
             -4.8155751,
             10.2217618,
             -12.14481273,
             8.49018171,
             -3.3066882,
             0.56088705,
         ],
         device=tensor.device,
         dtype=tensor.dtype,
     )
     return F.lfilter(tensor, a_coeffs, b_coeffs)
Esempio n. 4
0
    def test_perf_biquad_filtering(self):

        fn_sine = os.path.join(self.test_dirpath, "assets", "whitenoise.wav")

        b0 = 0.4
        b1 = 0.2
        b2 = 0.9
        a0 = 0.7
        a1 = 0.2
        a2 = 0.6

        # SoX method
        E = torchaudio.sox_effects.SoxEffectsChain()
        E.set_input_file(fn_sine)
        _timing_sox = time.time()
        E.append_effect_to_chain("biquad", [b0, b1, b2, a0, a1, a2])
        waveform_sox_out, sr = E.sox_build_flow_effects()
        _timing_sox_run_time = time.time() - _timing_sox

        _timing_lfilter_filtering = time.time()
        waveform, sample_rate = torchaudio.load(fn_sine, normalization=True)
        waveform_lfilter_out = F.lfilter(
            waveform, torch.tensor([a0, a1, a2]), torch.tensor([b0, b1, b2])
        )
        _timing_lfilter_run_time = time.time() - _timing_lfilter_filtering

        assert torch.allclose(waveform_sox_out, waveform_lfilter_out, atol=1e-4)
        _test_torchscript_functional(
            F.lfilter, waveform, torch.tensor([a0, a1, a2]), torch.tensor([b0, b1, b2])
        )
Esempio n. 5
0
    def test_perf_biquad_filtering(self):

        fn_sine = common_utils.get_asset_path('whitenoise.wav')

        b0 = 0.4
        b1 = 0.2
        b2 = 0.9
        a0 = 0.7
        a1 = 0.2
        a2 = 0.6

        # SoX method
        E = torchaudio.sox_effects.SoxEffectsChain()
        E.set_input_file(fn_sine)
        E.append_effect_to_chain("biquad", [b0, b1, b2, a0, a1, a2])
        waveform_sox_out, _ = E.sox_build_flow_effects()

        waveform, _ = torchaudio.load(fn_sine, normalization=True)
        waveform_lfilter_out = F.lfilter(waveform, torch.tensor([a0, a1, a2]),
                                         torch.tensor([b0, b1, b2]))

        torch.testing.assert_allclose(waveform_lfilter_out,
                                      waveform_sox_out,
                                      atol=1e-4,
                                      rtol=1e-5)
Esempio n. 6
0
def _shallow_ar_inference(out, stream_sizes, analysis_filts):
    from torchaudio.functional import lfilter

    out_streams = split_streams(out, stream_sizes)
    # back to conv1d friendly (B, C, T) format
    out_streams = map(lambda x: x.transpose(1, 2), out_streams)

    out_syn = []
    for sidx, os in enumerate(out_streams):
        out_stream_syn = torch.zeros_like(os)
        a = analysis_filts[sidx].get_filt_coefs()
        # apply IIR filter for each dimiesion
        for idx in range(os.shape[1]):
            # NOTE: scipy.signal.lfilter accespts b, a in order,
            # but torchaudio expect the oppsite; a, b in order
            ai = a[idx].view(-1).flip(0)
            bi = torch.zeros_like(ai)
            bi[0] = 1
            out_stream_syn[:, idx, :] = lfilter(os[:, idx, :],
                                                ai,
                                                bi,
                                                clamp=False)
        out_syn += [out_stream_syn]

    out_syn = torch.cat(out_syn, 1)
    return out_syn.transpose(1, 2)
Esempio n. 7
0
 def test_shape(self, shape):
     torch.random.manual_seed(42)
     waveform = torch.rand(*shape, dtype=self.dtype, device=self.device)
     b_coeffs = torch.tensor([0, 0, 0, 1], dtype=self.dtype, device=self.device)
     a_coeffs = torch.tensor([1, 0, 0, 0], dtype=self.dtype, device=self.device)
     output_waveform = F.lfilter(waveform, a_coeffs, b_coeffs)
     assert shape == waveform.size() == output_waveform.size()
 def func(tensor):
     a = torch.tensor([0.7, 0.2, 0.6],
                      device=tensor.device,
                      dtype=tensor.dtype)
     b = torch.tensor([0.4, 0.2, 0.9],
                      device=tensor.device,
                      dtype=tensor.dtype)
     return F.lfilter(tensor, a, b)
Esempio n. 9
0
    def test_perf_biquad_filtering(self):
        b0 = 0.4
        b1 = 0.2
        b2 = 0.9
        a0 = 0.7
        a1 = 0.2
        a2 = 0.6

        data, path = self.get_whitenoise()
        result = F.lfilter(data, torch.tensor([a0, a1, a2]), torch.tensor([b0, b1, b2]))
        self.assert_sox_effect(result, path, ['biquad', b0, b1, b2, a0, a1, a2])
    def forward(
        self,
        x: "torch.Tensor",
        y: Optional["torch.Tensor"] = None
    ) -> Tuple["torch.Tensor", Optional["torch.Tensor"]]:
        """
        Apply filter to a single sample `x`.

        :param x: A single audio sample.
        :param y: Label of the sample `x`. This function does not affect them in any way.
        :return: Similar sample.
        """
        import torch  # lgtm [py/repeated-import]
        from torchaudio.functional import lfilter

        if int(torch.__version__.split(".")[1]) > 5:
            x_preprocess = lfilter(
                b_coeffs=torch.tensor(self.numerator_coef,
                                      device=self._device),
                a_coeffs=torch.tensor(self.denominator_coef,
                                      device=self._device),
                waveform=x,
                clamp=False,
            )
        else:
            x_preprocess = lfilter(
                b_coeffs=torch.tensor(self.numerator_coef,
                                      device=self._device),
                a_coeffs=torch.tensor(self.denominator_coef,
                                      device=self._device),
                waveform=x,
            )

        if self.clip_values is not None:
            x_preprocess = x_preprocess.clamp(min=self.clip_values[0],
                                              max=self.clip_values[1])

        return x_preprocess, y
Esempio n. 11
0
    def _test_lfilter_basic(self, dtype, device):
        """
        Create a very basic signal,
        Then make a simple 4th order delay
        The output should be same as the input but shifted
        """

        torch.random.manual_seed(42)
        waveform = torch.rand(2, 44100 * 1, dtype=dtype, device=device)
        b_coeffs = torch.tensor([0, 0, 0, 1], dtype=dtype, device=device)
        a_coeffs = torch.tensor([1, 0, 0, 0], dtype=dtype, device=device)
        output_waveform = F.lfilter(waveform, a_coeffs, b_coeffs)

        assert torch.allclose(waveform[:, 0:-3], output_waveform[:, 3:], atol=1e-5)
Esempio n. 12
0
    def test_simple(self):
        """
        Create a very basic signal,
        Then make a simple 4th order delay
        The output should be same as the input but shifted
        """

        torch.random.manual_seed(42)
        waveform = torch.rand(2, 44100 * 1, dtype=self.dtype, device=self.device)
        b_coeffs = torch.tensor([0, 0, 0, 1], dtype=self.dtype, device=self.device)
        a_coeffs = torch.tensor([1, 0, 0, 0], dtype=self.dtype, device=self.device)
        output_waveform = F.lfilter(waveform, a_coeffs, b_coeffs)

        self.assertEqual(output_waveform[:, 3:], waveform[:, 0:-3], atol=1e-5, rtol=1e-5)
Esempio n. 13
0
 def test_lfilter_shape(self, input_shape, coeff_shape, target_shape):
     torch.random.manual_seed(42)
     waveform = torch.rand(*input_shape,
                           dtype=self.dtype,
                           device=self.device)
     b_coeffs = torch.rand(*coeff_shape,
                           dtype=self.dtype,
                           device=self.device)
     a_coeffs = torch.rand(*coeff_shape,
                           dtype=self.dtype,
                           device=self.device)
     output_waveform = F.lfilter(waveform, a_coeffs, b_coeffs)
     assert input_shape == waveform.size()
     assert target_shape == output_waveform.size()
Esempio n. 14
0
    def test_lfilter_9th_order_filter_stability(self):
        """
        Validate the precision of lfilter against reference scipy implementation when using high order filter.
        The reference implementation use cascaded second-order filters so is more numerically accurate.
        """
        # create an impulse signal
        x = torch.zeros(1024, dtype=self.dtype, device=self.device)
        x[0] = 1

        # get target impulse response
        sos = signal.butter(9, 850, 'hp', fs=22050, output='sos')
        y = torch.from_numpy(signal.sosfilt(sos, x.cpu().numpy())).to(self.dtype).to(self.device)

        # get lfilter coefficients
        b, a = signal.butter(9, 850, 'hp', fs=22050, output='ba')
        b, a = torch.from_numpy(b).to(self.dtype).to(self.device), torch.from_numpy(
            a).to(self.dtype).to(self.device)

        # predict impulse response
        yhat = F.lfilter(x, a, b, False)
        self.assertEqual(yhat, y, atol=1e-4, rtol=1e-5)
Esempio n. 15
0
    def _test_lfilter(self, waveform, device):
        """
        Design an IIR lowpass filter using scipy.signal filter design
        https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.iirdesign.html#scipy.signal.iirdesign

        Example
          >>> from scipy.signal import iirdesign
          >>> b, a = iirdesign(0.2, 0.3, 1, 60)
        """

        b_coeffs = torch.tensor(
            [
                0.00299893,
                -0.0051152,
                0.00841964,
                -0.00747802,
                0.00841964,
                -0.0051152,
                0.00299893,
            ],
            device=device,
        )
        a_coeffs = torch.tensor(
            [
                1.0,
                -4.8155751,
                10.2217618,
                -12.14481273,
                8.49018171,
                -3.3066882,
                0.56088705,
            ],
            device=device,
        )

        output_waveform = F.lfilter(waveform, a_coeffs, b_coeffs)
        assert len(output_waveform.size()) == 2
        assert output_waveform.size(0) == waveform.size(0)
        assert output_waveform.size(1) == waveform.size(1)
        _test_torchscript_functional(F.lfilter, waveform, a_coeffs, b_coeffs)
    def test_perf_biquad_filtering(self):

        b0 = 0.4
        b1 = 0.2
        b2 = 0.9
        a0 = 0.7
        a1 = 0.2
        a2 = 0.6

        # SoX method
        E = torchaudio.sox_effects.SoxEffectsChain()
        E.set_input_file(self.noise_filepath)
        E.append_effect_to_chain("biquad", [b0, b1, b2, a0, a1, a2])
        waveform_sox_out, _ = E.sox_build_flow_effects()

        waveform_lfilter_out = F.lfilter(self.noise_waveform,
                                         torch.tensor([a0, a1, a2]),
                                         torch.tensor([b0, b1, b2]))

        self.assertEqual(waveform_lfilter_out,
                         waveform_sox_out,
                         atol=1e-4,
                         rtol=1e-5)