Dans cet exercice, on étudie le spectre d’un signal musical réel ainsi que les effets d’une limitation de spectre sur son écoute.
Cet exercice peut être fait avec votre musique favorite au format WAV. À défaut, vous pouvez télécharger une musique libre de droits au lien suivant : https://www.free-stock-music.com/fsm-team-escp-enlia-take-me-to-the-moon.html
La première étape consiste à charger votre fichier dans Python grâce aux instructions suivantes.
from scipy.io import wavfile
fe, son = wavfile.read('nom_de_votre_fichier.wav')fe contient alors la fréquence d’échantillonnage du signal, et son contient les échantillons du signal audio.
La plupart des fichiers musicaux sont stéréo et contiennent donc deux canaux. La variable son est alors un tableau numpy avec deux colonnes, une pour chaque canal.
1/ Définir une variable signal qui contient le signal d’un seul canal (par exemple le canal gauche) du fichier audio.
s[i,j] pour la valeur de s à la i-ème ligne et la j-ème colonne.[:]signal = son[:, 0]2/ Tracer le signal en fonction du temps.
np.arange(N) qui génère un tableau de N valeurs allant de 0 à N-1.La première étape est de recréer le tableau des temps. La période d’échantillonnage est l’inverse de la fréquence d’échantillonnage. Les temps sont des valeurs espacées de la période d’échantillonnage et sont en même nombre que les points du signal.
import numpy as np
Te = 1 / fe
t = np.arange(len(signal)) * TeOn peut ensuite tracer le signal en fonction du temps grâce à la bibliothèque matplotlib.
import matplotlib.pyplot as plt
plt.figure("Signal")
plt.clf()
plt.plot(t, signal)
plt.xlabel('Temps (s)')
plt.ylabel('Amplitude')
plt.show()Pour écouter le signal audio dans Python, on peut utiliser la bibliothèque IPython.display comme suit :
from IPython.display import Audio, display
display(Audio(signal, rate=fe))3/ Calculer et tracer le spectre du signal audio en utilisant les fonctions np.fft.rfft et np.fft.rfftfreq. Le spectre sera stocké dans un tableau nommé spectre.
np.abs.Le spectre est calculé avec
spectre = np.fft.rfft(signal)
fréquences = np.fft.rfftfreq(len(signal), Te)On peut ensuite tracer le spectre en utilisant matplotlib.
plt.figure("Spectre")
plt.clf()
plt.plot(fréquences, np.abs(spectre), label='signal original')
plt.legend()
plt.xlabel('Fréquence (Hz)')
plt.ylabel('Amplitude')
plt.show()Les grandes ondes ont des bandes de de large.
4/ Calculer la fréquence maximale d’un signal émis sur les grandes ondes.
La largeur de bande est le double de la fréquence maximale d’où
5/ Pour simuler l’effet de ce filtrage, définir un tableau spectre_filtré qui correspond à spectre pour les fréquences inférieures à et nul pour les fréquences supérieures. spectre_filtré aura autant d’éléments que spectre.
np.copy. Parcourir le spectre original et mettre à zero pour les fréquences supérieures à .spectre_filtré = np.copy(spectre)
for i in range(len(spectre)):
if fréquences[i] > 9e3/2:
spectre_filtré[i] = 06/ Recomposer le signal temporel à partir du spectre filtré en utilisant np.fft.irfft. Écouter le son correspondant et le comparer au son non filtré.
signal_filtré = np.fft.irfft(spectre_filtré)
display(Audio(signal_filtré, rate=fe))L’altération du signal est perceptible, il parait moins précis et n’est pas fidèle à l’original.
7/ Reprendre les questions précédentes pour une diffusion sur la bande FM, avec un spectre audio limité à .
spectre_filtré_FM = np.copy(spectre)
for i in range(len(spectre)):
if fréquences[i] > 15e3:
spectre_filtré_FM[i] = 0
signal_filtré_FM = np.fft.irfft(spectre_filtré_FM)
display(Audio(signal_filtré_FM, rate=fe))L’altération du signal est imperceptible (par moi en tout cas), la diffusion en FM préserve mieux l’intégrité du signal.