Entraînez-vous en construisant un algorithme de compression sonore

À vous de jouer !

Pour vous entraîner, réalisez cet exercice étape par étape. Une fois terminé, vous pouvez comparer votre travail avec les pistes que je vous propose.

Dans cette activité, vous allez :

  • Construire votre propre algorithme de compression sonore !
  • Construire l'algorithme de décompression associé.

Esquisse générale de l'algorithme

L'idée générale de l'algorithme de compression sonore que vous allez inventer est la suivante :

  • Plutôt que d'écrire les valeurs du signal temporel, vous allez écrire les valeurs fréquentielles. Vous allez créer un script "encodage.m" qui fait cela.
  • Le signal sera reconstruit à partir de sa TF par le script "decodage.m" que vous allez écrire.
  • Comme beaucoup de valeurs des spectres sont nulles ou presque, vous n'allez écrire que les valeurs non nulles.
  • Au final, on espère que le fichier qui contient ces informations prendra moins de place que l'original.

Voici des instructions plus détaillées.

Acquisition du signal

Vous trouverez le fichier sonore à traiter ici.

Ce fichier sonore n'est pas du tout compressé, c'est-à-dire qu'il contient toute l'information sur l'amplitude de variation du haut parleur à n'importe quel moment du temps. Ces informations sont mises sous la forme d'une suite de nombre (un signal), au format texte. Vous pouvez d'ailleurs l'ouvrir avec un éditeur de texte (attention, si vous l'ouvrez avec le Bloc-notes, cela peut prendre beaucoup de temps étant donné la taille du fichier. Préférez un éditeur spécialisé pour le code comme Notepad++ sous Windows par exemple).

Si vous faites un clic droit sur ce fichier, vous constaterez que sa taille est de 5.5 Mo. 

Définition des paramètres utiles pour le script "encodage.m"

La fréquence d'échantillonnage vous est donnée : elle vaut 44100 Hz.

  • Que vaut la période d'échantillonnage ? Appellez-la Te.
  • Combien y a-t-il de points dans le signal ? Appelez le N.
  • Construisez l'espace des fréquences. Appelez le freq. Faites-en un vecteur colonne (et non pas une ligne).

Actions sur le spectre

  • Calculez la transformée de Fourier du signal. Appelez-la TF_son.
  • Tracez le spectre en annotant les axes.

Vous remarquerez plusieurs choses, premièrement le spectre est symétrique. Cela est dû à deux choses: le signal est réel, et il n'est pas continu (il est échantillonné). Ce phénomène est difficile à expliquer sans la théorie de l'échantillonnage que vous n'avez pas vue.

Le point important à remarquer est que le spectre est symétrique, cela signifie donc qu'il ne sera pas nécessaire de tout enregistrer, une moitié suffira !


