Reputation: 35179
I have stereo audio data represented by a numpy array with a shape of (2500, 2)
. I'd like to filter it using scipy's signal.sosflt()
function, but I'm getting:
ValueError: Invalid zi shape. With axis=0, an input with shape (2500, 2), and an sos array with 2 sections, zi must have shape (2, 2, 2), got (2, 2).
The only complexity in the code is that I'm initializing zi once when processing the first buffer, then using it to condition the filter on subsequent calls:
from scipy import signal
def setup():
zi = None
# define a narrow band filter centered around 440 Hz.
sos = signal.butter(2, [438, 442], btype='bandpass', output='sos', fs=48000)
def process(src, dst):
# src and dst shape = (2500, 0)
if zi is None:
zi = signal.sosfilt_zi(sos) # initialize zi on first buffer
dst, zi = signal.sosfilt(sos, src, axis=0, zi=zi)
(Note: I've tried axis=-1
and axis=1
but neither of those are correct.)
Upvotes: 2
Views: 804
Reputation: 35179
A solution, but perhaps not the cleanest:
Since the source data is stereo, sosfilt
needs two copies of zi
, one for each channel. The following will work, but only if src
has two columns:
from scipy import signal
def setup():
zi = None
# define a narrow band filter centered around 440 Hz.
sos = signal.butter(2, [438, 442], btype='bandpass', output='sos', fs=48000)
def process(src, dst):
# src and dst shape = (2500, 0)
if zi is None:
tmp = signal.sosfilt_zi(sos)
zi = [tmp, tmp] # assumes source data has two columns
dst, zi = signal.sosfilt(sos, src, axis=0, zi=zi)
This works, but a more general solution would initialize zi
based on the shape of the source data.
Upvotes: 1