Lors de mes présentations orales, j'ai diffusé une animation réalisée à l'aide du moteur Manim, dont l'excellente chaîne 3Blue1Brown se sert pour mettre en image des concepts mathématiques

La vidéo a été étoffée depuis la première présentation. C'est ici l'occasion d'expliquer comment générer des animations dans ce genre.


La méthode Hagerman et Olofsson offre la possibilité de séparer les sources de parole et de bruit en sortie d'aide auditive, afin d'en étudier les effets distincts. Il en est beaucoup question dans mes recherches. Elle nécessite deux enregistrements A et B (dont le bruit est en opposition de phase), comme l'expliquent les formules suivantes :

  • l'addition des signaux A et B génère le double du signal, sans le bruit,
  • tandis que la soustraction génère le double du bruit, sans le signal.
{ A = S i g n a l + N o i s e B = S i g n a l N o i s e { A + B = S + N + S N = 2 S A B = S + N S + N = 2 N
hostmath.com

Installation de Manim dans un Notebook Jupyter

Jupyter est une application web de programmation interactive, héritée de iPython et dédiée aux langages interprétés tels que Julia, Python et R - d'où le nom. Quant à Manim il peut être utilisé de deux manières.

  • soit en ligne de commande :
manim -p -ql example.py SquareToCircle
  • soit dans une cellule Jupyter :
%%manim [CLI options] MyAwesomeScene

class MyAweseomeScene(Scene):
    def construct(self):
        ...

Dans les deux cas, on obtiendra un fichier vidéo .mp4. Pour installer Manim sous Debian, il faudra commencer par ajouter les dépendances :

apt install build-essential python3-dev libcairo2-dev libpango1.0-dev ffmpeg

Puis utiliser le gestionnaire de paquets pip, ou conda (ou encore son alternative ultra rapide mamba) pour ajouter le programme en question :

conda install manim

+ de détails

Code source

Ci-dessous, le code saisi dans une cellule Jupyter pour générer la première partie de la vidéo. Dans cette "Scene", on utilise les fonctions suivantes :

  • Write pour faire apparaître le texte progressivement
  • FadeOut pour le faire disparaître en fondu
  • Axes pour générer un repère orthogonal
  • Scale pour mettre l'objet à l'échelle
  • Shift pour décaler l'objet
  • Create pour dessiner l'objet progressivement
  • Flip pour retourner l'objet
  • Stretch pour étirer l'objet

Enfin, la fonction sinus provient du paquet numpy. Idem pour la fonction random qui permet de générer du bruit aléatoire.

%%manim -ql HagermanOlofsson

class HagermanOlofsson(Scene):

    def construct(self):

        title1 = Text("La méthode", font="Ubuntu")
        title2 = Text("Hagerman & Olofsson", font="Ubuntu").next_to(title1, DOWN)
        self.play(Write(title1), Write(title2))
        self.wait(2)
        self.play(FadeOut(title1), FadeOut(title2))

        title3 = Text("L'addition des signaux de parole avec le bruit en opposition de phase", font="Ubuntu").scale(0.6)
        title4 = Text("donne le double du signal, sans le bruit...", font="Ubuntu").scale(0.6).next_to(title3, DOWN)
        self.play(Write(title3), Write(title4))
        self.wait(3)
        self.play(FadeOut(title3), FadeOut(title4))

        axes_up = Axes(
            x_range=[0, 12.56, 1],
            y_range= [-2, 2, 1],
            #axes_color=GRAY,
        )
        axes_up.scale(0.5).shift(1.8 * UP)

        axes_down = Axes(
            x_range=[0, 12.56, 1],
            y_range= [-2, 2, 1],
            #axes_color=GRAY,
        )
        axes_down.scale(0.5).shift(2 * DOWN)

        labels_up = axes_up.get_axis_labels(
            Tex(r"\tiny{temps [s]}"), Tex(r"\tiny{niveau [dB]}")
        )
        labels_down = axes_down.get_axis_labels(
            Tex(r"\tiny{temps [s]}"), Tex(r"\tiny{niveau [dB]}")
        )

        #Graph Up
        self.play(Create(axes_up), run_time = 2)
        self.play(Create(labels_up), run_time = 1)

        graph_up = axes_up.plot(lambda x : np.sin(x), color = GOLD_A)
        signal_A = MathTex(r"signal\ A", color = GOLD_B)
        signal_A.scale(0.9)
        signal_A_coord = axes_up.input_to_graph_point(8.5,graph_up)
        signal_A.next_to(signal_A_coord,RIGHT+UP)

        # Graph Down
        self.play(Create(axes_down), run_time = 2)
        self.play(Create(labels_down), run_time = 1)

        graph_down = axes_down.plot(lambda x : np.sin(x), color = BLUE_D)
        signal_B = MathTex(r"signal\ B", color = BLUE_D)
        signal_B.scale(0.9)
        signal_B_coord = axes_down.input_to_graph_point(8.5,graph_down)
        signal_B.next_to(signal_B_coord,RIGHT+UP)

        noise = axes_up.plot(lambda x : (2*np.random.rand()-1)/2,color = YELLOW_D,)
        noise_label = MathTex(r"bruit", color = YELLOW_D)
        noise_label_coord = axes_up.input_to_graph_point(11,graph_up)
        noise_label.next_to(noise_label_coord,RIGHT+DOWN)

        self.play(Create(graph_up), run_time = 2)
        self.play(Create(signal_A))
        self.play(Create(graph_down), run_time = 2)
        self.play(Create(signal_B))
        self.play(Create(noise))
        self.play(Create(noise_label))

        self.play(noise.animate.stretch_to_fit_height(0.5))
        self.play(noise.animate.stretch_to_fit_height(1.5))
        self.play(noise.animate.stretch_to_fit_height(1))
        self.wait(1)

        noise2=noise.copy()
        noise2.generate_target()
        noise2.target.shift(3.8*DOWN)
        self.play(MoveToTarget(noise2))
        self.wait(1)
        self.play(noise2.animate.flip(RIGHT).set_color(ORANGE))
        self.wait(2)

        plus = MathTex(r"+", color = PURPLE_C)
        plus.scale(4).shift(5*LEFT)
        self.play(Create(plus))

        noise2.generate_target()
        noise2.target.shift(3.8*UP)
        graph_down.generate_target()
        graph_down.target.shift(3.7*UP)

        self.play(FadeOut(axes_down,labels_down,signal_B), MoveToTarget(noise2), MoveToTarget(graph_down))
        self.wait(1)
        signal_AB = MathTex(r"signal\ A + B", color = GREEN_C)
        signal_AB.scale(0.9)
        signal_AB_coord = axes_up.input_to_graph_point(8.5,graph_up)
        signal_AB.next_to(signal_AB_coord,RIGHT+UP)
        self.play(FadeOut(noise, noise2, noise_label, graph_down, plus), graph_up.animate.stretch(2,1).set_color(GREEN_C), TransformMatchingTex(signal_A, signal_AB))
        self.wait(3)

Mon mémoire a été sélectionné pour concourir au Prix 2021 du Collège National d'Audioprothèse pour l'école de Bordeaux. S'il n'a pas été primé, on m'a demandé d'en faire un résumé pour une publication dans les Cahiers de l'Audition.

La difficulté a été de réduire le volume de cette revue de littérature de 76 pages à 11, sans perdre le fil de la construction par chapitre. Première coupe importante, j'ai supprimé les rappels théoriques. Si je retirais encore la page de garde, les remerciements, la table des matières, les listes des figures, des tableaux et des abréviations, l'introduction, les annexes 1 & 2, alors je tombais à 31 pages. Il restait donc à réduire de ⅔.


Finalement, nous retrouverons l'article à la page 15 du numéro 2 des Cahiers de l'Audition 2023.

This browser does not support PDFs. Please download the PDF to view it: Download PDF.

En 2022, le Collège National d'Audioprothèse organisait le 26e EPU sur la théme "Nouvelles connaissances : nouvelles pratiques ?".

Le samedi 26 novembre à la Cité des Sciences et de l’Industrie, à La Villette (Paris), je présentais donc mon mémoire dans le cadre du Prix 2021.


Vous trouverez ci-dessous les diapositives qui accompagnaient la présentation orale.


Techniquement, il s'agit d'un iframe incluant un Google Slide en mode présentation :

<iframe src="https://docs.google.com/presentation/d/e/2PACX-1vTjWalTqNghkXdKob7wbL3tD096YK668vs_JhBwpGzlq5ciqC4EDXB-pltZPBqL5HZ7IlkBjNp76h0w/embed?start=false&loop=false&delayms=3000" frameborder="0" width="100%" height="100%" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>

Autres modèles de mémoire

Je vous propose de vous rendre sur memau.eu, un site conçu par Nicolas Vannson et Paul Aptel, pour obtenir un maximum d'information sur la conception d'un mémoire en audiologie.

Cette ressource précieuse contient :

  • des mémoires d'audioprothèse,
  • des modèles de documents,
  • des outils de rédaction et de recherche.

Et plus encore !

Zotero est un standard de la recherche documentaire. Il est publié sous licence libre GNU AGPL v3. Le logiciel permet notamment de regrouper, d'organiser et de commenter des références de publications scientifiques.

À l'aide du connecteur Chrome, on peut même insérer un article intéressant directement dans notre base de données locale, sans quitter la navigation web. Si le papier est diffusé librement, ou si vous êtes connecté à votre bibliothèque universitaire, le connecteur se chargera également de rapatrier le fichier PDF pour une consultation ultérieure. Voici comment j'ai utilisé Zotero en complément du moteur de recherche PubMed.

La "Query box" de PubMed

Il s'agit de la zone de recherche avancée dans laquelle on peut saisir des termes de recherche, qu'on coordonnera à l'aide des mots clés OR, AND et NOT :

(performance OR evaluation OR efficacy OR assessment 
    OR comparison OR predict* OR benefit)
    AND (hearing aid*)
    NOT (cochlear implant)
    AND (noise reduc* OR denois* OR de-noise OR signal-to-noise ratio OR SNR)
    AND (speech*)

Aller sur PubMed

L'interface générera d'elle-même des alternatives aux termes de recherche. Par exemple, la première notion de "performance" est automatiquement doublée par les mots "perform", "performable", "performance", "performances", "performative", "performatively", "performatives", "performativities", "performativity", "performed", "performer", "performers", "performing" et "performs".

L'acquisition des sources

Dans Zotero, j'ai organisé les dossiers par source :

  1. Le dossier PubMed contient donc tous les articles en provenance de ce moteur de recherche.
  2. Certains articles étant eux-mêmes une compilation d'autres sources, ils sont déposés dans leurs propres dossiers.
  3. J'ai aussi intégré la bibliographie des mémoires d'audioprothèse et des thèses de médecine proches de mon sujet.
À cet instant, en mars 2021, j'avais 450 références à lire et à trier.

Les marqueurs

Une fois qu'on a défini le plan du mémoire, on peut passer au marquage des articles dans Zotero. Les marqueurs font toute la puissance du logiciel. J'ai choisi de créer les intitulés suivants, selon la provenance et la destination des articles dans mon écrit :

  • Source
    • source:recherches : articles qui proviennent de PubMed,
    • source:memoire-audio : cités dans des mémoires d'audioprothèse antérieurs,
    • source:documents-pro : lus dans publications professionnels (rapports, livres blancs, posters, etc.),
  • Dossier
    • dossier:delerce-blog-comparaison : en citation d'un article de blog de Xavier Delerce,
    • dossier:lesimple-livre-blanc : dans le livre blanc Bernafon de Chistophe Lesimple,
    • [...]
  • Destination
    • dest:1.1-contexte : à citer dans ma première partie,
    • dest:1.2-problematique : idem,
    • [...]
    • dest:5.2-jusquou-clinique : idem, chapitre 5,
    • dest:biblio : tout article qui figurera dans ma bibliographie,
  • Tag
    • tag:ficher-lecture : ai-je rédigé une fiche de lecture ou non ?
    • tag:hors-sujet : s'agit-il d'un hors-sujet ?

En combinant ces marqueurs, et y associant une couleur à chacun, la manipulation des références devient un jeu d'enfant.

Les marqueurs dans Zotero.

Le fichier de bibliographie

Grâce à ce travail liminaire, la création du fichier de bilbiographie devient simple elle aussi. Il suffit de sélectionner le marqueur dest:biblio pour afficher les articles concernés dans la fenêtre centrale. On les sélectionne tous (Ctrl + A), puis on va dans Fichier > Exporter la bibliothèque. Là, on choisit le format BibTex et on obtient notre fichier bibliographie.bib.

@article{may_signal-noise-ratio-aware_2018,
        title = {Signal-to-{Noise}-{Ratio}-{Aware} {Dynamic} {Range} {Compression} in {Hearing} {Aids}},
        volume = {22},
        issn = {2331-2165},
        doi = {10.1177/2331216518790903},
        abstract = {Fast-acting dynamic range compression is a level-dependent amplification scheme [...]},
        language = {eng},
        journal = {Trends in Hearing},
        author = {May, Tobias and Kowalewski, Borys and Dau, Torsten},
        month = dec,
        year = {2018},
        pmid = {30117366},
        pmcid = {PMC6100123},
        keywords = {Humans, Speech Perception, Hearing Aids, Noise, Signal-To-Noise Ratio, Time Factors, hearing-aid signal processing, signal-to-noise ratio, wide dynamic range compression},
        pages = {2331216518790903},
        file = {May et al. - 2018 - Signal-to-Noise-Ratio-Aware Dynamic Range Compress.pdf:/home/benoit/Zotero/storage/73SVBMCC/May et al. - 2018 - Signal-to-Noise-Ratio-Aware Dynamic Range Compress.pdf:application/pdf},
}
Un article qui sera cité en tant que "May et al., 2018" dans le document final.

Consulter l'article Export final pour en savoir plus sur l'arborescence des fichiers et sur la génération du mémoire.