Attention : On pourrait penser que l'on vient de diviser par deux la taille du signal, mais c'est aller un peu vite en besogne.
En effet ce que vous allez écrire dans votre fichier, ce sera les valeurs de la TF qui sont des nombres complexes, c'est-à-dire qu'ils sont deux fois plus gros (un nombre complexe, c'est deux nombre réels) qu'un nombre normal (réel). On n'a donc pour l'instant rien gagné.

  • Fabriquez TF_half et freq_half, qui ne contient qu'une moitié du spectre.
  • Fabriquez un vecteur colonne appelé indices, qui contient des valeurs allant de 1 à N, espacés de 1.
  • Fabriquez deux vecteurs l'un appelé indices_non_nuls et l'autre valeurs_non_nulles qui contient les indices des fréquences à garder ainsi que les valeurs de la TF où le spectre est non nul.
  • Choisissez et commentez la valeur du seuil qui déterminera si le spectre est quasi nul ou non.

Écriture du fichier compressé

  • Séparez partie réelle et partie imaginaire de valeurs_non_nulles  en deux tableaux.
  • Enregistrez au format ascii (texte) les infos dont vous avez besoin.
Pour enregistrer les vecteurs colonnes a, b et c dans un fichier texte, utilisez la commande :
tosave = [a b c]; tosave = single(tosave);
%on change le type des nombres de double vers single (16 bits au lieu de 32 bits, nous n'avons pas besoin de beaucoup de chiffres significatifs) save('nom_du_fichier.txt','tosave','-ascii');

  • Le fichier obtenu est-il plus petit que le fichier original ? Si non, changez la valeur de votre seuil jusqu'à ce qu'il le soit.

Décodage

Dans cette partie, vous allez faire le chemin inverse de ce que vous avez fait dans "encodage.m".

Vous avez le droit de connaître a priori :

  • La fréquence échantillonnage (Fe = 44100)
  • Le nombre de points du fichier original N (on pourrait imaginer mettre cette information dans un header du fichier compressé).

Créez un nouveau script, qui lui aussi commence par :

clear all; close all; clc;
% Nettoie l'espace mémoire, ferme les fenêtres et vide l'invité de commande


  • Chargez le fichier 'son_compresse.txt'.
  • Reconstruisez la transformée de Fourier complète. Notez que vous n'êtes pas obligé de rendre le signal symétrique à nouveau.
  • Reconstruisez le signal temporel avec une fft inverse. Si votre signal contient des valeurs imaginaires, ne gardez que la partie réelle.
  • Jouez le signal obtenu avec la commande suivante : sound(votreson, Frequence_echantillonnage)

Analyse qualitative des résultats

  • Commentez la qualité auditive de votre résultat.
  • Déterminez comment évolue la qualité auditive du son lorsque vous augmentez ou diminuez la valeur du seuil.
  • Déterminez la valeur du seuil nécessaire pour que le son du violon ne soit plus reconnaissable. Quelle taille fait le fichier compressé pour cette valeur de seuil ?

À vous d'inventer !

  • Proposez des voies d'amélioration de l'algorithme d'encodage.

La puissance d'un signal sonore pendant la durée T est définie mathématiquement par :

Puissance d'un signal sonore pendant la durée T

Puissance d'un signal sonore pendant la durée T

C'est donc la valeur moyenne de u2.

  • Que vaut la puissance du signal original complet ? Que vaut la puissance pendant la première seconde seulement ?
  • Tracez la puissance glissante sur une fenêtre de 0.1 s (utilisez la convolution). Déduisez-en le moment où le son est le plus fort.
  • Proposez une méthode qui permettrait d'atténuer les variations de puissance sonore (nuances) dans une musique.

Livrables

Vérifiez bien que vous avez les éléments suivants :

  1. Un script nommé "encodage.m" qui fera les choses suivantes, à partir d'un fichier sonore non compressé au format texte :
    • il normalisera la puissance sonore pour supprimer les variations d'intensité ;
    • il encodera la musique dans un fichier texte nommé "son_compresse.txt".
  2. Un script nommé "décodage.m" qui chargera le fichier "son_compresse_X_Y.txt" et jouera la musique.

  3. Un fichier texte nommé "readme.txt" qui contient les instructions d'utilisation de vos fichiers ainsi que les commentaires sur la performance de votre algorithme.

Terminez toutes vos lignes par des points-virgule !

Vos scripts commenceront par la ligne suivante :

clear all; close all; clc;
% Nettoie l'espace mémoire, ferme les fenêtres et vide l'invite de commande


Par souci d'uniformisation, vous travaillerez sous Octave.!


Puis-je utiliser des sous-fonctions ?
Oui, si vous souhaitez que votre script principal soit plus lisible, vous pouvez l'accompagner de fonctions (une seule fonction par fichier). Dans ce cas, joignez évidemment vos fonctions et n'oubliez pas de bien expliquer le rôle et le fonctionnement de votre fonction en commentaires.

Vérifiez votre travail

Alors, vous êtes allé au bout ? Suivez le guide pour vérifier votre travail !

  • Lancez Octave, et assurez-vous que le répertoire de travail est bien celui qui contient les fichiers que vous avez décompressés.
  • Ouvrez le fichier readme avec n’importe quel éditeur de texte.
  • Lisez les instructions d’exécution de fichier qui vous sont données.
  • Ouvrez les fichiers encodage.m et decodage.m avec un éditeur (celui d’Octave convient).
  • Exécutez le fichier encodage.m (il y a peut-être des paramètres à régler). Si cela ne fonctionne pas, essayez de comprendre ce qui ne va pas dans le code, et modifiez-le pour que cela fonctionne si possible.
  • Déterminez la taille (en Mo) du fichier texte son_compresse.txt produit (clic droit > propriétés). Cette taille est à comparer à la taille du fichier original ViolonActivite.txt.
  • Exécutez le fichier decodage.m. Si cela ne fonctionne pas, essayez de comprendre ce qui ne va pas dans le code, et modifiez le pour que cela fonctionne si possible.
  • N’oubliez pas de monter le son (ou de le baisser).
  • Lisez les réponses aux questions/commentaires qui doivent se trouver dans le fichier readme.txt.

 Vérifier que vous avez rempli les critères suivants :

  • Le code source est lisible et bien commenté.
  • Le compromis entre taille du fichier et qualité audio est évoqué.
  • Le code s’exécute comme le décrit le readme, sans effort de ma part.
  • De nombreuses voies d’améliorations pertinentes sont présentées.
  • Le fichier readme est clair.

Voici un exemple pour vous permettre de vérifier votre travail.