sem2 done

This commit is contained in:
Priec
2025-12-07 00:10:47 +01:00
parent d94c92eead
commit 262a0f2bbe
7 changed files with 1453 additions and 0 deletions

198
semestralka2/final.m Normal file
View 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 multinotch filter from flac2 noise analysis ---
y_sem2_notch = filtfilt(sos_all, g_all, y_sem2);
% --- Step 2 (optional): add bandpass filter for speech 1008000 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 bandpass)\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 + BandPass'); 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;