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.
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.
| 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 |
Flat ceiling (main seating zone):
4300 − floorRise(r)Dished floor:
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:
Corner geometry — 45° chamfer:
Corner staging void (HVAC):
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
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).
Drivers:
Crossover innovation (key design element):
Polar response (measured):
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:
MR12 AUX2 (HF driver) PEQ crossover settings:
Acoustic EQ (Channel 1 TEQ insert): Applied full-range before the crossover split, corrects room acoustics per installation.
Measurement protocol:
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).
| File | Description |
|---|---|
| church-acoustic-suite.jsx | Complete single-file React application — all components, geometry engine, UI |
| CLAUDE.md | This project reference document |
| CLAUDE_CHAT.md | Full transcript of the original design chat (historical reference) |
| README.md | Repository readme |
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 promptGeometry engine:
ceilHeightAtRadius(r, hall) — returns floor-to-ceiling clearance at radius rfloorHeightAtRadius(r, hall) — returns floor rise above centre datum at radius rcomputeHallGeometry(hall) — builds rowData array with per-row geometrycomputeCoverage(hall, speakers, rowData) — computes slant distance, delay, Haas status, off-axis angle, SPL per row×ring combinationcomputeFlutter(hall) — calculates flutter echo fundamentals and harmonicsComponents:
SectionDiagram — SVG cross-section showing ceiling, floor dish, speaker positions and coverage raysCoverageHeatmap — SVG grid (rows × speaker rings) colour-coded by Haas statusHallTab — Hall dimension inputs, ceiling/dish inputs, row geometry table, flutter analysisSpeakerTab — Per-ring editor (radius, power, sensitivity, phase, drop rod)CoverageTab — Coverage heatmap + full data tableAnalysisTab — REW API connection + Ollama/Claude analysis with streamingSettingsTab — LLM provider selection (Ollama or Anthropic), REW host/port, system promptApp — Root with tab navigation and logThe 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:
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
GET /application — connection testPUT /roomsim/room-size — push room dimensionsGET /roomsim/frequency-response?micposition=Main&ppo=24 — fetch simulated frequency response (Base64 big-endian float32 array)-api launch flag)Ollama (preferred — local/private):
OLLAMA_ORIGINS=* ollama serve for CORSollama pull llama3.2, mistral, qwen2.5POST /api/chat with streamingAnthropic Claude (fallback):
POST https://api.anthropic.com/v1/messagesAnalysis 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 the 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.
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:
npm create vite@latest -- --template reactsrc/App.jsx with church-acoustic-suite.jsxnpm run devOLLAMA_ORIGINS=* ollama serve