# Church Acoustic Analysis Suite — Project Reference ## Project Purpose A React single-file web application for acoustic analysis of a Plymouth Brethren Christian Church (PBCC) "Universal Hall" — specifically the MS6 ceiling speaker system. The tool models the hall geometry, computes speaker coverage per row, checks Haas window compliance, analyses flutter echo risk, connects to REW (Room EQ Wizard) API for measurements, and sends all data to a local Ollama LLM (or Claude API) for structured acoustic recommendations. --- ## Hall Geometry — Confirmed Measurements ### Critical geometry rule — read carefully **The CEILING IS FLAT.** It is one horizontal plane at a constant absolute height of **4300mm above the centre floor datum** across the entire main seating zone. **The FLOOR IS DISHED** (bowl shape). It is lowest at the centre (communion table area) and rises outward toward the perimeter. The apparent "ceiling height" (floor-to-ceiling clearance) decreases toward the perimeter solely because the floor rises. There is no slope in the ceiling itself over the main seating area. ### Plan dimensions | Parameter | Value | Source | |---|---|---| | Seating plan | 20,914mm × 20,914mm | SK-303 + confirmed | | Half-width (centre to wall) | 10,457mm | 20914 / 2 | | Row 1 front edge (inner radius) | 2,210mm from centre | Confirmed | | Row pitch (FFL to FFL) | 883mm | Confirmed | | Number of main rows | 8 | Confirmed | | Row 8 back face | 8,411mm from centre | SK-303 drawing | | Back aisle width | 2,046mm | 10457 − 8411 = 2046 ✓ | | Corner rows per corner | 4 rows | Confirmed | | Corner row pitch | 883mm (same as main) | Confirmed | | Corner row 1 front | ~620mm from edge of circular seating | Confirmed | **Row mid-bench radii (ear position):** | Row | Front edge (mm) | Mid-bench ear (mm) | |---|---|---| | 1 | 2,210 | 2,651 | | 2 | 3,093 | 3,534 | | 3 | 3,976 | 4,418 | | 4 | 4,859 | 5,301 | | 5 | 5,742 | 6,184 | | 6 | 6,625 | 7,067 | | 7 | 7,508 | 7,950 | | 8 | 8,391 | 8,833 → back face 8,411 | ### Section — ceiling and floor **Flat ceiling (main seating zone):** - Absolute height: **4300mm** above centre floor datum (0mm reference) - This is constant across the entire main seating zone - Floor-to-ceiling clearance at any radius = `4300 − floorRise(r)` **Dished floor:** - Centre (communion table zone, r ≈ 0–2210mm): **0mm** (lowest, flat zone) - Rises linearly from row 1 outward to row 8 - Total dish rise from centre to row 8 back (r=8411mm): **700mm** - Dish slope: 700mm over 8411mm ≈ **1:12** (approximately 1:8 per SK-303, measured from row 1) - Rise per row ≈ 87.5mm **Floor-to-ceiling clearance per row (flat ceiling @ 4300mm):** | Row | Floor rise (mm) | Floor-to-ceiling (mm) | |---|---|---| | Centre | 0 | 4,300 | | Row 1 mid | ~55 | ~4,245 | | Row 2 mid | ~140 | ~4,160 | | Row 3 mid | ~220 | ~4,080 | | Row 4 mid | ~310 | ~3,990 | | Row 5 mid | ~400 | ~3,900 | | Row 6 mid | ~480 | ~3,820 | | Row 7 mid | ~565 | ~3,735 | | Row 8 mid | ~650 | ~3,650 | | Row 8 back | 700 | 3,600 | **Corner area ceiling:** - The ceiling drops in the corner zones due to building structure (lower roof soffit) - Floor-to-ceiling behind last corner row: **2,950mm** - This is a structural change, not a continuation of the main flat ceiling **Corner geometry — 45° chamfer:** - The building corners are cut at 45° behind the last corner seating row - The perimeter wall in each corner is not a right-angle but a diagonal plane at 45° to the two adjacent side walls - This means corner listeners face the hall centre across the chamfered geometry, not across a square corner - Acoustic implication: the 45° angled surface redirects reflections diagonally inward rather than straight back — less flutter risk than a 90° corner, but creates oblique reflections toward the main seating zone - The geometry code currently approximates corner rows by radial position only; the 45° chamfer is not yet explicitly modelled in plan view **Corner staging void (HVAC):** - Below the corner seating there is a structural void — the corner seating is raised staging - This void is used as a plenum/duct for the HVAC ventilation system - The surfaces of this void (floor and underside of staging) are insulated to reduce sound transmission into and out of the ventilation path - Acoustic implication: the insulation damps what would otherwise be hard reflective surfaces; effectively the corner underfloor is acoustically treated - HVAC noise ingress from this void into the seating area is a risk factor — any REW measurement showing low-frequency noise floor elevation in the corner zone should be investigated against HVAC operating state **Ear height above local floor:** 1,100mm (seated listener, consistent throughout) **Ceiling tile grid:** 600mm × 600mm acoustic tiles — constrains speaker positions to 600mm increments from the grid --- ## Speaker System ### Layout — all flush mounted, NO drop rods All speakers sit flush with the ceiling (acoustic face at ceiling level). There are no drop rods anywhere. | Ring | Count | Radius from centre | Ceiling height at radius | Notes | |---|---|---|---|---| | Centre | 1 | 0mm | ~4,300mm | Over communion table | | Inner ring | 8 | 5,720mm | ~4,060mm | Between rows 4–5 | | Outer ring | 8 | 8,600mm | ~3,580mm | Just inside row 8 back (8,411mm) | | Corner | 8 (2 per corner) | 10,310mm | ~2,950mm | 1,500mm from side walls | **Total: 25 speakers, all flush with ceiling.** Speaker height above centre floor datum = ceiling height at that radius (since drop rod = 0). ### Corner speaker position - Radius: 10,310mm from centre - 1,500mm from each side wall (wall at 10,457mm → one axis coordinate = 8,957mm) - Cartesian: approximately (8,957mm, 5,107mm) from centre (solving 10,310² = 8,957² + y²) ### MS6 Speaker — Technical Specification (ISS 1, June 2024, Dudley Wilkin) **Drivers:** - LF: Visaton FRS8M — 8Ω, 30W, 88dB/1W/1m, resonant freq 125Hz, response 100Hz–20kHz - HF: Visaton G20SC — 8Ω, 20mm soft dome tweeter, 88dB/1W/1m, response 1,200Hz–30kHz - Driver spacing: 90mm centre-to-centre **Crossover innovation (key design element):** - Conventional crossovers cause destructive interference lobes at 2–5kHz — exactly the consonant intelligibility band (P, T, F, S) - MS6 uses MIDAS MR12 digital mixer as active crossover with a **hard frequency gap** - LF driver hard cut-off: **2,792Hz** - HF driver starts: **3,225Hz** - Gap: **433Hz** wide, centred around 3kHz — inaudible but eliminates driver overlap - Result: zero horizontal lobes, near-circular polar response to 55° off-axis **Polar response (measured):** - At 30° off-axis: near-perfect circular across 200Hz–10kHz - At 55° off-axis: still excellent circular response - **Maximum coverage angle: 55° off-axis from directly below** **Signal chain:** ``` Mono audio source → MIDAS MR12 Ch1 (Acoustic TEQ insert for room EQ) → Bus 1 → AUX1 → LF PEQ (crossover cut) → LF amplifier → 100V line → LF transformers → Bus 2 → AUX2 → HF PEQ (crossover cut) → HF amplifier → 100V line → HF transformers ``` **MR12 AUX1 (LF driver) PEQ crossover settings:** - Low: −15dB @ 3k09, Q=10 - Low2: −15dB @ 3k31, Q=10 - LoMid: −15dB @ 3k43, Q=10 - HiMid: +4dB @ 2k79, Q=10 **MR12 AUX2 (HF driver) PEQ crossover settings:** - Low: −15dB @ 2k79, Q=10 - Low2: −15dB @ 2k99, Q=10 - LoMid: +5.5dB @ 3k20, Q=10 - HiMid: +0.5dB @ 3k55, Q=10 **Acoustic EQ (Channel 1 TEQ insert):** Applied full-range before the crossover split, corrects room acoustics per installation. **Measurement protocol:** - Use ARTA software with impulse window (minimum 10ms window) - Never use TrueRTA or any continuous-signal method - Mic minimum 2m from speaker (far field), at 90° horizontal so both drivers are equidistant ### Historical system context (Dudley Wilkin documentation, 1970–2024) - **1970s:** 4 corner column speakers — poor coverage, excited all room echoes - **1982:** First ceiling ring — 8 speakers at row 5 radius + 4 diagonal + corner staging speakers - **1986:** Anti-phasing breakthrough — quadrant anti-phasing creates null lines along aisle centrelines; each listener hears only one speaker segment → major intelligibility improvement - **2010:** Proposed new layout — centre speaker (rows 1–3) + main ring (rows 4+) + outer ring fill; reduces count from 21 to 13 - **MS6 (2024):** New bespoke two-driver speaker with gap crossover replacing earlier drivers **Anti-phasing principle:** Adjacent speaker segments operate in opposite polarity. Null lines form along aisle centrelines. A listener on either side of an aisle hears only the speaker from their segment. This eliminates cross-segment interference and dramatically improves STI (Speech Transmission Index). --- ## Acoustic Analysis Objectives ### Key metrics (in priority order) 1. **STIPA** — Speech Transmission Index for PA systems (IEC 60268-16); the single number that captures all intelligibility-degrading effects; target ≥ 0.75 (Excellent) 2. **Direct-to-Reverberant ratio** per seat — primary intelligibility driver; improved by anti-phasing (each listener hears only their nearest segment) 3. **Haas window compliance** — speakers reaching a listener more than 30ms after the nearest speaker cause echo/colouration; 10–30ms causes tonal colouration; both degrade STI modulation depth 4. **Off-axis angle** per speaker per row — must be within 55° MS6 coverage cone 5. **SPL at ear** per row — from inverse square law using speaker sensitivity and power 6. **Flutter echo** — flat ceiling + rising floor creates parallel surfaces at decreasing clearance toward perimeter; harmonics in 500–4kHz band directly degrade STI ### STIPA measurement **STIPA** (Speech Transmission Index for PA systems) is the simplified single-measurement STI method defined in IEC 60268-16. It uses a pre-recorded test signal with specific modulation at frequencies across seven octave bands (125 Hz–8 kHz), played through the live PA system and measured with a handheld analyser. **IEC 60268-16 rating scale:** | Rating | STI range | Colour | | ------ | --------- | ------ | | Excellent | 0.75–1.00 | Green | | Good | 0.60–0.75 | Blue | | Fair | 0.45–0.60 | Amber | | Poor | 0.30–0.45 | Orange | | Bad | 0.00–0.30 | Red | Target for this hall: ≥ 0.75 (Excellent) Measurement equipment: NTI Acoustilyzer AL1 or equivalent STIPA-capable analyser. Key degradation mechanisms in this hall (computed risk factors in Analysis tab): - Haas echo rows (>30ms) — directly reduce modulation depth in all STI bands - Off-axis coverage gaps (outside 55° cone) — reduces signal level, lowering D/R ratio - Flutter harmonics in 500–4kHz speech band — reduce modulation depth at those frequencies - Tile diffraction at ~571Hz — may introduce a spectral dip in a critical STI band - HVAC noise via corner staging void — raises background noise floor in corner seating **STIPA vs continuous-sound measurement:** STIPA is valid for this hall type (it uses a modulated test signal, not raw SLM levels). Standard pink noise SLM readings are still invalid for checking individual speaker coverage due to anti-phase null lines. ### Haas window rules applied in code - **Primary:** nearest speaker to that row (0ms excess) — green - **OK:** 0–10ms Haas excess — blue (slight colouration, acceptable) - **Warn:** 10–30ms Haas excess — amber (audible colouration, degrades STI) - **Danger:** >30ms Haas excess — red (distinct echo, significantly degrades STI) ### Flutter echo analysis - Flutter frequency at each zone = speed of sound / (2 × floor-to-ceiling clearance at ear level) - At row 8 (clearance ≈ 2,500mm ear-to-ceiling): flutter fundamental ≈ 69Hz, harmonics at 137Hz, 206Hz — in speech fundamental range - 600mm tile grid creates diffraction grating effect at ~571Hz - Harmonics landing in 500–4kHz range are flagged as STI risk factors in the Analysis tab --- ## Codebase ### Files | File | Description | |---|---| | [church-acoustic-suite.jsx](church-acoustic-suite.jsx) | Complete single-file React application — all components, geometry engine, UI | | [CLAUDE.md](CLAUDE.md) | This project reference document | | [CLAUDE_CHAT.md](CLAUDE_CHAT.md) | Full transcript of the original design chat (historical reference) | | [README.md](README.md) | Repository readme | ### App structure (church-acoustic-suite.jsx) **Constants:** - `C` — colour palette (dark theme) - `HALL_DEFAULTS` — confirmed hall geometry (20,914mm sq, 8 rows, dish floor, flat ceiling) - `SPEAKER_DEFAULTS` — 4 rings: centre, inner (×8, r=5720mm), outer (×8, r=8600mm), corner (×8, r=10310mm) - `SETTINGS_DEFAULTS` — Ollama/Claude API config, REW host/port, system prompt **Geometry engine:** - `ceilHeightAtRadius(r, hall)` — returns floor-to-ceiling clearance at radius r - `floorHeightAtRadius(r, hall)` — returns floor rise above centre datum at radius r - `computeHallGeometry(hall)` — builds rowData array with per-row geometry - `computeCoverage(hall, speakers, rowData)` — computes slant distance, delay, Haas status, off-axis angle, SPL per row×ring combination - `computeFlutter(hall)` — calculates flutter echo fundamentals and harmonics **Components:** - `SectionDiagram` — SVG cross-section showing ceiling, floor dish, speaker positions and coverage rays - `CoverageHeatmap` — SVG grid (rows × speaker rings) colour-coded by Haas status - `HallTab` — Hall dimension inputs, ceiling/dish inputs, row geometry table, flutter analysis - `SpeakerTab` — Per-ring editor (radius, power, sensitivity, phase, drop rod) - `CoverageTab` — Coverage heatmap + full data table - `AnalysisTab` — REW API connection + Ollama/Claude analysis with streaming - `SettingsTab` — LLM provider selection (Ollama or Anthropic), REW host/port, system prompt - `App` — Root with tab navigation and log ### Known code issue to fix The `ceilHeightAtRadius()` function currently stores three separate ceiling heights (`ceilAtRow1Front: 4338`, `ceilAtRow8Back: 3600`, `ceilAtCornerBack: 2950`) and interpolates between them — this incorrectly models a **sloped ceiling**. **Correct model:** ceiling is flat at a single absolute height (`ceilFlat = 4300mm`) above centre datum. Floor-to-ceiling at any radius = `4300 − floorHeightAtRadius(r)`. The corner area ceiling (2950mm) is a separate structural change that should be applied only in the corner zone. The `HALL_DEFAULTS` and geometry engine need to be refactored to: ```js ceilFlat: 4300, // flat ceiling, mm above centre floor datum cornerCeilClearance: 2950, // floor-to-ceiling in corner zone (structural drop) dishRise: 700, // floor rise from centre to row 8 back face ``` --- ## REW API Integration - REW runs locally on port 4735 by default - Endpoint: `GET /application` — connection test - Endpoint: `PUT /roomsim/room-size` — push room dimensions - Endpoint: `GET /roomsim/frequency-response?micposition=Main&ppo=24` — fetch simulated frequency response (Base64 big-endian float32 array) - Full API spec: https://www.roomeqwizard.com/help/help_en-GB/html/api.html - REW must be started with API enabled (Preferences → API, or `-api` launch flag) - Browser must run on same machine as REW (localhost only by design) --- ## LLM Integration **Ollama (preferred — local/private):** - Requires `OLLAMA_ORIGINS=* ollama serve` for CORS - Models: pull e.g. `ollama pull llama3.2`, `mistral`, `qwen2.5` - Endpoint: `POST /api/chat` with streaming **Anthropic Claude (fallback):** - API key entered in Settings tab - Endpoint: `POST https://api.anthropic.com/v1/messages` - Default model: claude-sonnet-4-20250514 **Analysis prompt:** Sends complete hall geometry, per-row coverage data (slant, delay, Haas, off-axis, SPL), flutter echo analysis, and optional REW frequency data. Requests structured sections: hall assessment, coverage issues, speaker position optimisation, Haas/delay analysis, anti-phasing assessment, MR12 EQ recommendations, ARTA measurement protocol. **Analysis prompt:** You are an expert acoustic consultant specialising in distributed ceiling speaker systems for large assembly halls. You have deep knowledge of accoustic ceiling speaker layout and design, including the MS6 speaker (Visaton FRS8M + G20SC drivers), the MIDAS MR12 active crossover with its 433 Hz gap at 3 kHz, anti-phasing techniques, and the Haas effect in multi-speaker environments. Analyse the provided coverage data and give specific, technical, actionable recommendations. --- ## Build / Run This is a standalone React JSX file intended for use in a CodeSandbox, Vite React project, or similar. It uses only React hooks (`useState`, `useCallback`, `useRef`, `useEffect`) with no external dependencies beyond React itself. To run locally: 1. Create a Vite React project: `npm create vite@latest -- --template react` 2. Replace `src/App.jsx` with `church-acoustic-suite.jsx` 3. `npm run dev` 4. Start REW on same machine with API enabled 5. Start Ollama with CORS enabled: `OLLAMA_ORIGINS=* ollama serve`