{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "675b9869",
   "metadata": {},
   "source": [
    "# Traitement du Signal - TP3 : Transformée de Fourier (Partie 2)\n",
    "\n",
    "Ce TP complète ce qui a été vu dans le TP3, avec deux nouveaux exercices. Voilà... après, s'il n'y a pas plus de trucs à dire... pas besoin de faire plus long...\n",
    "\n",
    "Vous pouvez directement copier les cellules pour les mettre à la fin du TP3 précédent, ou alors juste compléter ce notebook séparément. Faites comme vous voulez"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8b493b0e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Chargement des librairies\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "312522cc",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## Exercice 6 : Comment compresser un signal ?\n",
    "\n",
    "Dans cet exercice, on va voir comment on peut **compresser** théoriquement un signal, grâce à sa représentation fréquentielle. Pour cela, il nous faut un signal. Tracez le signal **périodique** carré de période $T$ et d'amplitude $A$, dont l'équation de la période est la suivante : \n",
    "\n",
    "\\begin{equation*}\n",
    "    c(t) = \\left \\{\n",
    "            \\begin{array}{ll}\n",
    "                A & 0 \\leq t \\leq \\frac{T}{2}\\\\\n",
    "                -A & \\frac{T}{2} \\leq t \\leq T \\\\\n",
    "            \\end{array}\n",
    "            \\right.\n",
    "\\end{equation*}\n",
    "\n",
    "Le signal évoluera de 0 à 1 secondes avec une fréquence d'échantillonage $f_e = 10000$ Hz. La période $T$ est de 0.1 secondes, et l'amplitude $A$ est à 1.\n",
    "\n",
    "Créez et tracez ce signal."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9e79555f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "\n",
    "# Création de l'axe temporel\n",
    "...\n",
    "\n",
    "# Création du signal carré\n",
    "...\n",
    "\n",
    "# Affichage du signal carré\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8fca9c80",
   "metadata": {},
   "source": [
    "Effectuez maintenant une transformée de Fourier réelle sur le signal carré, et affichez le spectre d'amplitude."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9ce830a4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Transformée de Fourier réelle du signal c(t)\n",
    "...\n",
    "\n",
    "# Affichage du spectre d'amplitude de C(f)\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a425050a",
   "metadata": {},
   "source": [
    "**_QUESTION :_** Quel est la précision spectrale ? *(c'est-à-dire l'écart entre 2 fréquences analysées après Transformée de Fourier)*"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "05e111ac",
   "metadata": {},
   "source": [
    "**_REPONSE :_**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b55858fa",
   "metadata": {},
   "source": [
    "Affichez ensuite le spectre d'amplitude mais zoomé sur les 1000 premières fréquences."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b113cb88",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Affichage du spectre d'amplitude de C(f) sur les 1000 premières fréquences\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ee047866",
   "metadata": {},
   "source": [
    "**_QUESTION :_** Au vu du spectre d'amplitude zoomé, quelle est la fréquence fondamentale du signal ? Quelles sont les harmoniques ?\n",
    "\n",
    "*Note : Je vous conseille d'utiliser la fonction find_peaks de scipy pour détecter les pics importants de votre spectre d'amplitude*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9f60f1bd",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Récupération des pics de fréquences du spectre d'amplitude\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4e0ca4ed",
   "metadata": {},
   "source": [
    "**_REPONSE :_**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "132e08fc",
   "metadata": {},
   "source": [
    "**_QUESTION :_** Est-ce que les valeurs calculées correspondent à la théorie ? *(cf : Ex 2.2 c du TD)*"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df7dd68f",
   "metadata": {},
   "source": [
    "**_REPONSE :_** "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7856ebf2",
   "metadata": {},
   "source": [
    "L'objectif de la compression ici va être de simplifier le signal en ne gardant que les plus grandes amplitudes du signal. Il y'a 2 manières de réaliser cela:\n",
    "- Ne gardez que les $K$ fréquences avec les plus grandes amplitudes\n",
    "- Ne gardez que les fréquences dont l'amplitude est supérieure à un seuil défini\n",
    "\n",
    "Les fréquences significatives sont donc conservées, et les autres sont mises à zéro."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2915894f",
   "metadata": {},
   "source": [
    "Implémentez dans un premier temps la fonction permettant de ne garder que les $K$ fréquences les plus significatives (c'est-à-dire avec la plus grande amplitude). Votre fonction prendra en entrée un signal fréquentiel et un nombre $K$ de fréquences à garder, et retournera le signal fréquentiel modifié."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0f8c7fbc",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Développement de la fonction qui sélectionne les K fréquences les plus significatives\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "373da43c",
   "metadata": {},
   "source": [
    "Appliquez votre fonction sur la TF du signal carré pour ne garder que les 5 fréquences les plus significatives. Affichez ensuite le spectre d'amplitude."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bd0444f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Modification de la TF du signal carré pour ne garder que les 5 fréquences les plus significatives\n",
    "...\n",
    "\n",
    "# Affichage du spectre d'amplitude du signal fréquentiel modifié\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc943482",
   "metadata": {},
   "source": [
    "Effectuez la transformée inverse sur ce nouveau signal fréquentiel, et affichez le résultat sur une même figure avec le signal original."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "db81d7b0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# TF inverse du nouveau signal fréquentiel\n",
    "...\n",
    "\n",
    "# Affichage des deux signaux temporels sur une même figure\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "70f0a669",
   "metadata": {},
   "source": [
    "Afin de mesurer la ressemblance entre le signal original et le signal compressé, on va calculer le **rapport signal sur bruit**. Pour rappel, cette métrique indique la puissance du signal par rapport à la puissance de son bruit. Plus le rapport est grand, plus le signal est puissant par rapport à son bruit, et donc plus le bruit est faible. Pour cela, nous allons utiliser la formule suivante :\n",
    "\n",
    "\\begin{equation*}\n",
    "    R_{S/B} = 10*log_{10}(\\frac{\\sum c[n]²}{\\sum(c[n]-ĉ[n])²})\n",
    "\\end{equation*}\n",
    "\n",
    "Ici, $c$ correspond à notre signal original et $ĉ$ notre signal compressé. Le bruit est donc la différence entre le signal original et le signal compressé. De ce fait, plus le rapport est grand, plus la puissance du signal est grande par rapport à la puissance de la différence entre les deux signaux, et donc plus le signal compressé est proche du signal original.\n",
    "\n",
    "La mesure se calcule en décibels (dB), afin d'utiliser une échelle logarithmique plus lisible :\n",
    "- *0 dB* : Le signal et l'erreur ont la même puissance, donc le signal compressé est très loin de représenter le signal original\n",
    "- *> 10 dB* : Le signal domine clairement le bruit\n",
    "- *20-30 dB* : On a une bonne qualité de reconstruction\n",
    "- *40 dB* : Le signal compressé est quasi indiscernable de l'original.\n",
    "\n",
    "Développez une fonction de calcul de rapport signal sur bruit, et appliquez la fonction sur votre signal original et votre signal compressé"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b98b538b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Fonction de calcul du rapport S/B\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eee7a2be",
   "metadata": {},
   "source": [
    "Répétez les mêmes opérations pour avoir sur la même figure le signal original et plusieurs versions compressées du signal ($K = 1, 5, 20, 100$)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3066da64",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Affichage du signal original et de ses versions compressées\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22682bc0",
   "metadata": {},
   "source": [
    "Calculez les différents rapports $S/B$ en variant $K$ par puissances de 2 (jusqu'à $K = N$, le nombre d'échantillons de fréquences). Tracez la courbe du rapport $S/B$ en fonction de $K$.\n",
    "\n",
    "*Note : En récupérant le nombre de bits pour coder $N$ (N.bit_length()), on peut trouver facilement la dernière puissance de 2 inférieure à $N$*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2ec6c5b0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Compression du signal avec K variant en puissances de 2\n",
    "...\n",
    "\n",
    "# Affichage du rapport S/B en fonction de K\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0cfe1988",
   "metadata": {},
   "source": [
    "**_QUESTION :_** A partir de quelle valeur de $K$ a-t-on une compression acceptable ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8878c4de",
   "metadata": {},
   "source": [
    "**_REPONSE :_**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "70530bfa",
   "metadata": {},
   "source": [
    "## Exercice 7 : Mon audio est beaucoup trop lourd...\n",
    "\n",
    "J'ai trop peu d'espace sur mon ordi, au point de ne plus avoir la place pour mon nouveau son. Vous pouvez m'aider ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6b119a41",
   "metadata": {},
   "source": [
    "Chargez l'audio *music.wav* et tracez le signal."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2196b900",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Chargement et affichage de music.wav\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dff89516",
   "metadata": {},
   "source": [
    "Effectuez une transformée de Fourier réelle sur le signal audio et affichez le spectre d'amplitude du résultat obtenu."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "277d7cea",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Transformée de Fourier réelle de l'audio\n",
    "...\n",
    "\n",
    "# Affichage du spectre d'amplitude de M(f)\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f4e10f15",
   "metadata": {},
   "source": [
    "Comme effectué dans l'exercice précédent, compressez votre signal en ne gardant que $K$ composantes, avec $K$ variant en puissances de 2 jusqu'à $K=N$. Calculez le rapport signal sur bruit à chacun des $K$ et tracez la courbe du rapport $S/B$ en fonction de $K$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9d0b6190",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Compression du signal avec K variant en puissances de 2\n",
    "...\n",
    "\n",
    "# Affichage du rapport S/B en fonction de K\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "709eb03f",
   "metadata": {},
   "source": [
    "Récupérez les valeurs minimums de $K$ tels que le rapport $S/B$ est supérieur ou égal à 10, 20 et 30 dB. Compressez l'audio original avec ces 3 valeurs de $K$ et enregistrez les différentes versions dans un fichier WAV."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f6ff4dc2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Récupération des K minimums tels que le rapport S/B est supérieur ou égal à 10, 20 et 30 dB\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e1a77d0",
   "metadata": {},
   "source": [
    "**_QUESTION :_** Comment est la qualité sonore des différents extraits compressés ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61b6dbbc",
   "metadata": {},
   "source": [
    "**_REPONSE :_**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2035b0b1",
   "metadata": {},
   "source": [
    "**_QUESTION :_** Est-ce que les fichiers compressés ont un poids plus léger (en octets) ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e9780df",
   "metadata": {},
   "source": [
    "**_REPONSE :_**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d49b3c49",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "*Le résultat n'est pas concluant ? C'est normal !*\n",
    "\n",
    "La compression audio ne fonctionne pas exactement comme ça... Le principe reste le même : éliminer des fréquences inutiles en les mettant à zéro. Cependant, c'est fait de manière plus intelligente :\n",
    "- On supprime les fréquences audios inperceptibles par l'oreille humaine\n",
    "- On supprime les fréquences inaudibles dans le contexte (ex: un son fort à 1kHz rend inaudible un son plus faible à 1,05 kHz)\n",
    "\n",
    "Ensuite, les autres fréquences ne sont pas laissées telles qu'elles, mais elles sont quantifiées. Cela consiste à donner moins de précision sur les fréquences à faible amplitude tout en conservant une grande précision pour les fréquences à forte amplitude. De ce fait, on réduit drastiquement la taille requise pour encoder le signal audio, et donc on peut compresser efficacement un fichier.\n",
    "\n",
    "Bref, votre expérience n'a pas fonctionné, mais ça nous a permis de voir dans les grandes lignes la base de la compression MP3 !"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "TIM",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
