Download as pdf or txt
Download as pdf or txt
You are on page 1of 15

Kalman.

Py

November 23, 2023

[4]: import numpy as np


import matplotlib.pyplot as plt
import librosa
from scipy.signal import welch
import time

# Record the start time


start_time = time.time()

# Load the speech signal


file_path = "mono.wav" # Replace with the actual path to your audio file
signal, sr = librosa.load(file_path, sr=None, mono=True)

# Create AWGN noise


noise = 0.1 * np.random.normal(size=len(signal))

# Mix the signal with noise


noisy_signal = signal + noise

# Define Kalman filter parameters


dt = 1.0 # Time step
A = np.array([[1, dt],
[0, 1]]) # State transition matrix (constant velocity model)
H = np.array([[1, 0]]) # Measurement matrix (measuring position)

# Process and measurement noise covariance matrices


Q = 0.01 * np.eye(2) # Process noise covariance
R = np.array([[1]]) # Measurement noise covariance

# Initial state and covariance


x_hat = np.array([0, 0]) # Initial state [position, velocity]
P = np.eye(2) # Initial covariance matrix

# Number of time steps


num_steps = len(signal)

# Kalman filter loop

1
filtered_states = np.zeros((num_steps, 2))

for k in range(num_steps):
# Prediction step
x_hat_minus = A @ x_hat
P_minus = A @ P @ A.T + Q

# Update step
K = P_minus @ H.T @ np.linalg.inv(H @ P_minus @ H.T + R)
x_hat = x_hat_minus + K @ (noisy_signal[k] - H @ x_hat_minus)
P = (np.eye(2) - K @ H) @ P_minus

# Save filtered state


filtered_states[k, :] = x_hat

# Calculate time-domain MSE


mse_time_domain = np.mean((signal - filtered_states[:, 0])**2)

# Calculate frequency-domain MSE using Blackman-Tukey method


frequencies, psd_original = welch(signal, fs=sr, nperseg=256, window='blackman')
frequencies, psd_noisy = welch(noisy_signal, fs=sr, nperseg=256,␣
↪window='blackman')

frequencies, psd_filtered = welch(filtered_states[:, 0], fs=sr, nperseg=256,␣


↪window='blackman')

mse_freq_domain = np.mean((psd_original - psd_filtered)**2)

# Plot the results


