CLAUDE.md 15 KB

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. Direct-to-Reverberant ratio per seat — primary intelligibility driver
  2. Haas window compliance — speakers reaching a listener more than 30ms after the nearest speaker cause echo/colouration; 10–30ms causes tonal colouration
  3. Off-axis angle per speaker per row — must be within 55° MS6 coverage cone
  4. SPL at ear per row — from inverse square law using speaker sensitivity and power
  5. Flutter echo — flat ceiling + rising floor creates parallel surfaces at decreasing clearance toward perimeter

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)
  • Danger: >30ms Haas excess — red (distinct echo)

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

Codebase

Files

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

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:

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