Tp1
Objectif :
Comprendre l'effet de la decimation et de l'interpolation sur un signal audio, ainsi que
l'importance des filtres dans ces processus
Exercice1
import numpy as np ;import matplotlib.pyplot as plt ;from scipy.signal import resample_poly, firwin,
lfilter ;default_fs = 20000 # Fréquence d'échantillonnage ;D = 4 # Facteur de décimation ;L = 3 #
Facteur d'interpolation ;# Génération du signal ;n = np.arange(0, 200) # 200 échantillons ;y = np.sin(2
* np.pi * 1000 * n / default_fs) + 0.5 * np.sin(2 * np.pi * 3000 * n / default_fs) ;#
Décimation ;fs_decimated = default_fs / D ;fc = fs_decimated / 2 ;lowpass_filter = firwin(31, fc,
fs=default_fs, pass_zero=True) ;filtered_y = lfilter(lowpass_filter, 1, y) ;y_decimated =
filtered_y[::D] ;# Interpolation ;fs_interpolated = fs_decimated * L ;y_interpolated =
resample_poly(y_decimated, L, 1) ;N = len(y) ;freq_original = np.fft.fftfreq(len(y),
d=1/default_fs) ;spectrum_original = np.abs(np.fft.fft(y)) / N ;freq_decimated =
np.fft.fftfreq(len(y_decimated), d=1/fs_decimated) ;spectrum_decimated =
np.abs(np.fft.fft(y_decimated)) / N ;freq_interpolated = np.fft.fftfreq(len(y_interpolated_fir),
d=1/fs_interpolated) ;spectrum_interpolated = np.abs(np.fft.fft(y_interpolated_fir)) / N ;# Affichage
des spectres ;plt.figure() ;plt.plot(freq_original[:len(freq_original)//2],
spectrum_original[:len(spectrum_original)//2]) ;plt.title("Spectre du signal
original") ;plt.xlabel("Fréquence (Hz)") ;plt.ylabel("Amplitude") ;plt.grid() ;plt.figure()
;plt.plot(freq_decimated[:len(freq_decimated)//2],
spectrum_decimated[:len(spectrum_decimated)//2]) ;plt.title("Spectre après
décimation") ;plt.xlabel("Fréquence
(Hz)") ;plt.ylabel("Amplitude") ;plt.grid() ;plt.figure() ;plt.plot(freq_interpolated[:len(freq_interpolate
d)//2], spectrum_interpolated[:len(spectrum_interpolated)//2]) ;plt.title("Spectre après
interpolation") ;plt.xlabel("Fréquence (Hz)") ;plt.ylabel("Amplitude") ;plt.grid() ;plt.show()
Questions
1. Quelle est la Fréquence d’échantillonnage après décimation
2. Quelle est la Fréquence d’échantillonnage après interpolation
3. Pourquoi filtrer avant la décimation ?
4. Donner le type de filtre et la fréquence de coupure
5. Pourquoi filtrer après interpolation ?
6. Quelle est l’effet d'un filtre idéal après interpolation
7. Donner vos remarques sur les spectres obtenus. Quelle est le problème qui se pose et
pourquoi. Donner la solution
Exercice 2
Nous disposons d'un fichier audio "vousavezducourrierenattente.wav", dont nous allons
modifier la frequence d'echantillonnage en appliquant des operations de decimation et
d'interpolation.
1. Analyser et expliquer le fonctionnement du programme 1.
2. Analyser l'impact des filtres sur la qualite du son obtenu.
3. Dans le programme 2, quel est l’interet du programme et quelle est la difference entre
les parties Cas 1 et Cas 2 ?
Programme 1
import numpy as np ;import matplotlib.pyplot as plt ;import scipy.signal as sp
from scipy.io import wavfile as wf ;import winsound
# Charger le fichier audio
fname = "vousavezducourrierenattente.wav" ;fe, x = wf.read(fname)
# Temps associe
Te = 1 / fe ;N = len(x) ;t = np.arange(N) * Te
def play_sound(signal, fs, msg, filename="temp_sound.wav"):
print(msg)
# Normaliser le signal pour eviter l'ecretage
signal_norm = np.int16(signal / np.max(np.abs(signal)) * 32767)
# Sauvegarder temporairement le fichier WAV
wf.write(filename, fs, signal_norm)
# Lire le fichier avec winsound
winsound.PlaySound(filename, winsound.SND_FILENAME)
# JOUER LE SIGNAL ORIGINAL
play_sound(x, fe, " Lecture du signal original")
D = 2 ;x_decimated = x[::D]
# JOUER LE SIGNAL DECIME
play_sound(x_decimated, fe // D, " Lecture apres decimation sans filtrage")
# Filtrage anti-repliement avant decimation
fc =(fe // (2 * D));b, a =sp.butter(4, fc / (fe / 2), btype='low') ;x_filtered = sp.filtfilt(b, a, x)
x_decimated_filtered = x_filtered[::D]
# JOUER LE SIGNAL DECIME FILTRE
play_sound(x_decimated_filtered, fe // D, " Lecture apres decimation avec filtrage")
# INTERPOLATION
L = 2 ;x_interpolated = np.zeros(L * len(x_decimated)) ;x_interpolated[::L] = x_decimated
# JOUER LE SIGNAL INTERPOLE
play_sound(x_interpolated, fe, " Lecture apres interpolation sans filtrage")
# Filtrage apres interpolation
b, a = sp.butter(4, 0.5, btype='low') ;x_interpolated_filtered = sp.filtfilt(b, a, x_interpolated)
# JOUER LE SIGNAL INTERPOLE FILTRE
play_sound(x_interpolated_filtered, fe, " Lecture apres interpolation avec filtrage")
Programme2
import numpy as np ;import matplotlib.pyplot as plt ;import scipy.signal as sp
from scipy.io import wavfile as wf ;import winsound
# Charger le fichier audio
fname = "vousavezducourrierenattente.wav" ;fe, x = wf.read(fname)
Te = 1 / fe ;N = len(x) ;t = np.arange(N) * Te
# Fonction pour jouer un son
def play_sound(signal, fs, msg, filename="temp_sound.wav"):
print(msg)
signal_norm = np.int16(signal / np.max(np.abs(signal)) * 32767)
wf.write(filename, fs, signal_norm)
winsound.PlaySound(filename, winsound.SND_FILENAME)
# JOUER LE SIGNAL ORIGINAL
play_sound(x, fe, " Lecture du signal original")
### CAS 1
D = 2 ;fc = fe / (2 * D) ;b, a = sp.butter(4, fc / (fe / 2), btype='low') ;x_filtered = sp.filtfilt(b, a, x)
;x_decimated = x_filtered[::D]
play_sound(x_decimated, fe // D, " Lecture apres decimation avec filtrage")
L = 3 ;x_interpolated = np.zeros(L * len(x_decimated)) ;x_interpolated[::L] = x_decimated
b, a = sp.butter(4, 0.5, btype='low') ;x_interpolated_filtered = sp.filtfilt(b, a, x_interpolated)
play_sound(x_interpolated_filtered, int(fe * 1.5), " Lecture apres interpolation avec filtrage")
### CAS 2
L = 3 ;D = 2 ;x_interpolated2 = np.zeros(L * len(x)) ;x_interpolated2[::L] = x
b, a = sp.butter(4, 0.5, btype='low') ;x_interpolated_filtered2 = sp.filtfilt(b, a, x_interpolated2)
;x_final = x_interpolated_filtered2[::D]
play_sound(x_final, int(fe * 1.5), " Lecture apres interpolation puis decimation")
Exercice 3
Soit le programme suivant
import numpy as np ;import matplotlib.pyplot as plt ;from scipy.io import wavfile ;from
scipy.signal import resample_poly ;from scipy.fftpack import fft ;# Charger le fichier
audio ;file_path = "youhavealotofwork.wav" ;fs, signal = wavfile.read(file_path) ;up_factor =
147 ;down_factor = 160 ;# Appliquer l'interpolation et la decimation ;signal_resampled =
resample_poly(signal, up_factor, down_factor) ;fs_resampled = fs * up_factor / down_factor #
Nouvelle frequence d'echantillonnage ;# Calcul du temps ;t_original = np.linspace(0, len(signal) /
fs, len(signal), endpoint=False) ;t_resampled = np.linspace(0, len(signal_resampled) /
fs_resampled, len(signal_resampled), endpoint=False)
print(f"Nombre d'echantillons (original) : {len(signal)}")
print(f"Nombre d'echantillons (reechantillonne) : {len(signal_resampled)}")
print(f"Duree originale : {len(signal) / fs:.3f} s")
print(f"Duree apres reechantillonnage : {len(signal_resampled) / fs_resampled:.3f} s")
# Tracer les signaux temporels
plt.figure(figsize=(10, 6)) ;plt.subplot(2, 1, 1) ;plt.plot(t_original[:1000], signal[:1000],
label="Signal original") ;plt.plot(t_resampled[:1000], signal_resampled[:1000], label="Signal
reechantillonne", linestyle="--") ;plt.title("Comparaison dans le domaine
temporel") ;plt.xlabel("Temps (s)") ;plt.ylabel("Amplitude") ;plt.legend() ;
# Comparaison dans le domaine frequentiel
fft_original = np.abs(fft(signal)) ;fft_resampled = np.abs(fft(signal_resampled)) ;freq_original =
np.fft.fftfreq(len(fft_original), 1 / fs) ;freq_resampled = np.fft.fftfreq(len(fft_resampled), 1 /
fs_resampled) ;plt.subplot(2, 1, 2) ;plt.plot(freq_original[:len(fft_original)//2],
fft_original[:len(fft_original)//2], label="Spectre original")
;plt.plot(freq_resampled[:len(fft_resampled)//2], fft_resampled[:len(fft_resampled)//2],
label="Spectre reechantillonne", linestyle="--") ;plt.title("Comparaison dans le domaine
frequentiel") ;plt.xlabel("Frequence (Hz)") ;plt.ylabel("Amplitude (spectre)") ;plt.legend()
;plt.tight_layout() ;plt.show()
Questions :
1. Pourquoi utilise-t-on la fonction resample_poly pour le reechantillonnage du signal ?
2. Quelle est l'importance des facteurs up_factor = 147 et down_factor = 160 dans la
conversion de la frequence d'echantillonnage ?
3. Quelle est la difference entre la comparaison temporelle et la comparaison
frequentielle effectuee dans ce code ?