ΑΛΛΟΤΡΟΠΙΑΣ
Ec(h)o-Processing — Seismic Audio Modulation System
SYSTEM DATASHEET  /  REV 1.0  /  BELFAST 2026

00   CONCEPT
  ΑΛΛΟΤΡΟΠΙΑΣ
  Ec(h)o-Processing | Seismic Audio Modulation System   
Technical dev_ Valeri
PS³ 11 Rosemary Street, Belfast BT1 1QA Saturday 21 March – Thursday 2 April Late Night Art (6–9pm) on 2 April Artists: Rosa Catalano Donatella Guarino Marina Iodice Informed by Marina Iodice's PhD research, Ulster University ───────────────────────────────────────────────────────────────── The exhibition links geological and social instability across two territories — Vesuvian and Northern Irish — through projected graphs, artefacts, maps, sound, and video. The artists evoke instability as both a physical and social condition, where ambiguous traces are shaped by tension and transformation, whilst depictions of horizons and boundaries imply unseen forces at work.
01   AUDIO SIGNAL CHAIN
 
[ AUDIO SOURCE ]
    │  3 × ambient recordings .mp3 (loop)
    │  selectable channels: TRACK 1 / 2 / 3
    │  nominal duration: ~330 s per file
    ▼
[ DELAY NODE ]
    delayTime: 0.08 s – 0.35 s
    (controlled by seismic cluster density)
        │
        ▼
[ FEEDBACK GAIN NODE ]
    gain: 0.10 – 0.65
    (cluster density → gain)
        │
        └── feedback loop returning to delay
        ▼
[ MAIN GAIN ]
    nominal: 0.70
    on seismic event: glitch envelope

    ML < 2.6  → +20% peak, duration 0.3 s
    ML ≥ 2.6  → cut to 0.0 for 0.1 s
                return in 2.5 s
        ▼
[ BIQUAD LPF FILTER ]
    type: low-pass
    resting state: 18,000 Hz
    on event: closes to 4,000 Hz
    Q: 1.2
        ▼
[ ANALYZER ]
    fftSize: 2048
    feeds the waveform canvas (section A)
        ▼
[ COMPRESSOR ]
    threshold: –1 dBFS
    ratio: 20:1
    attack: 1 ms
    release: 50 ms
        ▼
[ AUDIO DESTINATION / SPEAKERS ]
02   SEISMIC DATA → AUDIO PARAMETER MAPPINGS
  Three seismic parameters are extracted per event and mapped
  continuously to the audio chain. Each operates independently.

  ─────────────────────────────────────────────────────────────────
  PARAMETER 1 — MAGNITUDE  (event-triggered)
  ─────────────────────────────────────────────────────────────────

    source:   ML (local magnitude) from INGV seismic log
    norm:     ML / 4.4  →  0.0 – 1.0

    ML < 2.0  →  MINOR glitch
                 gain spike +20%, duration 150–250ms
                 4-cycle opacity flicker on display

    2.0 ≤ ML < 2.6  →  MINOR / STRONG threshold
                        gain spike, lpf partially closes

    ML ≥ 2.6  →  STRONG event
                  gain cuts to 0.0 for 0.1s
                  returns over 2.5s exponential curve
                  lpf closes fully to 4,000 Hz
                  terminal log entry generated

    ML ≥ 3.0  →  MAINSHOCK
                  extreme display corruption
                  8–12 title glitch pulses
                  monitor shake animation triggered

    detection window:  ±60s from current sequence position
    event cooldown:    tracked per event ID (no re-trigger)

  ─────────────────────────────────────────────────────────────────
  PARAMETER 2 — DEPTH  (continuous)
  ─────────────────────────────────────────────────────────────────

    source:   depth in km from hypocenter data
    norm:     (depth – 1.5) / (5.0 – 1.5)  →  0.0 – 1.0
              shallow (1.5km) = 0.0  →  playbackRate 0.93 (low)
              deep    (5.0km) = 1.0  →  playbackRate 1.04 (high)

    effect:   audio.playbackRate  (Web Audio API)
              preservesPitch = false
              → pitch and speed both shift together

    transition: exponential smoothing  α = 0.02 / animation frame
                ~5–8 seconds to reach target value
                creates very slow drift, barely perceptible

  ─────────────────────────────────────────────────────────────────
  PARAMETER 3 — CLUSTER DENSITY  (continuous)
  ─────────────────────────────────────────────────────────────────

    source:   events per 10-minute window around current position
    norm:     cluster_count / 15  →  0.0 – 1.0

    targets:
      delayTime   →  0.08s + norm × (0.35 – 0.08)
      feedbackGain →  0.10 + norm × (0.65 – 0.10)

    transition:  AudioParam.setTargetAtTime(), τ = 0.7s
                 → smooth ramp, no zipper noise

    effect:  at low density (isolated events): short, sparse echo
             at high density (swarm):          long, saturated echo
             →  voice multiplication, unstable overlap

  ─────────────────────────────────────────────────────────────────
  MECHANICAL LAYER — WOW & FLUTTER  (always active during playback)
  ─────────────────────────────────────────────────────────────────

    independent of seismic data — simulates tape degradation

    WOW   (slow):   brownian random walk
                    frequency:   0.05 – 0.12 Hz
                    amplitude:   ±0.003 – ±0.007 playbackRate
                    mean-revert: restore = 0.003, friction = 0.85
                    re-randomize: every 18–24s

    FLUTTER (fast): brownian random walk
                    frequency:   0.15 – 0.35 Hz
                    amplitude:   ±0.001 – ±0.004 playbackRate
                    mean-revert: restore = 0.005, friction = 0.88

    final playbackRate = seismic_depth_drift + wow + flutter
                       = (0.93–1.04)        + (±0.007) + (±0.004)
                       = total range approx  0.919 – 1.051

    perceptibility: ±0.4–1.1%  —  below conscious threshold,
                                   above zero  →  the signal is
                                   always slightly wrong
03   DISPLAY — SECTION A: SEISMOGRAPH
  Real-time waveform trace of the seismic influence magnitude.
  Drawn on a canvas element, updated every animation frame (~60fps).

  ┌───────────────────────────────────────────────┐
  │ amplitude                                     │
  │  +1.0 ┤                                       │ 
  │       │    ╭─╮         ╭──╮                   │
  │       │   ╱   ╲       ╱    ╲    ╭╮            │
  │  0.0  ┤──╱─────╲─────╱──────╲──╱──╲───────────│
  │       │         ╲   ╱        ╲╱    ╲.         │
  │       │          ╲─╱                ╲───.     │
  │  –1.0 ┤                                       │
  │       └───────────────────────────────────────│
  │        t=0                             t=now  │
  └───────────────────────────────────────────────┘

  x axis:  time — scrolling left, each frame adds one sample
           maxDataPoints = canvas.width (auto-resizes to element)

  y axis:  seismic amplitude — calculated per frame:
           if seismicMod active and magnitude > 0:
             amp = sin(ct × freq × π) × base × 0.3
                 + sin(ct × freq/2 × π) × base × 0.7
                 + random() × base × 0.2
             where base = ML / 4.4,  freq = 2 + (ML × 0.5)
           else:
             amp = (random() – 0.5) × 0.01   (noise floor)

  scale:   auto-adjusts to peak value, smoothed α = 0.1
           → waveform always fills the canvas vertically

  color:   rgba(255, 255, 255, 0.6)  solid stroke
           no fill, no grid, no labels — pure trace
04   DISPLAY — SECTION B: DOT MATRIX
  A 150-node grid representing population displacement from
  Belfast during the Troubles (1969–1973).

  Each lit dot (●) stands for approximately 400 displaced persons.
  As the installation runs, dots extinguish one by one, following
  the chronology of historical displacement waves. Each
  disappearance is irreversible for the duration of the
  performance — no dot returns.

  total represented:  150 × 400 = ~60,000 persons
  source period:      1969–1973 displacement events

  ┌───────────────────────────────────────────────────┐
  │  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●   │
  │  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●   │
  │  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●   │
  │  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ●  ○  ○  ○  ○  ○   │  ← extinguishing
  │  ○  ○  ○  ○  ○  ○  ○  ○  ○  ○  ○  ○  ○  ○  ○  ○   │
  │  ○  ○  ○  ○  ○  ○  ○  ○  ○  ○  ○  ○  ○  ○  ○  ○   │
  │                                                   │
  │  ●  lit    = person still present                 │
  │  ○  unlit  = person displaced / removed           │
  └───────────────────────────────────────────────────┘

  wave chronology (extinguishing order):
    1969 — August riots, first mass displacement
    1970 — continued movement, intimidation campaigns
    1971 — largest single-year displacement
    1972 — Bloody Friday, accelerated clearances
    1973 — residual movement, community fragmentation

  rendering:
    canvas 2D, dots drawn as filled arcs
    active:       rgba(255,255,255, 0.7)  radius 3px
    extinguished: not drawn  (void is literal absence —
                  the dot does not fade or grey out,
                  it simply ceases to exist in the grid)
    layout: auto-grid, margin 12px, spacing calculated from
            canvas dimensions / sqrt(150) per axis
05   DISPLAY — SECTION C: VOID BARS
  Four horizontal bars, one per year (1969–1972).
  Each bar represents the volume of families displaced
  in that calendar year — specifically the inhabitants
  evacuated from Rione Terra (Pozzuoli), the ancient
  hilltop neighbourhood progressively cleared as ground
  uplift from bradyseism rendered it uninhabitable.

  ┌───────────────────────────────────────────────────┐
  │                                                   │
  │  1969  [░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│        ]│
  │                                          └── void │
  │  1970  [░░░░░░░░░░░░░░░░░░░░░░░│                 ]│
  │                                                   │
  │  1971  [░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│    ]│
  │                                                   │
  │  1972  [░░░░░░░░░░░░░░░│                         ]│
  │                                                   │
  │  ░ fill = families still present / accounted for  │
  │    void = families removed (empty space, no fill) │
  │    border-right of void = marker line             │
  └───────────────────────────────────────────────────┘

  displacement chronology — Rione Terra, Pozzuoli:
    1969 — first bradyseismic unrest; structural surveys begin,
           initial voluntary relocations of at-risk families
    1970 — municipal evacuation order issued; majority of
           remaining residents cleared from the rione
    1971 — forced clearance of holdouts; area sealed;
           largest single-year displacement count
    1972 — final residual families removed; Rione Terra
           abandoned and closed to habitation

  mechanics:
    each bar has two layers:
      .void-bar-fill   — white fill, right-to-left, width = 100%
                         at start, depletes as log processes
      .void-bar-void   — transparent, left-to-right, width = 0%
                         grows as displacement events are logged
                         right edge = 1px white line (the front)

    transition: cubic-bezier(0.25, 0.46, 0.45, 0.94), 2s
    on depletion event: pulse animation, 0.8s ease-out

  data source:
    Menoni, S., Galderisi, A., Carrion, D., & Gerosa, C. (2024)
    "Cross-Sectoral and Multilevel Dimensions of Risk and
     Resilience Management in Urban Areas Enabled by
     Geospatial Data Processing"
    Sustainability, 16(19), 8712
    https://www.mdpi.com/2071-1050/16/19/8712
    — displacement of inhabitants from Rione Terra, Pozzuoli
06   DISPLAY — SECTION D: GROUND UPLIFT GRAPH
  Ground uplift curve for the Campi Flegrei area (Pozzuoli),
  plotted as a continuous ascending line on a canvas element.
  The data traces the vertical displacement of the ground
  surface caused by bradyseism — the slow, episodic inflation
  of the volcanic system beneath the bay.

  ┌──────────────────────────────────────────────────┐
  │uplift                                            │
  │(cm)                                              │
  │+300 ┤                                  ●.        │
  │     │                                 ╱          │
  │+200 ┤                                ╱           │
  │     │                           ╱╲  ╱            │
  │+100 ┤                          ╱  ╲╱             │
  │     │               ╱╲        ╱                  │
  │  0  ┤──────────────╱──╲──────╱────────────────── │
  │     └──┬──────┬──────┬──────┬──────┬──────┬───   │
  │       70     74     82     84     00     24      │
  └──────────────────────────────────────────────────┘

  key episodes:
    1969–1972  — first bradyseismic crisis, Rione Terra evacuated
    1982–1984  — second crisis, major uplift acceleration,
                 further evacuations from Pozzuoli centre
    2000–2024  — renewed unrest, cumulative uplift reaching
                 record levels by the time of this dataset

  the graph moves only upward.
  the ground does not return.

  source:
    Menoni, S., Galderisi, A., Carrion, D., & Gerosa, C. (2024)
    "Cross-Sectoral and Multilevel Dimensions of Risk and
     Resilience Management in Urban Areas Enabled by
     Geospatial Data Processing"
    Sustainability, 16(19), 8712
    https://www.mdpi.com/2071-1050/16/19/8712
    — ground movement / vertical displacement data
