{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d81d27b2",
   "metadata": {},
   "source": [
    "# Traitement du Signal - TDM6 : Convolution\n",
    "\n",
    "---\n",
    "\n",
    "Aujourd'hui, on va faire des convolutions. Beaucoup de convolutions. On va coder la fonction, puis l'utiliser dans plein de situations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c5538380",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Import des librairies\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0212a1cd",
   "metadata": {},
   "source": [
    "## Exercice 1 : Comment on fait une convolution ?!\n",
    "\n",
    "Bon, comme premier exercice, vous avez l'habitude maintenant, on va voir comment faire une convolution avec votre package préféré, à savoir NumPy.\n",
    "\n",
    "Pour rappel, la fonction de convolution entre un signal *f(t)* et *g(t)* :\n",
    "\n",
    "\\begin{equation*}\n",
    "f(t) \\ast g(t) = \\int_{-\\infty}^{\\infty} f(\\tau) g(t - \\tau) \\, d \\tau\n",
    "\\end{equation*}\n",
    "\n",
    "Evidemment, cette formule fonctionne en analogique, mais on fait du numérique ici, ce qui signifie qu'il faut utiliser la fonction de convolution discrète : \n",
    "\n",
    "\\begin{equation*}\n",
    "(f \\ast g)[k]=\\sum_{n} f[n] \\cdot g[k-n] ( \\cdot T_e)\n",
    "\\end{equation*}\n",
    "\n",
    "Ici, $T_e$ est le temps d'échantillonage de $f$ et $g$.\n",
    "\n",
    "*\"Pourquoi $T_e$ est entre parenthèse dans l'équation ?\"*\n",
    "\n",
    "Dis-donc, t'as un oeil de lynx ! Ces parenthèses ne sont pas là tout à fait au hasard, on en reparle plus tard...\n",
    "\n",
    "Pour convoluer, il nous faut 2 signaux d'entrée, enfin un signal et une réponse impulsionnelle (c'est aussi un signal):\n",
    "\n",
    "- $x(t) = \\Pi_{1}(t-t_0)$, avec $t_0 = 2$ \n",
    "- $h(t) = e^{-t}$ \n",
    "\n",
    "Les deux signaux ont une fréquence d'échantillonnage de $100 Hz$. $f(t)$ évolue durant 10 secondes, et $h(t)$ durant 5 secondes.\n",
    "\n",
    "Créez les deux signaux et tracez les sur une même figure"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4b695b9e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Création et affichage des deux signaux\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "699c274b",
   "metadata": {},
   "source": [
    "Créez maintenant ces deux signaux sur la plateforme web, visualisez le résultat de la convolution, et répondez aux questions suivantes\n",
    "\n",
    "***_ATTENTION_:** Faites attention à ne pas confondre le signal et la réponse impulsionnelle sur la plateforme, car le résultat ne sera pas le même !*"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c333449d",
   "metadata": {},
   "source": [
    "**_QUESTION :_** Sur combien de temps évolue le signal convolué ? A quoi cela correspond ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "36cf9b63",
   "metadata": {},
   "source": [
    "**_REPONSE :_**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7d800690",
   "metadata": {},
   "source": [
    "**_QUESTION :_** Quelle est l'amplitude maximum du signal convolué ? Et à quel $t$ ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "37d8240d",
   "metadata": {},
   "source": [
    "**_REPONSE :_**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84d5c3e5",
   "metadata": {},
   "source": [
    "**_QUESTION :_** Quelle est l'amplitude maximum du signal convolué **avec l'option de normalisation cochée** ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e001587a",
   "metadata": {},
   "source": [
    "**_REPONSE :_**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "20c43641",
   "metadata": {},
   "source": [
    "Pour la normalisation, on en parle après. On va pouvoir commencer à la coder avec NumPy. Et pour ça, on a une superbe fonction: *np.convolve*"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c382d90d",
   "metadata": {},
   "source": [
    "**_QUESTION :_** Que prend en entrée la fonction *np.convolve* et que renvoie elle en sortie ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3daff681",
   "metadata": {},
   "source": [
    "**_REPONSE :_**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8874e697",
   "metadata": {},
   "source": [
    "Utilisez la fonction *np.convolve* avec votre signal $x(t)$ et votre réponse impulsionnelle $h(t)$ et tracez le résultat **brut**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d13800b5",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Convolution des deux signaux\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3b0ca9d0",
   "metadata": {},
   "source": [
    "**_QUESTION :_** Par rapport au résultat vu sur la plateforme, quels sont les points communs ? Quelles sont les différences ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b4b42197",
   "metadata": {},
   "source": [
    "**_REPONSE :_**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e216aca8",
   "metadata": {},
   "source": [
    "Ok, on va s'attaquer à l'axe temporel. On n'a pas de fonction NumPy pour calculer l'axe temporel de la convolution. Cepedant, ce n'est pas très compliqué, car:\n",
    "- Le signal convolué commence à 0 secondes\n",
    "- Le temps d'échantillonnage du signal convolué est le même que pour les deux signaux en entrée\n",
    "\n",
    "Calculez l'axe temporel du signal convolué, et tracez le résultat de la convolution avec cet axe\n",
    "\n",
    "*Note: si vous ne savez pas comment faire, sachez qu'on a déjà fait ça lors des deux précédents TDM (lorsqu'on effectuait une transformée de Fourier inverse)*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "85ac29d8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Calcul de l'axe temporel de la convolution et affichage du résultat\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "350a2563",
   "metadata": {},
   "source": [
    "**_QUESTION :_** Est-ce que le résultat correspond à ce qui est attendu ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51f70587",
   "metadata": {},
   "source": [
    "**_REPONSE :_**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b93d1d01",
   "metadata": {},
   "source": [
    "Bon, bah c'est pas si compliqué la convolution. Mais il manque un détail...\n",
    "\n",
    "Comme vous avez pu le voir sur la plateforme, il y a une option pour **normaliser** la convolution. Dans le calcul fait précédemment, la convolution ne dépend pas du temps d'échantillonnage. De ce fait, on a une amplitude très haute, qui ne correspond pas vraiment à la réalité. Du moins à la théorie.\n",
    "\n",
    "Pour normaliser la convolution, il suffit donc tout simplement de multiplier le résultat de la convolution par le temps d'échantillonnage $T_e$.\n",
    "\n",
    "Calculez maintenant la convolution normalisée et affichez le résultat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f58199eb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Calcul de la convolution normalisée et affichage du résultat\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ed593de1",
   "metadata": {},
   "source": [
    "*\"Ok, mais alors pourquoi la normalisation ici est une option ?\"*\n",
    "\n",
    "En effet, à l'instar de la corrélation, on pourrait se dire qu'il faut multiplier par le temps d'échantillonnage car sinon le résultat n'est pas correct. Mais c'est un peu plus compliqué que ça:\n",
    "- Lorsqu'on veut reproduire des résultats théoriques (à savoir obtenir les mêmes résultats que vus en TD par exemple), il faut effectivement normaliser par le temps d'échantillonnage, car le calcul de la convolution est une intégrale\n",
    "- En pratique (donc dans le magnifique monde du numérique), on va au contraire ne pas normaliser par le temps d'échantillonnage, notamment lorsqu'on effectue un filtrage (prochaine séance de TDM). Pour ne pas exploser l'amplitude du signal convolué cependant, le filtre (donc la réponse impulsionnelle) est conçue de sorte que la somme des coefficients (la somme du vecteur) est égale à 1\n",
    "\n",
    "*\"Bah du coup, c'est quoi la bonne réponse ? Car moi, je veux juste avoir les points pour valider l'EC\"*\n",
    "\n",
    "Super la mentalité ! Et pour répondre à la question, il n'y a pas de bonne réponse: tout dépend du contexte...\n",
    "\n",
    "Bref, par défaut, on ne fera pas de normalisation en multipliant par le temps d'échantillonnage, mais selon l'exercice, le contexte, il se peut qu'on ait besoin de normaliser. Voilà voilà...\n",
    "\n",
    "Pour finir cet exercice, une petite golden cellule, afin de regrouper tout cette montagne (non) de code. Précisez les deux cas vus précédemment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a33d6f47",
   "metadata": {},
   "outputs": [],
   "source": [
    "# GOLDEN CELLULE A COMPLETER\n",
    "# Convolution de deux signaux\n",
    "\n",
    "# Paramètres (MODIFIEZ AVEC VOS NOMS DE VARIABLES)\n",
    "# ... :  un signal temporel à convoluer, vecteur Numpy\n",
    "# ... : la réponse impulsionnelle (signal temporel, vecteur Numpy)\n",
    "# ... : le temps d'échantillonnage\n",
    "\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f350f1a0",
   "metadata": {},
   "source": [
    "## Exercice 2 : Allez, on recode la convolution !\n",
    "\n",
    "*\"Oh non ! Recoder la fonction !\"*\n",
    "\n",
    "Eh oui, dans cet exercice, on va recoder la fonction de convolution... Mais rassurez vous, ça ne va pas être très compliqué. Alors pourquoi ?\n",
    "\n",
    "Je vous remets ici la formule de la convolution de deux signaux (vecteurs NumPy) $f$ et $g$, en numérique:\n",
    "\n",
    "\\begin{equation*}\n",
    "(f \\ast g)[k]=\\sum_{n} f[n] \\cdot g[k-n] ( \\cdot T_e)\n",
    "\\end{equation*}\n",
    "\n",
    "La formule de la convolution rappelle fortement la formule de la corrélation, qui pour rappel, est la suivante:\n",
    "\n",
    "\\begin{equation*}\n",
    "C_{fg}[k] = \\sum_n f[n] \\cdot g^*[n-k] ( \\cdot T_e)\n",
    "\\end{equation*}\n",
    "\n",
    "Les ressemblances ici sont assez fortes, donc l'objectif dans cet exercice va être de reprendre les fonctions développées précédemment dans le TDM3 sur la corrélation, et de faire les quelques modifications nécessaires pour effectuer une convolution.\n",
    "\n",
    "Donc, dans un premier temps, ouvrez votre TDM3 sur la corrélation (de préférence la correction qui est déjà disponible), et récupérez les fonction de padding et shift, qui ne seront pas modifiées pour la convolution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9bd87ff2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Fonctions de padding et de shift (TDM3)\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b630791d",
   "metadata": {},
   "source": [
    "**Si vous ne vous rappelez plus de l'utilité de ces 2 fonctions, n'hésitez pas à relire le TDM3 !**\n",
    "\n",
    "Ensuite, pour la corrélation, nous avions développé une fonction qui calculait le score de la corrélation entre deux signaux $f$ et $g$ avec un décalage de $k$ cases appliqué sur le signal $g$ (*correlation_at_k*). On va ici transformer cette fonction pour qu'elle calcule le score de convolution entre deux signaux $f$ et $g$ avec un décalage de $k$ cases appliqué sur le signal $g$. Pour cela, il y a 4 modifications à apporter:\n",
    "\n",
    "- Le signal $g$ doit être retourné en tout début de la fonction\n",
    "- Comme le signal est retourné, le décalage de $g$ ($k$ cases initialement) devient un décalage de $k - (M - 1)$ cases, avec $M$ la taille de $g$\n",
    "- Le calcul final se fait avec $g$ et non $g^*$\n",
    "- La normalisation par multiplication avec $T_e$ est à enlever\n",
    "\n",
    "A vous de jouer, créez la fonction *convolution_at_k*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "338cf878",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Développement de la fonction de calcul du score de convolution entre deux signaux à un décalage k fixé\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "534deec7",
   "metadata": {},
   "source": [
    "Dernière étape: la modification de la fonction de convolution. La fonction prend en entrée deux signaux $f$ et $g$, ainsi que le temps d'échantillonnage $T_e$, et renvoie la convolution entre $f$ et $g$ et l'axe temporel associé. Comparé à la fonction de corrélation réalisé durant le TDM3, il faut avant tout modifier la création de l'axe temporel. Comme évoqué précédemment, l'axe temporel correspond à la somme des longueurs des deux signaux moins un, commence à 0 secondes et est échantillonné à $T_e$.\n",
    "\n",
    "A vous de jouer, développez la fonction de convolution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "96f259e2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Fonction de convolution entre les signaux f et g avec un pas d'échantillonage de Te\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7cfc24b0",
   "metadata": {},
   "source": [
    "Tout est prêt ? Super, vérifiez que votre fonction est correcte en traçant le signal obtenu de la convolution, et en le comparant avec le résultat de convolution non normalisé obtenu via NumPy. On croise les doigts :D"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9856e9bb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Calcul de la convolution entre les signaux x et h avec un pas d'échantillonage de Te, et affichage du résultat avec la fonction convolution de Numpy\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2d12b2ad",
   "metadata": {},
   "source": [
    "Si vous avez **exactement** la même courbe, c'est réussi ! Et on peut passer à la suite ;)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f17f482f",
   "metadata": {},
   "source": [
    "## Exercice 3 : J'adore mon signal, je voudrais l'avoir tout le temps !\n",
    "\n",
    "Pour ce troisième exercice, on va transformer un signal bref en un signal périodique.\n",
    "\n",
    "Commencez par créer un signal triangulaire :\n",
    "\n",
    "\\begin{equation*}\n",
    "    x(t) = \\Delta(t) = 1-|t-1|\n",
    "\\end{equation*}\n",
    "\n",
    "Le signal évoluera entre 0 et 2 secondes, avec une fréquence d'échantillonage de $100 Hz$. Créez et affichez le signal."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "08dcac84",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Création et affichage du signal triangulaire\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e0fb058",
   "metadata": {},
   "source": [
    "L'objectif maintenant va être de rendre ce signal périodique sur une durée de 0 à 10 secondes. Pour cela, on va créer le signal $h(t)$ approprié, tel que $y(t) = x(t) \\ast h(t)$ est le même signal que $x(t)$ mais périodique ($T=len(x)$) et évoluant entre 0 et 10 secondes."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fb7e8f74",
   "metadata": {},
   "source": [
    "**_QUESITON :_** Quel doit être le signal $h(t)$ pour construire le signal $y(t)$ souhaité ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "608ce2bd",
   "metadata": {},
   "source": [
    "**_REPONSE :_**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "48490f6b",
   "metadata": {},
   "source": [
    "Construisez le signal $h(t)$ approprié pour notre tâche et affichez le résultat."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e751da4b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Création de h(t) et affichage\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "529ce21d",
   "metadata": {},
   "source": [
    "Appliquez la convolution avec la fonction *np.convolve* sur les signaux $x(t)$ et $h(t)$ et affichez le résultat."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e0cf92d4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Convolution entre x(t) et h(t) et affichage du résultat\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5f83ca6e",
   "metadata": {},
   "source": [
    "**_QUESTION :_** Est-ce que le résultat obtenu est celui attendu ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e9d752b5",
   "metadata": {},
   "source": [
    "**_REPONSE :_**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "70ed5865",
   "metadata": {},
   "source": [
    "Corrigez le résultat obtenu, afin d'obtenir exactement 5 périodes.\n",
    "\n",
    "*Pour cela, il suffit de raccourcir le signal de sortie*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1d7b57f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Correction du signal convolué pour le faire tenir sur 10 secondes, et affichage du résultat\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "045efc7d",
   "metadata": {},
   "source": [
    "Modifiez maintenant $h(t)$ en augmentant la période ($T = 3 s$), puis en diminuant la période ($T = 1.5 s$) **sans modifier $x(t)$**. Effecutez les convolutions entre $x(t)$ et les nouvelles versions de $h(t)$ et affichez les résultats."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "22c4c397",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Modification de h(t) avec T = 3 secondes\n",
    "..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6fd0eb3d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Modification de h(t) avec T = 1.5 secondes\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ff5c6214",
   "metadata": {},
   "source": [
    "**_QUESTION :_** Est-ce que les produits de convolution sont périodiques ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f498b8c2",
   "metadata": {},
   "source": [
    "**_REPONSE :_**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "16512b07",
   "metadata": {},
   "source": [
    "## Exercice 4 : HEEEEEEE OOOOHHHHH\n",
    "\n",
    "J'ai trouvé une superbe musique pas très connue, mais je la trouve un peu plate... J'aimerai avoir un peu de reverbe dessus (de l'écho comme dans un grand batîment). Vous pouvez m'aider ?\n",
    "\n",
    "Chargez le fichier *audio.wav* et tracez le spectre audio."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ab1613c2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Chargement de l'extrait audio, et affichage du spectre audio\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8ee206d7",
   "metadata": {},
   "source": [
    "Pour créer de la reverbe ici, on va utiliser ce qu'on a fait durant tout le TP : la convolution. Pour cela, on va utiliser une réponse impulsionnelle enregistrée dans un endroit avec de l'écho. Ici, on a le fichier *eglise.wav* qui est une réponse impulsionnelle enregistrée dans une église. Si vous êtes intéressé par d'autres réponses impulsionnelles, je vous conseille ce lien : https://www.openair.hosted.york.ac.uk/?page_id=36\n",
    "\n",
    "Chargez le fichier audio *eglise.wav* et tracez le spectre audio."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cbb18e64",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Chargement de la réponse impulsionnelle, et affichage du spectre audio\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5a4c0728",
   "metadata": {},
   "source": [
    "Avant de faire la convolution, on va convertir nos données, ici typées int16 (entiers codés sur 16 bits). \n",
    "\n",
    "Normalisez les données en :\n",
    "- convertissant les audios en float\n",
    "- divisant les audios par 32768"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "87dce3b4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Normalisation de l'extrait audio et de la réponse impulsionnelle\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1293c7fb",
   "metadata": {},
   "source": [
    "Calculez maintenant la convolution entre vos deux audios normalisés. **N'oubliez pas l'axe temporel !**\n",
    "\n",
    "*Bon, ça va prendre un peu de temps, ne soyez pas étonné...*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b50b3a72",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Convolution de l'extrait audio normalisé et de la réponse impulsionnelle normalisée\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b75e5602",
   "metadata": {},
   "source": [
    "Malgré la normalisation des extraits audios, la sortie de convolution peut créer des pics trop forts (ici au-dessus de 1). Corrigez l'audio :\n",
    "- Détectez s'il y a au moins un pic (en calculant le maximum)\n",
    "- S'il y'a un pic au-dessus de 1 (ou en-dessous de -1), normalisez l'audio en le divisant par le maximum et en multipliant par 0.999"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2bb63b0c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Correction de pics trop élevés par normalisation\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ecc1d3fc",
   "metadata": {},
   "source": [
    "Convertissez l'audio pour coller à celui d'origine. Pour cela :\n",
    "- Multipliez l'audio par 32768\n",
    "- Convertissez l'audio en entier 16 bits"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fdb085ae",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Conversion de l'audio en entier 16 bits\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "081f7b59",
   "metadata": {},
   "source": [
    "Affichez le spectre audio du résultat. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "06449a3e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Affichage du spectre d'audio résultat\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0ad4051d",
   "metadata": {},
   "source": [
    "Pour finir, enregistrez l'audio et écoutez le résultat. Alors, qu'est-ce que ça donne ?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "906dfed5",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A COMPLETER\n",
    "# Enregistrement du son final avec reverb\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e908fb8f",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## La convolution au service de l'art\n",
    "\n",
    "Ici, juste un bonus, pas de code, mais c'est pour ceux qui sont curieux ;)\n",
    "\n",
    "Via l'exercice précédent, on a vu comment faire une reverb. Pour cela, on a enregistré une réponse impulsionnelle dans une église, ce qui a permis de créer notre signal reverb. Cependant, on peut aussi créer des réponses impulsionnelles via des objets du quotidien, comme par exemple un jouet à ressort : https://www.openair.hosted.york.ac.uk/?page_id=652\n",
    "\n",
    "De ce fait, on peut créer des sons très spéciaux, servant d'effet sonore au cinéma par exemple. Ces réponses impulsionnelles peuvent aussi être générées. On peut alors ainsi transformer un son à sa guise, créant ainsi de nouvelles sonorités uniques.\n",
    "\n",
    "Par exemple, la Loopstation RC-505 est un appareil permettant non seulement de créer des \"loops sonores\" (c'est-à-dire qu'on enregistre un son et il se répète indéfiniment), mais également de rajouter des effets sonores sur les audios durant l'enregistrement ou a posteriori. La machine a été designée particulèrement pour les artistes vocaux (chant, beatbox). Et tout ça à partir de convolution pour créer des sons originaux.\n",
    "\n",
    "Un extrait pour finir : 2 artistes beatbox en battle 1v1 qui utilisent la loopstation pour leurs morceaux avec uniquement leurs voix en entrée : https://youtu.be/niZJPoxiv40?si=Uo_hrlOj3iyLechd&t=74"
   ]
  }
 ],
 "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
}
