Chiarezza (C80) – App Interattiva

C80 = 10·log₁₀( E0–80ms / E80ms–∞ ). Carica un impulso (IR) o genera una stanza sintetica, vedi le aree di energia precoce/tardiva, ascolta l'effetto sul segnale e misura il valore C80.

1) Carica o genera un impulso

(WAV/MP3/FLAC; l'app rileva automaticamente il picco del diretto)

Oppure: Genera IR sintetico

1.6 s
20 ms
DRR −3 dB
0.35
Che cos'è C80? (spiegazione)

C80 misura il rapporto tra l'energia sonora che arriva nei primi 80 ms dopo il suono diretto (utile alla chiarezza) e l'energia che arriva dopo (percepita come riverbero che riduce l'intelligibilità). Valori tipici: +2…+8 dB indicano buona chiarezza; valori negativi (es. −2 dB) indicano ascolto confuso. Per il parlato si usa spesso C50 (soglia a 50 ms).

2) Grafici

Energia 0–80 ms Energia > 80 ms Curva di Schroeder
C80 (dB)
C50 (dB)
Early 0–80 ms
Late >80 ms
Metodo di calcolo (formule)

Dato un impulso h(t), con energia e(t)=h(t)^2, si definisce t0 al picco del diretto. Allora:

Eearly = ∫t0t0+80ms e(t) dt,   Elate = ∫t0 e(t) dt − Eearly

C80 = 10·log10( Eearly / Elate )    (analogamente C50 sostituendo 80→50 ms)

La curva di Schroeder è l'integrale cumulativo inverso: S(τ)=∫τ e(t) dt, normalizzata a 0 dB al valore massimo.

3) Impostazioni analisi

−40 dBFS 80 ms

Suggerimento: carica un IR reale di un teatro, oppure genera vari RT60/DRR e ascolta come cambia l'intelligibilità.

4) Test integrati

(verifica findT0, coerenza C80/C50, monotonia al variare del DRR)
Premi "Esegui test" per i risultati…

Guida funzioni (per sviluppatori)

Panoramica

Questa sezione documenta ogni funzione presente nell'app: scopo, parametri, ritorni e note d'uso/robustezza.

dB(x), pow10(d), ampFromDb(d), clamp(v,min,max)
  • dB(x): converte un rapporto di potenza x in decibel (10·log10). Protegge da zero con un floor a 1e‑20.
  • pow10(d): converte decibel in rapporto di potenza 10^(d/10). Utile per operare su energie.
  • ampFromDb(d): converte dB in ampiezza (dBFS): 10^(d/20). Usato nel gate relativo al picco.
  • clamp: limita un valore nell'intervallo [min,max] per evitare indici fuori range e soglie degeneri.
findT0(data, fs, mode, gateDB)

Determina il riferimento temporale t0 dell'impulso:

  • mode="zero": restituisce 0 (inizio file).
  • mode="peak": indice del picco (valore assoluto massimo).
  • mode="gate": primo campione che supera la soglia relativa al picco: thr = |peak|·ampFromDb(gateDB).

Robustezza: gestisce lunghezze nulle, picco=0, e applica clamp alla soglia.

Ritorno: indice intero (sample) di t0.

energyBands(ir, fs, split_ms, t0)

Calcola le energie early (t0→t0+split) e late (oltre split) su ir e ricava C = 10·log10(early/late).

  • ir: array di ampiezze (Float32).
  • fs: frequenza di campionamento.
  • split_ms: soglia di chiarezza (tipico 80 ms o 50 ms).
  • t0: indice di riferimento.

Restituisce: { early, late, C, splitN, e } dove e è l'energia per campione.

schroeder(e)

Integra all'indietro l'energia e per ottenere la curva cumulativa normalizzata 0..1 (curva di Schroeder).

decodeFile(file), mixToMono(ab)
  • decodeFile: usa WebAudio per decodificare l'ArrayBuffer del file audio. Gestione errori con alert.
  • mixToMono: se l'AudioBuffer è multi‑canale, media i canali in un buffer mono nuovo (stessa lunghezza e fs).
makeBurst(sec), play(buffer), playConvolved(ir)
  • makeBurst: genera un burst sintetico (somma di tre sinusoidi) con inviluppo ~60 ms, utile per valutare la chiarezza.
  • play: riproduce un AudioBuffer direttamente in output.
  • playConvolved: convoluzione del burst con l'IR in un ConvolverNode, per ascoltare l'effetto ambientale.
synthesizeIR(opts) & helper dbToLin

Crea un'IR sintetica con diretto a 2 ms, predelay selezionabile, coda esponenziale da RT60 e riflessioni precoci sparse.

  • rt60: tempo per -60 dB (decadimento esponenziale).
  • predelayMs: ritardo tra diretto e prime riflessioni.
  • drrDB: rapporto diretto/riverbero; scala il picco diretto rispetto all'RMS della coda.
  • diffusion: intensità di rumore/early randomizzate.

Ritorna un AudioBuffer mono.

drawAll(ir, fs, t0, splitMs)

Disegna sul canvas: griglia, aree early/late, forma d'onda, curva di Schroeder e marker t0/split.

Usa un lock drawing e requestAnimationFrame per evitare ridisegni re‑entranti.

analyzeAndDraw(), setMetric, fmt
  • analyzeAndDraw: calcola bande a 80/50 ms, aggiorna le metriche e chiama drawAll. Protetto da lock analyzing.
  • setMetric: assegna testo alle metriche nel DOM.
  • fmt: formattazione numerica (1 o 2 decimali, simbolo — per non finiti).
UI & Test: syncLabels(), handlers, runTests(), assert()
  • syncLabels: aggiorna i badge vicino agli slider.
  • Handlers: creazione/sostituzione IR, caricamento file, ricalcolo parametri, export PNG/CSV, resize sicuro.
  • runTests: esegue 5 test funzionali (t0‑peak/gate, coerenza C80, monotonia con DRR, relazione C50≤C80 con RT60 lungo). Output nel box test.
  • assert: helper che rende ✅/❌ con descrizione.

Valori ottimali di C80

I valori considerati ottimali dipendono dall'uso dello spazio:

  • Musica sinfonica / sale da concerto: C80 intorno a −2 dB ÷ +2 dB. Una chiarezza troppo elevata può rendere il suono aspro, mentre valori leggermente negativi mantengono la fusione orchestrale.
  • Musica da camera: C80 fra 0 dB e +4 dB per assicurare definizione senza perdere calore.
  • Parola / teatri di prosa: C80 ideale fra +2 dB e +8 dB, perché serve una forte intelligibilità.
  • Valori troppo bassi (sotto −2 dB) → parlato poco comprensibile, musica confusa.
  • Valori troppo alti (> +8 dB) → sensazione secca e poco naturale.

In generale, per la voce e la chiarezza del parlato, un intervallo di +2…+8 dB è considerato ottimale.