07   TERMINAL LOG — SYNTHESIS ENGINE OUTPUT
  The terminal displays real-time synthesis state per event.
  Format on seismic event trigger:

  ══════════════════════════════════════════
  EVT  20/05/2024  12:05:00 UTC  [STRONG_AF]
  ── SEISMIC INPUT ─────────────────────────
   ML=2.80  z=4.20km  cluster=6ev/10min
   P_arr=+0.700s  S_arr=+1.200s  ΔP-S=0.500s
   norm_mag=63.4%  norm_dep=77.1%  norm_clu=40.0%
   peak_inf=7.230  seqPos=2100.0s/41400s
  ── SYNTH ENGINE STATE ────────────────────
   [PITCH_DRIFT]  rate=0.9712  →0.9680  Δ=–0.47st
   [DELAY_ECHO ]  time=189ms  feedback=0.320
   [GAIN_FILTER]  gain=0.735  lpf=9080Hz (50.4%)  Q=1.2
   [GLITCH_ENV ]  type=SPIKE_ENV  duration=300ms→1000ms
   [COMPRESSOR ]  thr=–1dBFS  ratio=20:1  atk=1ms  rel=50ms
  ══════════════════════════════════════════

  event types:
    [MINOR_AF]   ML < 2.6   minor tremor
    [STRONG_AF]  ML 2.6–3.5  significant event
    [MAIN_AF]    ML ≥ 3.5    mainshock

  P_arr / S_arr:  estimated wave arrivals at surface
                  calculated from depth and standard
                  crustal velocity model (Vp=6.0km/s, Vs=3.5km/s)
  ΔP-S:           P–S interval → proxy for source distance

  norm_* values:  all 0–100%,  used directly as modulation depth
  peak_inf:       composite influence score driving fragility engine
08   FRAGILITY ENGINE
  A continuous background process that introduces visual
  degradation proportional to the current seismic state.
  Runs independently of event triggers — it is ambient instability.

  ─────────────────────────────────────────────────────────────────
  FRAGILITY VALUE  f  ∈  [0.05, 1.0]
  ─────────────────────────────────────────────────────────────────

    without seismic mod:
      f = 0.05  (baseline noise, always present)

    with seismic mod active:
      f = (norm_magnitude × 0.72)
        + (norm_cluster   × 0.28)
        + 0.05

    → magnitude contributes 72% of fragility
    → cluster density contributes 28%
    → baseline 5% ensures the system is never fully stable

  ─────────────────────────────────────────────────────────────────
  CYCLE INTERVAL
  ─────────────────────────────────────────────────────────────────

    interval = lerp(5000ms, 800ms, f)  ±20% jitter

    f = 0.05  →  next effect in ~5000ms  (quiet)
    f = 0.50  →  next effect in ~2900ms  (active)
    f = 1.00  →  next effect in ~800ms   (crisis)

  ─────────────────────────────────────────────────────────────────
  EFFECTS  (one per cycle, weighted random selection)
  ─────────────────────────────────────────────────────────────────

    TERMINAL CORRUPTION
      probability:  always available
      target:       1 random line in terminal log
      intensity:    3% – 21% of characters replaced
                    character set: █▓▒░│┤╬═▀▄■╠╦╩
      duration:     60ms – 180ms, then restored
      opacity:      0.55 – 0.90 during corruption

    CRT POWER DIP
      probability:  increases with f
      target:       entire monitor opacity
      floor:        0.35 – 0.80 (lower = more severe)
      cycles:       1 – 2 flicker pulses
      effect:       simulates power brownout

    TITLE GLITCH
      probability:  low at f < 0.3,  high at f > 0.7
      target:       ΑΛΛΟΤΡΟΠΙΑΣ title (canvas + credits)
      intensity:    3% – 21% character substitution
      duration:     80ms per pulse
      both instances glitch simultaneously

  ─────────────────────────────────────────────────────────────────
  DISPLACEMENT LOG GLITCH  (on event, separate from fragility)
  ─────────────────────────────────────────────────────────────────

    triggered on each displacement log entry:
      header lines:    2-cycle opacity flicker 0.3↔0.9, 55ms
      pattern lines:   flicker + character corruption ∝ intensity
      data lines:      shimmer if intensity ≥ 0.7
                       extreme 4-cycle white flash if ≥ 0.95
09   VIDEO SYSTEM
  Three video channels (VIDEO 1 / 2 / 3) cycle automatically
  when the VIDEO switch is active. Each channel maps to a
  separate <video> element loaded as local file.

  loop schedule (approximate):
    phase 0:  initial dark (no video)          ~2–4s
    phase 1:  channel active, loop             variable
    phase 2:  glitch transition → dark         ~0.5s
    phase 3:  dark pause                       ~1–2s
    phase 4:  next channel loads, glitch in    ~0.5s

  glitch levels applied to video:
    .video-glitch          →  hue-rotate ±10°, brightness ±25%
                               contrast ×1.4, scale ±2%, shift ±2px
    .video-glitch-extreme  →  hue-rotate ±20°, brightness ±50%
                               contrast ×1.9, scale ±4%, shift ±4px

  seismic influence on video:
    glitch probability and severity scale with getSeismicGlitchLevel()
    → same fragility value f drives video degradation
    at f ≥ 0.8:  extreme glitch applied to transition
    at f ≥ 0.55: standard glitch applied

  noise overlay:
    canvas drawn over video, randomized per frame during transitions
    white noise at variable opacity (0.2 – 0.6)
    duration: 250ms – 500ms per transition
