Unverified Commit 2cf59c41 authored by moto's avatar moto Committed by GitHub
Browse files

Add allpass filter to functional (#444)

parent 3549c57b
...@@ -83,6 +83,11 @@ Functions to perform common audio operations. ...@@ -83,6 +83,11 @@ Functions to perform common audio operations.
.. autofunction:: highpass_biquad .. autofunction:: highpass_biquad
:hidden:`allpass_biquad`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. autofunction:: allpass_biquad
:hidden:`equalizer_biquad` :hidden:`equalizer_biquad`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......
...@@ -148,6 +148,26 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -148,6 +148,26 @@ class TestFunctionalFiltering(unittest.TestCase):
assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-3) assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-3)
_test_torchscript_functional(F.highpass_biquad, waveform, sample_rate, CUTOFF_FREQ) _test_torchscript_functional(F.highpass_biquad, waveform, sample_rate, CUTOFF_FREQ)
def test_allpass(self):
"""
Test biquad allpass filter, compare to SoX implementation
"""
CENTRAL_FREQ = 1000
Q = 0.707
noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.mp3")
E = torchaudio.sox_effects.SoxEffectsChain()
E.set_input_file(noise_filepath)
E.append_effect_to_chain("allpass", [CENTRAL_FREQ, str(Q) + 'q'])
sox_output_waveform, sr = E.sox_build_flow_effects()
waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True)
output_waveform = F.allpass_biquad(waveform, sample_rate, CENTRAL_FREQ, Q)
assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4)
_test_torchscript_functional(F.allpass_biquad, waveform, sample_rate, CENTRAL_FREQ, Q)
def test_equalizer(self): def test_equalizer(self):
""" """
Test biquad peaking equalizer filter, compare to SoX implementation Test biquad peaking equalizer filter, compare to SoX implementation
......
...@@ -22,6 +22,7 @@ __all__ = [ ...@@ -22,6 +22,7 @@ __all__ = [
"lfilter", "lfilter",
"lowpass_biquad", "lowpass_biquad",
"highpass_biquad", "highpass_biquad",
"allpass_biquad",
"equalizer_biquad", "equalizer_biquad",
"biquad", "biquad",
'mask_along_axis', 'mask_along_axis',
...@@ -794,6 +795,35 @@ def lowpass_biquad(waveform, sample_rate, cutoff_freq, Q=0.707): ...@@ -794,6 +795,35 @@ def lowpass_biquad(waveform, sample_rate, cutoff_freq, Q=0.707):
return biquad(waveform, b0, b1, b2, a0, a1, a2) return biquad(waveform, b0, b1, b2, a0, a1, a2)
def allpass_biquad(waveform, sample_rate, central_freq, Q=0.707):
# type: (Tensor, int, float, float) -> Tensor
r"""Design two-pole all-pass filter. Similar to SoX implementation.
Args:
waveform(torch.Tensor): audio waveform of dimension of `(..., time)`
sample_rate (int): sampling rate of the waveform, e.g. 44100 (Hz)
central_freq (float): central frequency (in Hz)
q_factor (float): https://en.wikipedia.org/wiki/Q_factor
Returns:
output_waveform (torch.Tensor): Dimension of `(..., time)`
References:
http://sox.sourceforge.net/sox.html
https://www.w3.org/2011/audio/audio-eq-cookbook.html#APF
"""
w0 = 2 * math.pi * central_freq / sample_rate
alpha = math.sin(w0) / 2 / Q
b0 = 1 - alpha
b1 = -2 * math.cos(w0)
b2 = 1 + alpha
a0 = 1 + alpha
a1 = -2 * math.cos(w0)
a2 = 1 - alpha
return biquad(waveform, b0, b1, b2, a0, a1, a2)
def equalizer_biquad(waveform, sample_rate, center_freq, gain, Q=0.707): def equalizer_biquad(waveform, sample_rate, center_freq, gain, Q=0.707):
# type: (Tensor, int, float, float, float) -> Tensor # type: (Tensor, int, float, float, float) -> Tensor
r"""Design biquad peaking equalizer filter and perform filtering. Similar to SoX implementation. r"""Design biquad peaking equalizer filter and perform filtering. Similar to SoX implementation.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment