Commit 960644eb by orsier

Fifth commit

parent 93f46b7a
Showing with 177 additions and 0 deletions
import numpy as np
from scipy import signal
import soundfile as sf
import matplotlib.pyplot as plt
from scipy.fft import fft, fftfreq
# Function for Low-Pass Filter
def low_pass_filter(data, cutoff, sample_rate, order=4):
nyquist = 0.5 * sample_rate # Nyquist frequency
normal_cutoff = cutoff / nyquist
b, a = signal.butter(order, normal_cutoff, btype='low', analog=False)
filtered_data = signal.lfilter(b, a, data)
return filtered_data
# Function for Notch Filter
def notch_filter(data, freq, sample_rate, quality_factor=30):
nyquist = 0.5 * sample_rate # Nyquist frequency
freq_norm = freq / nyquist
b, a = signal.iirnotch(freq_norm, quality_factor)
filtered_data = signal.lfilter(b, a, data)
return filtered_data
def plot_filtered_signal_mono(filtered_data, samplerate):
"""Plot and save the monofasic waveform and spectrogram of the filtered data."""
# Ensure the filtered_data is 1-dimensional
print(f"Shape of filtered_data: {filtered_data.shape}")
if filtered_data.ndim > 1:
print("Filtered data has more than one dimension, selecting the first channel for mono display.")
filtered_data = filtered_data[:, 0] # Use the first channel if data is stereo
# Ensure the length is a power of two for optimal FFT performance (zero-padding if necessary)
n = len(filtered_data)
print(f"Length of filtered_data: {n}")
# Limit padding to the next power of two (max 2048 to avoid excessive memory usage)
max_pad_length = 2048
n_padded = min(max(n, 2 ** int(np.ceil(np.log2(n)))), max_pad_length) # Use the next power of two or limit to max_pad_length
print(f"Padding length: {n_padded}")
# Ensure n_padded is at least n to prevent negative padding
n_padded = max(n, n_padded)
# Padding for the data
filtered_data_padded = np.pad(filtered_data, (0, n_padded - len(filtered_data)), mode='constant')
print(f"Shape of padded filtered_data: {filtered_data_padded.shape}")
# Perform FFT on the padded data
yf_filtered = fft(filtered_data_padded)
# Generate the corresponding frequency axis
xf = fftfreq(n_padded, 1 / samplerate)
# Keep only positive frequencies
positive_freqs = xf > 0
xf_pos = xf[positive_freqs]
# Ensure the correct indexing for positive frequencies (Trim if necessary)
yf_filtered_pos = np.abs(yf_filtered[positive_freqs])
print(f"Shape of positive frequency spectrum: {yf_filtered_pos.shape}")
# Create a figure with two subplots
fig, axs = plt.subplots(1, 2, figsize=(18, 6))
# Plot the waveform (Time Domain) of the filtered signal
axs[0].plot(filtered_data, label='Filtered Signal', linestyle='-', alpha=0.7)
axs[0].set_title("Waveform (Time Domain) - Filtered Signal")
axs[0].set_xlabel("Sample Index")
axs[0].set_ylabel("Amplitude")
axs[0].legend()
# Plot the spectrogram (Frequency Domain) of the filtered signal
axs[1].plot(xf_pos, yf_filtered_pos, label='Filtered Signal', linestyle='-', alpha=0.7)
axs[1].set_title("Spectrogram (Frequency Domain) - Filtered Signal")
axs[1].set_xlabel("Frequency (Hz)")
axs[1].set_ylabel("Magnitude")
axs[1].legend()
# Adjust layout and save the figure
plt.tight_layout()
plt.show() # Display the plot
plt.close() # Ensure the figure is cleared after saving
def plot_comparison_signals(signal1, signal2, samplerate, label1, label2):
"""Plot and save the waveform and spectrogram for comparing two signals on the same plot."""
# Ensure the signals are 1-dimensional
if signal1.ndim > 1:
signal1 = signal1[:, 0] # Use the first channel if data is stereo
if signal2.ndim > 1:
signal2 = signal2[:, 0] # Use the first channel if data is stereo
# Ensure the length is a power of two for optimal FFT performance (zero-padding if necessary)
n1 = len(signal1)
n2 = len(signal2)
max_pad_length = 2048
n_padded1 = min(max(n1, 2 ** int(np.ceil(np.log2(n1)))), max_pad_length)
n_padded2 = min(max(n2, 2 ** int(np.ceil(np.log2(n2)))), max_pad_length)
n_padded1 = max(n1, n_padded1)
n_padded2 = max(n2, n_padded2)
signal1_padded = np.pad(signal1, (0, n_padded1 - len(signal1)), mode='constant')
signal2_padded = np.pad(signal2, (0, n_padded2 - len(signal2)), mode='constant')
# Perform FFT on the padded data
yf_signal1 = fft(signal1_padded)
yf_signal2 = fft(signal2_padded)
# Generate the corresponding frequency axis
xf1 = fftfreq(n_padded1, 1 / samplerate)
xf2 = fftfreq(n_padded2, 1 / samplerate)
positive_freqs1 = xf1 > 0
positive_freqs2 = xf2 > 0
xf_pos1 = xf1[positive_freqs1]
xf_pos2 = xf2[positive_freqs2]
yf_signal1_pos = np.abs(yf_signal1[positive_freqs1])
yf_signal2_pos = np.abs(yf_signal2[positive_freqs2])
# Create a figure with two subplots
fig, axs = plt.subplots(1, 2, figsize=(18, 6))
# Plot the waveform (Time Domain) comparing the two signals on the first subplot
axs[0].plot(signal1, label=label1, linestyle='-', alpha=0.7)
axs[0].plot(signal2, label=label2, linestyle='--', alpha=0.7)
axs[0].set_title("Waveform (Time Domain) - Comparison")
axs[0].set_xlabel("Sample Index")
axs[0].set_ylabel("Amplitude")
axs[0].legend()
# Plot the spectrogram (Frequency Domain) comparing the two signals on the second subplot
axs[1].plot(xf_pos1, yf_signal1_pos, label=label1, linestyle='-', alpha=0.7)
axs[1].plot(xf_pos2, yf_signal2_pos, label=label2, linestyle='--', alpha=0.7)
axs[1].set_title("Spectrogram (Frequency Domain) - Comparison")
axs[1].set_xlabel("Frequency (Hz)")
axs[1].set_ylabel("Magnitude")
axs[1].legend()
# Adjust layout and save the figure
plt.tight_layout()
plt.show() # Display the plot
plt.close() # Ensure the figure is cleared after saving
# Main processing
def main():
# Load the audio files
audio_file = "./test_guitarGDrive/223/mixture_223.wav" # Replace with your audio file path
model_filtered_file = "./test_guitarGDrive/223/vocals.wav" # Replace with the filtered audio from the model path
clean_file = "./test_guitarGDrive/223/target.wav" # Replace with the clean audio path
audio, sample_rate = sf.read(audio_file)
model_filtered, _ = sf.read(model_filtered_file)
clean, _ = sf.read(clean_file)
print(f"Loaded audio: {audio_file}")
print(f"Sample rate: {sample_rate} Hz, Audio length: {len(audio)/sample_rate:.2f} seconds")
# Apply Low-Pass Filter
cutoff_freq = 20000 # Hz
lpf_output = low_pass_filter(model_filtered, cutoff_freq, sample_rate)
print(f"Applied Low-Pass Filter with cutoff frequency {cutoff_freq} Hz.")
# Apply Notch Filter
notch_freq = 11000 # Hz
q_factor = 30
notch_output = notch_filter(lpf_output, notch_freq, sample_rate, q_factor)
print(f"Applied Notch Filter at {notch_freq} Hz with Q-factor {q_factor}.")
plot_comparison_signals(model_filtered,clean,sample_rate,"Demucs (clean)","Original (target)")
plot_comparison_signals(model_filtered,audio,sample_rate,"Demucs (clean)","Mixture (noise)")
if __name__ == "__main__":
main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment