Blog

BeatViewer

July 12, 2023

*BeatViewer* est un module [Python](https://www.python.org/) qui analyse un flux audio, en extrait le [tempo](https://en.wikipedia.org/wiki/Tempo) et les [battements](https://en.wikipedia.org/wiki/Beat_(music)) puis génère des [visuels](https://en.wikipedia.org/wiki/VJing) qui y répondent, le tout en temps réel. # Genèse du projet L'idée est venue d'une pensée naïve : il ne doit pas être trop difficile d'identifier les battements d'une musique. Mon idée de base était d'exploiter l'énergie du signal, et d'identifier les instants où augmentait fortement. Malheureusement, cela ne suffit pas vraiment, car en conditions réelles, beaucoup d'événements peuvent produire des variations brusques de l'énergie, sans toutefois constituer des battements. Je me suis donc penché sur des procédés plus avancés, qui exploitent davantage l'aspect répétitif et structuré du rythme. Notamment, voici quelques articles qui m'ont bien guidé dans ce projet : - M Müller. 2015. *Fundamentals of music processing: Audio, analysis, algorithms, applications* - Mottaghi et al. 2017. *Obtain: Real-time beat tracking in audio signals* [[PDF]](https://arxiv.org/ftp/arxiv/papers/1704/1704.02216.pdf) - Percival et al. 2014. *Streamlined tempo estimation based on autocorrelation and cross-correlation with pulses* [[PDF]](http://percival-music.ca/research/2014_taspl_percival.pdf) - M Krzyżaniak. 2021. Musical robot swarms, timing and equilibria [[PDF]](https://www.tandfonline.com/doi/pdf/10.1080/09298215.2021.1910313) Contre toutes attentes, implémenter, bien que légèrement adaptée, une solution testée et approuvée, génère de meilleurs résultats. La preuve en images :

Démonstration de la réactivité du détecteur

Le détecteur en poche, l'idée était alors de l'utiliser pour contrôller des visuels et les adapter au rythme de la musique. J'ai commencé par utiliser [Pygame](https://www.pygame.org/news), le moteur de jeu de base de Python, mais les résultats restent très élémentaires. Plutôt, j'ai cherché à interfacer le détecteur avec d'autres outils, comme les clients sockets (comme l'API JavaScript [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)) ou le logiciel [OBS](https://obsproject.com/fr). Enfin, j'ai également adapté une idée de [Davis et al. 2018](http://www.abedavis.com/files/papers/VisualRhythm_Davis18.pdf) pour synchroniser les mouvements apparaissant dans une vidéo sur les battements de la musique, permettant ainsi de synchroniser continuement des événements visuels et auditifs.

Les différents visuels implémentés pour la v1 de BeatViewer. Dans le sens de la lecture : rectangles, tunnel, galaxy, fluid, BlinkingSlideshow (script OBS), SeekOnBeat (script OBS), warp, waves, stars

# Vulgarisation sur YouTube En marge de ces travaux, je réfléchissais également à réaliser une vidéo pour vulgariser la théorie, décrire ma démarche et présenter les résultats. L'idée me semblait bonne, mais je sous-estimais clairement le travail que cela représentait. Néanmoins, ceci est désormais abouti, et à retrouver sur ma chaîne YouTube :

YouTube Thumbnail
Le Danseur de rythme, sur YouTube

L'aventure fut longue et laborieuse, entre les difficultés d'écriture, de tournage, un déménagement, des piqûres de tiques dans la forêt, la documentation ~~peu évocatrice~~ de [Manim](https://www.manim.community/) pour faire les animations, une diction problématique, …

Google Docs screenshot
Capture d'écran du script (partiel) de la vidéo

Photos des coulisses : DJing avec vidéoprojecteur et installation dans la forêt
Quelques captures de l'envers du décor

Adobe Premiere screenshot
Capture d'écran du banc de montage de la vidéo (en trois parties, car je ne disposais pas d'assez de RAM 😵)

Toujours est-il que la vidéo est désormais en-ligne. Elle dure une quarantaine de minutes, malgré des coupes assez brutales, comme la narration d'un bug extrêment sournois que j'ai pu rencontrer : en Python, la suppression de deux lignes déclarant des listes vides absolument inutilisées ailleurs causait un crash presque immédiat du détecteur. Je n'ai jamais vraiment compris le problème, même si je crois désormais qu'il s'agissait d'un problème de gestion de mémoire lors de l'initialisation d'un processus fils. # Développements futurs Le code source du projet est disponible sur [GitHub](https://github.com/ychalier/beatviewer). Il est bien entendu ouvert aux contributions ! Notamment, il faudrait améliorer les performances du détecteur, et ajouter de nouveaux visuels. Dans la vidéo, j'évoque par exemple l'idée d'interfacer le détecteur avec un moteur de jeu 3D comme [Unity](https://unity.com/) ou [Unreal Engine](https://www.unrealengine.com/), pour pouvoir faire des choses que Pygame ne permet pas. À ce propos, les prochains visuels pourraient aller plus loin dans l'exploitation des données du détecteur, en incluant davantage les *onsets* et le tempo, ou en tirant profit de la structure rythmique classique des musiques électroniques : quatre battements par mesure, quatre mesures par phrase. Typiquement, on pourrait imaginer des événements plus importants lors des changements de phrases. Également, on pourrait exploiter des données moins discrètes, comme l'énergie instantannée du signal (ou plutôt de l'OSS) au moment du battement, pour créer des visuels plus expressifs, qui pourraient mieux reprendre les *émotions* de la musique. Michael Krzyżaniak, dont je me suis bien inspiré pour le détecteur, aborde également ce sujet dans [un cours sur les contrôleurs musicaux](https://youtu.be/yXlsGElRBkg?t=280). Enfin, le détecteur peut avoir d'autres utilités que les visuels, que j'aimerais également exploiter, plus liées à l'exercice du platinisme. On peut, par exemple, analyser une piste pour obtenir une progression plus exacte du tempo que celle offerte par les logiciels de traitements grands publics. Une idée serait également d'exploiter ce logiciel pour quantiser un enregistrement live, dont le tempo fluctue beaucoup, dans l'idée d'en faire des *mash-ups* ou des *remixs*. Bref, il reste encore beaucoup de pain sur la planche.