···11# See https://github.com/typst/hayagriva/pull/192
22# yaml-language-server: $schema=https://raw.githubusercontent.com/typst/hayagriva/0c640417cfb35067c13f1ee0ce0ee35f57a897fb/hayagriva.schema.json
3344+# TODO raise an issue , anchors are not interpreted
55+# today: &retrieved
66+# type: web
77+# date: 2025-03-22
88+49webmidi:
510 type: reference
1111+ title: Web MIDI API
612 url: https://developer.mozilla.org/en-US/docs/Web/API/Web_MIDI_API
1313+ date: 2025-03-22
1414+ organization: Mozilla Developer Network
1515+ author: MDN Authors
1616+1717+pianowasmdemo:
1818+ type: video
1919+ title: Démo de piano avec shapemaker
2020+ url: https://www.instagram.com/p/C6byymcou5k/
2121+ date: 2024-05-01
2222+ author: Gwenn Le Bihan
2323+2424+wasmbindgen:
2525+ type: book
2626+ title: The `wasm-bindgen` Guide
2727+ url: https://rustwasm.github.io/wasm-bindgen/introduction.html
2828+ date: 2025-03-22
2929+ author: Rust and WebAssembly Working Group
3030+3131+wasm:
3232+ title: WebAssembly
3333+ type: web
3434+ url: https://webassembly.org/
3535+ date: 2025-03-22
3636+ author: WebAssembly Community Group
7373838+svginhtml:
3939+ title: Scalable Vector Graphics (SVG) 2 § 1.1 About SVG
4040+ type: reference
4141+ url: https://svgwg.org/svg2-draft/intro.html#AboutSVG
4242+ date: 2023-03-08
4343+ author:
4444+ - Amelia Bellamy-Royds
4545+ - Chris Lilley
4646+ - Tavmjong Bah
4747+ - Dirk Schulze
4848+ - Eric Willigers
4949+ publisher: W3C Editor's Draft
paper/main.pdf
This is a binary file and will not be displayed.
+63
paper/main.typ
···66666767== Temps réel: WASM et WebMIDI
68686969+Il est possible de réagir en temps réel à des pressions de touches sur des appareils conçus pour la production musicale assistée par ordinateur (MAO): des claviers, des potentiomères pour ajuster des réglages affectant le timbre d'un son, des pads pour déclencher des sons et, par exemple, jouer des percussions, etc.
7070+7171+Ces appareils sont appelés "contrôleurs MIDI", du protocole standard qui régit leur communication avec l'ordinateur.
7272+7373+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écéssaire à la mise en place #footnote[
7474+ 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 dispostif un site web, il suffit de brancher son contrôleur à l'ordinateur d'un·e ami·e, et c'est tout bon.
7575+].
7676+7777+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.
7878+7979+Mais bien évidemment, tout le code de Shapemaker, tout ses capacités de génération de formes, sont implémentées en Rust.
8080+8181+Il existe cependant un moyen de "faire tourner du code Rust" dans un navigateur Web: la compilation vers WebAssembly (WASM) @wasm.
8282+8383+En exportant la _crate_ shapemaker en bibliothèque Javascript via wasm-bindgen @wasmbindgen, il est donc possible d'exoser à 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:
8484+8585+#figure(caption: "Exposition de fonctions à WASM depuis Rust", [
8686+```rust
8787+#[wasm_bindgen]
8888+pub fn render_image(opacity: f32, color: Color) -> Result<(), JsValue> {
8989+ let mut canvas = /* ... */
9090+9191+ *WEB_CANVAS.lock().unwrap() = canvas;
9292+ render_canvas_at(String::from("body"));
9393+9494+ Ok(())
9595+}
9696+```
9797+])
9898+9999+#figure(caption: "Utilisation des fonctions exposées dans un script Javascript", [
100100+```js
101101+import init, { render_image } from "./shapemaker.js"
102102+103103+void init()
104104+105105+navigator.requestMIDIAccess().then((midiAccess) => {
106106+ Array.from(midiAccess.inputs).forEach((input) => {
107107+ input[1].onmidimessage = (msg) => {
108108+ const [cmd, ...args] = [...msg.data]
109109+ if (cmd !== 144) return
110110+111111+ // Touche enfoncée
112112+ const [pitch, velocity] = args
113113+114114+ // get octave from pitch
115115+ const octave = Math.floor(pitch / 12) - 1
116116+117117+ if (velocity === 0) {
118118+ fadeOutElement(frameElement(color))
119119+ } else {
120120+ render_image(velocity / 128, octave)
121121+ }
122122+ }
123123+ })
124124+})
125125+```
126126+])
127127+128128+Au final, on peut arriver à une performance live interactive @pianowasmdemo intéréssante, et assez réactive pour ne pas avoir de latence (et donc de désynchronisation audio/vidéo) perceptible.
129129+130130+Les navigateurs Web supportant nativement le format SVG, qui se décrit notamment comme incluable directement dans le code HTML d'une page web @svginhtml, il est possible de simplement générer le code SVG, et de laisser le navigateur faire le rendu, ce qui s'avère être une solution très performante.
131131+69132== Amplitudes de _stems_
7013371134== Export MIDI
+1-1
paper/template.typ
···2222 show math.equation: set block(spacing: 0.65em)
2323 set math.equation(numbering: "(1)")
2424 set heading(numbering: "1.1 ")
2525- show heading: set text(font: "Martian Mono")
2525+ // show heading: set text(font: "Martian Mono")
26262727 // Set run-in subheadings, starting at level 4.
2828 show heading: it => {