# MIT License, Copyright (c) 2020 Alexandre Défossez. # Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved. # # Modified from julius(https://github.com/adefossez/julius/blob/main/tests/test_filters.py) import math import random import sys import unittest import paddle from audio.audiotools.core import highpass_filter from audio.audiotools.core import highpass_filters def pure_tone(freq: float, sr: float=128, dur: float=4, device=None): """ Return a pure tone, i.e. cosine. Args: freq (float): frequency (in Hz) sr (float): sample rate (in Hz) dur (float): duration (in seconds) """ time = paddle.arange(int(sr * dur), dtype="float32") / sr return paddle.cos(2 * math.pi * freq * time) def delta(a, b, ref, fraction=0.9): length = a.shape[-1] compare_length = int(length * fraction) offset = (length - compare_length) // 2 a = a[..., offset:offset + length] b = b[..., offset:offset + length] # 计算绝对差值,均值,然后除以ref的标准差,乘以100 return 100 * paddle.mean(paddle.abs(a - b)) / paddle.std(ref) TOLERANCE = 1 # Tolerance to errors as percentage of the std of the input signal class _BaseTest(unittest.TestCase): def assertSimilar(self, a, b, ref, msg=None, tol=TOLERANCE): self.assertLessEqual(delta(a, b, ref), tol, msg) class TestHighPassFilters(_BaseTest): def setUp(self): paddle.seed(1234) random.seed(1234) def test_keep_or_kill(self): for _ in range(10): freq = random.uniform(0.01, 0.4) sr = 1024 tone = pure_tone(freq * sr, sr=sr, dur=10) # For this test we accept 5% tolerance in amplitude, or -26dB in power. tol = 5 zeros = 16 # If cutoff frequency is under freq, output should be input y_pass = highpass_filter(tone, 0.9 * freq, zeros=zeros) self.assertSimilar( y_pass, tone, tone, f"freq={freq}, pass", tol=tol) # If cutoff frequency is over freq, output should be zero y_killed = highpass_filter(tone, 1.1 * freq, zeros=zeros) self.assertSimilar( y_killed, 0 * tone, tone, f"freq={freq}, kill", tol=tol) def test_fft_nofft(self): for _ in range(10): x = paddle.randn([1024]) freq = random.uniform(0.01, 0.5) y_fft = highpass_filter(x, freq, fft=True) y_ref = highpass_filter(x, freq, fft=False) self.assertSimilar(y_fft, y_ref, x, f"freq={freq}", tol=0.01) def test_constant(self): x = paddle.ones([2048]) for zeros in [4, 10]: for freq in [0.01, 0.1]: y_high = highpass_filter(x, freq, zeros=zeros) self.assertLessEqual(y_high.abs().mean(), 1e-6, (zeros, freq)) def test_stride(self): x = paddle.randn([1024]) y = highpass_filters(x, [0.1, 0.2], stride=1)[:, ::3] y2 = highpass_filters(x, [0.1, 0.2], stride=3) self.assertEqual(y.shape, y2.shape) self.assertSimilar(y, y2, x) y = highpass_filters(x, [0.1, 0.2], stride=1, pad=False)[:, ::3] y2 = highpass_filters(x, [0.1, 0.2], stride=3, pad=False) self.assertEqual(y.shape, y2.shape) self.assertSimilar(y, y2, x) if __name__ == "__main__": unittest.main()