this repo has no description
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

📝 Finish reread!!

+66 -48
+24
paper/bibliography.yaml
··· 388 388 url: 389 389 value: https://v2.tauri.app/blog/tauri-20/#hot-module-replacement 390 390 date: 2025-03-24 391 + 392 + imagemagick: 393 + title: ImageMagick -- Mastering Digital Image Alchemy 394 + type: web 395 + url: 396 + value: https://imagemagick.org/index.php 397 + date: 2025-03-26 398 + 399 + ffmpeg: 400 + title: FFmpeg 401 + type: web 402 + url: 403 + value: https://ffmpeg.org/ 404 + date: 2025-03-26 405 + 406 + libx264order: 407 + title: Dynamic pipeline, "non-strictly-monotonic PTS" warning with x264enc after switching source 408 + type: article 409 + author: popo2 popo2 410 + publisher: Narkive Mailing List Archive, gstreamer-devel@list.freedesktop.org 411 + date: 2012-11-26 412 + url: 413 + value: https://gstreamer-devel.narkive.com/LJuu7yM3/dynamic-pipeline-non-strictly-monotonic-pts-warning-with-x264enc-after-switching-source 414 + date: 2025-03-26
paper/main.pdf

This is a binary file and will not be displayed.

+42 -48
paper/main.typ
··· 579 579 580 580 Ce contexte, en plus de quelques informations déposées par la boucle de rendu (milliseconde actuelle, numéro de frame actuel, etc), contient surtout _des informations musicales sur l'instant présent_, comme les notes actuellement jouées, les amplitudes instantanées de chaque piste, etc. 581 581 582 - Afin d'obtenir ces information, il faut bien analyser quelque chose: la question est donc: de quels fichiers ou signaux tirer parti pour construire ces informations de synchronisation? 582 + Afin d'obtenir ces information, il faut bien analyser quelque chose---la question est donc: de quels fichiers ou signaux tirer parti pour construire ces informations de synchronisation? 583 583 584 584 Les sous-sections suivantes traites des différentes approches explorées: 585 585 586 - / Amplitudes _stems_-par-_stems_: utilisation des signaux audio bruts depuis des exports piste par piste du morceau 586 + / Amplitudes des _stems_: utilisation des signaux audio bruts depuis des exports piste par piste du morceau 587 587 / Analyse de fichiers MIDI: utilisation d'un standard stockant les notes jouées dans le temps. 588 588 / Analyse de fichiers .flp: utilisation des fichiers de projet de FL Studio, un logiciel de production musicale. C'est l'équivalent d'un fichier source en programmation, là où l'export .mp3 serait l'équivalent d'un exécutable. 589 589 / Sondes dans le logiciel de MAO#footnote[MAO: Musique Assistée par Ordinateur]: utilisation de plugins VST pour envoyer des informations de synchronisation potentiellement arbitraire, directement depuis le logiciel de production musicale. ··· 592 592 Dans chacun de ces cas, l'objectif est de pouvoir inférer depuis ces ressources les informations suivantes: 593 593 594 594 - Le BPM#footnote[Beats per minute, aussi appelé tempo], avec éventuellement des évolutions au cours du morceau 595 - - Des marqueurs temporels, permettant de réagir à des changements de phrases musicales (par exemple, la classique construction _build-up_ / _drop_ / _break_ en EDM#footnote[Electronic Dance Music]), sans avoir à coder en dur un timestamp dans le code de la vidéo: ces marqueurs sont placés dans le logiciel de production musicale (cf #ref(<flstudiomarkers>), #ref(<flstudiomarkers>, form: "page")) 595 + - Des marqueurs temporels, permettant de réagir à des changements de phrases musicales (par exemple, la classique construction _build-up_ / _drop_ / _break_ en EDM#footnote[Electronic Dance Music]), sans avoir à coder en dur un timestamp dans le code de la vidéo. Ces marqueurs sont placés dans le logiciel de production musicale (cf #ref(<flstudiomarkers>), #ref(<flstudiomarkers>, form: "page")) 596 596 - Pour chaque instrument, et à chaque instant: 597 597 - Les notes jouées: pitch#footnote[hauteur] et vélocité#footnote[intensité avec laquelle la note a été jouée] 598 598 - Des éventuelles évolutions de paramètres influant sur le timbre de l'instrument (ouverture d'un filtre passe bas pour un synthétiseur, pédale de sustain pour un piano, etc) 599 599 600 600 601 - == Amplitudes _stems_-par-_stems_ 601 + == Amplitudes des _stems_ 602 602 603 - Cette approche consiste à demander à l'artiste de fournir un fichier audio par piste du morceau de musique. On entend "piste" ici assez vaguement, plus le nombre de fichiers est grand, plus il est possible de réagir à des changements d'amplitudes individuels. En général, une piste correspond un-à-un à un instrument. 603 + Cette approche consiste à demander à l'artiste de fournir un fichier audio par piste du morceau de musique. La définition de "piste" est ici assez vague. Plus le nombre de fichiers est grand, plus il est possible de réagir à des changements d'amplitudes individuels. En général, une piste à un instrument. 604 604 605 605 === Accessibilité 606 606 607 607 Exporter un projet en fichiers audios piste-par-piste, des _stems_, est une pratique plutôt courante, par exemple lors de concours de remix @remixconteststems, pour fournir aux participant·e·s les éléments du morceau séparés et ainsi faciliter la création d'un remix. 608 608 609 - On pourrait faciliter encore plus l'usage en, par exemple, proposant de faire de la séparation de source par réseaux neuronaux si l'artiste ne peut pas ou ne souhaite pas faire un export en stems @sourcesep. Cette approche serait d'autant plus utile car l'on n'a pas le besoin ici d'une qualité sonore sur les pistes séparées, étant donné que l'on ne s'en sert qu'à des fins d'analyse pour de la synchronisation. 610 - 611 - 609 + On pourrait faciliter encore plus l'usage en, par exemple, proposant de faire de la séparation de source par réseaux neuronaux si l'artiste ne peut pas ou ne souhaite pas faire un export en stems @sourcesep. Cette approche resterait pertinente même en cas de résultats habituellements considérés comme insatisfaisants dans le domaine de la séparation de sources, étant donné que l'on ne s'en sert qu'à des fins d'analyse pour de la synchronisation -- l'export audio final du morceau fournit à lui seul la bande son de la vidéo. 612 610 613 611 === Performance 614 612 615 - Néanmoins, ce processus de lire dans une structure de donnée les amplitudes à chaque instant reste assez coûteux, que ce soit en temps de calcul ou en mémoire. 613 + Néanmoins, ce processus demande de remplir une structure de donnée avec des amplitudes _à chaque instant_, ce qui est assez coûteux, que ce soit en temps de calcul ou en mémoire. 616 614 617 615 === Faisabilité 618 616 619 - De plus, la correspondance signal $mapsto$ note jouée est beaucoup moins évidente qu'elle n'en paraît. Un signal peut être décomposé en amplitude et fréquence, mais une note possède deux caractéristiques bien plus utiles aux musicien·ne·s: 617 + La correspondance signal $mapsto$ note jouée est beaucoup moins évidente qu'elle ne le paraît. Un signal peut être décomposé en amplitude et fréquence, mais une note possède deux caractéristiques bien plus utiles aux musicien·ne·s: 620 618 621 - / Vélocité $cancel(arrow.l.bar)$ amplitude: Les amplitudes d'un signal sont très variables, et il est difficile de déterminer un seuil de déclenchement efficace, en prenant en compte la présence d'effets (en particulier l'echo ou la réverbération). 619 + / Vélocité $cancel(arrow.l.bar)$ amplitude: Les amplitudes d'un signal sont très variables, et il est difficile de déterminer un seuil de détection efficace pour considéré qu'une note a été jouée, surtout en la présence d'effets (en particulier de l'echo ou de la réverbération). 622 620 / Pitch $arrow.l.bar$ fréquence: Pour obtenir le pitch d'une note, il faut effectuer une analyse fréquentielle du signal. Ceci pourrait à priori ne pas être trop complexe, mais n'a pas été tenté étant donné les difficultés soulevées par le point précédent. Il est en plus très difficile de séparer plusieurs notes d'un accord. 623 621 624 622 ··· 633 631 - Pour chaque piste: les notes jouées (pitch et vélocité) 634 632 - Pour le morceau dans sa globalité, le BPM 635 633 636 - Bien que l'on puisse assez facilement inférer une sorte d'amplitude simulée à partir des vélocités, le problème inverse se pose: si l'on veut animer un objet en prenant en compte les échos, par exemple, MIDI ne peut pas nous aider. 634 + Bien que l'on puisse assez facilement inférer une sorte d'amplitude simulée à partir des vélocités, le problème opposé se pose: si l'on veut animer un objet en prenant en compte les échos, par exemple, MIDI ne peut pas nous aider. 637 635 638 636 Mais pour de nombreux usages, le résultat final paraît beaucoup plus "en réaction avec la musique" qu'avec une approche par amplitudes réelles, certainement grâce à la précision apportée par le fait d'utiliser les évènements de notes jouées "à la source". 639 637 ··· 653 651 ) 654 652 655 653 656 - …Sauf que les coordonnées temporelles MIDI sont en _deltas de ticks MIDI_. Les ticks sont indépendant du BPM, et les deltas sont des simples différences du nombre de ticks passés entre deux évènements. 654 + …Sauf que les coordonnées temporelles MIDI sont en _deltas de ticks MIDI_. Les ticks sont indépendant du BPM, et les deltas sont de simples différences du nombre de ticks passés entre deux évènements. 657 655 658 - La durée d'un tick est aussi dépendante du _PPQ_, ou _Pulse per quarter_, qui correspond à la résolution temporelle d'un fichier MIDI, c'est l'équivalent des FPS en vidéos ou de la fréquence d’échantillonnage en audio @midippq. 656 + La durée d'un tick est aussi dépendante du _PPQ_, ou _Pulse per quarter_, qui correspond à la résolution temporelle d'un fichier MIDI -- c'est l'équivalent des FPS en vidéos ou de la fréquence d’échantillonnage en audio @midippq. 659 657 660 658 #codesnippet( 661 659 include-function( ··· 720 718 721 719 === Conclusion 722 720 723 - Cette méthode, malgré l'aspect fastidieux de sa mise en place, est une amélioration nette par rapport à l'approche par amplitude: 721 + Cette méthode, malgré l'aspect fastidieux de sa mise en place, est une amélioration nette par rapport à l'approche par amplitude 724 722 725 723 #codesnippet[ 726 724 #monospace[ ··· 750 748 751 749 === FL Studio 752 750 753 - Il existe une bibliothèque Python, pyflp @pyflp, qui permet de parser les fichiers de projets FL Studio, et d'en extraire la quasi totalité. 751 + Il existe une bibliothèque Python, pyflp @pyflp, qui permet de parser les fichiers de projets FL Studio, et d'en extraire la quasi totalité des informations intéréssantes. 754 752 755 753 #codesnippet( 756 754 size: 0.9em, ··· 768 766 769 767 ==== Performance 770 768 771 - Étant donné que l'adapter est en Python, l'intégrer proprement dans Shapemaker consisterai à éventuellement utiliser une solution de FFI#footnote[Foreign Function Interface, permettant d'appeler des fonctions écrites dans un autre langage de programmation] comme PyOxide @pyo3, ce qui demanderait également beaucoup de travail d'adaptation. 769 + Étant donné que l'adapter est en Python, l'intégrer proprement dans Shapemaker consisterai à éventuellement utiliser une solution de FFI#footnote[Foreign Function Interface, permettant d'appeler des fonctions écrites dans un autre langage de programmation] comme PyOxide @pyo3, ce qui demanderait beaucoup de travail d'adaptation. 772 770 773 771 == Dépôt de "sondes" dans le logiciel de MAO <crate::vst> 774 772 ··· 781 779 782 780 L'avantage de cette approche est qu'elle est agnostique au logiciel de MAO: en effet, VST est _le_ standard de plugins audio, supporté par tout les logiciels. 783 781 784 - C'est via cette technologie que les artistes peuvent jouer des instruments virtuels, allant des pianos physiquement simulés @pianoteq, en passant par vocaloïdes#footnote[simulateurs de parole chantée, cas à application musicale de la synthèse vocale] (comme par exemple Hatsune Miku @mikudayooo), aux synthétiseurs additifs, soustractifs, à wavetables (dont un exemple très populaire est Serum @serum). 782 + C'est via cette technologie que les artistes peuvent jouer des instruments virtuels, allant des pianos physiquement simulés @pianoteq, en passant par vocaloïdes#footnote[simulateurs de parole chantée, cas à application musicale de la synthèse vocale] (comme par exemple Hatsune Miku @mikudayooo), aux synthétiseurs additifs, soustractifs ou à wavetables (dont un exemple très populaire est Serum @serum). 785 783 786 784 C'est aussi cette technologie qui est utilisée pour appliquer des effets aux signaux audio créés par les instruments (on parle de VST _effets_, contrairement aux VST _générateurs_), allant des modélisations de pédales d'effets de guitare ou de compresseurs analogiques à tube, aux simulation de compression digitale de signaux ("bitcrushing"), aux égaliseurs fréquentiels. 787 785 ··· 799 797 800 798 Autre possibilité, qui s'avère utile parmi nos objectifs: les VSTs peuvent exposer à l'hôte (le logiciel de MAO) des paramètres changeables, ce qui permet de faire évoluer le timbre d'un instrument, l'intensité d'une réverbération, etc. Faire varier des paramètres au cours du temps est un aspect essentiel de la musique, en particulier électronique, qui contribue à "donner vie" à un morceau. 801 799 802 - On peut donc également exposer des paramètres sur notre VST-sonde, qui peuvent servir à automatiser des changements de couleurs, de formes, etc, en suivant une évolution dans le timbre d'un instrument, par exemple, depuis la source directement (il suffit d'envoyer le signal d'automatisation au VST-sonde, en plus de l'instrument lui-même). 800 + On peut donc également définir des paramètres sur notre VST-sonde, qui peuvent servir à, par exemple, automatiser des changements de couleurs en suivant une évolution dans le timbre d'un instrument, depuis la source directement (il suffit d'envoyer le signal d'automatisation au VST-sonde, en plus de l'instrument lui-même). 803 801 804 - On exfiltre ensuite ces données hors du logiciel vers un "beacon", via un simple API WebSocket, qui permet une communication instantanée beaucoup plus performante que des requêtes HTTP, et est plus approprié à l'envoie de potentiellement plusieurs milliers de points de données par secondes: en effet, le VST-sonde s’immisçant dans la chaîne de traitement audio, il ne doit pas la ralentir considérablement, sous peine de rendre le logiciel de MAO inutilisable 802 + On exfiltre ensuite ces données hors du logiciel vers un "beacon", via un simple API WebSocket, qui permet une communication instantanée beaucoup plus performante que des requêtes HTTP, et est plus approprié à l'envoie de potentiellement plusieurs milliers de points de données par secondes: en effet, le VST-sonde s’immisçant dans la chaîne de traitement audio, il ne doit pas la ralentir considérablement, sous peine de rendre le logiciel de MAO inutilisable. 805 803 806 804 #codesnippet( 807 805 caption: "Implémentation de la fonction permettant à une probe de se signaler auprès du beacon", ··· 820 818 ], 821 819 ) 822 820 823 - Enfin, on utilise la crate _nih-plug_ @nihplug pour exporter la partie VST de notre code en un plugin VST, chargeable dans un logiciel de MAO 821 + Enfin, on utilise la crate _nih-plug_ @nihplug pour exporter la partie VST de notre code en un fichier `.vst3`, chargeable dans un logiciel de MAO. 824 822 825 823 #diagram( 826 824 caption: [Exfiltration de données depuis la chaîne de traitement du logiciel de MAO], ··· 875 873 876 874 subgraph cluster_shapemaker { 877 875 label = "Shapemaker" 878 - wip[label="(en développement)", shape="plaintext"] 876 + wip[label="(en développement)", shape="plaintext", color=darkblue] 879 877 beacon -> wip 880 878 } 881 879 ··· 924 922 925 923 Ces appareils sont appelés "contrôleurs MIDI", du protocole standard qui régit leur communication avec l'ordinateur. 926 924 927 - S'il est évidemment possible d'interagit avec ces contrôleurs depuis un programme natif (c'est après tout ce que font les logiciels de production musicale), j'ai préféré tenté l'approche Web, pour en faciliter l'accessibilité et en réduire le temps nécessaire à la mise en place #footnote[ 925 + S'il est évidemment possible d'interagir avec ces contrôleurs depuis un programme natif (c'est après tout ce que font les logiciels de production musicale), j'ai préféré tenté l'approche Web, pour en faciliter l'accessibilité et en réduire le temps nécessaire à la mise en place #footnote[ 928 926 Imaginez, votre ordinateur a un problème 5 minutes avant le début d'une installation live, et vous aviez prévu d'utiliser Shapemaker pour des visuels. En faisant du dispositif un site web, il suffit de brancher son contrôleur à l'ordinateur d'un·e ami·e, et c'est tout bon. 929 927 ]. 930 928 931 929 Comme pour de nombreuses autres technologies existant à la frontière entre le matériel et le logiciel, les navigateurs mettent à disposition des sites web une technologie permettant de communiquer avec les périphériques MIDI connectés à la machine: c'est l'API WebMIDI @webmidi. 932 930 933 - Mais bien évidemment, tout le code de Shapemaker, tout ses capacités de génération de formes, sont implémentées en Rust. 931 + Mais bien évidemment, tout le code de Shapemaker, toutes ses capacités de génération de formes, sont implémentées en Rust. 934 932 935 - Il existe cependant un moyen de "faire tourner du code Rust" dans un navigateur Web: la compilation vers WebAssembly (WASM), un langage assembleur pour le web @wasm, qui est une cible de compilation pour quelques des langages compilés plus modernes, comme Go @gowasm or Rust @rustwasm 933 + Il existe cependant un moyen de "faire tourner du code Rust" dans un navigateur Web: la compilation vers WebAssembly (WASM), un langage assembleur pour le web @wasm, qui est une cible de compilation pour quelques des langages compilés plus modernes, comme Go @gowasm or Rust @rustwasm. 936 934 937 - En exportant la _crate_ shapemaker en bibliothèque Javascript via wasm-bindgen @wasmbindgen, il est donc possible d’exposer à une balise #raw("<script>", lang: "html") les fonctions de la bibliothèque, et brancher donc celles-ci à des _callbacks_ donnés par l'API WebMIDI: 935 + En exportant la _crate_ shapemaker en bibliothèque Javascript via wasm-bindgen @wasmbindgen, il est donc possible d’exposer à une balise #raw("<script>", lang: "html") les fonctions de la bibliothèque, pour les brancher à un _callback_ donné par l'API WebMIDI: 938 936 939 937 #figure( 940 938 caption: "Exposition de fonctions à WASM depuis Rust, et utilisation de celles-ci dans un script Javascript", ··· 990 988 991 989 = Performance 992 990 993 - Les premiers prototypes de Shapemaker avait une implémentation sérielle, ou le code Rust ne s'occupait seulement de la partie génération de formes et sérialisation en SVG. Chaque frame SVG étaient sauvegardées dans un fichier, puis converti en PNG en ligne de commande via ImageMagick. Les frames étaient ensuite concaténées en une vidéo via FFmpeg, également en ligne de commande. 991 + Les premiers prototypes de Shapemaker avait une implémentation sérielle, ou le code Rust s'occupait seulement de la partie génération de formes et sérialisation en SVG. Chaque frame SVG était sauvegardée dans un fichier, puis converti en PNG en ligne de commande via ImageMagick @imagemagick. Les frames étaient ensuite concaténées en une vidéo via FFmpeg, également en ligne de commande. 994 992 995 993 #diagram( 996 994 caption: [Pipeline de rendu, premier prototype], ··· 998 996 ```dot 999 997 digraph { 1000 998 rankdir="LR"; 999 + compound=true; 1001 1000 node [shape="record"]; 1002 1001 subgraph cluster_each_frame { 1003 1002 label = "Chaque frame" ··· 1005 1004 label = "Rust" 1006 1005 canvas -> "Frame 0037.svg" 1007 1006 } 1008 - "Frame 0037.svg" -> "Frame 0037.png" [label="$ magick convert"] 1007 + "Frame 0037.svg" -> "Frame 0037.png" [label="$ magick"] 1009 1008 } 1010 - "Frame 0037.png" -> "video.mp4" [label="$ ffmpeg"] 1009 + "Frame 0037.png" -> "video.mp4" [label="$ ffmpeg", ltail=cluster_each_frame] 1011 1010 } 1012 1011 ```, 1013 1012 ) 1014 1013 1015 - Un des plus gros gains de performance a été d'éliminer le plus d'I/O#footnote[Input/Output] possible, et notamment aussi d'éviter un encodage/décodage PNG en passant des pixmap (matrices de pixels) directement 1014 + Un des plus gros gains de performance a été achevé en éliminant le plus d'I/O#footnote[Input/Output] possible ainsi qu'un encodage/décodage PNG, en passant des pixmap (matrices de pixels) directement. 1016 1015 1017 1016 1018 1017 #diagram( 1019 - caption: [Pipeline de rendu sans #emph[shell-out]s#footnote[Invoquer un programme en ligne de commande (dans un shell), au lieu de faire tourner du code dans le programme courant]], 1018 + caption: [Pipeline de rendu sans #emph[shell-out]#footnote[Invoquer un programme en ligne de commande (dans un shell), au lieu de faire tourner du code dans le programme courant]s], 1020 1019 size: 85%, 1021 1020 ```dot 1022 1021 digraph { 1023 1022 rankdir="LR"; 1023 + compound=true; 1024 1024 node [shape="record"]; 1025 1025 subgraph cluster_rust { 1026 1026 label = "Rust" ··· 1029 1029 canvas -> "SVG string" 1030 1030 "SVG string" -> "Pixmap" [label="resvg"] 1031 1031 } 1032 - Pixmap -> "video.mp4" [label="libx264"] 1032 + Pixmap -> "video.mp4" [label="libx264", ltail=cluster_each_frame] 1033 1033 } 1034 1034 } 1035 1035 ```, 1036 1036 ) 1037 1037 1038 - L'inconvénient est que, pour la partie encoding vidéo, il n'existe pas encore vraiment d'encodeur H.264#footnote[Codec vidéo, très souvent utilisé pour les fichiers MP4, par exemple] en pur Rust, la plupart des solutions étant des bindings#footnote[bibliothèque utilisant des FFIs pour donner un accès idiomatique à une bibliothèque provenant d'un autre langage de programmation] vers des bibliothèques C, notamment ffmpeg. 1038 + L'inconvénient est que, pour la partie encodage vidéo, il n'existe pas encore vraiment d'encodeur H.264#footnote[Codec vidéo, très souvent utilisé pour les fichiers MP4, par exemple] en pur Rust, la plupart des solutions étant des bindings#footnote[bibliothèque utilisant des FFIs pour donner un accès idiomatique à une bibliothèque provenant d'un autre langage de programmation] vers des bibliothèques C, notamment ffmpeg @ffmpeg. 1039 1039 1040 1040 Cela rend l'installation de la bibliothèque beaucoup plus complexe, notamment sur Windows (les logiciels de production musicale sont très rares à fonctionner correctement sur Linux, surtout quand on prend en compte que les VSTs doivent eux aussi fonctionner sur Linux): 1041 1041 ··· 1115 1115 1116 1116 == Rastérisation parallèle <perf-parallelrasterize> 1117 1117 1118 - Si la partie `render_to_svg` n'est pas parallélisable car il faut bien faire exécuter tout les hooks dans l'ordre, la rastérisation des SVG sortants, elle, est bien parallélisable. Malheureusement, le gain de performance n'a pas été significatif. 1118 + Si la partie `render_to_svg` n'est pas parallélisable car il faut bien faire exécuter tous les hooks dans l'ordre, la rastérisation des SVG sortants, elle, est bien parallélisable. Malheureusement, le gain de performance n'a pas été significatif, au contraire: rastériser toutes les frames, avant de commencer à encoder, implique de remplir la RAM avec des pixmaps -- une par frame -- ce qui conduit à une utilisation complète de toute la RAM de la machine, et bloque ainsi le système. Une approche avec une _queue_ de taille maximale limitée, de laquelle l'encodeur pourrait récupérer les pixmaps rastérisées, reste à explorer. 1119 1119 1120 1120 == Encodage H.264 parallèle? 1121 1121 1122 - Si l'on est bien capable de donner à l'encodeur nos frames dans le désordre, tout en lui indiquant le timestamp de chaque frame, l'encodeur ne supporte pas de recevoir les frames dans le désordre: 1123 - 1124 - #align(center)[ 1125 - 1126 - ] 1127 - 1128 - Il est donc impossible de paralléliser l'encodage 1122 + Si l'on est bien capable de donner à l'encodeur nos frames dans le désordre, tout en lui indiquant le timestamp de chaque frame, l'encodeur doit recevoir les frames dans l'ordre @libx264order. Il est donc impossible de paralléliser l'encodage. 1129 1123 1130 1124 == Pixmap et frames HWC: 100ms de standards 1131 1125 ··· 1139 1133 ``` 1140 1134 ] 1141 1135 1142 - Tandis que la bibliothèque utilisée, _video-rs_, attend une matrice HWC, ou height-width-channels, de pixels RGB @videorshwc, @videorshcwframe, @array3rust: 1136 + Tandis que la bibliothèque utilisée, _video-rs_, attend une matrice HWC, ou height-width-channels, de pixels RGB @videorshwc @videorshcwframe @array3rust: 1143 1137 1144 1138 #align(center)[ 1145 1139 ``` ··· 1187 1181 1188 1182 On effectue toujours de la copie, mais la conversion est nettement plus rapide ainsi. 1189 1183 1190 - Bien évidemment, il ne faut pas faire d'erreur dans les calculs des coordonnées des pixels, ce qui peut donner des résultats surprenants, et éventuellement artistiquement intéréssants: 1184 + Bien évidemment, il ne faut pas faire d'erreur dans les calculs des coordonnées des pixels, ce qui peut donner des résultats surprenants, même si éventuellement artistiquement intéréssants: 1191 1185 1192 1186 #grid( 1193 1187 columns: (1fr, 1fr), ··· 1205 1199 1206 1200 Une solution serait de passer à une bibliothèque plus bas niveau et voir s'il est possible de donner directement les données de pixmap à l'encodeur, sans conversion, ou tout du moins sans avoir à copier les données. 1207 1201 1208 - Une autre solution est de faire proposer une contribution à la bibliothèque de rendu utilisée par _resvg_, _tiny_skia_#footnote[Tiny-skia est notamment utilisé par Typst @typsttinyskia @typsttinyskiacargotoml, l'alternative moderne à LaTeX sur laquelle ce papier a été typeset], pour pouvoir instrumentaliser les lectures et écritures à sa pixmap, et ainsi écrire dans la représentation voulue par libx264 directement. 1202 + Une autre solution est de proposer une contribution à la bibliothèque de rendu utilisée par _resvg_, _tiny_skia_#footnote[Tiny-skia est notamment utilisé par Typst @typsttinyskia @typsttinyskiacargotoml, l'alternative moderne à LaTeX sur laquelle ce papier a été typeset], pour y ajouter la possibilité d'instrumentaliser les lectures et écritures à sa pixmap, et ainsi stocker la représentation voulue par libx264 directement. 1209 1203 1210 1204 == SVG vers string vers SVG <perf-svgstring> 1211 1205 1212 - Comme on peut le remarquer, il y a un gain de performance assez conséquent de possible si l'on parvient à utiliser usvg, non seulement pour la rastérisation, mais également pour la construction de l'arbre SVG: sur une boule de rendu de 167 ms, *on passe 29% du temps à parser un arbre SVG sérialisé, alors que l'on vient de construire cette arbre*. 1206 + Comme on peut le remarquer, un gain de performance assez conséquent est possible si l'on parvient à utiliser usvg, non seulement pour la rastérisation, mais également pour la construction de l'arbre SVG: sur une boule de rendu de 167 ms, *on passe 29% du temps à parser un arbre SVG sérialisé, alors que l'on vient de construire cette arbre.* 1213 1207 1214 1208 = Conclusion 1215 1209 ··· 1223 1217 1224 1218 Enfin, un des points les plus importants à améliorer reste la "feedback loop" _pendant la conception d'une procédure de génération_, qui reste extrêmement longue à cause de la lenteur de compilation de Rust, et du fait que, contrairement à un logiciel de montage vidéo, par exemple, on ne peut que re-rendre la vidéo en MP4 (même si l'on peut décider de rendre qu'une petite partie), ouvrir le fichier, et regarder le résultat. 1225 1219 1226 - Une idée serait de, là aussi, utiliser le backend WASM/WebMIDI pour fournir une sorte de preview du code en temps réel: une interface simple permet de placer une tête de lecture à un instant, et montre la frame à cet instant, et se rafraîchit quand le code change. Avec éventuellement la possibilité de faire "play". 1220 + Une idée serait de, là aussi, utiliser le backend WASM/WebMIDI pour fournir une sorte de preview du code en temps réel: une interface simple permettrait de placer une tête de lecture à un instant pour y montrer la frame, et se rafraîchirait quand le code change. Avec éventuellement la possibilité de faire "play". 1227 1221 1228 1222 Encore faut-il que la vitesse de recompilation de Rust le permette, même si ce serait à proiri possible tant que la crate utilisant Shapemaker (celle que l'artiste écrit) reste légère. 1229 1223 ··· 1233 1227 1234 1228 Cela permettrait éventuellement aussi d'améliorer la vitesse de compilation de la crate écrite par l'artiste, qui pourrait, si elle est trop faible, empêcher l'implémentation de la solution de feedback loop telle qu'évoquée plus tôt. Des projets comme Tauri embarque un système de HMR#footnote[Hot Module Replacement, permettant de recharger du code en temps réel sans recharger la page, technologie assez prévalente dans le développement web frontend], non pas pour leur bibliothèque Rust, mais pour les bindings JavaScript exposé aux utilisateur·ice·s de la bibliothèque @taurihmr. 1235 1229 1236 - On pourrait même envisager afficher cette _preview_ dans le logiciel de MAO, en tant qu'un 2e VST, "Shapemaker Preview". Ceci demande d'implémenter encore un backend de rendu, autre que H.264 ou WASM, mais serait certainement la meilleure solution en terme d'UX#footnote[expérience utilisateur·ice] 1230 + On pourrait même envisager afficher cette _preview_ dans le logiciel de MAO, en tant qu'un 2e VST, "Shapemaker Preview". Ceci demande d'implémenter encore un backend de rendu, autre que H.264 ou WASM, mais serait certainement la meilleure solution en terme d'UX#footnote[expérience utilisateur·ice]. 1237 1231 1238 1232 == Code source 1239 1233 ··· 1247 1241 1248 1242 == Exemples 1249 1243 1250 - Le projet n'étant pas encore terminé, il n'a pas encore de clips musicaux publiés. Cependant, voici des liens vers quelques tests: 1244 + Le projet n'étant pas encore terminé, il n'y a pas encore de clips musicaux publiés. Cependant, voici des liens vers quelques tests: 1251 1245 1252 1246 - #link("https://youtu.be/3lx6VAz_UKM") 1253 1247 - #link("https://instagram.com/p/C62JfogoUt9")