∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿
██████╗ ██╗ ██████╗ ██████╗██████╗ █████╗ ██████╗██╗ ██╗
██╔══██╗██║██╔═══██╗██╔════╝██╔══██╗██╔══██╗██╔════╝╚██╗ ██╔╝
██████╔╝██║██║ ██║██║ ██████╔╝███████║██║ ╚████╔╝
██╔══██╗██║██║ ██║██║ ██╔══██╗██╔══██║██║ ╚██╔╝
██████╔╝██║╚██████╔╝╚██████╗██║ ██║██║ ██║╚██████╗ ██║
╚═════╝ ╚═╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝
███████╗███╗ ██╗ ██████╗ ██╗███╗ ██╗███████╗
██╔════╝████╗ ██║██╔════╝ ██║████╗ ██║██╔════╝
█████╗ ██╔██╗ ██║██║ ███╗██║██╔██╗ ██║█████╗
██╔══╝ ██║╚██╗██║██║ ██║██║██║╚██╗██║██╔══╝
███████╗██║ ╚████║╚██████╔╝██║██║ ╚████║███████╗
╚══════╝╚═╝ ╚═══╝ ╚═════╝ ╚═╝╚═╝ ╚═══╝╚══════╝
cybernetic feedback → multispecies parliament
∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿─∿
A live audiovisual instrument and a deployable public artifact that couples three registers into a single feedback loop: a public blockchain, a deliberative assembly (the multispecies parliament), and the phenology of a tropical dry forest. Every control parameter simultaneously drives SuperCollider audio synthesis and visual modules (slots 0–9, P, F, B, E, and R) via a bidirectional OSC/WebSocket bridge.
Rather than "visualizing data," the engine performs a cybernetic coupling where the forest, blockchain protocols, and human actions hold equal standing as political agents.
Slot F · DarkForest — the forest reading itself while the chain flows. Strata after Humboldt; every binomial is a member of the parliament.
The core contribution of the BiocracyEngine lies in translating critical, decolonial, and political theory into working technical constraints in software. It stands as a concrete, deployable counter-model to Nature Fintech and "Ecological State Protocols" by compiling philosophy into executable rules rather than citing it as external authority.
- Glissant's Right to Opacity: Implemented as a software constraint. The Opacity Clause (visualized via the
opacityFloorparameter) withholds a deterministic fraction of active species labels from the projection. This clause is declared untranslatable to sound (it does not alter the SuperCollider synthesis), honoring Glissant's assertion that the subaltern must have a right to remain opaque and unconsumed by the Western gaze. - Agamben's Coming Community: Seated in the code as a parliament of singularities, never identities. The assembly does not classify species by their economic value or utility, but by their sheer presence.
- "Absence is Voice": In slot P (Phenological Calendar) and slot F (DarkForest), species that fall below the sensory detection threshold are not deleted or set to zero; instead, they persist in the background as 1-bit dither or visual shimmer. Their absence speaks as a low-level frequency, asserting that what is unmeasured still participates.
- Seasonal Benches: The membership and voting weight of the parliament's benches recompose dynamically following the seasonal cycles of the phenological calendar.
The pipeline used here is: Acoustic Sensor → Vectorization → Smart Contract.
An important architectural claim of this work is that the same sensing pipeline constitutes either surveillance or a parliament depending only on the architecture of power surrounding it. Vectorization and remote sensing are not inherently tools of extraction; they can be configured to establish local sovereignty, turning a surveillance mesh into a site of representation.
The BioToken inverts the "tokenize-the-planet" logic of carbon credits and biodiversity offsets. It is:
- A unit of political inscription (participation) rather than a tradable asset (commodity).
- A non-financialized protocol designed to register validated conservation actions and deep listening.
- A buildable counter-model to speculative "Ecological State Protocols" and Nature Fintech.
The system routes conservation value and decision-making sovereignty directly to the local, marginal community (El Balzal, Córdoba, Colombia). Data sovereignty is kept local, and the honest limits of the system—such as the dependencies and boundaries of chain-level governance—are made visible in the interface rather than hidden behind greenwashed UI templates.
Rather than using the standardized global taxonomies of the IUCN Red List as an absolute authority, the engine maps the forest's own local seasonal calendar using a 572-species inventory from the Reserva Manakai. Ecological time governs the synthesis: the seasonal weight and active-species fraction are fed back into SuperCollider to drive harmonicrich and texturedepth.
Rooted in SubAmérica and technodiversity (Yuk Hui), this project fuses Investigación-Acción Participativa (IAP, after Orlando Fals Borda) with on-chain governance. The result is delivered as a liminal research object rather than a finished artwork, making it reproducible and adaptable by other territorial communities.
The project is released across three software repositories and a community-facing field tool:
- BiocracyEngine: The core audiovisual synthesis, WebGL/Three.js projection, and MIDI/OSC bridge engine.
- bioacoustic-scripts: The python-based web3 blockchain parser and audio-vector feature extraction tools.
- dIAP (Decolonial IAP): Decentralized action research protocols and on-chain assembly tools.
- Biomap SoundWalk App: A participatory listening and conservation instrument. It turns guided soundwalks in Reserva Manakai into logged acts of ecological presence, fusing deep listening and passive acoustic monitoring (PAM) in one field tool. The app carries the incentive layer, distributing BioToken-registered rewards to the El Balzal community for validated conservation actions, closing the loop between listening, inscription, and economic sustainability.
ETH Blockchain
│
▼
eth_sonify.py (web3 Python scraper)
│ OSC → UDP:57120
▼
SuperCollider
├─ 1_server_config.scd MOTU/CoreAudio auto-detect
├─ 2_midi_control.scd Faderfox LC2 → ~buses (20 CC)
├─ 3_synthdefs.scd SynthDefs (opalKick/Perc/Drone/Dust/Bell)
├─ 4_gui.scd SC GUI knobs (20 params, amber palette)
├─ 5_beat_engine.scd Evolving beat engine (TX-driven melodic pool)
├─ 6_osc_handlers.scd OSC in from HTML/bridge → ~buses
└─ audio out → MOTU 828x or CoreAudio stereo
│
│ OSC echo → UDP:3333 (~visualsDest)
▼
parliament-bridge.js (Node.js, OSC↔WebSocket)
│ UDP:3333 ← SC / MIDI echo
│ WS:3334 ↔ browser
│ HTTP:3335 /diag
│
│ SC_TO_CH path translation:
│ /soneth/* → /ch/setXxx (method-trigger)
│ /parliament/* and /agent/* → raw pass-through
│
▼
nw_wrld Electron browser (parliament.html)
│
├─ HTML sliders (34 sliders, 4 rows + Beat Engine)
│ └─ input → sendOSC → WS → bridge → SC bus
│ └─ patchStoreFromSlider → __applySonethToViz (DIAG-tracked)
│
├─ SC echo → onmessage → __applySonethToViz (DIAG-tracked)
│
└─ applySonethToViz(key, v) ─────────────────────────────────────────┐
│ │
├─ Slot 0 ParliamentStage.js (Three.js) │
├─ Slot 1 AsteroidWaves (p5.js) → __slot1Soneth │
├─ Slot 2 LowEarthPoint (Three.js) │
├─ Slot 3 PerlinBlob (p5.js) → __slot3Soneth │
├─ Slot 4 TimeTravel (p5.js) → __slot4Soneth │
├─ Slot 5 DynamicGraphs (p5.js) → __slot5Soneth │
├─ Slot 6 DynamicOptimality (p5.js) → __slot6Soneth │
├─ Slot 7 Geometry (p5.js) → __slot7Soneth │
├─ Slot 8 MemoryHierarchy (p5.js) → __slot8Soneth │
├─ Slot 9 Hashing (p5.js) → __slot9Soneth │
├─ Slot P PhenologicalCalendar (Three.js · fetched module) │
├─ Slot F DarkForest (Three.js · fetched module) │
├─ Slot B Transito (Three.js · fetched module) │
│ └─ reverse: throughput → /soneth/drone* → bridge → SC │
├─ Slot E Estratos (Three.js · fetched module) │
│ └─ forward: __phenoParams → bancada pins the strata, │
│ activityThreshold → population, opacityFloor + │
│ seasonalWeight → which species are present today │
└─ Slot R Registro (canvas · pretext ASCII field × slot 6) ──┘
└─ reverse: buffer → /soneth/memoryfeed, consensus → atmospheremix
MIDI (Faderfox Micromodul LC2) ──► SC buses ──► OSC echo ──► bridge ──► browser
Every parameter change is reflected across all three control surfaces:
HTML slider ──► SC bus ──► SC GUI knob (visual update)
└──► OSC echo ──► HTML slider (position sync)
└──► applySonethToViz (12 slots)
MIDI CC ────► SC bus ──► SC GUI knob (visual update)
└──► OSC echo ──► HTML slider (position sync)
└──► applySonethToViz (12 slots)
SC GUI knob ► SC bus ──► OSC echo ──► HTML slider (position sync)
└──► applySonethToViz (12 slots)
Four processes are managed by start_ecosystem.sh:
| App | Process | Ports | Role |
|---|---|---|---|
| Python ETH | eth_sonify.py (venv) |
→ UDP 57120 | web3 scraper; per-tx /eth/note + /eth/tx_info, per-block /eth/block |
| SuperCollider | sclang start_sonification.scd |
in 57120 (OSC) + MIDI; out 3333; scsynth 57110 | audio engine, GUI, beat engine, drone, master limiter |
| Bridge | parliament-bridge.js (Node) |
in UDP 3333; WS 3334; out UDP 57120; HTTP 3335 /diag |
OSC ↔ WebSocket, path translation |
| Browser | webpack-dev-server + Electron | HTTP 9001; WS 3334 | parliament.html GUI, store, visual slots |
| Laser (opt) | laser-bridge.js (Node, LASER=1) |
WS 3337 in; USB → Helios DAC | vector frames → ILDA / laser onto the forest |
10 core parameters × 10 visual slots = 100 bindings. Every slider/knob/CC drives both SC audio buses and all visualizations simultaneously.
| Param | MIDI CC | SC Audio | Slot 0 Parliament | Slot 1 Asteroid | Slot 2 LowEarth | Slot 3 Perlin |
|---|---|---|---|---|---|---|
| volume | CC 0 | master volume | pt light intensity | wave stroke alpha | white cloud opacity | stroke opacity |
| pitchShift | CC 1 | freq ±2 oct | species Z amplitude | lane X offset | cloud Y-stretch | noise intensity |
| timeDilation | CC 2 | env stretch ×0.5–6 | orbit speed | noise X zoom | rotation damping | cycle frames |
| spectralShift | CC 3 | LPF sweep 80–3000 Hz | bloom threshold | amber-cyan tint | line hue shift | layer compression |
| spatialSpread | CC 4 | quad pan L↔R | camera distance | lane spread | lines XY spread | blob X/Y offset |
| textureDepth | CC 32 | granular density | film grain | grid line density | point size | stroke weight |
| atmosphereMix | CC 33 | reverb 0–0.9 | afterimage damp | background ghosting | red cloud opacity | layer count |
| memoryFeed | CC 34 | delay feedback 0–0.8 | bloom strength | ghost trail alpha | red lines opacity | ghost alpha |
| harmonicRich | CC 35 | FM ratio 0.1–8 | lissajous complexity | harmonic overlay | Bézier Z-scale | hue drift |
| resonantBody | CC 36 | filter Q 0.1–0.8 | chroma aberration | peak dot glow | red cloud scale | inner weight |
| Param | MIDI CC | SC Audio |
|---|---|---|
| masterAmp | CC 5 | layer trim — pads, drone and beat engine from one control |
| filterCutoff | CC 6 | broad tone tilt, under spectralShift's absolute setting |
| noiseLevel | CC 7 | pink-noise breath under the pad |
| noiseFilt | CC 8 | noise LPF 200–2000 Hz |
| droneDepth | CC 9 | how far the sub body sinks |
| droneFade | CC 37 | glide time on the drone's own controls |
| droneSpace | CC 38 | reverb room size |
| droneMix | CC 39 | dry drone ↔ fully bloomed (wash + sub) |
| delayFeedback | CC 40 | comb delay feedback |
| transactionInfluence | CC 41 | how far chain activity bends the engine |
Six of these (CC 5, 6, 9, 37, 38, 39) previously wrote to control buses that no UGen read —
\opalDronedid not declare them and\elektronBellread them into variables it discarded. They now shape the drone.
Seven independent schemes for deriving rhythm from the chain's own temporal structure, rather than decorating a fixed 16-step grid with it. Each is a checkbox in the control panel, a MIDI CC, and a preset-persisted registry entry. All off reproduces the previous engine exactly — they are additive.
| Toggle | OSC | CC | Reads |
|---|---|---|---|
| Bloque = Compás | /rhythm/blockbar |
17 | the real ~12 s block period as the bar; tx index as phase |
| Acento por Gas | /rhythm/gasaccent |
18 | priority-over-base-fee ratio → accent and dynamics |
| Entropía | /rhythm/entropy |
19 | dispersion of inter-arrival times → swing, subdivision |
| Dirección = Voz | /rhythm/voices |
20 | counterparty address → register; a returning actor returns audibly |
| Semilla de Hash | /rhythm/hashseed |
21 | block hash seeds that bar's cell — different, yet reproducible |
| Tres Relojes | /rhythm/polyclock |
22 | block, arrival and decay on clocks with no integer relation |
| Silencio | /rhythm/silence |
23 | chain quiet relative to its own rate → real rests |
Entropía is rate-invariant by construction. It is the standard deviation of
log intervals, so sd(log(k·x)) = sd(log x): scaling every arrival by 2×, 5×
or 10× leaves the reading unchanged. It measures la forma de las llegadas, no
cuántas. Measured on a linear coefficient of variation it clipped to 1.0
permanently, because a window mixing 0.05 s intra-block arrivals with ~12 s
block gaps always has a CV above 2.
Performance safety. Silence can never strand a set: the rest threshold is clipped to 0.5–4 s, and above a 20 s gap the grid resumes — a dead feed must read as failure, not as a musical rest. A starvation guard forces a pad through if a transaction arrived but nothing sounded for 6 s, so no combination of the 128 possible toggle states can mute a layer indefinitely.
Master limiter. Nothing previously protected the output — every synth wrote
straight to Out.ar(0, …) and they summed unbounded (16 concurrent pads reached
1.34 full-scale before the drone and beat layers were added). A LeakDC → Limiter at 0.92 sits at the tail of the root node. Its failure mode is benign:
if the node is missing or mis-ordered it reads silence and ReplaceOut writes
zeros before the sources add theirs, so the worst case is no limiting, never
no sound.
Projects the engine's vector geometry onto a real-world forest. Lasers draw sparse bright strokes (not rasterised images), so the browser sends a small laser-friendly scene — not the 3-D framebuffer.
browser laserTap ──WS:3337──► laser-bridge.js ──USB──► Helios DAC ──► laser
└──────────────► frames.ild (ILDA fmt 5)
Enable: LASER=1 ./start_ecosystem.sh (off by default). With no DAC and no native binding it runs DRY (logs only) — safe to start anywhere.
Frame contract (browser → bridge): normalised, centre (0,0), x,y ∈ −1..1.
{ "type":"laserFrame", "pps":30000,
"points":[ {"x":-0.8,"y":0.0,"r":0,"g":200,"b":90,"blank":false}, … ] }Frame source (src/projector/laserTap.ts, started by parliamentEntry.init):
window.__laserFrame— any module may publish its own vector scene.- slot-P default — the phenological year-ring + a marker at today's active species (
window.__activeSpecies). A sensitive species is not drawn: the opacity clause (Glissant) extended into physical space — the vulnerable being is never cast onto the real forest.
./start_ecosystem.shLaunches all services: nw_wrld, parliament-bridge, SuperCollider, Python ETH scraper.
cd nw_wrld_local && node diag-sweep.jsSends all 22 params through the bridge (0 → 1 → 0.5), then runs a continuous volume LFO.
The single most useful tool when something "sounds wrong". SuperCollider posts one line every 2 s describing what it is actually receiving and doing:
tail -f sclang_log.txt | grep MON[MON] flags:B-E---S bells:47/gate:310/cap:12/bar:88 env(atk/dec/amp):0.81/0.83/0.071
prio:0.264 ent:0.517 dens:0.312 blk:25670857 txN:290 idx:289 base:0.051 synths:9
| Field | Answers |
|---|---|
flags |
B G E V H P S — uppercase means that toggle reached SC. Settles "is the control even connected?" without guessing. |
bells |
pads spawned, and skipped by which gate: gate time-gate, cap synth ceiling, bar block-phase quantization |
env |
atk/dec/amp of the last pad — if these stop being identical, the envelope is responding to the transaction |
prio ent dens |
live chain-derived values; a constant here means a mapping has saturated |
blk txN idx base |
whether the enriched eth_sonify.py payload is arriving at all |
Three OSC controls, from anything that can reach SC on 57120:
| Address | Effect |
|---|---|
/diag/osctrace 1 |
OSCFunc.trace — post every inbound OSC message; the definitive test of whether a control reaches SC |
/diag/monitor 0 |
silence the [MON] line |
/diag/reset |
zero the pad counters to measure a fresh window |
The registry banner in sclang_log.txt confirms the engine loaded the current
sources — worth checking first when a change appears to have no effect, since
start_sonification.scd reads all twelve .scd files from disk at boot:
Parameter registry loaded: 35 parameters, 39 OSC routes, 34 MIDI CCs.
Master limiter active (2 ch, ceiling 0.92) — output can no longer clip.
MIT License
