docs: add nested CLAUDE.md tree

Root CLAUDE.md (overview, where-to-look, conventions) plus
nested files for data_only_viz, oscope-of, launcher.
sound_algo already had its own nested tree.

Sized for the ~150-instruction budget: root 43 lines,
each nested 43-52 lines, telegraphic style.
This commit is contained in:
L'électron rare
2026-05-13 10:56:55 +02:00
parent ef288a7664
commit 0825b35463
4 changed files with 181 additions and 0 deletions
+43
View File
@@ -0,0 +1,43 @@
# AV-Live
Live coding audio-visual performance system : moteur SuperCollider, visualiseur openFrameworks piloté par un oscilloscope Hantek 6022BL, app menubar macOS qui orchestre le tout.
## Communication
Toujours répondre en français à l'utilisateur. Code, commentaires de code, commits et docs en anglais.
## Stack par sous-projet
| Sous-projet | Stack |
|-------------|-------|
| `sound_algo/` | SuperCollider (sclang + scsynth), 1099 SynthDefs, 345 tracks |
| `oscope-of/` | openFrameworks C++, libusb (Hantek bulk), GLSL 150 GL 3.2 core |
| `launcher/` | SwiftUI menubar app, Swift Package Manager |
| `data_only_viz/` | Python 3.11+ via `uv`, Metal natif (pyobjc), multi-backends pose |
| `web_realart/` | Node.js, Express, OSC bridge |
## Where to Look
| Tâche | Emplacement |
|-------|-------------|
| Ajouter / modifier un SynthDef, track, palette | `sound_algo/` (déjà documenté en nested) |
| Toucher au visualiseur, shaders, FFT, Hantek | `oscope-of/` |
| Modifier l'app menubar macOS | `launcher/` |
| Détection pose / mesh / body tracking | `data_only_viz/` |
| Bridge web / UI de live coding | `web_realart/` |
| Plans / specs en cours | `docs/superpowers/plans/` |
## Conventions globales
- Python : **uv** systématiquement (jamais pip/poetry/conda directs).
- Pas d'emojis dans code/docs/commits sauf demande explicite.
- Commits : sujet ≤ 50 char, body ≤ 72 char/ligne, pas d'attribution AI, pas de `--no-verify`, pas d'underscore dans le scope (hooks enforcent).
- `*.pt`, `*.ckpt`, `*.safetensors`, `*.mlpackage` exclus par `.gitignore` racine.
## Agent Workflow
Explore localise → librarian lit (>500 lignes) → tu raisonnes → general-purpose implémente → validator vérifie. Lance les tâches indépendantes en parallèle.
## Guidance imbriquée
Chaque sous-projet majeur a son propre `CLAUDE.md`. Claude charge automatiquement le plus proche du fichier édité (« closest wins »). N'ajouter ici que ce qui s'applique à TOUS les sous-projets.
+52
View File
@@ -0,0 +1,52 @@
# data_only_viz
Visualiseur natif Metal (pyobjc) pour le mode data-only d'AV-Live : capture caméra → détection pose multi-personne → tracker → rendu Metal → OSC out vers `oscope-of`.
## Environnement
```bash
cd data_only_viz
uv sync # base
uv sync --extra pose # MediaPipe + YOLO + Ultralytics
uv sync --extra nlf # Neural Localizer Fields (SMPL body mesh)
uv sync --extra detrpose # DETRPose transformer (clone manuel — voir detrpose.py)
uv run python -m data_only_viz.main # lancement standard
```
Python **3.11+** requis. `pyproject.toml` est la source de vérité — ne jamais éditer `uv.lock` à la main.
## Backends pose disponibles
| Backend | Fichier | Statut |
|---------|---------|--------|
| MediaPipe Holistic | `holistic.py` | stable |
| Ultralytics YOLOv8-pose | `pose.py` | stable, modèle `yolov8n-pose.pt` à la racine repo |
| Apple Vision (Core ML) | `apple_vision_pose.py`, `coreml_pose.py` | macOS uniquement |
| DETRPose | `detrpose.py` | clone manuel + checkpoint, voir docstring |
| NLF (SMPL body mesh) | `nlf_worker.py` | TorchScript, **bloqué CPU/MPS** (NotImplementedError 2026-05-13), CUDA-only ; checkpoints via `scripts/setup_nlf.sh` |
| Multi-HMR | `multi_hmr_scaffold.md` | scaffold seulement |
| SMPLER-X / WHAM-TRAM | `*_scaffold.md` | scaffold seulement |
## Conventions
- État partagé multi-thread : `state.py` expose `State.lock()` — toujours mutationner sous lock.
- Filtrage temporel : `euro_filter.py` (One Euro Filter) sur les keypoints avant tracker.
- Association multi-personne : `tracker.py` IoU-based, `scipy.optimize.linear_sum_assignment`.
- Shaders Metal dans `shaders/` (`.metal`), recompilés au runtime ; topologie mesh (SMPL faces) en binaire dans `mesh_topology.py`.
- OSC out : `osc_listener.py` / `pose_bridge.py` — destination `oscope-of` sur `:57123`.
## Tests
```bash
uv run pytest tests/ -v
```
Tests TDD-first pour `nlf_worker.py` ; valider avant chaque commit qui touche un worker.
## Anti-patterns
- Ne pas charger un modèle ML sans guard `try/except ImportError` — les optional-extras peuvent manquer.
- Ne pas committer `*.pt`, `*.ckpt`, `*.safetensors`, `*.mlpackage` (gitignore racine).
- Ne pas appeler `state.persons_nlf = ...` hors `with state.lock():`.
- Ne pas hardcoder le device (`cuda`/`mps`/`cpu`) : détecter via `torch.backends.mps.is_available()` puis fallback.
- Pas de `print` dans la boucle de rendu — utiliser un logger conditionnel.
+43
View File
@@ -0,0 +1,43 @@
# launcher — AVLiveLauncher
App menubar macOS (SwiftUI, SwiftPM, macOS 11+) qui démarre/arrête `sclang+scsynth`, le serveur web et `oscope-of`, log les sorties, et expose un mode picker.
## Build
```bash
cd launcher
./build.sh # script standard
# ou manuellement :
swift build -c release
.build/release/AVLiveLauncher
```
Cible : **macOS 11+**, Swift 5.7+. Package Swift, pas de Xcode project requis.
## Modules
| Fichier | Rôle |
|---------|------|
| `AVLiveLauncherApp.swift` | `@main`, scene menubar, app lifecycle |
| `MenuBarContent.swift` | UI du menu (start/stop, état des process) |
| `ModePickerWindow.swift` | Fenêtre picker de mode (data-only vs full vs ...) |
| `ProcessManager.swift` | Spawn / kill / monitor des process enfants |
| `OSCSender.swift` | Envoi OSC (typiquement vers `:57121` sclang, `:57123` oscope) |
| `LogView.swift` | UI live des logs stdout/stderr des process |
| `AV-Live-Body/` | Ressources / modèles annexes (body mesh assets) |
## Conventions
- Toute opération asynchrone : `Task { @MainActor in ... }` pour UI updates.
- Pas de bloc `DispatchQueue.main.sync` (deadlock garanti depuis MainActor).
- `ProcessManager` est `@MainActor` — interactions process via async/await, jamais `Process.waitUntilExit()` bloquant en main.
- Chemins absolus vers les binaires (sclang, node, oscope-of) résolus une fois au startup et stockés ; ne pas redécouvrir à chaque démarrage.
- Logs ring-buffer borné (pas de croissance illimitée dans `LogView`).
## Anti-patterns
- Ne pas committer `build/` ni `.build/`.
- Ne pas hardcoder un chemin utilisateur (`/Users/electron/...`) — passer par `FileManager` + chemins relatifs au repo ou bookmarks.
- Ne pas mélanger `Process.terminate()` et `kill -9` sans escalade (SIGTERM → wait → SIGKILL).
- Pas d'AppKit `NSApp.terminate` direct depuis un closure background — toujours hop sur MainActor.
- Ne pas dépendre d'un Xcode project : le SwiftPM `Package.swift` est la source de vérité.
+43
View File
@@ -0,0 +1,43 @@
# oscope-of
Visualiseur openFrameworks C++ : capture Hantek 6022BL via libusb → FFT 2048 → 41 backgrounds + 14 OS pixel-art + 10 scrollers + chaîne post-FX GLSL.
## Build
```bash
cd oscope-of
make # debug
make Release # release
make RunRelease # lance bin/oscope-of (Release)
```
Dépendances oF dans `addons.make`. Cible macOS principale (Hantek via libusb bulk transfers).
## Architecture
| Composant | Fichier |
|-----------|---------|
| Capture USB Hantek (1-48 MS/s, 2 ch 8-bit) | `HantekDevice.{h,cpp}` |
| Downsampling + FFT 2048 bandes bass/mid/treble/kick/snare | `AudioAnalyzer.{h,cpp}`, `FFT.{h,cpp}` |
| Données scope partagées | `ScopeData.h` |
| 41 backgrounds + 5 OS shaders + 14 logos + scrollers | `visualizers/` |
| Chaîne post-FX (ACES, bloom, chroma, scanlines, glitch...) | `PostFx.{h,cpp}` |
| Demo FX (copper bars, sine scroller, bobs) | `DemoFx.{h,cpp}` |
| OSC reçu depuis sound_algo (`:57123`) + envoyé | `OscClient.{h,cpp}` |
| App lifecycle | `ofApp.{h,cpp}`, `main.cpp` |
## Conventions
- **GLSL 150 GL 3.2 core** uniquement — pas de GL 2.1 legacy. Shaders en `bin/data/shaders/`.
- Pas d'allocations dans `update()` / `draw()` — buffers FFT préalloués.
- Hantek bulk transfer : timeout court, fallback gracieux si scope absent (mode démo).
- Les 15 demoparties touchent un état global `currentDemo` dans `ofApp` — toujours mettre à jour les bindings clavier (`keyPressed`) AZERTY (`&é"'(§è!``1-8`).
- `greetings.txt` (sine scroller) chargé depuis `bin/data/` au startup — éviter relectures.
## Anti-patterns
- Ne pas appeler `glDrawArrays` sans bind VAO préalable (GL 3.2 core l'exige).
- Ne pas faire `new` dans la hot loop — utiliser `ofVbo` / `ofFbo` membres.
- Ne pas faire d'I/O fichier dans `draw()`.
- Ne pas committer `bin/oscope-of*` (binaires) ni `bin/data/*.mov` (gros).
- Ne pas ajouter de dépendance non-headless sans l'inscrire dans `addons.make`.