10   DATA SOURCES
  SEISMIC DATA
    network:    OV — INGV Osservatorio Vesuviano
    station:    CSFT  (Solfatara, Campi Flegrei, Naples)
    date:       20/05/2024
    format:     MiniSEED → JSON (custom conversion)
    channels:   HHZ  HHN  HHE  (100 samples/s)
    converter:  https://φαινόμενα.com/mseed_json.html
    catalog:    https://eida.ingv.it/

  DISPLACEMENT DATA
    Menoni, S., Galderisi, A., Carrion, D., & Gerosa, C. (2024)
    "Cross-Sectoral and Multilevel Dimensions of Risk and
     Resilience Management in Urban Areas Enabled by
     Geospatial Data Processing"
    Sustainability, 16(19), 8712
    https://www.mdpi.com/2071-1050/16/19/8712

    CAIN Web Service — Conflict Archive on the INternet
    https://cain.ulster.ac.uk/issues/housing/docs/nicrc.htm

  AUDIO
    field recordings: original material recorded in
                      Alexandra Park, Belfast
                      May 2025 – November 2025
    processing:       Web Audio API (browser-native)
    no external audio libraries used
11   MINISEED → JSON CONVERSION PIPELINE
  Raw seismic data from INGV/EIDA is distributed in MiniSEED
  format (.mseed) — a binary standard for seismic time-series.
  The system cannot read this directly; a conversion step
  produces the JSON structure the installation expects.

  ─────────────────────────────────────────────────────────────────
  WHAT IS MINISEED
  ─────────────────────────────────────────────────────────────────

    MiniSEED (mini-SEED) is the international standard for
    archiving and exchanging digital seismic data. Records are
    organized in fixed-length blocks (512–8192 bytes each),
    each containing a fixed header (48 bytes), optional
    blockettes for metadata, and compressed time-series data.

    Compression encoding (this installation):
      Steim-1 / Steim-2  (primary INGV/EIDA formats)
      INT16, INT32, FLOAT32  (also supported)

    Source catalog:  https://eida.ingv.it/
    Station:         CSFT — Solfatara, Campi Flegrei
    Channels:        HHZ  HHN  HHE  (100 samples/s)

  ─────────────────────────────────────────────────────────────────
  CONVERTER TOOL
  ─────────────────────────────────────────────────────────────────

    browser-based, no external dependencies
    https://φαινόμενα.com/mseed_json.html

    input:   .mseed file (drag & drop or file picker)
    output:  .json file (download after conversion)

    pipeline:
      1. reads all fixed-length records from the binary file
      2. decodes Steim compression or raw integer/float data
      3. concatenates all records into one continuous trace
      4. runs STA/LTA event detection on the trace
      5. estimates magnitude proxy from amplitude vs noise floor
      6. exports structured JSON for the installation

  ─────────────────────────────────────────────────────────────────
  STA/LTA EVENT DETECTION
  ─────────────────────────────────────────────────────────────────

    STA = Short-Term Average  (local energy, ~signal)
    LTA = Long-Term Average   (background energy, ~noise)

    trigger:    STA/LTA ratio exceeds upper threshold
    detrigger:  STA/LTA ratio falls below lower threshold
    min gap:    minimum silence interval between events

    all three parameters are configurable in the tool interface

  ─────────────────────────────────────────────────────────────────
  OUTPUT JSON STRUCTURE
  ─────────────────────────────────────────────────────────────────

    {
      "metadata": {
        "network":       "OV",
        "station":       "CSFT",
        "channel":       "HHZ",
        "start_time":    "2024-05-20T...",
        "sampling_rate": 100
      },
      "events": [
        {
          "timestamp":   1716238260.0,
          "magnitude":   2.80,
          "depth_km":    4.20,
          "cluster":     6
        },
        ...
      ],
      "frames": [
        {
          "timestamp":   1716238260.0,
          "amplitude":   0.00234
        },
        ...
      ]
    }

    metadata   → station identity and timing reference
    events     → detected seismic events (drives audio modulation)
    frames     → downsampled amplitude trace (drives display)
Rosa Catalano Donatella Guarino Marina Iodice
PS³   11 Rosemary Street, Belfast BT1 1QA  ·  opening 21.03.26  ·  closing 02.04.26
technical dev_  ·   · Valeria Vito