Überblick
Eingabe: Der Nutzer gibt Raummaße / Form / Materialien, Lautsprecher- und Hörposition ein — oder die Geometrie wird mit dem AR-Maßband (ohne LiDAR) oder per LiDAR-Scan (RoomPlan) erfasst.
- Lokalisierung früher Reflexionen
- RT60 (gemessen + simuliert) plus EDT / C50 / C80 / D50 (aus der simulierten RIR abgeleitet)
- Liste der Raummoden-Frequenzen
- Panel-Layout (Position, Anzahl, Produkt-SKU)
- 3D-Visualisierung + Reflexionsenergie-Heatmap
- PDF-Export in Montagehandbuch-Qualität
- Messung über das iPhone-Mikrofon (Sweep / Klatschen)
Rechteckige, L-, U-förmige und beliebige einfache Polygon-Räume werden unterstützt; Reflexionen 1. Ordnung sowie Flächen-/Enthaltensein-Berechnung nutzen das echte Polygon; Ordnung 2/3 und Raummoden nähern über die Bounding Box (siehe §9).
Akustikmodell
2.1 Sabine RT60
Die klassische Sabine-Formel:
- $V$
- Raumvolumen (m³); bei Polygonen Shoelace-Fläche × Höhe, abzüglich Hindernissen (Stützen / Träger).
- $\sum_i S_i \alpha_i$
- Fläche × Absorptionsgrad je Fläche. Koeffizienten über 6 Oktavbänder (125 / 250 / 500 / 1k / 2k / 4k Hz).
- $0.161$
- = 24·ln(10)/c, mit c = 343 m/s (20 °C).
Die App liefert 4 Ausstattungs-Presets (leerer harter Raum / typisch harte Oberflächen / Möbel / bereits behandelt), je mit Absorptionskurve pro Band; die Einzelwert-RT60-Schätzung und das Panel-Budget nutzen einen Mittel-Hochton-Durchschnittskoeffizienten, die 6-Band-Sabine-Kurve speist die Bandanzeige. Auch das Ziel-RT60 ist eine 6-Band-Kurve, passend zu Normen wie EBU Tech 3276 / THX, die einen längeren Tiefbass-Nachhall zulassen.
2.2 Image-Source-Methode (ISM)
Erste Reflexionen per Spiegelung: Quelle an der Wand spiegeln; der Schnittpunkt der Strecke „Spiegelquelle → Hörer“ mit der Wand ist der Reflexionspunkt.
- Rechteckiger Raum: Spiegelung an allen 6 Ebenen — geschlossene Lösung.
- Nicht rechteckig (
PolygonReflectionCalculator): jedes Wandsegment ausRoomPolygon.walls()spiegeln und Parameter s ∈ [0, 1] prüfen (Boden-/Decken-Reflexionen erfordern zusätzlich Reflexions-XY im Polygon); Pfade 1. Ordnung durchlaufen zudem einen 2D-Verdeckungstest — kreuzt ein Abschnitt Quelle→Punkt→Hörer ein anderes Wandsegment, wird der Pfad verworfen.
Mehrfachreflexionen (Ordnung 1–3) implementiert MultiOrderReflectionCalculator nach dem rekursiven Ansatz von pyroomacoustics:
- Alle Wandsequenzen [s₁, …, sₙ] aufzählen, benachbarte Wände verschieden
- Spiegelquellen-Iteration: S₀ = Quelle, Sₖ = mirror(Sₖ₋₁, sₖ)
- Rückverfolgung vom Hörer: Sₙ → Hörer trifft sₙ in Pₙ; Sₙ₋₁ → Pₙ trifft sₙ₋₁ in Pₙ₋₁; rekursiv zurück
- Jeder Schnittpunkt muss im gültigen Wandbereich liegen und t ∈ (0, 1)
2.3 Pfadenergie
Breitband-Energie als Funktion von Reflexionsanzahl und Distanzdämpfung:
- α wird auf [0, 0.99] begrenzt, damit α = 1 kein log(0) oder pow(negativ, N) = NaN erzeugt
- Distanzdämpfung folgt der sphärischen Ausbreitung 1/r²
- Umrechnung in dB über 10·log₁₀ (Energiedomäne)
Die Energie pro Band wird für die 6 Oktavbänder separat berechnet (Koeffizient aus finishProfile.absorptionByBand).
2.4 RT60-Schätzung (gemessen)
ImpulseResponseEstimator:
- Matched Filtering: der aufgenommene 0,45-s-Sweep wird invers gefiltert (ESS / Farina) zu einem Impuls, ~+32 dB effektiver SNR
- rmsEnvelope: gleitende RMS-Hüllkurve
- Schroeder-Rückwärtsintegration: E_back(t) = ∫ₜ^∞ s²(τ) dτ, mit 10·log₁₀ normiert ergibt die EDC-Kurve
- Lineare Steigungsregression: bevorzugt T30 [−5, −35 dB] je SNR, sonst T20 [−5, −25] oder T10 [−5, −15]
- RT₆₀ = −60 / Steigung
RT60 pro Band: auf den gefilterten Samples Bandpass an ISO-Oktavmitten (250 / 500 / 1k / 2k / 4k), Q = √2, dann Schroeder je Band.
2.5 RIR-Simulation
SimulatedRIRGenerator wandelt Mehrfachreflexionspfade in diskrete Impulse in einem 8 kHz × 0,5 s PCM-Puffer:
for path in reflectionPaths:
t = path.totalDistance / speedOfSound
amp = 10^(path.relativeEnergyDB / 20)
impulse[round(t * sampleRate)] += amp
Den Direktschall-Impuls hinzufügen, dann Schroeder-Integration für EDT / RT60 / C50 / C80 / D50.
2.6 Raummoden
Modale Frequenzen eines rechteckigen Raums:
Klassifiziert nach Anzahl der von null verschiedenen nₓ, n_y, n_z: 1 = axial, 2 = tangential, 3 = schräg.
Die Enumeration deckt n ≤ 4 pro Achse bis 300 Hz ab. Nicht rechteckige Räume schätzen Moden über die Bounding Box (exakte Moden brauchen FEM); in der UI ausgewiesen.
Geometriesystem
3.1 Unterstützte Formen
- Rechteck — Breite × Länge × Höhe
- L-Form — eine nw × nl-Kerbe an einer Ecke entfernen
- U-Form — eine nw × nl-Kerbe mittig an einer Wand entfernen
- Benutzerdefiniert — beliebiges einfaches Polygon (≥ 3, ≤ 24 Ecken)
Alle nicht rechteckigen Formen werden über RoomPolygon.from(shape:, bboxWidth:, bboxLength:) zur CCW-Eckenliste. Reflexionen 1. Ordnung, Fläche / Umfang und Enthaltensein nutzen diese Ecken direkt; ein ungültiges eigenes Polygon (< 3 / > 24 Ecken, selbstschneidend, Fläche nahe null) fällt still auf das umschließende Rechteck zurück.
3.2 Polygon-Geometrie-Werkzeuge
- Fläche — Shoelace-Formel
- Umfang — Summe der Kantenlängen
- contains(x, y) — Ray-Casting mit Rand-Epsilon (verhindert Fehler an Ecken)
- clamped(point) — Rechtecke nutzen den schnellen Pfad [0, w] × [0, l]; andere das echte [minₓ, maxₓ] × [min_y, max_y] aus
polygon.boundingBox, prüfen polygon.contains und Binärsuche zum Bbox-Zentrum, falls außerhalb - walls() — zerlegt das Polygon in nach Innennormalen klassifizierte Segmente (leftWall / rightWall / frontWall / backWall), sodass der rechteckige Panel-Empfehler wiederverwendet wird
- PolygonValidator.isSimple — prüft ein nicht selbstschneidendes einfaches Polygon
3.3 RoomPlan-Scan
RoomCaptureSession (iOS-16+-API; die App schaltet das Scannen erst ab iOS 17 frei) wird genutzt; CapturedRoomMapper bildet den Scan auf ScannedRoom ab (wallSegments + openings + furniture). Koordinaten-Mapping:
Scans werden nach Wandanzahl klassifiziert: genau 4 Segmente gelten direkt als Rechteck; alles andere durchläuft RectangularRoomSimplifier.polygonShapeFromScan, das wallSegments zu Polygon-Ecken verkettet. RoomPlan-Endpunkte haben typ. 3–8 cm Fehler; eine 12-Segment-Schleife kann 5 cm akkumulieren, daher 12 cm Schließ-Epsilon. Schließt die Kette nicht, Rückfall auf die Bounding Box und Aufforderung zum erneuten Scan.
3.4 AR-Maßband
Ohne LiDAR übernimmt ARTapeMeasureView (RealityKit-ARView mit World-Tracking): Fadenkreuz auf die Wand richten und per Doppeltipp Start / Ende setzen, nacheinander Breite → Länge → Höhe, dann bestätigen — mit Kamera-Berechtigungsführung und Tracking-Fehler-Hinweisen.
3.5 Freier Vertex-Editor
FreeVertexEditorView erlaubt das Ziehen von Ecken auf einem SwiftUI-Canvas:
- Langes Drücken zum Löschen (bei > 3 Ecken, damit ≥ 3 bleiben)
- Jeder Zieh-Frame wird mit
isSimplevalidiert; eine selbstschneidende Position wird schlicht nicht übernommen (die Ecke bleibt stehen). Tippen auf leere Fläche fügt eine Ecke auf der nächsten Kante ein; dazu kommen ein numerischer Editor je Ecke und ein Reset auf das umschließende Rechteck - 0,05-m-Raster-Einrastung
- Ein Rand von max(0,5, bbox × 0,2) m außerhalb der Bbox erlaubt das Ziehen über die Bbox hinaus (die Elternansicht vergrößert room.width / length automatisch)
Hörzonen & Multi-Listener
AcousticConfiguration.listeners unterstützt 1..N Hörpositionen (bei 0 Hörern wird eine Standard-Primärposition samt Warnung synthetisiert; bei 0 Lautsprechern übernehmen die Vorlagen aus §5.2). Die Analyse führt die Image-Source-Methode je Hörer aus und fügt Reflexionspunkte in ein Array zusammen (primärer Hörer zuerst). Der Empfehler gewichtet jede Wand nach Punktanzahl (cap = max(6, speakerCount × listenerCount)); mehrere Sitze an einer Wand treiben sie ans Budgetlimit.
- In 3D nutzen sekundäre Hörer Opacity 0,45 + Scale 0,75
- Draufsicht (RoomPlanView): primäre Punkte volle Farbe r=5, sekundäre Opacity 0,45 r=3
- Die Liste (RecommendationView) zeigt nur primäre Punkte; Fußnote „+ N Reflexionen bereits berücksichtigt“
Mehrfachreflexionen / RIR / Heatmap werden weiterhin einmal für den primären Hörer berechnet (O(speakers × surfaces³) je Hörer ist zu schwer, RIR ist eine Einzelpunkt-Metrik).
Empfehlungssystem
PanelPlacementRecommender liefert [PanelRecommendation], je mit: Position (links / rechts / Decke / vorn / hinten / Ecke), Anzahl, Priorität (essenziell / stark / empfohlen / optional), effectivenessMultiplier, targetReflectionPointId.
5.1 Proportionale Zuteilung (größter Rest)
Das alte gierige add() ließ Wände verhungern: linke Wand verbrauchte das Budget → rechte 0; bei knappem Budget auch Decke / vorn / hinten. Neu: Methode des größten Rests:
- Raw-Desired je Wand berechnen (Punktanzahl + Raumtiefe + Anwendungsfall)
- floor(raw × budget / total) als Anfangszuteilung
- Wände mit raw > 0 erhalten ≥ 1 Panel; nur wenn das Budget kleiner ist als die Zahl nachgefragter Wände, werden Flächen genullt, niedrigste Priorität zuerst
- falls Summe > Budget, vom kleinsten Bruchrest aufwärts kürzen
- Links/Rechts-Symmetrie: bei raw[0] == raw[1] alloc[0] == alloc[1] erzwingen
- Restbestand nach größtem Bruchteil umverteilen
5.2 Anwendungsfall-Vorlagen
Ohne platzierte Lautsprecher gelten anwendungsspezifische Vorlagen:
- Besprechungsraum: Decke 35 % + Rückwand 20 % + je Seitenwand 12 %
- Podcast: direkt vor dem Mikrofon 25 % + je Seite 18 % + Decke 20 %
- Studio: symmetrische Vier-Wand-Dämpfung + bis zu 4 Eck-Bassfallen im Budget (der echte Budget-Bypass greift nur auf dem Pfad dichter Tieftonmoden aus §5.3)
- Allgemeines Hören: symmetrische Basis + Hinweis, Lautsprecher hinzuzufügen
5.3 Physikalische Muss-Maßnahmen umgehen das Budget
Eck-Bassfallen werden bei dichten 80–150-Hz-Moden auf 4 erzwungen und umgehen das totalPanel-Limit. Grund: In Ecken ist der Schalldruck am höchsten, Bassfallen dort ~1,5× effizienter — physikalische Notwendigkeit.
5.4 Hörnahe Gewichtung
Ein Nachlauf markiert Empfehlungen innerhalb 1,5 m eines Hörers als .nearListener, setzt effectivenessMultiplier ×1,15 und vermerkt dies in Titel / Begründung.
Messung
6.1 ESS-Sweep
Nach Farinas Methode:
- Logarithmischer Sweep 180 Hz → 4 kHz, 0,45 s
- Inversfilter (
makeInverseSweep) = Zeitumkehr + Amplitudenhüllkurve mit +6 dB/Oktave (mit der Frequenz steigend, gegen das rosa ESS-Spektrum) - Aufnahme via AVAudioRecorder als verlustfreies Linear PCM (16-bit Mono .caf, ~96 dB Dynamik — perceptual Codecs gehören nicht in die Impulsmessung; die Abtastrate folgt der Audio-Session — 44,1 kHz am internen Mikrofon, native 48 kHz bei USB-Messmikrofonen)
- Zurücklesen → Matched Filter → analyzeImpulse
makeInverseSweep(sampleRate:) ist parametrisiert) — das Matched Filtering ist damit immer aktiv, bei 44,1 kHz (internes Mikrofon) wie bei 48 kHz (USB-Messmikrofone).6.2 Klatsch-Impuls
Ohne Wiedergabe — der Nutzer klatscht einmal kräftig in einem 1-s-Fenster; insgesamt 4,5 s aufgenommen (~3,5 s Ausklang). Direkt zu analyzeImpulse (kein Matched Filter nötig; ein Klatschen ist bereits ein schmaler Impuls). Deckt das 125-Hz-Band ab, das der Sweep (ab 180 Hz) verfehlt.
6.3 Gemessen vs. simuliert
MeasuredVsSimulatedCard nimmt das letzte gemessene RT60 und zeigt die Abweichung zum simulierten RT60:
6.4 Umgebungsrauschen & Kalibrierung
AmbientNoiseEstimator nimmt 3 s Stille auf (je 100 ms an den Enden beschnitten) für das Grundrauschen: Breitband-Mittel / -Spitze in dBFS + 5-stufige Ruhebewertung (dBFS nur relativ, bis eine SPL-Kalibrierung dB SPL liefert). Die Nahfeld-Latenzkalibrierung nutzt denselben ESS-Sweep: Telefon ≤ 30 cm vor den Lautsprecher, Verzögerung Aufnahmestart → Impulsspitze (inkl. bewusstem 250-ms-Vorlauf), idealerweise 2–3 Läufe — Streuung der letzten 3 Messungen < 5 ms = hohe, < 20 ms = mittlere Konfidenz. Die Latenz ist an das aktuelle Paar „Eingang + Ausgaberoute“ gebunden, verfällt bei jeder Änderung und wird bei Fernmessungen automatisch abgezogen.
6.5 USB-Messmikrofone & Ausgaberouting
Die Eingangsauswahl der Messseite listet internes Mikrofon und class-compliant USB-Eingänge (z. B. miniDSP UMIK-1 / UMIK-2); ein routeChangeNotification-Listener fällt aufs interne Mikrofon zurück, wenn das externe verschwindet. Aufnahme- und Sweep-Raten folgen der Session (UMIK-1 = 48 kHz). REW-.txt-Kalibrierdateien lassen sich direkt importieren (Auswertung von Sens Factor / SERNO, lineare Interpolation in Log-Frequenz, Endpunkt-Clamp; 90°-Datei für Raummessungen empfohlen) — die Korrektur verschiebt nur die Bandpegel-Anzeige, nie die RT60-Abklingsteigung.
Einmalige SPL-Kalibrierung: Schallpegelkalibrator (Standard 94 dB @ 1 kHz) aufs Mikrofon, die App tastet 3 s Pegel ab und leitet den dBFS → SPL-Offset ab — danach zeigen Messwerte echte dB SPL. Die Kalibrierung (Kurve + Offset) ist an die UID des Eingangsports gebunden und wird in ~/Library/Application Support/mic_calibration.json persistiert; bei Eingangswechsel warnt die UI in Orange, dass die Kalibrierung nicht gilt — neu importieren und kalibrieren.
Die Wiedergabe läuft über den System-Routenwähler (AVRoutePickerView-Wrapper, auf den Karten für Sweep / Nahfeld-Kalibrierung); die Session erlaubt AirPlay / Bluetooth A2DP / HFP für Testsignale über externe Lautsprecher, ohne externe Ausgabe wird der Lautsprecher erzwungen. Der Aufnahmeeingang ist immer explizit auf die Nutzerwahl gepinnt (USB-Mikrofon oder intern), damit das Mikrofon eines Bluetooth-Geräts während der Wiedergabe nicht den Eingang kapert und die Messung verunreinigt.
Visualisierung & Ausgabe
7.1 3D-Ansicht
Room3DController rendert mit SceneKit: Wände / Boden / Decke / Lautsprecher (dünnes Gehäuse + Akzent + Kanal-Pille) / Hörer (FE-Glyph + Stiel) / Hindernisse (transluzente SCNBox) / empfohlene Panels / Mehrfachreflexions-Pfadsegmente / Reflexionsenergie-Overlay.
7.2 Reflexionsenergie-Heatmap
ReflectionEnergyMapGenerator akkumuliert die Energie jedes Pfads auf das uCells × vCells-Raster der Wand (Standard 12×6). Eine Karte je Wand, in 3D als Energie-Farbschicht (Blau → Cyan → Grün → Gelb → Rot).
EnergyHeatmapRenderer wandelt das Raster in ein UIImage: Block-Zellen à 16 px (keine Interpolation zwischen Zellen, damit Rasterkanten lesbar bleiben; die Glättung an der Wand übernimmt SceneKits bilineare Texturfilterung) + eigener 5-Stufen-Farbverlauf (Blau → Cyan → Grün → Gelb → Rot) + Alpha linear von 0,20 bis 0,85 nach Energieposition auf fester −30…0-dB-Skala (−∞ voll transparent).
7.3 RIR-Faltungs-Vorschau
RIRPreviewPlayer (AVAudioEngine + AVAudioPlayerNode) faltet ein prozedural synthetisiertes Trockensignal (gezupfte Saite / Klatsch-Burst / vokalartige Sprache — keine mitgelieferten Samples) mit dem simulierten RIR — hörbar „unbehandelt vs. behandelt“.
Zeitbereichs-Faltung RIRConvolver.convolve(dry:rir:) direkt O(N × M) (N = trockene Samples, M = RIR), Peak-normiert auf 0,9 gegen Clipping.
7.4 PDF-Montagehandbuch
ReportExporter rendert ein A4-PDF (595 × 842 pt) via UIGraphicsPDFRenderer:
- Raumübersicht + 3D-Schnappschuss
- 6-Band-RT60-Balkendiagramm Sabine-Schätzung vs. Ziel (gemessenes RT60 fließt nicht ins PDF)
- Reflexionspunkt-Tabelle + Moden-Tabelle + Risikoübersicht
- Empfohlene-Panel-Tabelle (die BOM-Einkaufsliste erscheint in der App, nicht im PDF)
- Geist-Schrift + PingFangSC-Fallback (CoreText cascadeList, damit CJK nicht als □□□ erscheint)
7.5 Projekt-Persistenz
ProjectStore (Actor) schreibt ~/Library/Application Support/Acouvero/projects.json: [RoomProject], je mit Room + Lautsprechern + Hörern + Empfehlungen + panelCountOverrides. Beim ersten Start migrieren Daten automatisch aus dem alten Verzeichnis FindEcho/ (FindEcho ist der interne Codename vor der Umbenennung, in Codesymbolen bewusst beibehalten).
MeasurementStore (Actor) schreibt measurements.json: [MeasurementResult], per roomId mit dem Projekt verknüpft.
Beide nutzen elementweise Decode-Wiederherstellung (Throwable<T>-Wrapper) — ein defekter Datensatz lässt nicht die ganze Liste scheitern.
MicCalibrationStore schreibt ~/Library/Application Support/mic_calibration.json (Wurzelverzeichnis, kein Unterordner): REW-Kalibrierkurve + SPL-Offset, an die Eingangsport-UID gebunden — bei Eingangswechsel ist erneutes Importieren / Kalibrieren nötig.
Engineering-Hinweise
8.1 SwiftUI + @Observable
Das ViewModel (FindEchoViewModel) nutzt Swift 5.9 @Observable — Statusfelder direkt beobachtet, kein Combine. AcousticAnalysis-Ergebnisse werden per Equatable-Vergleich von AcousticConfiguration gecacht:
var analysis: AcousticAnalysis {
let cfg = configuration
if let cached = cachedAnalysis, cachedConfiguration == cfg {
return cached
}
let result = analysisService.analyze(cfg)
cachedConfiguration = cfg
cachedAnalysis = result
return result
}
8.2 Actor-Isolation
ProjectStore und MeasurementStore sind actors, die IO / Async natürlich serialisieren; RoomPlanService ist eine @MainActor-Klasse. Die UI nutzt async / await; der Hauptthread wird nie durch Disk-IO blockiert.
8.3 AVAudio-Lebenszyklus
AudioSessionManager zentralisiert die Session-Kategorie (.playback für RIR-Vorschau, .playAndRecord für Messung). Unterbrechungsschutz gibt es auf beiden Pfaden: messseitig lauscht ein InterruptionMonitor in AudioMeasurementService auf AVAudioSession.interruptionNotification — ein Anruf / Siri während Sweep, Klatschen oder Umgebungsrauschen verwirft das Ergebnis mit Fehler; vorschauseitig hört RIRPreviewPlayer ebenfalls zu und stoppt den Player-Node, isPlaying wird gelöscht. Auch ein Routenwechsel mitten in der Messung verwirft den Lauf.
8.4 Task-Abbruch
Die Faltungs-Wiedergabe ist ein Hintergrund-Task; schnelle Taps lösen pendingPlayTask?.cancel() plus Task.isCancelled-Doppelprüfung aus, um Out-of-order-MainActor-Schreibvorgänge zu verhindern.
8.5 Testabdeckung
AllShapesAndUseCasesTests nutzt das Swift-Testing-Framework für die volle Matrix — jede Form × jeder Anwendungsfall (ein Hörer; Lautsprecher je nach Fall als Stereopaar oder einzeln mittig) — und prüft:
analysis.reflectionPaths.count >= 1analysis.warningsenthält den Näherungshinweis für nicht rechteckige Räume- die empfohlene Panel-Summe ist nicht negativ (totalPanelCount ≥ 0; keine Budget-Assertion)
- selbstschneidende eigene Polygone fallen sicher zurück (kein Crash, Degradierung zum Rechteck)
- Ecken < 3 und weitere Randfall-Rückfälle
8.6 Plattform & Lokalisierung
Deployment-Target iOS 17.0, iPhone + iPad; null Drittanbieter-Abhängigkeiten (keine SPM- / CocoaPods-Pakete) — nur System-Frameworks (SwiftUI / SceneKit / ARKit / RoomPlan / AVFoundation / Accelerate). Lokalisierung per .xcstrings-Katalog: Chinesisch als Quellsprache plus English / Français / Deutsch / Español / Português (Brasil) — 6 Sprachen, in der App oder systemfolgend umschaltbar.
Bekannte Grenzen
- Multi-Order in nicht rechteckigen Räumen via Bounding Box — Flutter-/Slapback-Risiko 2./3. Ordnung nahe konkaven Ecken kann abweichen. Erste Ordnung nutzt das echte Polygon.
- Raummoden in nicht rechteckigen Räumen via Bounding Box geschätzt — exakte Moden brauchen FEM.
- Messung mit iPhone-Mikrofon — unkalibriert; nicht-flacher Frequenzgang / Empfindlichkeit. Zuverlässigkeit immer
.low, als Quervergleich zur geometrischen Schätzung. Mit einem USB-Messmikrofon (miniDSP UMIK-1 / UMIK-2) und geladener REW-Kalibrierdatei werden die Bandpegel gemäß Kalibrierkurve korrigiert; eine einmalige 94-dB-SPL-Referenz zeigt danach Umgebungs- und Messpegel als absolute dB SPL (vorher nur dBFS). - Einzelquellen-ISM-Annahme — ignoriert Gehäusebeugung, Horn-Richtwirkung u. a.
- Keine Bassfallen-Modellierung — Probleme unter 80 Hz liegen außerhalb des Sabine-Modells und brauchen dedizierte Tieftonbehandlung.
- AR-Scan-Genauigkeit — RoomPlan-Endpunkte typ. 3-8 cm Fehler; 12-Segment-Schleife kann 5+ cm akkumulieren. Wanddicke nicht modelliert.
Referenzen
- Sabine, W. C. (1922). Collected Papers on Acoustics. Harvard University Press.
- Allen, J. B., & Berkley, D. A. (1979). Image method for efficiently simulating small-room acoustics. JASA, 65(4), 943–950.
- Schroeder, M. R. (1965). New method of measuring reverberation time. JASA, 37(3), 409–412.
- Farina, A. (2000). Simultaneous measurement of impulse response and distortion with a swept-sine technique. Audio Engineering Society Convention 108.
- Scheibler, R., Bezzam, E., & Dokmanić, I. (2018). Pyroomacoustics: A Python package for audio room simulation and array processing algorithms. ICASSP 2018.
- EBU Tech 3276. Listening conditions for the assessment of sound programme material.
- ITU-R BS.1116. Methods for the subjective assessment of small impairments in audio systems.
- BB93 — Acoustic design of schools (UK).
- THX Pro Cinema Certification requirements.