diff --git a/ANNEXE_CODES_Matlab.m b/ANNEXE_CODES_Matlab.m new file mode 100644 index 0000000000000000000000000000000000000000..286ef5654b8cf7568fe9eefcd2186e1c70c066c0 --- /dev/null +++ b/ANNEXE_CODES_Matlab.m @@ -0,0 +1,620 @@ +%% SYNTHÈSE ADDITIVE + +% Question 1.1 : +% filename = '/Users/alexandredherissart/Desktop/SAR Audio/single_tone_clarinet-a3.wav'; +% figureTitle = 'Spectre en amplitude de clarinette'; +% plotColor = [1, 0.5, 0]; +% +% [x, fe] = audioread(filename); +% if size(x,2) > 1 +% x = x(:,1); +% end +% N = length(x); +% +% X = fft(x); +% Xs = fftshift(X); +% f = linspace(-fe/2, fe/2, N); +% A_dB = 20*log10(abs(Xs) + eps); +% +% % Recherche de la fréquence fondamentale +% [~, idx_max] = max(abs(Xs)); +% f1 = abs(f(idx_max)); +% +% figure; +% plot(f, A_dB, 'Color', plotColor, 'LineWidth', 1.5); +% grid on; +% title(figureTitle, 'Interpreter', 'none'); +% xlabel('Fréquence (Hz)'); +% ylabel('Amplitude (dB)'); +% hold on; +% +% % Annotation de la fréquence fondamentale +% yl = ylim; +% plot([f1 f1], yl, '--k', 'LineWidth', 1); +% text(f1, yl(2)-5, sprintf('f1 = %.2f Hz', f1), ... +% 'HorizontalAlignment', 'left', 'BackgroundColor', 'w', 'EdgeColor', 'k'); +% +% hold off; + +% Question 1.2 +% nmax = 8; +% pct = 0.05; +% +% [x1, fs] = audioread('/Users/alexandredherissart/Desktop/SAR Audio/single_tone_piano1.wav'); +% [x2, ~ ] = audioread('/Users/alexandredherissart/Desktop/SAR Audio/single_tone_piano2.wav'); +% +% Nfft = 2^nextpow2( max(length(x1), length(x2)) ); +% X1 = fftshift( fft(x1, Nfft) ); +% X2 = fftshift( fft(x2, Nfft) ); +% f = linspace(-fs/2, fs/2, Nfft); +% +% figure; +% plot(f, 20*log10(abs(X1)), 'b'); hold on; +% plot(f, 20*log10(abs(X2)), 'r'); +% xlabel('Hz'); +% ylabel('dB'); +% legend('Piano 1','Piano 2'); +% title('Spectres comparés de piano1 et piano2'); +% +% pos = f >= 0; +% [fmax1, idx1] = max(abs(X1(pos))); +% [fmax2, idx2] = max(abs(X2(pos))); +% fp = f(pos); +% f1_1 = fp(idx1); +% f1_2 = fp(idx2); +% +% fh1 = zeros(1,nmax); +% fh2 = zeros(1,nmax); +% for n = 1:nmax +% % Piano 1 +% mask1 = (f > n*f1_1*(1-pct)) & (f < n*f1_1*(1+pct)); +% [~, k1] = max(abs(X1(mask1))); +% idx_m1 = find(mask1); +% fh1(n) = f(idx_m1(k1)); +% % Piano 2 +% mask2 = (f > n*f1_2*(1-pct)) & (f < n*f1_2*(1+pct)); +% [~, k2] = max(abs(X2(mask2))); +% idx_m2 = find(mask2); +% fh2(n) = f(idx_m2(k2)); +% end +% +% n = 1:nmax; +% xi1 = 1200 * log2( fh1 ./ (n * f1_1) ); +% xi2 = 1200 * log2( fh2 ./ (n * f1_2) ); +% +% rms1 = sqrt(mean(xi1.^2)); +% rms2 = sqrt(mean(xi2.^2)); +% fprintf('\nRMS inharmonicité Piano1 : %.2f \n', rms1); +% fprintf('RMS inharmonicité Piano2 : %.2f \n', rms2); +% +% if rms1 < rms2 +% fprintf('\n=> Le piano 1 est plus harmonieux .\n'); +% else +% fprintf('\n=> Le piano 2 est plus harmonieux .\n'); +% end + +% Question 1.3 : +% filename = '/Users/alexandredherissart/Desktop/SAR Audio/single_tone_piano1.wav'; +% nmax = 8; +% win_rel = 0.05; +% +% [x, fs] = audioread(filename); +% x = x(:,1); +% N = length(x); +% Nfft = 2^nextpow2(N); +% X = fft(x, Nfft); +% Xs = fftshift(X); +% f = linspace(-fs/2, fs/2, Nfft); +% +% % Détection de la fondamentale +% pos = (f >= 0); +% [~, ix0] = max(abs(Xs(pos))); +% fp = f(pos); +% f1 = fp(ix0); +% +% A = zeros(nmax,1); +% for n = 1:nmax +% f0 = n*f1; +% mask = (f >= f0*(1-win_rel)) & (f <= f0*(1+win_rel)); +% [~, loc] = max(abs(Xs(mask))); +% idx = find(mask); +% idx_pk = idx(loc); +% A(n) = 2*abs(Xs(idx_pk)) / Nfft; +% end +% +% % Synthèse additive +% t = (0:N-1)/fs; +% x_synth = zeros(size(t)); +% for n = 1:nmax +% x_synth = x_synth + A(n)*sin(2*pi*n*f1*t); +% end +% +% % Écoute et sauvegarde +% sound(x_synth, fs); +% audiowrite('synth_piano1.wav', x_synth, fs); + +% Question 1.4 +% [y, fs] = audioread('/Users/alexandredherissart/Desktop/SAR Audio/synth_piano1.wav'); +% N = length(y); +% +% A = round(0.1 * N); % Attack = 10% +% D = round(0.1 * N); % Decay = 10% +% R = round(0.1 * N); % Release= 10% +% S = N - (A + D + R); % Sustain +% +% % Enveloppe +% env = [ ... +% linspace(0, 1, A), ... +% linspace(1, 0.7, D), ... +% 0.7 * ones(1, S), ... +% linspace(0.7, 0, R) ... +% ]; +% +% y_env = y(1:length(env)) .* env'; +% +% t2 = (0:length(env)-1)/fs; +% figure; +% subplot(2,1,1); +% plot(t2, env, 'LineWidth',1.2); +% grid on; +% title('Enveloppe ADSR simple'); +% xlabel('Temps (s)'); +% ylabel('Amplitude enveloppe'); +% +% subplot(2,1,2); +% plot(t2, y_env); +% grid on; +% title('Signal synthétisé avec ADSR'); +% xlabel('Temps (s)'); +% ylabel('Amplitude signal'); +% +% soundsc(y_env, fs); +% audiowrite('synth_ADSR_piano1.wav', y_env, fs); + +% Question 1.5 : +% filename = '/Users/alexandredherissart/Desktop/SAR Audio/single_tone_piano1.wav'; +% nmax = 8; +% win_rel = 0.05; +% +% [x, fs] = audioread(filename); +% x = x(:,1); +% N = length(x); +% Nfft = 2^nextpow2(N); +% X = fft(x, Nfft); +% Xs = fftshift(X); +% f = linspace(-fs/2, fs/2, Nfft); +% +% % Détection de la fondamentale +% pos = (f >= 0); +% [~, idx0] = max(abs(Xs(pos))); +% fp = f(pos); +% f1 = fp(idx0); +% +% % Méthode 1 : Synthèse par IFFT +% Ys_trunc = zeros(size(Xs)); +% for n = 1:nmax +% f0 = n * f1; +% mask = abs(f - f0) <= f0 * win_rel; +% idx_pos = find(mask, 1, 'first'); +% idx_neg = Nfft - idx_pos + 1; +% Ys_trunc(idx_pos) = Xs(idx_pos); +% Ys_trunc(idx_neg) = Xs(idx_neg); +% end +% Y_trunc = ifftshift(Ys_trunc); +% y_ifft = real(ifft(Y_trunc, Nfft)); +% y_ifft = y_ifft(1:N); +% +% % Méthode 2 : Synthèse additive +% A = zeros(nmax,1); +% for n = 1:nmax +% f0 = n * f1; +% mask = (f >= f0*(1-win_rel)) & (f <= f0*(1+win_rel)); +% [~, loc] = max(abs(Xs(mask))); +% idx = find(mask); +% A(n) = 2*abs(Xs(idx(loc))) / Nfft; +% end +% +% t = (0:N-1)/fs; +% x_synth = zeros(size(t)); +% for n = 1:nmax +% x_synth = x_synth + A(n) * sin(2*pi*n*f1*t); +% end +% +% figure; +% subplot(3,1,1); +% plot(t, x); +% title('Signal original'); +% xlabel('Temps (s)'); ylabel('Amplitude'); grid on; +% +% subplot(3,1,2); +% plot(t, y_ifft); +% title('Synthèse IFFT (8 harmoniques)'); +% xlabel('Temps (s)'); ylabel('Amplitude'); grid on; +% +% subplot(3,1,3); +% plot(t, x_synth); +% title('Synthèse additive (8 harmoniques)'); +% xlabel('Temps (s)'); ylabel('Amplitude'); grid on; +% +% % Écoute et sauvegarde +% soundsc(y_ifft, fs); +% audiowrite('synth_ifft_8harm.wav', y_ifft, fs); +% +% sound(x_synth, fs); +% audiowrite('synth_additive_8harm.wav', x_synth, fs); + + +%% SYNTHÈSE SOUSTRACTIVE + +% Question 2.1 : +% fs = 8000; +% f0 = 440; +% t = 0:1/fs:2/f0; +% +% % signaux +% x_sq = square(2*pi*f0*t); +% x_sd = sawtooth(2*pi*f0*t); +% +% % spectres +% Nfft = 1024; +% f = linspace(-fs/2, fs/2, Nfft); +% Xsq = fftshift(fft(x_sq, Nfft)); +% Xsd = fftshift(fft(x_sd, Nfft)); +% +% figure; +% subplot(2,2,1); +% plot(t, x_sq); +% title('Signal carré'); xlabel('Temps (s)'); ylabel('Amplitude'); +% grid on; +% +% subplot(2,2,2); +% plot(t, x_sd); +% title('Signal dent de scie'); xlabel('Temps (s)'); ylabel('Amplitude'); +% grid on; +% +% S = abs(fft(x_sq)); +% D = abs(fft(x_sd)); +% f = (0:N-1)*fs/N; +% +% figure; +% subplot(2,1,1); +% stem(f(1:10), S(1:10)); +% title('Spectre signal carré'); xlabel('Hz'); ylabel('|S|'); +% +% subplot(2,1,2); +% stem(f(1:10), D(1:10)); +% title('Spectre dent de scie'); xlabel('Hz'); ylabel('|D|'); + +% Question 2.2 : +% fs = 8000; +% f0 = 440; +% t = 0:1/fs:2/f0; +% Nfft = 1024; +% +% x_sq = square(2*pi*f0*t); +% x_sd = sawtooth(2*pi*f0*t); +% +% % Définition du filtre y[k] +% b = [1 1]/2; +% a = 1; +% +% % Spectres d’entrée +% f = linspace(-fs/2, fs/2, Nfft); +% Xsq = fftshift(fft(x_sq, Nfft)); +% Xsd = fftshift(fft(x_sd, Nfft)); +% +% % Réponse théorique du filtre +% w = 2*pi * f / fs; +% Hth = (1 + exp(-1j*w)) / 2; +% Hmag = abs(Hth); +% +% % Spectres de sortie théoriques (|H|·|X|) +% Ysq_th = Hmag .* abs(Xsq); +% Ysd_th = Hmag .* abs(Xsd); +% +% % Simulation par filtrage et FFT des sorties +% y_sq = filter(b, a, x_sq); +% y_sd = filter(b, a, x_sd); +% Ysq_im = fftshift(fft(y_sq, Nfft)); +% Ysd_im = fftshift(fft(y_sd, Nfft)); +% +% figure; +% +% % Carré +% subplot(2,1,1); +% plot(f, 20*log10(Ysq_th + eps), 'k-', 'LineWidth',1.3); hold on; +% plot(f, 20*log10(abs(Ysq_im) + eps), 'r--','LineWidth',1.2); +% xlim([-3000 3000]); +% xlabel('Fréquence (Hz)'); +% ylabel('Amplitude (dB)'); +% title('Signal carré filtré : théorie vs simulation'); +% legend('Théorique |H|\cdot|X|','Simulation filter→FFT','Location','Best'); +% grid on; +% +% % Dent de scie +% subplot(2,1,2); +% plot(f, 20*log10(Ysd_th + eps), 'k-', 'LineWidth',1.3); hold on; +% plot(f, 20*log10(abs(Ysd_im) + eps), 'r--','LineWidth',1.2); +% xlim([-3000 3000]); +% xlabel('Fréquence (Hz)'); +% ylabel('Amplitude (dB)'); +% title('Signal dent de scie filtré : théorie vs simulation'); +% legend('Théorique |H|\cdot|X|','Simulation filter→FFT','Location','Best'); +% grid on; + +% Question 2.3 : +% fs = 8000; +% f0 = 440; +% T = 1; +% t = 0:1/fs:T-1/fs; +% +% % Enveloppe ADSR identique pour tous +% A = round(0.1*fs); +% D = round(0.1*fs); +% R = round(0.1*fs); +% S = length(t) - (A+D+R); +% env = [linspace(0,1,A), ... +% linspace(1,0.7,D), ... +% 0.7*ones(1,S), ... +% linspace(0.7,0,R)]; +% +% x_sq = square(2*pi*f0*t); +% x_sd = sawtooth(2*pi*f0*t); +% +% % Synthèse soustractive (filtre passe-bas) +% b = [1 1]/2; a = 1; +% y_sq_sub = filter(b,a, x_sq .* env); +% y_sd_sub = filter(b,a, x_sd .* env); +% +% % Synthèse additive +% y_sq_add = zeros(size(t)); +% for n = 1:10 +% y_sq_add = y_sq_add + (4/(pi*(2*n-1))) * sin(2*pi*(2*n-1)*f0*t); +% end +% y_sq_add = y_sq_add .* env; +% +% y_sd_add = zeros(size(t)); +% for n = 1:10 +% y_sd_add = y_sd_add + (2/(pi*n)) * (-1)^(n+1) * sin(2*pi*n*f0*t); +% end +% y_sd_add = y_sd_add .* env; +% +% soundsc(y_sq_sub, fs); pause(T+0.5); +% soundsc(y_sd_sub, fs); pause(T+0.5); +% soundsc(y_sq_add, fs); pause(T+0.5); +% soundsc(y_sd_add, fs); +% +% figure('Position',[100 100 900 600]); +% subplot(2,2,1); +% plot(t, y_sq_sub); title('Soustractive – Carré'); xlabel('Temps (s)'); ylabel('Amplitude'); +% subplot(2,2,2); +% plot(t, y_sd_sub); title('Soustractive – Scie'); xlabel('Temps (s)'); +% subplot(2,2,3); +% plot(t, y_sq_add); title('Additive – Carré'); xlabel('Temps (s)'); +% subplot(2,2,4); +% plot(t, y_sd_add); title('Additive – Scie'); xlabel('Temps (s)'); + +% Question 2.4 : +% fs = 8000; +% f0 = 440; +% T = 1; +% t = 0:1/fs:T-1/fs; +% A = round(0.1*fs); D = A; R = A; S = length(t)-(A+D+R); +% env = [linspace(0,1,A), linspace(1,0.7,D), 0.7*ones(1,S), linspace(0.7,0,R)]; +% +% x = square(2*pi*f0*t).*env; +% +% d_fir4 = designfilt('lowpassfir', ... +% 'FilterOrder',4, ... +% 'CutoffFrequency',2000, ... +% 'SampleRate',fs); +% +% d_fir16 = designfilt('lowpassfir', ... +% 'FilterOrder',16, ... +% 'CutoffFrequency',1500, ... +% 'SampleRate',fs); +% +% [bb2, aa2] = butter(2, 0.25); +% +% [bc4, ac4] = cheby2(4, 40, 0.2); +% +% filterAnalyzer( d_fir4, ... +% d_fir16, ... +% bb2, aa2, ... +% bc4, ac4 ); + + +%% EFFETS AUDIO-NUMÉRIQUES + +% Certaines questions ne figurent pas ici étant donné que l'entièreté du +% code est donnée sur le livrable + +% Question 3.3 : +% xe1 = randn(1, 1000); +% xe2_full = conv(rectwin(200), rectwin(200)); +% xe2 = xe2_full(1:min(1000, length(xe2_full))); +% xe2 = xe2 / max(abs(xe2)); +% +% % Autocorrélations normalisées +% r1 = xcorr(xe1, 'coeff'); +% r2 = xcorr(xe2, 'coeff'); +% +% lags1 = (-length(xe1)+1):(length(xe1)-1); +% lags2 = (-length(xe2)+1):(length(xe2)-1); +% fs = 44100; +% t1 = lags1 / fs; +% t2 = lags2 / fs; +% +% % Largeur à -3 dB +% idx1 = find(r1 >= 0.5); +% idx2 = find(r2 >= 0.5); +% L1 = (idx1(end) - idx1(1)) / fs; +% L2 = (idx2(end) - idx2(1)) / fs; +% +% figure; +% +% subplot(2,1,1); +% plot(t1, r1, 'b'); grid on; +% xlabel('Décalage (s)'); ylabel('R_{x_1x_1}'); +% title('Autocorrélation normalisée de xe1'); +% text(0.01, 0.8, sprintf('largeur_{R1 @0.5} = %.5f s', L1), 'BackgroundColor','w'); +% +% subplot(2,1,2); +% plot(t2, r2, 'r'); grid on; +% xlabel('Décalage (s)'); ylabel('R_{x_2x_2}'); +% title('Autocorrélation normalisée de xe2'); +% text(0.01, 0.8, sprintf('largeur_{R2 @0.5} = %.5f s', L2), 'BackgroundColor','w'); + +% Question 3.4 : +% data = load('/Users/alexandredherissart/Desktop/SAR Audio/signal_excitation.mat'); +% xe = data.xe1; +% fs = data.fe; +% +% % Simulation de la propagation dans la pièce +% ye = simule_piece(xe, fs); +% +% [Ryx, lags] = xcorr(ye, xe); +% +% idx = (lags >= 0); +% h_est = Ryx(idx); +% t = lags(idx) / fs; +% h_est = h_est / max(abs(h_est)); +% +% figure; +% plot(t, h_est, 'LineWidth',1.5); +% grid on; +% xlabel('Temps (s)'); +% ylabel('Amplitude normalisée'); +% title('Réponse impulsionnelle estimée via corrélation croisée'); +% xlim([0 t(end)]); + +% Question 3.12 : +% Fe = 44100; +% +% % Parametres du delay +% tau_s = 0.25; +% g = 0.9; +% +% tau = round(tau_s * Fe); +% +% % Coefficients du filtre de Delay +% b = 1; +% a = [1, zeros(1, tau-1), g]; +% +% N_imp = 5 * tau; +% imp = [1; zeros(N_imp, 1)]; +% +% % Application du filtre pour obtenir h[k] +% h = filter(b, a, imp); +% +% k = (0:length(h)-1) / Fe; +% figure; +% stem(k, h, 'filled'); +% grid on; +% xlabel('Temps (s)'); +% ylabel('h(k)'); +% title('Reponse impulsionnelle du filtre de delay (\tau = 0.25s, g = 0.9)'); + +% Question 3.14 : +% load('h_delay.mat','h'); +% Fe = 44100; +% +% % FFT +% NFFT = 2^nextpow2(length(h)*4); +% f = (0:NFFT/2)*(Fe/NFFT); +% +% H_num = fft(h, NFFT); +% H_num = abs(H_num(1:NFFT/2+1)); +% +% % Reponse theorique du delay +% tau = round(0.25 * Fe); +% g = 0.9; +% w = 2*pi*f/Fe; +% H_th = 1 ./ sqrt(1 + 2*g*cos(w*tau) + g^2); +% +% figure; +% plot(f, 20*log10(H_th+eps), 'k-', 'LineWidth',1.5); hold on; +% plot(f, 20*log10(H_num+eps), 'r--','LineWidth',1.2); +% grid on; +% xlim([0 25]); +% xlabel('Frequence (Hz)'); +% ylabel('Gain (dB)'); +% title('Reponse frequentielle du filtre de delay : theorie vs FFT'); +% legend('Theorique','Par FFT de h','Location','Best'); + +% Question 3.15 : +% function y = effet_delay(x, tau, g, Fe) +% % vecteurs de coefficients pour filter +% b = 1; +% a = [1, zeros(1, tau-1), g]; +% +% % application du filtre IIR +% y = filter(b, a, x); +% end + +% Question 3.16 : +% [x, Fe] = audioread('/Users/alexandredherissart/Desktop/SAR Audio/piano_chord.wav'); +% +% tau_s = 0.25; +% tau = round(tau_s * Fe); +% g = 0.9; +% +% % Application de l'effet delay +% y_delay = effet_delay(x, tau, g, Fe); +% +% % Lecture des sons +% soundsc(x, Fe); +% pause(length(x)/Fe + 0.5); % signal sec +% soundsc(y_delay, Fe); % signal avec delay +% +% % Affichage des signaux +% t = (0:length(x)-1)/Fe; % axe temporel +% +% figure; +% subplot(2,1,1); +% plot(t, x); +% title('Signal original'); +% xlabel('Temps (s)'); +% ylabel('Amplitude'); +% +% subplot(2,1,2); +% plot(t, y_delay); +% title('Signal avec effet delay'); +% xlabel('Temps (s)'); +% ylabel('Amplitude'); + +% Question 3.18 : +% [x, Fe] = audioread('/Users/alexandredherissart/Desktop/SAR Audio/piano_chord.wav'); +% +% % Parametres du delay +% tau_s = 0.25; +% tau = round(tau_s * Fe); +% g = 0.9; +% K = 10; +% +% % Application de l'effet +% y_del_filt = effet_delay_filtre(x, tau, g, K, Fe); +% +% soundsc(x, Fe); +% pause(length(x)/Fe + 0.5); +% soundsc(y_del_filt, Fe); +% +% audiowrite('piano_chord_delay_filtre.wav', y_del_filt, Fe); + +% Question 3.19 : +% [x, Fe] = audioread('/Users/alexandredherissart/Desktop/SAR Audio/piano_chord.wav'); +% +% % Paramètres du delay +% tau_s = 0.25; +% tau = round(tau_s * Fe); +% g = 0.9; +% K = 10; +% +% % Application de l’effet +% y_del_filt = effet_delay_filtre(x, tau, g, K, Fe); +% +% soundsc(x, Fe); +% pause(length(x)/Fe + 0.5); +% soundsc(y_del_filt, Fe); +% +% audiowrite('piano_chord_delay_filtre.wav', y_del_filt, Fe); diff --git a/Livrable_Signal-DHERISSART-LELUAN.pdf b/Livrable_Signal-DHERISSART-LELUAN.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f98ca1c4a50097981b81a6cf18fc9a5091a51942 Binary files /dev/null and b/Livrable_Signal-DHERISSART-LELUAN.pdf differ