0
0
RosHow-ToBeginner · 4 min read

How to Apply Filter to Audio in Python: Simple Guide

To apply a filter to audio in Python, use scipy.signal to design the filter and scipy.signal.lfilter to apply it to the audio data array. First, read the audio file into a numpy array, then create a filter (like low-pass or high-pass), and finally apply it to modify the audio signal.
📐

Syntax

To filter audio, you typically use scipy.signal.butter to create a Butterworth filter and scipy.signal.lfilter to apply it.

  • butter(order, cutoff, btype, fs): designs the filter coefficients.
  • lfilter(b, a, data): applies the filter to the audio data array.
python
from scipy.signal import butter, lfilter

def butter_filter(data, cutoff, fs, order=5, btype='low'):
    b, a = butter(order, cutoff, btype=btype, fs=fs)
    filtered_data = lfilter(b, a, data)
    return filtered_data
💻

Example

This example reads a WAV audio file, applies a low-pass filter to remove high frequencies, and saves the filtered audio.

python
import numpy as np
from scipy.io import wavfile
from scipy.signal import butter, lfilter

# Define filter function
def butter_filter(data, cutoff, fs, order=5, btype='low'):
    b, a = butter(order, cutoff, btype=btype, fs=fs)
    return lfilter(b, a, data)

# Read audio file
fs, data = wavfile.read('input_audio.wav')

# If stereo, take one channel
if len(data.shape) > 1:
    data = data[:, 0]

# Apply low-pass filter with cutoff at 3000 Hz
filtered_data = butter_filter(data, cutoff=3000, fs=fs, order=6, btype='low')

# Convert to int16 for WAV format
filtered_data = np.int16(filtered_data / np.max(np.abs(filtered_data)) * 32767)

# Save filtered audio
wavfile.write('filtered_audio.wav', fs, filtered_data)

print('Filtering complete. Saved as filtered_audio.wav')
Output
Filtering complete. Saved as filtered_audio.wav
⚠️

Common Pitfalls

  • Not normalizing audio data: Audio data must be in a proper numeric range before filtering to avoid distortion.
  • Wrong filter parameters: Setting cutoff frequency above Nyquist frequency (half the sample rate) causes errors.
  • Ignoring stereo channels: Filtering only one channel or not handling stereo data properly can cause unexpected results.
  • Data type mismatch: After filtering, convert data back to integer type before saving as WAV.
python
from scipy.signal import butter, lfilter

# Wrong: cutoff frequency too high
try:
    b, a = butter(4, 50000, fs=44100)  # 50000 > 22050 Nyquist
except ValueError as e:
    print(f'Error: {e}')

# Right: cutoff frequency below Nyquist
b, a = butter(4, 10000, fs=44100)
print('Filter created successfully with cutoff 10000 Hz')
Output
Error: Digital filter critical frequencies must be 0 < Wn < 1 Filter created successfully with cutoff 10000 Hz
📊

Quick Reference

Remember these key points when filtering audio in Python:

  • Use butter to design filters and lfilter to apply them.
  • Cutoff frequency must be less than half the sample rate (Nyquist frequency).
  • Handle stereo audio by filtering each channel separately or selecting one channel.
  • Normalize and convert data types properly before saving audio files.

Key Takeaways

Use scipy.signal.butter to create filter coefficients and lfilter to apply the filter to audio data.
Ensure cutoff frequency is below half the sample rate to avoid errors.
Handle stereo audio carefully by processing each channel or selecting one channel.
Normalize audio data and convert it back to integer type before saving filtered audio.
Test filters with small audio clips to verify results before processing large files.