Basic Low-pass filter for audio processing- Python

631 Views Asked by At

I am receiving audio with a mic and want to filter out high frequency signal. I have followed all the step to design a simple lowpass filter but I get the error below

if x.shape[axis] <= edge: IndexError: tuple index out of range

My codes are below;

import pyaudio
import sys
import time
import matplotlib.pyplot as plt
import numpy as np
import scipy.signal



import struct
from gpiozero import LED, Button

import matplotlib.animation as animation
from matplotlib import style
style.use('fivethirtyeight')




CHUNK = 1024
FRAMES_PER_BUFFER = 3200
FORMAT = pyaudio.paInt16
CHANNELS = 1

RATE = 44100
    p = pyaudio.PyAudio()
    
    stream = p.open(
            format = FORMAT,
            channels = CHANNELS,
            rate = RATE,
            input = True,
            output = False,
            #input_device_index = 1,
            frames_per_buffer = FRAMES_PER_BUFFER
            )
    
    
    
    print('stream is starting')
    
    
    player = p.open(format = FORMAT,
             channels = CHANNELS,
             rate = RATE,
             input = True,
             output = True,
             frames_per_buffer = FRAMES_PER_BUFFER
    
            )
    while True:
        if button.is_pressed:
            print('MIC1 is running')
            if not started:
                stream.start_stream()
                started = True
    
        frames = []
        data = stream.read(CHUNK, exception_on_overflow = False)
        frames.append(data)    
        ##################### Lowpass Filter ###########################################
        a, b = scipy.signal.butter(2, 0.1, 'lowpass', analog = False)
        fdata = scipy.signal.filtfilt(b,a , data, axis=0)
        player.write(fdata)
       

                  
    
    else:
        if started:
            stream.stop_stream()
            started = False
        
        print('LED is ON')
        led.on()
        time.sleep(2)
        led.off()
        time.sleep(2)

if I remove the lowpass filter, the program works fine.

Any help?

1

There are 1 best solutions below

0
ShlomiF On

Regardless of any other problems there might be, you're passing a bytestring to the filter, and a bytstring has an "empty" shape, so even trying to access axis=0 results in the error you're seeing.
You probably want to convert to a numpy array, and then convert back, by changing the appropriate line to -

fdata = scipy.signal.filtfilt(b, a, np.frombuffer(data), axis=0).tobytes()

Note the usage of np.frombuffer and .tobytes().
You might also want to change the order of the filter coefficients, either on this same line, or on the line before...