plt.figure(figsize=(15, 12))
plt.subplot(411); plt.title("Original and Noisy Signal"); plt.xlabel("samples -␣
↪k")

plt.plot(signal, "b", label="Original Signal")


plt.plot(noisy_signal, "r", alpha=0.7, label="Noisy Signal")
plt.legend()

plt.subplot(412); plt.title("Kalman Filtered Signal"); plt.xlabel("samples - k")


plt.plot(filtered_states[:, 0], "g", label="Filtered Signal")
plt.legend()

plt.subplot(413); plt.title("Filter Error"); plt.xlabel("samples - k")


plt.plot(signal - filtered_states[:, 0], "r", label="Error")
plt.legend()

plt.subplot(414); plt.title("Power Spectral Densities"); plt.xlabel("Frequency␣


↪(Hz)")

plt.plot(frequencies, 10 * np.log10(psd_original), label="Original Signal")


plt.plot(frequencies, 10 * np.log10(psd_noisy), label="Noisy Signal")

2
plt.plot(frequencies, 10 * np.log10(psd_filtered), label="Filtered Signal")
plt.legend()

plt.tight_layout()
plt.show()

print(f"Time-domain MSE: {mse_time_domain}")


print(f"Frequency-domain MSE: {mse_freq_domain}")

# Record the end time


end_time = time.time()

# Calculate the elapsed time


elapsed_time = end_time - start_time
print(f"Elapsed time is: {elapsed_time} seconds.")

Time-domain MSE: 0.0031145180148064943


Frequency-domain MSE: 8.462180780909497e-14
Elapsed time is: 9.502384424209595 seconds.

3
import numpy as np
import matplotlib.pyplot as plt
import soundfile as sf

# Load audio file


file_path = "/content/gostopaudio.wav"
audio_signal, fs = sf.read(file_path)

# Convert stereo to mono if needed


if audio_signal.ndim == 2:
audio_signal = np.mean(audio_signal, axis=1)

# Add Gaussian noise to the audio signal


noise_level = 0.1
noise = noise_level * np.random.randn(len(audio_signal))
noisy_audio_signal = audio_signal + noise

# NLMS filter parameters


mu = 0.01 # Step size
order = 32 # Filter order
delta = 1e-5 # Small constant to avoid division by zero

# NLMS filter function


def nlms_filter(input_signal, desired_signal, order, mu, delta):
num_samples = len(input_signal)
weights = np.zeros(order)
output_signal = np.zeros(num_samples)
mse_values = np.zeros(num_samples - order)

for i in range(order, num_samples):


x = input_signal[i-order:i]
y_hat = np.dot(weights, x)
error = desired_signal[i] - y_hat
norm_factor = np.dot(x, x) + delta
weights = weights + (mu / norm_factor) * error * x
output_signal[i] = y_hat
mse_values[i - order] = np.mean((desired_signal[i-order+1:i+1]
- y_hat) ** 2)

return output_signal, mse_values

# Apply NLMS filter to the noisy audio signal


desired_signal = audio_signal # Using the original audio as the
desired signal for denoising
filtered_audio, mse_values = nlms_filter(noisy_audio_signal,
desired_signal, order, mu, delta)

# Calculate the error between the input audio and the filtered signal
error = audio_signal - filtered_audio
# Plotting
plt.figure(figsize=(12, 10))

plt.subplot(5, 1, 1)
plt.plot(audio_signal, label='Original Audio Signal')
plt.title('Original Audio Signal')
plt.xlabel('Sample')
plt.ylabel('Amplitude')
plt.legend()

plt.subplot(5, 1, 2)
plt.plot(noisy_audio_signal, label='Noisy Audio Signal', alpha=0.7)
plt.title('Noisy Audio Signal')
plt.xlabel('Sample')
plt.ylabel('Amplitude')
plt.legend()

plt.subplot(5, 1, 3)
plt.plot(filtered_audio, label='Filtered Audio Signal (NLMS)',
linestyle='dashed')
plt.title('Filtered Audio Signal (NLMS)')
plt.xlabel('Sample')
plt.ylabel('Amplitude')
plt.legend()

plt.subplot(5, 1, 4)
plt.plot(error, label='Error', color='red')
plt.title('Error Between Original and Filtered Signals')
plt.xlabel('Sample')
plt.ylabel('Amplitude')
plt.legend()

plt.subplot(5, 1, 5)
plt.plot(mse_values, label='Time Domain MSE', color='green')
plt.title('Time Domain MSE')
plt.xlabel('Sample')
plt.ylabel('MSE')
plt.legend()

plt.tight_layout()
plt.show()
import numpy as np
import matplotlib.pyplot as plt
import soundfile as sf
from scipy.signal import welch

# Load audio file


file_path = "/content/gostopaudio.wav" # Replace with the path to
your audio file
audio_signal, fs = sf.read(file_path)

# Convert stereo to mono if needed


if audio_signal.ndim == 2:
audio_signal = np.mean(audio_signal, axis=1)

# Add Gaussian noise to the audio signal


noise_level = 0.1
noise = noise_level * np.random.randn(len(audio_signal))
noisy_audio_signal = audio_signal + noise

# Display and Play the Original Audio


sf.write("original_audio.wav", audio_signal, fs)
display(Audio("original_audio.wav", rate=fs, autoplay=True))
plt.figure(figsize=(12, 5))
plt.subplot(3, 1, 1)
plt.plot(audio_signal)
plt.title('Original Audio Signal')
plt.xlabel('Sample')
plt.ylabel('Amplitude')

# Display and Play the Noisy Audio


sf.write("noisy_audio.wav", noisy_audio_signal, fs)
display(Audio("noisy_audio.wav", rate=fs, autoplay=True))
plt.subplot(3, 1, 2)
plt.plot(noisy_audio_signal)
plt.title('Noisy Audio Signal')
plt.xlabel('Sample')
plt.ylabel('Amplitude')

# Apply Wiener filter to denoise the audio signal


wiener_denoised_signal = np.zeros_like(noisy_audio_signal)
wiener_window_size = 5 # Adjust the Wiener filter window size as
needed

for i in range(len(noisy_audio_signal)):
start_idx = max(0, i - wiener_window_size // 2)
end_idx = min(len(noisy_audio_signal), i + wiener_window_size // 2
+ 1)
frame = noisy_audio_signal[start_idx:end_idx]

# Wiener filter
power_signal = np.mean(np.abs(frame) ** 2)
power_noise = np.mean(np.abs(noise[start_idx:end_idx]) ** 2)
wiener_factor = power_signal / (power_signal + power_noise)

wiener_denoised_signal[i] = wiener_factor * noisy_audio_signal[i]

# Display and Play the Denoised Audio


sf.write("denoised_audio.wav", wiener_denoised_signal, fs)
display(Audio("denoised_audio.wav", rate=fs, autoplay=True))
plt.subplot(3, 1, 3)
plt.plot(wiener_denoised_signal)
plt.title('Denoised Audio Signal (Wiener Filter)')
plt.xlabel('Sample')
plt.ylabel('Amplitude')

plt.tight_layout()
plt.show()

<IPython.lib.display.Audio object>

<IPython.lib.display.Audio object>

<IPython.lib.display.Audio object>
import numpy as np
import matplotlib.pyplot as plt
import soundfile as sf
from IPython.display import Audio

# Load audio file


file_path = "/content/gostopaudio.wav"
audio_signal, fs = sf.read(file_path)

# Convert stereo to mono if needed


if audio_signal.ndim == 2:
audio_signal = np.mean(audio_signal, axis=1)

# Add Gaussian noise to the audio signal


noise_level = 0.1
noise = noise_level * np.random.randn(len(audio_signal))
noisy_audio_signal = audio_signal + noise

# LMS filter parameters


mu = 0.01 # Step size
order = 32 # Filter order

# LMS filter function


def lms_filter(input_signal, desired_signal, order, mu):
num_samples = len(input_signal)
weights = np.zeros(order)
output_signal = np.zeros(num_samples)
mse_values = np.zeros(num_samples - order)

for i in range(order, num_samples):


x = input_signal[i-order:i]
y_hat = np.dot(weights, x)
error = desired_signal[i] - y_hat
weights = weights + mu * error * x
output_signal[i] = y_hat
mse_values[i - order] = np.mean((desired_signal[i-order+1:i+1]
- y_hat) ** 2)

return output_signal, mse_values

# Apply LMS filter to the noisy audio signal


desired_signal = audio_signal # Using the original audio as the
desired signal for denoising
filtered_audio, mse_values = lms_filter(noisy_audio_signal,
desired_signal, order, mu)

# Save audio files


sf.write("original_audio.wav", audio_signal, fs)
sf.write("noisy_audio.wav", noisy_audio_signal, fs)
sf.write("filtered_audio.wav", filtered_audio, fs)
# Playback original audio
print("Playing Original Audio:")
Audio("original_audio.wav")

# Playback noisy audio


print("Playing Noisy Audio:")
Audio("noisy_audio.wav")

# Playback filtered audio


print("Playing Filtered Audio:")
Audio("filtered_audio.wav")

# Plotting
plt.figure(figsize=(12, 15))

plt.subplot(5, 1, 1)
plt.plot(audio_signal, label='Original Audio Signal')
plt.title('Original Audio Signal')
plt.xlabel('Sample')
plt.ylabel('Amplitude')
plt.legend()

plt.subplot(5, 1, 2)
plt.plot(noisy_audio_signal, label='Noisy Audio Signal', alpha=0.7)
plt.title('Noisy Audio Signal')
plt.xlabel('Sample')
plt.ylabel('Amplitude')
plt.legend()

plt.subplot(5, 1, 3)
plt.plot(filtered_audio, label='Filtered Audio Signal (LMS)',
linestyle='dashed')
plt.title('Filtered Audio Signal (LMS)')
plt.xlabel('Sample')
plt.ylabel('Amplitude')
plt.legend()

plt.subplot(5, 1, 4)
plt.plot(audio_signal - filtered_audio, label='Error', color='red')
plt.title('Error Between Original and Filtered Signals')
plt.xlabel('Sample')
plt.ylabel('Amplitude')
plt.legend()

plt.subplot(5, 1, 5)
plt.plot(mse_values, label='Time Domain MSE', color='green')
plt.title('Time Domain MSE')
plt.xlabel('Sample')
plt.ylabel('MSE')
plt.legend()

plt.tight_layout()
plt.show()

Playing Original Audio:


Playing Noisy Audio:
Playing Filtered Audio:

You might also like