time stretch and pitch shift now use pysox
MODIFY
nussl/core/effects.py
nussl/core/effects.py
@@ -2,7 +2,7 @@ import numpy as np
import warnings
import ffmpeg
import tempfile
-from pysndfx import AudioEffectsChain
+import sox
# import av
# from av.filter import Filter, Graph
@@ -40,17 +40,6 @@ class FFmpegFilter(FilterFunction):
self.func = lambda stream: stream.filter(_filter, **filter_kwargs)
-class SoXFilter(FilterFunction):
- def __init__(self, _filter, **filter_kwargs):
- self.filter = _filter
- if _filter == "tempo":
- self.func = lambda stream: stream.tempo(**filter_kwargs)
- elif _filter == "pitch":
- self.func = lambda stream: stream.pitch(**filter_kwargs)
- else:
- raise ValueError
-
-
def build_effects_ffmpeg(audio_signal, filters, silent=False):
"""
build_effects_ffmpeg takes an AudioSignal object and a list of FFmpegFilter objects
@@ -133,6 +122,17 @@ def build_effects_ffmpeg(audio_signal, filters, silent=False):
return augmented_signal
+class SoXFilter(FilterFunction):
+ def __init__(self, _filter, **filter_kwargs):
+ self.filter = _filter
+ if _filter == "tempo":
+ self.func = lambda tfm: tfm.tempo(**filter_kwargs)
+ elif _filter == "pitch":
+ self.func = lambda tfm: tfm.pitch(**filter_kwargs)
+ else:
+ raise ValueError
+
+
def build_effects_sox(audio_signal, filters):
"""
build_effects_sox takes an AudioSignal object and a list of SoXFilter objects
@@ -146,12 +146,14 @@ def build_effects_sox(audio_signal, filters):
"""
audio_data = audio_signal.audio_data
- chain = AudioEffectsChain()
+ tfm = sox.Transformer()
+ # tfm.set_output_format(channels=audio_signal.num_channels)
for _filter in filters:
- chain = _filter(chain)
- augmented_data = chain(audio_data)
+ tfm = _filter(tfm)
+ augmented_data = tfm.build_array(input_array=np.transpose(audio_data),
+ sample_rate_in=audio_signal.sample_rate)
- return audio_signal.make_copy_with_audio_data(augmented_data)
+ return audio_signal.make_copy_with_audio_data(np.transpose(augmented_data))
def make_arglist_ffmpeg(lst, sep="|"):
@@ -178,7 +180,7 @@ def pitch_shift(shift):
Returns a SoXFilter, when called on an pysndfx stream, will increase the pitch
of the audio by a number of cents, denoted in shift.
Args:
- shift: The number of cents (1/100th of a half step) to shift the audio.
+ shift: The number of semitones to shift the audio.
Positive values increases the frequency of the signal
Returns:
filter: A SoXFilter object, to be called on an pysndfx stream
@@ -186,7 +188,7 @@ def pitch_shift(shift):
if not isinstance(shift, int):
raise ValueError("shift must be an integer.")
- return SoXFilter("pitch", shift=shift)
+ return SoXFilter("pitch", n_semitones=shift)
def _pass_arg_check(freq, poles, width_type, width):

MODIFY
requirements.txt
requirements.txt
@@ -17,5 +17,4 @@ gpytorch
ffmpeg-python
importlib_resources
pyloudnorm
-ffmpeg-python
-pysndfx
+sox --pre

MODIFY
tests/core/regression/augmentation/hooks.json
tests/core/regression/augmentation/hooks.json
{
"test_metrics": {
"variance": [
- 0.0006839861440408924
+ 0.0013409034068881005
],
"sum": [
- -0.09989267587661743,
- -0.09620010852813721
+ 0.578094482421875
]
}
}
\ No newline at end of file

MODIFY
tests/core/regression/augmentation/pitch_shift.json
tests/core/regression/augmentation/pitch_shift.json
{
"test_metrics": {
"variance": [
- 0.00030575075880514256
+ 0.00015023440962760138
],
"sum": [
- 0.08093607425689697,
- 0.07972097396850586
+ 0.2045145034790039
]
}
}
\ No newline at end of file

MODIFY
tests/core/regression/augmentation/time_stretch.json
tests/core/regression/augmentation/time_stretch.json
{
"test_metrics": {
"variance": [
- 0.0002797015205803802
+ 0.00014854395373656512
],
"sum": [
- 0.021883487701416016,
- 0.020734548568725586
+ -0.644632875919342
]
}
}
\ No newline at end of file

MODIFY
tests/core/test_effects.py
tests/core/test_effects.py
@@ -342,7 +342,7 @@ def test_hooks(mix_and_sources, check_against_regression_data):
signal = (
signal
.time_stretch(3)
- .pitch_shift(2000)
+ .pitch_shift(2)
.low_pass(512)
.high_pass(512)
.tremolo(5, .4)

time stretch and pitch shift now use pysox