sem2 done
This commit is contained in:
198
semestralka2/final.m
Normal file
198
semestralka2/final.m
Normal file
@@ -0,0 +1,198 @@
|
||||
clc;
|
||||
close all;
|
||||
clear;
|
||||
|
||||
%% === LOAD AUDIO FILES ===
|
||||
[y1, Fs1] = audioread('flac.wav');
|
||||
[y2, Fs2] = audioread('flac2.wav');
|
||||
|
||||
if size(y1,2) > 1, y1 = mean(y1,2); end
|
||||
if size(y2,2) > 1, y2 = mean(y2,2); end
|
||||
|
||||
t1 = (0:length(y1)-1) / Fs1;
|
||||
t2 = (0:length(y2)-1) / Fs2;
|
||||
|
||||
fprintf('Loaded flac.wav: %d samples, Fs = %d Hz\n', length(y1), Fs1);
|
||||
fprintf('Loaded flac2.wav: %d samples, Fs = %d Hz\n', length(y2), Fs2);
|
||||
|
||||
%% === TIME-DOMAIN WAVEFORMS ===
|
||||
figure;
|
||||
subplot(2,1,1);
|
||||
plot(t1, y1);
|
||||
xlabel('Time [s]');
|
||||
ylabel('Amplitude');
|
||||
title('flac.wav – Time Domain');
|
||||
grid on;
|
||||
|
||||
subplot(2,1,2);
|
||||
plot(t2, y2, 'r');
|
||||
xlabel('Time [s]');
|
||||
ylabel('Amplitude');
|
||||
title('flac2.wav – Time Domain');
|
||||
grid on;
|
||||
|
||||
%% === FREQUENCY-DOMAIN ANALYSIS (FFT) ===
|
||||
N1 = length(y1);
|
||||
N2 = length(y2);
|
||||
|
||||
X1 = fft(y1);
|
||||
X2 = fft(y2);
|
||||
|
||||
freq_shift1 = (-N1/2 : N1/2 - 1) * (Fs1 / N1);
|
||||
freq_shift2 = (-N2/2 : N2/2 - 1) * (Fs2 / N2);
|
||||
|
||||
% --- Real / Imag components ---
|
||||
figure;
|
||||
subplot(2,1,1);
|
||||
plot(freq_shift2, real(fftshift(X2)));
|
||||
xlabel('Frequency [Hz]');
|
||||
ylabel('Real Part');
|
||||
title('flac2.wav – Real Part of FFT');
|
||||
grid on;
|
||||
subplot(2,1,2);
|
||||
plot(freq_shift2, imag(fftshift(X2)), 'r');
|
||||
xlabel('Frequency [Hz]');
|
||||
ylabel('Imag Part');
|
||||
title('flac2.wav – Imaginary Part of FFT');
|
||||
grid on;
|
||||
|
||||
% --- Magnitude Spectrum ---
|
||||
figure;
|
||||
plot(freq_shift2, 20*log10(abs(fftshift(X2)) + eps), 'y');
|
||||
xlabel('Frequency [Hz]');
|
||||
ylabel('Magnitude [dB]');
|
||||
title('flac2.wav – Magnitude Spectrum');
|
||||
xlim([0 2000]);
|
||||
grid on;
|
||||
|
||||
%% === PEAK DETECTION TO FIND TONAL NOISE FREQUENCIES ===
|
||||
halfN2 = floor(N2/2);
|
||||
f2 = (0:halfN2-1)*(Fs2/N2);
|
||||
mag2 = abs(X2(1:halfN2));
|
||||
|
||||
[pks, locs] = findpeaks(mag2, 'MinPeakHeight', max(mag2)*0.1, ...
|
||||
'MinPeakDistance', round(10*N2/Fs2));
|
||||
|
||||
f_tonal = f2(locs);
|
||||
f_tonal = f_tonal(f_tonal > 30 & f_tonal < Fs2/2);
|
||||
f_tonal = sort(f_tonal(1:min(5, numel(f_tonal))));
|
||||
|
||||
fprintf('\nDetected tonal noise frequencies (from flac2.wav):\n');
|
||||
fprintf(' %.1f Hz\n', f_tonal);
|
||||
|
||||
%% === NOTCH FILTER DESIGN (Z-domain zeros/poles) ===
|
||||
r = 0.995; % pole radius
|
||||
sos_all = [];
|
||||
g_all = 1;
|
||||
|
||||
for i = 1:length(f_tonal)
|
||||
f0 = f_tonal(i);
|
||||
w0 = 2*pi*f0/Fs1; % use Fs1 so it matches flac.wav
|
||||
z = [exp(1j*w0) exp(-1j*w0)]; % zeros at ±ω0
|
||||
p = r*z; % poles slightly inside circle
|
||||
b = real(poly(z));
|
||||
a = real(poly(p));
|
||||
b = b / (sum(b)/sum(a)); % normalize gain
|
||||
[sos_i, g_i] = tf2sos(b, a);
|
||||
sos_all = [sos_all; sos_i];
|
||||
g_all = g_all * g_i;
|
||||
end
|
||||
|
||||
%% === VISUALIZE NOTCH FILTER RESPONSE ===
|
||||
figure;
|
||||
freqz(sos_all, 2048, Fs1);
|
||||
title('Notch Filter Cascade – Based on flac2 Noise Frequencies');
|
||||
|
||||
%% === APPLY NOTCH FILTERS TO SIGNALS ===
|
||||
y1_filtered = filtfilt(sos_all, g_all, y1); % Apply to flac.wav
|
||||
y2_filtered = filtfilt(sos_all, g_all, y2); % Apply to flac2.wav
|
||||
y1_filtered = y1_filtered / max(abs(y1_filtered));
|
||||
y2_filtered = y2_filtered / max(abs(y2_filtered));
|
||||
|
||||
audiowrite('filtered_flac.wav', y1_filtered, Fs1);
|
||||
audiowrite('filtered_flac2.wav', y2_filtered, Fs2);
|
||||
|
||||
fprintf('\nSaved:\n');
|
||||
fprintf(' filtered_flac.wav (filtered signal)\n');
|
||||
fprintf(' filtered_flac2.wav (filtered noise sample)\n');
|
||||
|
||||
%% === COMPARE ORIGINAL VS FILTERED SPECTRA ===
|
||||
N_plot = length(y1);
|
||||
f_plot = (0:N_plot/2-1) * Fs1 / N_plot;
|
||||
X1_orig = fft(y1);
|
||||
X1_filt = fft(y1_filtered);
|
||||
|
||||
figure;
|
||||
subplot(2,1,1);
|
||||
plot(f_plot, 20*log10(abs(X1_orig(1:N_plot/2))+eps));
|
||||
xlabel('Frequency [Hz]'); ylabel('Magnitude [dB]');
|
||||
title('flac.wav – Original Spectrum');
|
||||
xlim([0 2000]); grid on;
|
||||
|
||||
subplot(2,1,2);
|
||||
plot(f_plot, 20*log10(abs(X1_filt(1:N_plot/2))+eps), 'r');
|
||||
xlabel('Frequency [Hz]'); ylabel('Magnitude [dB]');
|
||||
title('flac.wav – After Notch Filtering');
|
||||
xlim([0 2000]); grid on;
|
||||
|
||||
%% === APPLY THE SAME FILTER TO sem2.wav ===
|
||||
fprintf('\n=== APPLYING DESIGNED FILTER TO sem2.wav ===\n');
|
||||
|
||||
[y_sem2, Fs_sem2] = audioread('sem2.wav');
|
||||
if size(y_sem2,2) > 1, y_sem2 = mean(y_sem2,2); end
|
||||
|
||||
if Fs_sem2 ~= Fs1
|
||||
warning('Sample rates differ – resampling sem2.wav to match notch filter design');
|
||||
y_sem2 = resample(y_sem2, Fs1, Fs_sem2);
|
||||
Fs_sem2 = Fs1;
|
||||
end
|
||||
|
||||
% --- Step 1: Apply multi‑notch filter from flac2 noise analysis ---
|
||||
y_sem2_notch = filtfilt(sos_all, g_all, y_sem2);
|
||||
|
||||
% --- Step 2 (optional): add band‑pass filter for speech 100‑8000 Hz ---
|
||||
[z_bp, p_bp, k_bp] = butter(4, [100 8000]/(Fs_sem2/2), 'bandpass');
|
||||
[sos_bp, g_bp] = zp2sos(z_bp, p_bp, k_bp);
|
||||
y_sem2_final = filtfilt(sos_bp, g_bp, y_sem2_notch);
|
||||
|
||||
% --- Normalize both versions ---
|
||||
y_sem2_notch = y_sem2_notch / (max(abs(y_sem2_notch)) + eps) * 0.95;
|
||||
y_sem2_final = y_sem2_final / (max(abs(y_sem2_final)) + eps) * 0.95;
|
||||
|
||||
% --- Save results ---
|
||||
audiowrite('sem2_notch_filtered.wav', y_sem2_notch, Fs_sem2);
|
||||
audiowrite('sem2_final.wav', y_sem2_final, Fs_sem2);
|
||||
fprintf('Saved:\n');
|
||||
fprintf(' sem2_notch_filtered.wav (notch filters only)\n');
|
||||
fprintf(' sem2_final.wav (notch + speech band‑pass)\n');
|
||||
|
||||
%% === VISUAL CHECK – BEFORE vs AFTER ===
|
||||
t_sem2 = (0:length(y_sem2)-1)/Fs_sem2;
|
||||
N_sem2 = length(y_sem2);
|
||||
f_sem2 = (0:N_sem2/2-1)*Fs_sem2/N_sem2;
|
||||
Y_orig = fft(y_sem2);
|
||||
Y_filt = fft(y_sem2_final);
|
||||
|
||||
figure;
|
||||
subplot(2,1,1);
|
||||
plot(t_sem2, y_sem2);
|
||||
xlabel('Time [s]'); ylabel('Amplitude');
|
||||
title('sem2.wav – Original Time Domain'); grid on;
|
||||
|
||||
subplot(2,1,2);
|
||||
plot(t_sem2, y_sem2_final, 'r');
|
||||
xlabel('Time [s]'); ylabel('Amplitude');
|
||||
title('sem2\_final.wav – After Notch + Band‑Pass'); grid on;
|
||||
|
||||
figure;
|
||||
subplot(2,1,1);
|
||||
plot(f_sem2, 20*log10(abs(Y_orig(1:N_sem2/2))+eps));
|
||||
xlabel('Frequency [Hz]'); ylabel('Magnitude [dB]');
|
||||
title('sem2.wav – Original Spectrum');
|
||||
xlim([0 2000]); grid on;
|
||||
|
||||
subplot(2,1,2);
|
||||
plot(f_sem2, 20*log10(abs(Y_filt(1:N_sem2/2))+eps), 'r');
|
||||
xlabel('Frequency [Hz]'); ylabel('Magnitude [dB]');
|
||||
title('sem2\_final.wav – After Filtering');
|
||||
xlim([0 2000]); grid on;
|
||||
Reference in New Issue
Block a user