- Implemented Hydra visualizations in `web_realart/public/hydra/app.js` and `index.html`.
- Created WebGL visualizer using Three.js and WebGPU in `web_realart/public/webgl/app.js` and `index.html`.
- Developed main landing page in `web_realart/public/index.html` to showcase different visualizations.
- Set up WebSocket server in `web_realart/server.js` to relay OSC messages to web clients.
- Added health check API endpoint for monitoring server status.
- Implemented new data feeds for Blitzortung, Bluesky, GCN, GitHub, Mempool, Netzfrequenz, OpenSky, RTE éCO2mix, SWPC, USGS.
- Introduced utility functions for rate limiting and hashing.
- Established OSC communication for data reception and processing.
- Created SuperCollider definitions for handling incoming data and generating audio output based on real-time data.
- Added configuration management for API credentials and polling intervals.
User : "pourquoi en brew ? pourquoi ne pas les inclures dans
le build ?".
Le DMG embarque maintenant TOUT — l'utilisateur n'a plus rien
à installer manuellement :
- SuperCollider.app 3.14 universel (~150 MB, téléchargé depuis
github.com/supercollider releases puis copié depuis le .dmg
monté + démonté)
- node-v20.18.0-darwin-arm64 binary (~70 MB) standalone dans
payload/runtime/
- libusb-1.0.0.dylib bundled dans oscope-of.app/Contents/
Frameworks/ avec install_name_tool -change pour le retrouver
via @executable_path/../Frameworks/libusb-1.0.0.dylib
DMG attendu ~250 MB au lieu de 10 MB. Mais entièrement
autonome : drag & drop, premier lancement, ça tourne.
INSTALL.txt + release notes mis à jour pour indiquer
"tout-inclus, rien à installer en plus".
Le DMG ne contenait que oscope-of.app. Maintenant inclut :
- oscope-of.app (visualizer)
- AVLiveLauncher.app (build via xcodebuild dans CI)
- sound_algo/ (source SuperCollider complète)
- INSTALL.txt avec prérequis brew + marche à suivre
User : "SphereWave est bien audio reactive avec le hantek ?"
+ "et l'utiliser dans toutes les démos".
Verification + amélioration audio reactivity :
AudioAnalyzer expose désormais publicly :
- monoDown() : ring downsamplé 48 kHz audio (kFftSize floats)
- magDown() : magnitudes FFT 1024 (bin width ~47 Hz)
- monoHead() : index courant dans le ring
- audioSr() : 48000
VisFrame ajout pointeurs optionnels monoDown / magDown +
monoHead populated par ofApp::update.
SphereWaveVis::update : préfère désormais magDown/monoDown du
frame (FFT downsamplée 47Hz/bin → vraie résolution audio
20Hz-16kHz) au lieu de la FFT raw Hantek interne (7800Hz/bin
qui collait toute la bande audio dans 3 bins).
Fallback sur l'ancienne FFT interne si downsamples non dispos.
Ajout SphereWave dans 2 démos supplémentaires :
- Demo 7 AMBIENT VOID : nouvelle scène SPHERE
- Demo 14 GRAND FINAL : nouvelle scène SPHERE
User : "tu m'adapte pour un clavier mac azerty fr".
Sur Mac AZERTY FR, la rangée du haut sans shift donne
& é " ' ( § è ! ç à au lieu de 1234567890. Et les symboles
US ! @ # $ % (shift+1..5 QWERTY) sont injouables.
Adaptations :
- Démos 0-9 : digits 1-0 + alias chars AZERTY FR direct
1 / & → demo 0 AMIGA
2 / é (0xe9) → demo 1 C64
3 / " → demo 2 ACID
4 / ' → demo 3 TUNNEL
5 / ( → demo 4 FREQ
6 / § (0xa7) → demo 5 GLITCH
7 / è (0xe8) → demo 6 AMBIENT
8 / ! → demo 7 RAVE
9 / ç (0xe7) → demo 8 MEMORY
0 / à (0xe0) → demo 9 GREETINGS
- Démos 10-14 : F6-F10 (universels, layout-indépendants)
remplace les anciens ! @ # $ % qui étaient inaccessibles
ou conflictuels sur AZERTY FR Mac.
- Beat-sync toggle : * (US) ou \ (universel).
Hint clavier mis à jour pour refléter le double mapping.
User : "la WAVE faut me faire un version sphérique 3D
spectrogramme et waveforme" + "tu mets aussi windows 1.0
windows 3.11 etc... lotus 123 tout les OS possibles".
SphereWaveVis 3D :
- Mesh sphère paramétrique 64x32 (longitude x latitude)
- Pour chaque vertex : rayon = base + FFT[bin proportionnel
à longitude] + waveform[sample_idx]
- FFT 1024 sur (CH1+CH2)/2 Hantek raw, log mapping
- Camera orbitale autour de la sphère, light point pulsé
sur kick avec couleur audio-modulée
- Render solid + wireframe overlay phosphor
- Couleur cycle hue + saturation modulée par mid+treble
Nouveau BgKind::SphereWave (35 backgrounds total).
13 logos OS/software PNG dans bin/data/sprites/ :
- windows_1_0, windows_311, windows_95
- lotus_123, msdos
- atari_fuji, apple_rainbow
- amiga_wb, nextstep, beos, os2_warp, irix
- zx_spectrum, c64_basic
+ 5 SVG vectoriels source dans le même dossier.
User : "la demo sur la touche 1 et la touche 2 ont toujours
la même tracks audio" + "tu vérifie les chevauchement de texte".
Audit : 3 démos commençaient avec J (6/9/10), 2 avec T (7/11),
2 avec M (0/1). Maintenant 15 albums premiers actes uniques :
M-N-A-P-I-V-J-T-U-W-O-E-R-Q-L
Overlaps UI corrigés :
- Barre progression narrative y=70 chevauchait le titre 2.5x
qui s'étend à y~80. Déplacée à y=92.
- Hint narratif H-48 chevauchait hint FX H-50. Déplacé à H-78.
- Hint narratif élargi pour mentionner ! @ # $ % et q.
User : "azertyuiop = type de scene et qsdfghjklmwxcvbn,;:= pour
les paramètres".
Refonte complete du clavier en layout AZERTY :
[Top row AZERTYUIOP] : 10 backgrounds live override
a = BoingBall z = Tunnel e = Metaballs
r = Voronoi t = Twister y = KIFS
u = Fire i = Mode7 o = Octahedron
p = PlasmaC64
[Middle/bottom rows] : 17 paramètres FX
s = SPD speed d = KCK kick f = ROL roll
g = PAN pan h = CRV curve j = TLX tileX
k = TLZ tileZ l = DIR direction m = BLM bloom
w = CHR chroma x = KAL kaleido c = SCN scanlines
v = PIX pixelate b = HUE hue n = GRN grain
, = VIG vignette ; = SAT saturation
: = reset all (shift+. AZERTY)
[F-keys] : system toggles déplacés
F1 fullscreen F2 GUI F3 postFx
F4 autoglitch F5 reload shaders
[Flèches up/down] : ajuste valeur du paramètre selectionné
[Espace] glitch pulse [q/esc] sortie narrative + bg override
liveBgOverride_ ajouté dans ofApp : permet override du
background scope4 hors mode narratif via touche scène.
drawScope4 priorité : narrative > liveBgOverride > toggles.
User : "le mode live on améliore l'interface UX. les contrôles
s'appellent pour une touche de a à z et flèches up down pour
changer la valeur".
Refonte du contrôle FX live :
Avant : 19 lettres en pairs (a/z s/x d/c e/v t/n u/m i/l o/h
+ j/y combo + w reset)
Après : 1 lettre = sélectionne 1 paramètre, flèches haut/bas
ajustent la valeur du paramètre sélectionné, w reset.
Mappings mnémoniques (évite f g p k r b déjà bindés) :
s : Speed (tunnel) d : pan amplitude (Drift)
c : Crushing kick boost v : curVe amplitude
l : roLL amplitude x : tile X (angulaire)
z : tile Z (profondeur) n : directioN lerp
UP / DOWN : ×1.20 / ×0.83 sur le param sélectionné, clamp [0.05;12].
W : reset tous les multipliers à 1.0.
Overlay FX bas écran : encadré magenta autour du slot actif,
couleur saturée pour le selected, hint clavier ligne au-dessus
"[s c l d v x z n] select [UP DOWN] adjust [w] reset all".
Le pipeline FBO de transition causait un flip Y persistant
des textes (FBO rendu top-left vs gl_FragCoord bottom-left
en GL). Le flip Y dans les shaders corrigeait la transition
mais pas le rendu courant. Solution simple : on bypass le FBO
et on rend directement à l'écran via postfx comme avant. Les
transitions visuelles sont assurées par le flash blanc 0.45s
+ le glitch RGB postfx 0.45s déclenchés sur enterScene().
Les 3 shaders transitions/*.frag restent dans le repo pour
un futur fix architectural propre.
3 nouveaux modèles 3D intégrés aux narrations :
- Demo 1 AMIGA : ajout PYRAMIDE acte 6
- Demo 3 ACID : ajout DNA HELIX + ROSACE après VORTEX
User : "1 et 2 ont la même tracks par exemple" + "ajoute encore
plus de gfx et de modèle 3D wireframe".
Audit album usage : M utilisé 12 fois (très redondant), 8
albums (B C D E K N O W) jamais utilisés.
Rebalance albums dans 5 démos :
- Demo 1 AMIGA : M/M/M/M/G/G → M/R/G/B/C
- Demo 2 C64 : M/M/M/M/V → M/C/D/K/V
- Demo 3 ACID : A/A/A/H/H/J → A/H/D/H/A/J
- Demo 4 TUNL : P/P/P/F → P/S/E/F
- Demo 5 FREQ : I/I/I/Q/Q/Q → I/W/C/Q/B/Q
- Demo 7 VOID : J/J/S/S → J/O/S/S/W/J
Maintenant 23/23 albums utilisés au moins une fois.
6 nouveaux modèles 3D wireframe-friendly :
- gear.ply : pignon 12 dents
- cone.ply : cône simple
- pyramid.ply : pyramide 4 cotés
- rose3d.ply : rosace polaire k=5 tessellation tube
- geosphere.ply : icosphere subdivisée niveau 2
- dna.ply : double helix tube avec 2 brins
35 modèles 3D au total. ModelVis affiche déjà les wireframes
en overlay (ofSetColor 255,230,180,120 + drawWireframe).
Bug critique : tous les textes apparaissaient en miroir
vertical depuis l'introduction des transitions FBO. Cause :
gl_FragCoord est bottom-left en GL alors que les FBO oF
sont rendus top-left. Solution : flip Y dans les 3 shaders
de transition (crossfade/dissolve/wipe).
vec2 px = vec2(gl_FragCoord.x, uRes.y - gl_FragCoord.y);
AMIGA TRIBUTE demo : BOING BALL maintenant en premier acte
au lieu d'INSERT DISK, pour que l'utilisateur voie tout de
suite la boule rouge/blanche emblematique du 1984 Amiga.
Transitions FBO entre scenes des demoparties :
- 2 ofFbo ping-pong (sceneFbo_[0/1]) capturent la scene rendue
complete (post FX inclus) avant affichage
- Sur enterScene() : swap idx + reset transitionT a 0, choisit
une transition aleatoire parmi 3 (crossfade/dissolve/wipe)
- transitionDur 0.7s, progression smoothee
- Composite final via shader transition qui blend sceneFbo[prev]
vers sceneFbo[cur] selon progression uT
3 transition shaders :
- crossfade.frag : mix lineaire prev/cur
- dissolve.frag : noise hashe en blocs 6x6, smoothstep autour
du seuil pour un fade doux
- wipe.frag : wipe radial depuis le centre + anneau lumineux
a la frontiere
Beat-sync mode :
- Touche '*' toggle beatSyncEnabled
- Quand actif, launchDemo queue dans pendingDemoIdx au lieu
de fire immediatement
- update() check kick rising edge (>0.55, prev<=0.55) → fire
la demo en attente
- Permet de synchroniser les transitions au prochain kick
pour fluidifier la performance live
Pour ponctuer les changements d'acte des demoparties, ajout
d'une transition punchy a chaque enterScene() :
- transitionFlash_ = 1.0 au debut, decay lineaire 0.45s
- Flash blanc plein ecran, alpha = 180 * t^2 (ease-out cubique)
- postfx_.triggerGlitch(0.7, 0.45) en parallele = block
displacement RGB sur la meme duree
- Drawn entre la waveform circulaire et l'overlay narratif
pour ne pas masquer le titre d'acte qui suit immediatement
15 albums utilises par les demoparties recoivent une SIGNATURE
distinctive plutot que reecrire 225 .scd individuellement :
palette/album_signatures.scd defines per-album :
- humanize tunables specifiques (timing/vel/detune)
- rotation pool restreint (ex: T = kicks gabber only)
- rotationEvery rate adapte (V=2 glitch fast, S=64 drone slow)
- auto_layer config (timbres + amp + octaves)
Signatures (A H M G L P J I Q T V U R S F) :
A acid 303+sub H acid trance saw M chiptune square
G detroit rhodes warmpad L garage vocalpad
P industrial growl hardlead J ambient choir drone
I liquid pluck Q neurofunk reese T gabber hoover growl
V glitch fmbell stab fast rotation
U vocal trance choir vocalpad R synthwave rhodes warmpad
S drone doom drone subboom -2oct F trance supersaw pad
~playAlbum est wrappe pour appliquer ~applyAlbumSig.(letter)
avant le lancement original. Conservation de ~playAlbum_orig.
OSC handlers added in web_bridge.scd :
- /control/setHumanize <0|1> toggle humanize global
- /control/setRotation <0|1> toggle synth rotation
- /control/setLayer <0|1> toggle auto layer
- /control/humanizeTiming <f> fine-tune timing 0..0.05s
- /control/humanizeVelocity <f> fine-tune vel 0..0.5
- /control/humanizeDetune <f> fine-tune detune 0..0.5
- /control/layerSet <inst...> full layer config update
Permet de piloter humanity depuis oscope-of par demo.
User : "tu refait aussi les tracks avec toutes les possibilité
de synth disponible pour plus de variation et d'humanité dans
ces créations". Niveau choisi : subtil.
3 axes implémentés en helpers globaux qui s'appliquent à TOUS
les 345 tracks existants sans les réécrire :
1) HUMANIZE (engine.scd, opt-in via ~humanizeOn défaut true)
- Timing offset Pwhite ±3.5ms par note (1.4% sur dur 0.25)
- Velocity Pwhite ±10% par note
- Micro-detune ±3 cents sur acid/melody/harmony midinote
- Appliqué aux 7 Pdef (kickSeq/hatSeq/snareSeq/clapSeq/percSeq/
acidSeq/melodySeq/harmonySeq) via Pfunc factories ~hTime
~hVel ~hDet déclarées dans ~reload
- Désactivable : ~humanizeOn = false; ~reload.value
- Tunables : ~humanizeTiming, ~humanizeVelocity, ~humanizeDetune
2) SYNTH ROTATION (palette/synth_rotation.scd, opt-in défaut OFF)
- 8 rotators (acid/bass/lead/pad/pluck/kick/hat/snare/melody)
- Pool de 19 versions par catégorie (acid_v1..v19 etc.)
- Cycle toutes les ~rotationEvery=8 notes (configurable)
- Vérifie SynthDescLib avant de switcher pour éviter crash
- Activation : ~setRotationOn.(true)
3) AUTO LAYER (palette/auto_layer.scd, opt-in défaut OFF)
- 3 layers parallèles à melody/harmony/acid
- Mirror Pdef qui rejouent le même score avec instrument
différent (warmPad/choir/sub_boom par défaut)
- Octave offset configurable, amp réduit (0.20-0.30)
- Pan opposé, attack/release plus mou, cutoff moins ouvert
- Activation : ~setAutoLayer.(true)
Hook chargement dans live/_load.scd après scales/melodies/
harmonics. Les modules sont silencieux jusqu'à activation.
Remplacement des 10 single-presets par 10 démoparties multi-actes
narratives complètes. Chaque touche 1..9 + 0 lance une démo
scénarisée qui boucle sur ses propres scènes.
10 démos (3-4 scènes chacune, 1.5-2.5 min) :
1 AMIGA TRIBUTE INSERT DISK / SCROLLZ / COPPER STORM
2 C64 LOWLIFE BOOT / PIXEL / CLIMAX
3 ACID JOURNEY DROP IN / 303 LOOP / PEAK / COMEDOWN
4 TUNNEL VISION DARK / WALLS / OPENING
5 FREQUENCIES SILENCE / BANDS / FULL
6 GLITCH WORLD PROBE / CORRUPT / CRASH
7 AMBIENT VOID DRIFT / DEEPNESS / RETURN
8 RAVE BUILD / FULL POWER / AFTER
9 MEMORY LANE REWIND / VAPOR / FOG
0 GREETINGS OPENING / ROLL CALL / FINALE
Chaque acte change : toggles visuels, scroller style, narration
texte, track SC associée. Auto-advance à la durée écoulée + loop
sur acte 0 quand la démo finit.
Bindings :
1..9 + 0 lance la démo correspondante
Enter next act
Esc / q sortie en mode live (pas de scénario)
Overlay : ligne 1 "DEMO N / 10 NAME" petit, ligne 2 "ACT N / M
TITLE" gros + barre de progression.
User : "tu me fait un vrais démo partie avec une narration et
des évolutions".
Mode narratif scripté — touche 'b' lance une démoparty de
~3.5 min en 6 actes qui évoluent visuellement et musicalement :
ACT 1 INTRO 25s starfield + neon scroll + ambient
ACT 2 FIRST PULSE 35s tunnel only + classic + industrial
ACT 3 FREQUENCIES 45s polar+spectro + wavy3D + detroit
ACT 4 FULL POWER 55s everything + rainbow + gabber
ACT 5 GLITCH 40s everything + glitch fx + glitch idm
ACT 6 OUTRO 30s starfield + mirror + vocal trance
Chaque acte :
- Applique un preset toggles (visuels)
- Change le style scroller
- Override le texte du scroller avec une narration scénarisée
- Lance l'album SC associé via OSC /control/playAlbum
- Avance auto au temps écoulé, fade in/out du titre
DemoFx::setText override le texte du scroller avec restauration
auto vers greetings.txt en sortie de mode narratif.
Bindings :
b lance la démo party narrative (ACT 1)
Enter skip à la scène suivante
Esc sortie du mode narratif
Overlay : titre "ACT N / 6 NAME" en gros + barre de progression
en haut, hint clavier en bas.
User : "les touches 0 à 10 lanceront une démo party avec la
track supercollider associée + plus de styles de scroller +
q reste le mode live".
DemoFx::ScrollerStyle (6 variants) :
- Classic sine wave wobble par défaut
- Wavy3D sine + scale per char (effet respiration 3D)
- Rainbow hue cycle large par char
- Mirror classic + reflet vertical en bas (alpha gradient)
- Glitch jitter horizontal + couleurs cassées (rouge/bleu)
- Neon outline cyan large + cœur magenta fin
ofApp::DemoPreset (10 presets) :
1 AMIGA classic -> album A (acid_journey)
2 C64 wavy3d -> album M (chiptune_madness)
3 OLDSKOOL mirror -> album G (detroit_soulful)
4 NEWSKOOL rainbow -> album L (future_garage)
5 TUNNEL classic -> album P (industrial)
6 STARFIELD neon -> album J (ambient_cinematic)
7 SCOPE classic -> album I (liquid_dnb)
8 CYBER glitch -> album V (glitch_idm)
9 VAPOR mirror -> album U (vocal_trance)
0 RAVE rainbow -> album T (hardcore_gabber)
Chaque preset = état toggles ScopeToggles + style scroller +
lettre album SC (envoyée via /control/playAlbum à sclang).
Touches 1..9 + 0 lancent les presets (au lieu de toggles
individuels). 'q' reste libre pour le mode live (contrôle
manuel des éléments via les autres touches a-z).
Overlay bas droite affiche le preset actif en gros (magenta).
User : "scope4 uniquement et les touches 0 à 9 sont différents
effets type demoscene".
- Touches 1..9 toggle chacune un effet du Scope4 :
1 tunnel 3D
2 starfield (remplace tunnel)
3 sine scroller (greetings.txt)
4 copper bars
5 logo bobs
6 HUD aléatoire sub-10Hz
7 spectro circular ring
8 polar central
9 waveform circulaire CRT
0 = reset all toggles aux défauts.
- Suppression des bindings 1-9/0/-/q qui changeaient de mode_,
Scope4 est désormais le seul rendu actif.
- Suppression des toggles symboles redondants ' ; , .
- Synchro DemoFx::*Enabled() avec scope4_ flags dans drawScope4.
Nouveau module DemoFx avec 4 effets demoscene classiques :
- Sine scroller : texte depuis bin/data/greetings.txt, scale 3x,
bobbing sin par char (amp 14px), couleurs phosphor cyclant.
~150 px/s, wrap automatique. Affiché en bas d'écran par-dessus
tout dans Scope4.
- Starfield 3D : 220 étoiles z-projetées, motion blur en streak
radial, peut REMPLACER le tunnel quand toggle actif.
- Copper bars : 6 bandes horizontales en haut, gradient sin
vertical, hue cyclant, blend additif, follow sin de la phase.
- Logo bobs : "AV-LIVE" 4x scale qui rebondit en arc de cercle,
scale wobble, hue cycle. En haut centré.
Toggles clavier (touches symboles hors zone FX a-z) :
' scroller on/off
; copper bars on/off
, bobs on/off
. starfield on/off (remplace le tunnel quand on)
bin/data/greetings.txt fourni avec contenu par défaut, éditable
à la volée — DemoFx::setup le lit au boot.
Overlay phosphor vert toujours visible dans Scope4, sans
dépendre du GUI (touche g). 8 slots horizontaux en bas :
label / touches a→z / valeur multiplicateur / barre log.
Couleurs des slots : vert calme à 1.0, vire ambre quand >1.0
(boost), vire bleu quand <1.0 (atténuation). Barre log
centrée sur 1.0, marqueur central tick. "[w] reset" à droite.
Blend additif pour s'intégrer au look CRT rétro de la wave
circulaire au-dessus.
User : "rendre le bias kick plus violent. ajuster la vitesse du
tunnel en /10 et ajouter des fx qui modifie les multiplicateur
avec le clavier (a→z)".
Approach:
- Vitesse base /10 : (0.6 + bpm*0.012) → (0.06 + bpm*0.0012).
Le flow général est lent, le kick frappe d'autant plus fort.
- Kick punch ×4 (vs ×1.5) sur travel, ×1.4 (vs 0.6) sur panY,
×0.6 (vs 0.25) sur la composante roll. Sensation d'impact.
- TunnelVis::Mults — struct de 8 multiplicateurs (speed,
kickBoost, rollAmp, panAmp, curveAmp, tileX, tileZ, dirLerp).
Appliqués in-place dans update/draw.
- Bindings clavier ofApp::keyPressed : 9 paires down/up
a/z : speed
s/x : kickBoost
d/c : rollAmp
e/v : panAmp
t/n : curveAmp
u/m : tileX
i/l : tileZ
o/h : dirLerp
j/y : speed + kickBoost combinés (tout ralentir/accélérer)
w : reset all to 1.0
Chaque pression × 0.83 (down) ou × 1.20 (up), clamp 0.05..12.
User : "sur les carraud du tunnel tu me fait un HUD aléatoire
sur les fréquence sous les 10Hz".
Approach:
- ofApp::drawTunnelHud — pool jusqu'à 14 items, refresh 1-2 par
frame toutes les 0.15-0.40s, life 0.8-2.5s par item.
- Chaque item = mini-cadre rectangulaire phosphor + label texte
(LFO/DC/DRIFT/SUB/MOD/Δf/PHASE/GAIN/BIAS/TRIG/PWM/ENV) +
valeur Hz aléatoire 0.2..9.9 Hz à 1 décimale.
- Position : périphérique (rad 0.34-0.49 du centre) → tombe sur
les "carreaux" visibles du tunnel, évite le polar central.
- Fade in 0.2s + fade out 0.4s + flicker scintillant phosphor.
- Blend additif → s'intègre au look CRT sans masquer les couches.
- Appelé dans drawScope4 juste après le tunnel.