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

Do not use SoxEffectsChain in sox compatibility test (#781)

This PR replaces `torchaudio.sox_effects.SoxEffectsChain` in `test_sox_compatibility` with bare `sox` command.

The parity of `torchaudio.sox_effects.SoxEffectsChain` against `sox` command is not tested and it has known issues https://github.com/pytorch/audio/issues/771, therefore it is not appropriate to use this class for testing other functions.
parent 131e48b6
...@@ -77,3 +77,24 @@ def convert_audio_file( ...@@ -77,3 +77,24 @@ def convert_audio_file(
command += [dst_path] command += [dst_path]
print(' '.join(command)) print(' '.join(command))
subprocess.run(command, check=True) subprocess.run(command, check=True)
def _flattern(effects):
if not effects:
return effects
if isinstance(effects[0], str):
return effects
return [item for sublist in effects for item in sublist]
def run_sox_effect(input_file, output_file, effect, *, output_sample_rate=None, output_bitdepth=None):
"""Run sox effects"""
effect = _flattern(effect)
command = ['sox', '-V', '--no-dither', input_file]
if output_bitdepth:
command += ['--bits', str(output_bitdepth)]
command += [output_file] + effect
if output_sample_rate:
command += ['rate', str(output_sample_rate)]
print(' '.join(command))
subprocess.run(command, check=True)
import unittest import unittest
import torch import torch
import torchaudio
import torchaudio.functional as F import torchaudio.functional as F
import torchaudio.transforms as T
from . import common_utils from .common_utils import (
skipIfNoSoxBackend,
skipIfNoExec,
@common_utils.skipIfNoSoxBackend TempDirMixin,
class TestFunctionalFiltering(common_utils.TempDirMixin, common_utils.TorchaudioTestCase): TorchaudioTestCase,
backend = 'sox' get_asset_path,
sox_utils,
def setUp(self): load_wav,
# 1. Create int16 signal to save as PCM wav save_wav,
# 2. Write to temp file get_whitenoise,
# 3. Load temp file into tensor to reuse in downstream tests )
# Prefer to use common_utils.load_wav() but this implementation does
# not match torchaudio.load and errors on downstream tests
super().setUp() @skipIfNoSoxBackend
@skipIfNoExec('sox')
self.NOISE_SAMPLE_RATE = 44100 # N.B. 44.1 kHz required by SoX deemph effect class TestFunctionalFiltering(TempDirMixin, TorchaudioTestCase):
noise_waveform_as_int = common_utils.get_whitenoise( def run_sox_effect(self, input_file, effect):
sample_rate=self.NOISE_SAMPLE_RATE, duration=5, dtype=torch.int16, scale_factor=0.9, output_file = self.get_temp_path('expected.wav')
) sox_utils.run_sox_effect(input_file, output_file, [str(e) for e in effect])
self.noise_filepath = self.get_temp_path("whitenoise.wav") return load_wav(output_file)
common_utils.save_wav(
self.noise_filepath, noise_waveform_as_int, self.NOISE_SAMPLE_RATE def assert_sox_effect(self, result, input_path, effects, atol=1e-04, rtol=1e-5):
expected, _ = self.run_sox_effect(input_path, effects)
self.assertEqual(result, expected, atol=atol, rtol=rtol)
def get_whitenoise(self, sample_rate=8000):
noise = get_whitenoise(
sample_rate=sample_rate, duration=3, scale_factor=0.9,
) )
self.noise_waveform, _ = torchaudio.load(self.noise_filepath, normalization=True) path = self.get_temp_path("whitenoise.wav")
save_wav(path, noise, sample_rate)
return noise, path
def test_gain(self): def test_gain(self):
test_filepath = common_utils.get_asset_path('steam-train-whistle-daniel_simon.wav') path = get_asset_path('steam-train-whistle-daniel_simon.wav')
waveform, _ = common_utils.load_wav(test_filepath) data, _ = load_wav(path)
result = F.gain(data, 3)
waveform_gain = F.gain(waveform, 3) self.assert_sox_effect(result, path, ['gain', 3])
self.assertTrue(waveform_gain.abs().max().item(), 1.)
E = torchaudio.sox_effects.SoxEffectsChain()
E.set_input_file(test_filepath)
E.append_effect_to_chain("gain", [3])
sox_gain_waveform = E.sox_build_flow_effects()[0]
self.assertEqual(waveform_gain, sox_gain_waveform, atol=1e-04, rtol=1e-5)
def test_dither(self): def test_dither(self):
test_filepath = common_utils.get_asset_path('steam-train-whistle-daniel_simon.wav') path = get_asset_path('steam-train-whistle-daniel_simon.wav')
waveform, _ = common_utils.load_wav(test_filepath) data, _ = load_wav(path)
result = F.dither(data)
waveform_dithered = F.dither(waveform) self.assert_sox_effect(result, path, ['dither'])
waveform_dithered_noiseshaped = F.dither(waveform, noise_shaping=True)
E = torchaudio.sox_effects.SoxEffectsChain() def test_dither_noise(self):
E.set_input_file(test_filepath) path = get_asset_path('steam-train-whistle-daniel_simon.wav')
E.append_effect_to_chain("dither", []) data, _ = load_wav(path)
sox_dither_waveform = E.sox_build_flow_effects()[0] result = F.dither(data, noise_shaping=True)
self.assert_sox_effect(result, path, ['dither', '-s'], atol=1.5e-4)
self.assertEqual(waveform_dithered, sox_dither_waveform, atol=1e-04, rtol=1e-5)
E.clear_chain()
E.append_effect_to_chain("dither", ["-s"])
sox_dither_waveform_ns = E.sox_build_flow_effects()[0]
self.assertEqual(waveform_dithered_noiseshaped, sox_dither_waveform_ns, atol=1e-02, rtol=1e-5)
def test_vctk_transform_pipeline(self):
test_filepath_vctk = common_utils.get_asset_path('VCTK-Corpus', 'wav48', 'p224', 'p224_002.wav')
wf_vctk, sr_vctk = common_utils.load_wav(test_filepath_vctk)
# rate
sample = T.Resample(sr_vctk, 16000, resampling_method='sinc_interpolation')
wf_vctk = sample(wf_vctk)
# dither
wf_vctk = F.dither(wf_vctk, noise_shaping=True)
E = torchaudio.sox_effects.SoxEffectsChain()
E.set_input_file(test_filepath_vctk)
E.append_effect_to_chain("gain", ["-h"])
E.append_effect_to_chain("channels", [1])
E.append_effect_to_chain("rate", [16000])
E.append_effect_to_chain("gain", ["-rh"])
E.append_effect_to_chain("dither", ["-s"])
wf_vctk_sox = E.sox_build_flow_effects()[0]
self.assertEqual(wf_vctk, wf_vctk_sox, rtol=1e-03, atol=1e-03)
def test_lowpass(self): def test_lowpass(self):
"""
Test biquad lowpass filter, compare to SoX implementation
"""
cutoff_freq = 3000 cutoff_freq = 3000
sample_rate = 8000
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise(sample_rate)
E.set_input_file(self.noise_filepath) result = F.lowpass_biquad(data, sample_rate, cutoff_freq)
E.append_effect_to_chain("lowpass", [cutoff_freq]) self.assert_sox_effect(result, path, ['lowpass', cutoff_freq], atol=1.5e-4)
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.lowpass_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, cutoff_freq)
self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_highpass(self): def test_highpass(self):
"""
Test biquad highpass filter, compare to SoX implementation
"""
cutoff_freq = 2000 cutoff_freq = 2000
sample_rate = 8000
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise(sample_rate)
E.set_input_file(self.noise_filepath) result = F.highpass_biquad(data, sample_rate, cutoff_freq)
E.append_effect_to_chain("highpass", [cutoff_freq]) self.assert_sox_effect(result, path, ['highpass', cutoff_freq], atol=1.5e-4)
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.highpass_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, cutoff_freq)
self.assertEqual(output_waveform, sox_output_waveform, atol=1.5e-3, rtol=1e-5)
def test_allpass(self): def test_allpass(self):
"""
Test biquad allpass filter, compare to SoX implementation
"""
central_freq = 1000 central_freq = 1000
q = 0.707 q = 0.707
sample_rate = 8000
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise(sample_rate)
E.set_input_file(self.noise_filepath) result = F.allpass_biquad(data, sample_rate, central_freq, q)
E.append_effect_to_chain("allpass", [central_freq, str(q) + 'q']) self.assert_sox_effect(result, path, ['allpass', central_freq, f'{q}q'])
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.allpass_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, central_freq, q)
self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_bandpass_with_csg(self): def test_bandpass_with_csg(self):
"""
Test biquad bandpass filter, compare to SoX implementation
"""
central_freq = 1000 central_freq = 1000
q = 0.707 q = 0.707
const_skirt_gain = True const_skirt_gain = True
sample_rate = 8000
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise(sample_rate)
E.set_input_file(self.noise_filepath) result = F.bandpass_biquad(data, sample_rate, central_freq, q, const_skirt_gain)
E.append_effect_to_chain("bandpass", ["-c", central_freq, str(q) + 'q']) self.assert_sox_effect(result, path, ['bandpass', '-c', central_freq, f'{q}q'])
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.bandpass_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE,
central_freq, q, const_skirt_gain)
self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_bandpass_without_csg(self): def test_bandpass_without_csg(self):
"""
Test biquad bandpass filter, compare to SoX implementation
"""
central_freq = 1000 central_freq = 1000
q = 0.707 q = 0.707
const_skirt_gain = False const_skirt_gain = False
sample_rate = 8000
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise(sample_rate)
E.set_input_file(self.noise_filepath) result = F.bandpass_biquad(data, sample_rate, central_freq, q, const_skirt_gain)
E.append_effect_to_chain("bandpass", [central_freq, str(q) + 'q']) self.assert_sox_effect(result, path, ['bandpass', central_freq, f'{q}q'])
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.bandpass_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE,
central_freq, q, const_skirt_gain)
self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_bandreject(self): def test_bandreject(self):
"""
Test biquad bandreject filter, compare to SoX implementation
"""
central_freq = 1000 central_freq = 1000
q = 0.707 q = 0.707
sample_rate = 8000
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise(sample_rate)
E.set_input_file(self.noise_filepath) result = F.bandreject_biquad(data, sample_rate, central_freq, q)
E.append_effect_to_chain("bandreject", [central_freq, str(q) + 'q']) self.assert_sox_effect(result, path, ['bandreject', central_freq, f'{q}q'])
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.bandreject_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE,
central_freq, q)
self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_band_with_noise(self): def test_band_with_noise(self):
"""
Test biquad band filter with noise mode, compare to SoX implementation
"""
central_freq = 1000 central_freq = 1000
q = 0.707 q = 0.707
noise = True noise = True
sample_rate = 8000
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise(sample_rate)
E.set_input_file(self.noise_filepath) result = F.band_biquad(data, sample_rate, central_freq, q, noise)
E.append_effect_to_chain("band", ["-n", central_freq, str(q) + 'q']) self.assert_sox_effect(result, path, ['band', '-n', central_freq, f'{q}q'])
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.band_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, central_freq, q, noise)
self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_band_without_noise(self): def test_band_without_noise(self):
"""
Test biquad band filter without noise mode, compare to SoX implementation
"""
central_freq = 1000 central_freq = 1000
q = 0.707 q = 0.707
noise = False noise = False
sample_rate = 8000
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise(sample_rate)
E.set_input_file(self.noise_filepath) result = F.band_biquad(data, sample_rate, central_freq, q, noise)
E.append_effect_to_chain("band", [central_freq, str(q) + 'q']) self.assert_sox_effect(result, path, ['band', central_freq, f'{q}q'])
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.band_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, central_freq, q, noise)
self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_treble(self): def test_treble(self):
"""
Test biquad treble filter, compare to SoX implementation
"""
central_freq = 1000 central_freq = 1000
q = 0.707 q = 0.707
gain = 40 gain = 40
sample_rate = 8000
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise(sample_rate)
E.set_input_file(self.noise_filepath) result = F.treble_biquad(data, sample_rate, gain, central_freq, q)
E.append_effect_to_chain("treble", [gain, central_freq, str(q) + 'q']) self.assert_sox_effect(result, path, ['treble', gain, central_freq, f'{q}q'])
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.treble_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, gain, central_freq, q)
self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_bass(self): def test_bass(self):
"""
Test biquad bass filter, compare to SoX implementation
"""
central_freq = 1000 central_freq = 1000
q = 0.707 q = 0.707
gain = 40 gain = 40
sample_rate = 8000
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise(sample_rate)
E.set_input_file(self.noise_filepath) result = F.bass_biquad(data, sample_rate, gain, central_freq, q)
E.append_effect_to_chain("bass", [gain, central_freq, str(q) + 'q']) self.assert_sox_effect(result, path, ['bass', gain, central_freq, f'{q}q'], atol=1.5e-4)
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.bass_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, gain, central_freq, q)
self.assertEqual(output_waveform, sox_output_waveform, atol=1.5e-4, rtol=1e-5)
def test_deemph(self): def test_deemph(self):
""" sample_rate = 44100
Test biquad deemph filter, compare to SoX implementation data, path = self.get_whitenoise(sample_rate)
""" result = F.deemph_biquad(data, sample_rate)
E = torchaudio.sox_effects.SoxEffectsChain() self.assert_sox_effect(result, path, ['deemph'])
E.set_input_file(self.noise_filepath)
E.append_effect_to_chain("deemph")
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.deemph_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE)
self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_riaa(self): def test_riaa(self):
""" sample_rate = 44100
Test biquad riaa filter, compare to SoX implementation data, path = self.get_whitenoise(sample_rate)
""" result = F.riaa_biquad(data, sample_rate)
E = torchaudio.sox_effects.SoxEffectsChain() self.assert_sox_effect(result, path, ['riaa'])
E.set_input_file(self.noise_filepath)
E.append_effect_to_chain("riaa")
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.riaa_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE)
self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_contrast(self): def test_contrast(self):
"""
Test contrast effect, compare to SoX implementation
"""
enhancement_amount = 80. enhancement_amount = 80.
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise()
E.set_input_file(self.noise_filepath) result = F.contrast(data, enhancement_amount)
E.append_effect_to_chain("contrast", [enhancement_amount]) self.assert_sox_effect(result, path, ['contrast', enhancement_amount])
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.contrast(self.noise_waveform, enhancement_amount)
self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_dcshift_with_limiter(self): def test_dcshift_with_limiter(self):
"""
Test dcshift effect, compare to SoX implementation
"""
shift = 0.5 shift = 0.5
limiter_gain = 0.05 limiter_gain = 0.05
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise()
E.set_input_file(self.noise_filepath) result = F.dcshift(data, shift, limiter_gain)
E.append_effect_to_chain("dcshift", [shift, limiter_gain]) self.assert_sox_effect(result, path, ['dcshift', shift, limiter_gain])
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.dcshift(self.noise_waveform, shift, limiter_gain)
self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_dcshift_without_limiter(self): def test_dcshift_without_limiter(self):
"""
Test dcshift effect, compare to SoX implementation
"""
shift = 0.6 shift = 0.6
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise()
E.set_input_file(self.noise_filepath) result = F.dcshift(data, shift)
E.append_effect_to_chain("dcshift", [shift]) self.assert_sox_effect(result, path, ['dcshift', shift])
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.dcshift(self.noise_waveform, shift)
self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_overdrive(self): def test_overdrive(self):
"""
Test overdrive effect, compare to SoX implementation
"""
gain = 30 gain = 30
colour = 40 colour = 40
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise()
E.set_input_file(self.noise_filepath) result = F.overdrive(data, gain, colour)
E.append_effect_to_chain("overdrive", [gain, colour]) self.assert_sox_effect(result, path, ['overdrive', gain, colour])
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.overdrive(self.noise_waveform, gain, colour)
self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_phaser_sine(self): def test_phaser_sine(self):
"""
Test phaser effect with sine moduldation, compare to SoX implementation
"""
gain_in = 0.5 gain_in = 0.5
gain_out = 0.8 gain_out = 0.8
delay_ms = 2.0 delay_ms = 2.0
decay = 0.4 decay = 0.4
speed = 0.5 speed = 0.5
sample_rate = 8000
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise(sample_rate)
E.set_input_file(self.noise_filepath) result = F.phaser(data, sample_rate, gain_in, gain_out, delay_ms, decay, speed, sinusoidal=True)
E.append_effect_to_chain("phaser", [gain_in, gain_out, delay_ms, decay, speed, "-s"]) self.assert_sox_effect(result, path, ['phaser', gain_in, gain_out, delay_ms, decay, speed, '-s'])
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.phaser(self.noise_waveform, self.NOISE_SAMPLE_RATE,
gain_in, gain_out, delay_ms, decay, speed, sinusoidal=True)
self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_phaser_triangle(self): def test_phaser_triangle(self):
"""
Test phaser effect with triangle modulation, compare to SoX implementation
"""
gain_in = 0.5 gain_in = 0.5
gain_out = 0.8 gain_out = 0.8
delay_ms = 2.0 delay_ms = 2.0
decay = 0.4 decay = 0.4
speed = 0.5 speed = 0.5
sample_rate = 8000
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise(sample_rate)
E.set_input_file(self.noise_filepath) result = F.phaser(data, sample_rate, gain_in, gain_out, delay_ms, decay, speed, sinusoidal=False)
E.append_effect_to_chain("phaser", [gain_in, gain_out, delay_ms, decay, speed, "-t"]) self.assert_sox_effect(result, path, ['phaser', gain_in, gain_out, delay_ms, decay, speed, '-t'])
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.phaser(self.noise_waveform, self.NOISE_SAMPLE_RATE,
gain_in, gain_out, delay_ms, decay, speed, sinusoidal=False)
self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_flanger_triangle_linear(self): def test_flanger_triangle_linear(self):
"""
Test flanger effect with triangle modulation and linear interpolation, compare to SoX implementation
"""
delay = 0.6 delay = 0.6
depth = 0.87 depth = 0.87
regen = 3.0 regen = 3.0
width = 0.9 width = 0.9
speed = 0.5 speed = 0.5
phase = 30 phase = 30
sample_rate = 8000
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise(sample_rate)
E.set_input_file(self.noise_filepath) result = F.flanger(
E.append_effect_to_chain("flanger", [delay, depth, regen, width, speed, "triangle", phase, "linear"]) data, sample_rate, delay, depth, regen, width, speed, phase,
sox_output_waveform, sr = E.sox_build_flow_effects() modulation='triangular', interpolation='linear')
self.assert_sox_effect(
output_waveform = F.flanger(self.noise_waveform, self.NOISE_SAMPLE_RATE, delay, depth, regen, result, path, ['flanger', delay, depth, regen, width, speed, 'triangle', phase, 'linear'])
width, speed, phase, modulation='triangular', interpolation='linear')
torch.testing.assert_allclose(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_flanger_triangle_quad(self): def test_flanger_triangle_quad(self):
"""
Test flanger effect with triangle modulation and quadratic interpolation, compare to SoX implementation
"""
delay = 0.8 delay = 0.8
depth = 0.88 depth = 0.88
regen = 3.0 regen = 3.0
width = 0.4 width = 0.4
speed = 0.5 speed = 0.5
phase = 40 phase = 40
sample_rate = 8000
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise(sample_rate)
E.set_input_file(self.noise_filepath) result = F.flanger(
E.append_effect_to_chain("flanger", [delay, depth, regen, width, speed, "triangle", phase, "quadratic"]) data, sample_rate, delay, depth, regen, width, speed, phase,
sox_output_waveform, sr = E.sox_build_flow_effects() modulation='triangular', interpolation='quadratic')
self.assert_sox_effect(
output_waveform = F.flanger(self.noise_waveform, self.NOISE_SAMPLE_RATE, delay, depth, result, path, ['flanger', delay, depth, regen, width, speed, 'triangle', phase, 'quadratic'])
regen, width, speed, phase, modulation='triangular', interpolation='quadratic')
torch.testing.assert_allclose(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_flanger_sine_linear(self): def test_flanger_sine_linear(self):
"""
Test flanger effect with sine modulation and linear interpolation, compare to SoX implementation
"""
delay = 0.8 delay = 0.8
depth = 0.88 depth = 0.88
regen = 3.0 regen = 3.0
width = 0.23 width = 0.23
speed = 1.3 speed = 1.3
phase = 60 phase = 60
sample_rate = 8000
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise(sample_rate)
E.set_input_file(self.noise_filepath) result = F.flanger(
E.append_effect_to_chain("flanger", [delay, depth, regen, width, speed, "sine", phase, "linear"]) data, sample_rate, delay, depth, regen, width, speed, phase,
sox_output_waveform, sr = E.sox_build_flow_effects() modulation='sinusoidal', interpolation='linear')
self.assert_sox_effect(
output_waveform = F.flanger(self.noise_waveform, self.NOISE_SAMPLE_RATE, delay, depth, result, path, ['flanger', delay, depth, regen, width, speed, 'sine', phase, 'linear'])
regen, width, speed, phase, modulation='sinusoidal', interpolation='linear')
torch.testing.assert_allclose(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_flanger_sine_quad(self): def test_flanger_sine_quad(self):
"""
Test flanger effect with sine modulation and quadratic interpolation, compare to SoX implementation
"""
delay = 0.9 delay = 0.9
depth = 0.9 depth = 0.9
regen = 4.0 regen = 4.0
width = 0.23 width = 0.23
speed = 1.3 speed = 1.3
phase = 25 phase = 25
sample_rate = 8000
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise(sample_rate)
E.set_input_file(self.noise_filepath) result = F.flanger(
E.append_effect_to_chain("flanger", [delay, depth, regen, width, speed, "sine", phase, "quadratic"]) data, sample_rate, delay, depth, regen, width, speed, phase,
sox_output_waveform, sr = E.sox_build_flow_effects() modulation='sinusoidal', interpolation='quadratic')
self.assert_sox_effect(
output_waveform = F.flanger(self.noise_waveform, self.NOISE_SAMPLE_RATE, delay, depth, result, path, ['flanger', delay, depth, regen, width, speed, 'sine', phase, 'quadratic'])
regen, width, speed, phase, modulation='sinusoidal', interpolation='quadratic')
torch.testing.assert_allclose(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_equalizer(self): def test_equalizer(self):
"""
Test biquad peaking equalizer filter, compare to SoX implementation
"""
center_freq = 300 center_freq = 300
q = 0.707 q = 0.707
gain = 1 gain = 1
sample_rate = 8000
E = torchaudio.sox_effects.SoxEffectsChain() data, path = self.get_whitenoise(sample_rate)
E.set_input_file(self.noise_filepath) result = F.equalizer_biquad(data, sample_rate, center_freq, gain, q)
E.append_effect_to_chain("equalizer", [center_freq, q, gain]) self.assert_sox_effect(result, path, ['equalizer', center_freq, q, gain])
sox_output_waveform, sr = E.sox_build_flow_effects()
output_waveform = F.equalizer_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, center_freq, gain, q)
self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5)
def test_perf_biquad_filtering(self): def test_perf_biquad_filtering(self):
b0 = 0.4 b0 = 0.4
b1 = 0.2 b1 = 0.2
b2 = 0.9 b2 = 0.9
...@@ -494,17 +296,9 @@ class TestFunctionalFiltering(common_utils.TempDirMixin, common_utils.Torchaudio ...@@ -494,17 +296,9 @@ class TestFunctionalFiltering(common_utils.TempDirMixin, common_utils.Torchaudio
a1 = 0.2 a1 = 0.2
a2 = 0.6 a2 = 0.6
# SoX method data, path = self.get_whitenoise()
E = torchaudio.sox_effects.SoxEffectsChain() result = F.lfilter(data, torch.tensor([a0, a1, a2]), torch.tensor([b0, b1, b2]))
E.set_input_file(self.noise_filepath) self.assert_sox_effect(result, path, ['biquad', b0, b1, b2, a0, a1, a2])
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)
if __name__ == "__main__": if __name__ == "__main__":
......
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