Acouvero
Descargar
TECHNICAL DOC · v0.4.0

Acústica de salas,
de la medición
al plan.

Acouvero es una herramienta de análisis acústico de salas y planificación de tratamiento para iPhone / iPad. Este documento es para lectores interesados en la ingeniería acústica o la implementación cliente: algoritmos, sistema geométrico, métodos de medición, motor de recomendación y notas de ingeniería.

Bandas de octava
6bandas
Formas
4geometrías
Reflexiones
1–3órdenes
§ 01

Visión general

Entrada: el usuario introduce dimensiones / forma / materiales, posiciones de altavoces y de escucha — o la geometría se mide con la cinta métrica AR (sin LiDAR) o se captura con un escaneo LiDAR (RoomPlan).

Salida
  • Localización de reflexiones tempranas
  • RT60 (medido + simulado) más EDT / C50 / C80 / D50 (derivados de la RIR simulada)
  • Lista de frecuencias modales
  • Plan de paneles (posición, cantidad, SKU)
  • Visualización 3D + mapa de energía de reflexión
  • Exportación PDF nivel manual de instalación
  • Medición con el micrófono del iPhone (barrido / palmada)

Se admiten salas rectangulares, en L, en U y polígonos simples arbitrarios; las reflexiones de 1er orden y el cálculo de área / pertenencia usan el polígono real; los órdenes 2/3 y los modos aproximan con la caja envolvente (véase §9).

§ 02

Modelo acústico

2.1 Sabine RT60

La fórmula clásica de Sabine:

SABINE · RT60 $$ RT_{60} = \frac{0.161 \cdot V}{\sum_i S_i \alpha_i} $$
$V$
Volumen (m³); para polígonos, área de Shoelace × altura, menos obstáculos (columnas / vigas).
$\sum_i S_i \alpha_i$
Superficie × coeficiente de absorción por cara. Coeficientes en 6 bandas (125 / 250 / 500 / 1k / 2k / 4k Hz).
$0.161$
= 24·ln(10)/c, con c = 343 m/s (20 °C).

La app incluye 4 preajustes de acabado (sala vacía y dura / acabado duro típico / mobiliario / ya tratado), cada uno con curva por banda; la estimación RT60 de valor único y el presupuesto de paneles usan un coeficiente medio de medios-agudos, mientras la curva Sabine de 6 bandas alimenta la vista por banda. El RT60 objetivo también es una curva de 6 bandas, acorde a normas como EBU Tech 3276 / THX que permiten una cola más larga en graves.

2.2 Método de fuentes imagen (ISM)

Las primeras reflexiones usan espejo: se refleja la fuente respecto al muro; la intersección del segmento «fuente espejo → oyente» con el muro es el punto de reflexión.

  • Sala rectangular: espejo en los 6 planos — solución cerrada.
  • No rectangular (PolygonReflectionCalculator): espejo en cada segmento de RoomPolygon.walls() y validar s ∈ [0, 1] (las reflexiones de suelo / techo exigen además el XY dentro del polígono); las rutas de 1er orden pasan también una prueba de oclusión 2D: cualquier tramo fuente→punto→oyente que cruce otro segmento de muro se descarta.

Las reflexiones multi-orden (1–3) las implementa MultiOrderReflectionCalculator según el enfoque recursivo de pyroomacoustics:

  1. Enumerar todas las secuencias de muros [s₁, …, sₙ], muros adyacentes distintos
  2. Iteración de fuente imagen: S₀ = fuente, Sₖ = mirror(Sₖ₋₁, sₖ)
  3. Trazado inverso desde el oyente: Sₙ → oyente corta sₙ en Pₙ; Sₙ₋₁ → Pₙ corta sₙ₋₁ en Pₙ₋₁; y así sucesivamente
  4. Cada intersección debe estar en el rango válido del muro y t ∈ (0, 1)
APROXIMACIÓN En salas no rectangulares, el multi-orden aproxima por la caja envolvente («reflexiones fantasma» cerca de esquinas cóncavas). El análisis descarta toda ruta cuyo punto esté a > 0,3 m de cada segmento real; solo las rutas válidas alimentan la detección de flutter / slapback.

2.3 Energía de trayectos

Energía de banda ancha según número de reflexiones y atenuación por distancia:

PATH ENERGY $$ E_{rel} = (1 - \bar{\alpha})^N \cdot \frac{d_{direct}^2}{d_{total}^2} $$
  • α se acota a [0, 0.99] para que α = 1 no produzca log(0) ni pow(negativo, N) = NaN
  • La atenuación sigue la divergencia esférica 1/r²
  • Conversión a dB con 10·log₁₀ (dominio de energía)

La energía por banda se calcula para las 6 bandas (coeficiente de finishProfile.absorptionByBand).

2.4 Estimación de RT60 (medida)

ImpulseResponseEstimator:

  • Filtrado adaptado: el barrido grabado de 0,45 s se filtra inverso (ESS / Farina) a un impulso, ~+32 dB de SNR efectiva
  • rmsEnvelope: envolvente RMS de ventana deslizante
  • Integración inversa de Schroeder: E_back(t) = ∫ₜ^∞ s²(τ) dτ, normalizada con 10·log₁₀ da la curva EDC
  • Regresión lineal de pendiente: T30 [−5, −35 dB] según SNR, con respaldo T20 [−5, −25] o T10 [−5, −15]
  • RT₆₀ = −60 / pendiente

RT60 por banda: sobre las muestras filtradas, paso de banda en centros ISO (250 / 500 / 1k / 2k / 4k), Q = √2, y Schroeder por banda.

2.5 Simulación de RIR

SimulatedRIRGenerator convierte las rutas multi-orden en impulsos discretos escritos en un búfer PCM de 8 kHz × 0,5 s:

SimulatedRIRGeneratorpseudocode
for path in reflectionPaths:
    t   = path.totalDistance / speedOfSound
    amp = 10^(path.relativeEnergyDB / 20)
    impulse[round(t * sampleRate)] += amp

Añadir el impulso del sonido directo y aplicar integración de Schroeder para EDT / RT60 / C50 / C80 / D50.

Comparación antes / después Cada ruta se atenúa por los paneles de los muros que toca, generando un RIR «tratado». La UI alterna A/B para mostrar la mejora de EDT / C50, y AVAudio convoluciona una señal seca para comparar de oído.

2.6 Modos propios

Frecuencias modales de una sala rectangular:

ROOM MODES $$ f_{n_x, n_y, n_z} = \frac{c}{2} \sqrt{\left(\frac{n_x}{L_x}\right)^2 + \left(\frac{n_y}{L_y}\right)^2 + \left(\frac{n_z}{L_z}\right)^2} $$

Clasificados según cuántos de nₓ, n_y, n_z son no nulos: 1 = axial, 2 = tangencial, 3 = oblicuo.

La enumeración cubre n ≤ 4 por eje hasta 300 Hz. Las salas no rectangulares estiman los modos con la caja envolvente (los modos exactos requieren FEM); se indica en la UI.

§ 03

Sistema geométrico

3.1 Formas admitidas

  • Rectángulo — ancho × largo × alto
  • Forma en L — quita una muesca nw × nl en una esquina
  • Forma en U — quita una muesca nw × nl en el centro de un muro
  • Personalizado — cualquier polígono simple (≥ 3, ≤ 24 vértices)

Todas las formas no rectangulares pasan a una lista de vértices CCW vía RoomPolygon.from(shape:, bboxWidth:, bboxLength:). Las reflexiones de 1er orden, área / perímetro y pertenencia usan estos vértices directamente; un polígono personalizado inválido (< 3 / > 24 vértices, autointersecado, área casi nula) degrada en silencio al rectángulo envolvente.

3.2 Utilidades de geometría poligonal

  • Área — fórmula de Shoelace
  • Perímetro — suma de longitudes de aristas
  • contains(x, y) — ray-casting con epsilon de borde (evita falsos negativos en esquinas)
  • clamped(point) — los rectángulos usan la vía rápida [0, w] × [0, l]; los demás el verdadero [minₓ, maxₓ] × [min_y, max_y] de polygon.boundingBox, prueban polygon.contains y búsqueda binaria hacia el centro si está fuera
  • walls() — divide el polígono en segmentos clasificados por normal interior (leftWall / rightWall / frontWall / backWall), reutilizando el recomendador rectangular
  • PolygonValidator.isSimple — valida un polígono simple sin autointersección

3.3 Escaneo RoomPlan

Se usa RoomCaptureSession (API de iOS 16+; la app exige iOS 17 para escanear) y CapturedRoomMapper mapea el escaneo a ScannedRoom (wallSegments + openings + furniture). Mapeo de coordenadas:

ARKit (x, y, z) → y es vertical App (x, y, z) → z es vertical Extremos de muro (z=0 suelo) App.x = ARKit.x App.y = ARKit.z App.z = 0 Centro de hueco / mueble  App.x = ARKit.x App.y = ARKit.z App.z = ARKit.y

El escaneo se clasifica por número de muros: exactamente 4 segmentos se tratan directamente como rectángulo; el resto pasa por RectangularRoomSimplifier.polygonShapeFromScan, encadenando wallSegments en vértices. Los extremos de RoomPlan erran 3–8 cm; un bucle de 12 segmentos puede acumular 5 cm, por eso el epsilon de cierre es 12 cm. Si no cierra, recurre a la caja envolvente y pide reescanear.

3.4 Cinta métrica AR

Sin LiDAR, ARTapeMeasureView (ARView de RealityKit con seguimiento de mundo) toma el relevo: apunta la retícula a la pared y toca dos veces para marcar inicio / fin, siguiendo ancho → largo → alto, y confirma para generar una sala rectangular — con guía de permiso de cámara y avisos de fallo de seguimiento.

3.5 Editor de vértices libres

FreeVertexEditorView permite arrastrar vértices en un Canvas de SwiftUI:

  • Mantén pulsado para borrar (con > 3 vértices, para que queden ≥ 3)
  • Cada frame de arrastre se valida con isSimple; una posición con autointersección simplemente no se aplica (el vértice se queda quieto). Tocar un área vacía inserta un vértice en la arista más cercana; hay además un editor numérico por vértice y un botón de restablecer al rectángulo envolvente
  • Ajuste a rejilla de 0,05 m
  • Un margen de max(0,5, bbox × 0,2) m fuera de la bbox permite arrastrar vértices más allá (la vista padre agranda room.width / length)
§ 04

Zonas de escucha y multi-oyente

AcousticConfiguration.listeners admite 1..N posiciones de escucha (con 0 oyentes se sintetiza una posición principal por defecto con aviso; con 0 altavoces toman el relevo las plantillas del §5.2). El análisis ejecuta el método de imágenes por oyente y fusiona los puntos en un array (el oyente principal primero). El recomendador pondera cada muro por su número de puntos (cap = max(6, speakerCount × listenerCount)); varios asientos compartiendo un muro lo empujan al tope del presupuesto.

Visual de UI
  • En 3D, los oyentes secundarios: opacidad 0,45 + escala 0,75
  • Vista superior (RoomPlanView): puntos primarios a todo color r=5, secundarios opacidad 0,45 r=3
  • La lista (RecommendationView) muestra solo puntos primarios; nota al pie «+ N reflexiones ya incluidas»

Las reflexiones multi-orden / RIR / mapa se calculan una vez para el oyente principal (O(speakers × surfaces³) por oyente es demasiado, y el RIR es de un solo punto).

§ 05

Motor de recomendación

PanelPlacementRecommender produce [PanelRecommendation], cada uno con: posición (muro izq. / der. / techo / frontal / trasero / esquina), cantidad, prioridad (esencial / fuerte / recomendado / opcional), effectivenessMultiplier, targetReflectionPointId.

5.1 Reparto proporcional (mayor resto)

El antiguo add() voraz dejaba muros sin nada: el izquierdo agotaba el presupuesto → el derecho 0; con presupuesto ajustado también techo / frontal / trasero. La nueva versión usa el método del mayor resto:

  • Calcular el «raw desired» por muro (nº de puntos + profundidad + caso de uso)
  • floor(raw × budget / total) como asignación inicial
  • los muros con raw &gt; 0 reciben ≥ 1 panel; solo cuando el presupuesto es menor que el número de muros con demanda se ponen superficies a cero, primero la prioridad más baja
  • si la suma &gt; presupuesto, recortar desde el menor resto fraccionario
  • pase de simetría izq./der.: si raw[0] == raw[1], forzar alloc[0] == alloc[1]
  • redistribuir el sobrante según la mayor fracción

5.2 Plantillas por caso de uso

Sin altavoces colocados, se aplican plantillas por caso de uso:

  • Sala de reuniones: techo 35 % + muro trasero 20 % + cada muro lateral 12 %
  • Pódcast: justo frente al micro 25 % + cada lado 18 % + techo 20 %
  • Estudio: amortiguación simétrica en 4 muros + hasta 4 trampas de graves en esquina dentro del presupuesto (el verdadero salto del presupuesto solo ocurre en la vía de modos graves densos del §5.3)
  • Escucha general: base simétrica + aviso para añadir altavoces

5.3 Las necesidades físicas saltan el presupuesto

Las trampas de graves de esquina se fuerzan a 4 cuando los modos 80–150 Hz son densos, saltando el tope totalPanel. Razón: en las esquinas la presión es máxima y las trampas son ~1,5× más eficientes — necesidad física.

5.4 Ponderación cercana al oyente

Una pasada final marca las recomendaciones a menos de 1,5 m de un oyente como .nearListener, effectivenessMultiplier ×1,15, y lo indica en el título / motivo.

§ 06

Medición

6.1 Barrido ESS

Según el método de Farina:

  • Barrido log. 180 Hz → 4 kHz, 0,45 s
  • Filtro inverso (makeInverseSweep) = inversión temporal + envolvente de amplitud de +6 dB/octava (creciente con la frecuencia, para compensar el espectro rosa del ESS)
  • Grabación con AVAudioRecorder a Linear PCM sin pérdida (mono 16 bits .caf, ~96 dB de rango dinámico — los códecs perceptuales no sirven para medir impulsos; la tasa sigue la sesión de audio — 44,1 kHz con el micro integrado, 48 kHz nativos con micros de medición USB)
  • Lectura → filtrado adaptado → analyzeImpulse
Alineación de muestreo El WAV de barrido, el barrido inverso y la grabación se generan a la tasa de muestreo real de la sesión de audio (makeInverseSweep(sampleRate:) está parametrizado) — el filtrado adaptado siempre está activo, tanto a 44,1 kHz (micro integrado) como a 48 kHz (micros de medición USB).

6.2 Impulso de palmada

Sin reproducción — el usuario da una palmada fuerte dentro de una ventana de 1 s; se graban 4,5 s en total (~3,5 s de cola). Va directo a analyzeImpulse (sin filtro adaptado; una palmada ya es un impulso estrecho). Cubre la banda de 125 Hz que el barrido (desde 180 Hz) no alcanza.

6.3 Medido vs simulado

MeasuredVsSimulatedCard toma el último RT60 medido y muestra la desviación frente al RT60 simulado:

< 15%el modelo y la medición coinciden
15–30%cierta divergencia (mobiliario / materiales no modelados)
> 30%gran divergencia — revisar geometría / materiales

6.4 Ruido ambiente y calibración

AmbientNoiseEstimator graba 3 s de silencio (recortando 100 ms en cada extremo) para el ruido de fondo: media / pico dBFS de banda ancha + valoración de silencio en 5 niveles (dBFS solo relativo hasta una calibración SPL, tras la cual se muestra dB SPL). La calibración de latencia de campo cercano reutiliza el mismo barrido ESS: teléfono a menos de 30 cm del altavoz, retardo inicio de grabación → pico del impulso (con un pre-roll deliberado de 250 ms), idealmente 2–3 pasadas — dispersión de las últimas 3 lecturas < 5 ms = confianza alta, < 20 ms = media. La latencia queda ligada al par «entrada + ruta de salida» actual, se invalida si cualquiera cambia y las mediciones lejanas muestran el retardo de propagación ya corregido.

6.5 Micros USB de medición y enrutado de salida

El selector de entrada de la página de medición lista el micro integrado y las entradas USB class-compliant (p. ej. miniDSP UMIK-1 / UMIK-2); una escucha de routeChangeNotification vuelve al micro integrado si el externo desaparece. Las tasas de grabación y barrido siguen la sesión (UMIK-1 = 48 kHz). Los archivos de calibración REW .txt se importan directamente (leyendo Sens Factor / SERNO, interpolación lineal en frecuencia logarítmica, clamp en extremos; se recomienda el archivo de 90° para medición de salas) — la corrección solo desplaza la muestra de niveles por banda, nunca la pendiente de decaimiento RT60.

Calibración SPL única: coloca un calibrador de nivel (94 dB @ 1 kHz por defecto) sobre el micro, la app muestrea 3 s de nivel para derivar el offset dBFS → SPL y las lecturas muestran dB SPL reales. La calibración (curva + offset) queda ligada al UID del puerto de entrada y se persiste en ~/Library/Application Support/mic_calibration.json; al cambiar de entrada, la UI avisa en naranja de que la calibración no aplica — reimportar y recalibrar.

La reproducción pasa por el selector de ruta del sistema (wrapper de AVRoutePickerView, en las tarjetas de barrido / calibración de campo cercano); la sesión permite AirPlay / Bluetooth A2DP / HFP para emitir los tonos por altavoces externos, con altavoz forzado si no hay. La entrada de grabación siempre queda fijada explícitamente a la elección del usuario (micro USB o integrado) para que el micro de un dispositivo Bluetooth no robe la entrada durante la reproducción y contamine la medición.

§ 07

Visualización y salida

7.1 Vista 3D

Room3DController renderiza con SceneKit: muros / suelo / techo / altavoces (caja fina + marca + píldora de canal) / oyente (glifo FE + tallo) / obstáculos (SCNBox translúcido) / paneles recomendados / segmentos de rutas multi-orden / superposición de mapa de energía.

DISEÑO · DIBUJO TÉCNICO Estilo «dibujo técnico» (aristas finas, iluminación constante, sin PBR), distinto del 3D fotorrealista.

7.2 Mapa de energía de reflexión

ReflectionEnergyMapGenerator acumula la energía de cada ruta en la rejilla uCells × vCells del muro (12×6 por defecto). Un mapa por muro, superpuesto en 3D (azul → cian → verde → amarillo → rojo).

EnergyHeatmapRenderer convierte la rejilla en UIImage: celdas «block» de 16 px (sin interpolación entre celdas, para que los bordes sigan legibles; el suavizado en el muro viene del filtrado bilineal de textura de SceneKit) + rampa propia de 5 tramos (azul → cian → verde → amarillo → rojo) + alfa mapeado linealmente de 0,20 a 0,85 según la posición de la energía en una escala fija de −30…0 dB (−∞ totalmente transparente).

7.3 Vista previa por convolución RIR

RIRPreviewPlayer (AVAudioEngine + AVAudioPlayerNode) convoluciona una señal seca sintetizada (cuerda pulsada / palmada / voz vocálica sintética — sin muestras incluidas) con el RIR simulado para oír «sin tratar vs tratado».

Convolución temporal RIRConvolver.convolve(dry:rir:) directa O(N × M) (N = muestras secas, M = RIR), normalizada a pico 0,9 para evitar recorte.

7.4 Manual de instalación PDF

ReportExporter genera un PDF A4 (595 × 842 pt) con UIGraphicsPDFRenderer:

  • Resumen de sala + captura 3D
  • Gráfico de barras RT60 de 6 bandas estimación Sabine vs objetivo (el RT60 medido no entra en el PDF)
  • Tabla de puntos + tabla de modos + resumen de riesgos
  • Tabla de paneles (la lista de compra BOM se muestra en la app, no en el PDF)
  • Fuente Geist + respaldo PingFangSC (CoreText cascadeList, para que el CJK no salga como □□□)

7.5 Persistencia de proyectos

ProjectStore (actor) escribe ~/Library/Application Support/Acouvero/projects.json: [RoomProject], cada uno con Room + altavoces + oyentes + recomendaciones + panelCountOverrides. En el primer arranque, los datos migran automáticamente del directorio antiguo FindEcho/ (FindEcho es el nombre en clave interno previo al renombrado, conservado a propósito en los símbolos del código).

MeasurementStore (actor) escribe measurements.json: [MeasurementResult], vinculado al proyecto por roomId.

Ambos usan recuperación de decodificación por elemento (envoltorio Throwable<T>) — un registro corrupto no hace fallar toda la lista.

MicCalibrationStore escribe ~/Library/Application Support/mic_calibration.json (raíz, sin subdirectorio): curva de calibración REW + offset SPL, ligados al UID del puerto de entrada — cambiar de entrada exige reimportar / recalibrar.

§ 08

Notas de ingeniería

8.1 SwiftUI + @Observable

El ViewModel (FindEchoViewModel) usa la macro @Observable de Swift 5.9 — campos observados directamente, sin Combine. Los resultados de AcousticAnalysis se cachean por comparación Equatable de AcousticConfiguration:

FindEchoViewModel.analysisswift
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 Aislamiento por actor

ProjectStore y MeasurementStore son actors, que serializan IO / async de forma natural; RoomPlanService es una clase @MainActor. La UI usa async / await; el hilo principal nunca se bloquea por IO de disco.

8.3 Ciclo de vida de AVAudio

AudioSessionManager centraliza la categoría de sesión (.playback para la vista previa RIR, .playAndRecord para la medición). La protección contra interrupciones cubre ambas rutas: en medición, un InterruptionMonitor dentro de AudioMeasurementService escucha AVAudioSession.interruptionNotification — una llamada / Siri durante el barrido, la palmada o el ruido ambiente descarta el resultado con error; en la vista previa, RIRPreviewPlayer también escucha y detiene el nodo de reproducción limpiando isPlaying. Un cambio de ruta de audio a mitad de medición también invalida la pasada).

8.4 Cancelación de tareas

La reproducción por convolución es una tarea de fondo; los toques rápidos disparan pendingPlayTask?.cancel() más una doble verificación Task.isCancelled para evitar escrituras desordenadas en MainActor.

8.5 Cobertura de pruebas

AllShapesAndUseCasesTests usa el framework Swift Testing para la matriz completa — cada forma × caso de uso (oyente único; altavoces en par estéreo o uno central según el caso) — y comprueba:

  • analysis.reflectionPaths.count >= 1
  • analysis.warnings incluye la nota de aproximación para salas no rectangulares
  • el total de paneles recomendados es no negativo (totalPanelCount ≥ 0; sin aserción de presupuesto)
  • los polígonos autointersecados degradan con seguridad (sin crash, a rectángulo)
  • vértices &lt; 3 y otros retrocesos de casos límite

8.6 Plataforma y localización

Destino de despliegue iOS 17.0, iPhone + iPad; cero dependencias de terceros (sin paquetes SPM / CocoaPods) — solo frameworks del sistema (SwiftUI / SceneKit / ARKit / RoomPlan / AVFoundation / Accelerate). Localización con catálogo .xcstrings: chino como lengua fuente más English / Français / Deutsch / Español / Português (Brasil) — 6 idiomas, conmutable en la app o siguiendo al sistema.

§ 09

Limitaciones conocidas

  1. Multi-orden en salas no rectangulares usa la caja envolvente — el riesgo de flutter / slapback de 2.º/3.º orden cerca de esquinas cóncavas puede desviarse. Los puntos de 1.er orden usan el polígono real.
  2. Modos en salas no rectangulares estimados por caja envolvente — modos exactos requieren FEM.
  3. Medición con el micrófono del iPhone — sin calibrar; respuesta / sensibilidad no planas. Fiabilidad siempre .low, como contraste con la estimación geométrica. Con un micro de medición USB (miniDSP UMIK-1 / UMIK-2) y su archivo de calibración REW cargado, los niveles por banda se corrigen según la curva de calibración; una calibración SPL de referencia de 94 dB muestra después los niveles ambiente y de medición como dB SPL absolutos (solo dBFS hasta entonces).
  4. Supuesto ISM de fuente única — ignora difracción de caja, directividad de bocina, etc.
  5. Sin modelado de trampas de graves — los problemas bajo 80 Hz quedan fuera del modelo de Sabine y requieren tratamiento dedicado.
  6. Precisión del escaneo AR — extremos de RoomPlan con error de 3-8 cm; un bucle de 12 segmentos puede acumular 5+ cm. No se modela el grosor de los muros.
§ 10

Referencias

  1. Sabine, W. C. (1922). Collected Papers on Acoustics. Harvard University Press.
  2. Allen, J. B., & Berkley, D. A. (1979). Image method for efficiently simulating small-room acoustics. JASA, 65(4), 943–950.
  3. Schroeder, M. R. (1965). New method of measuring reverberation time. JASA, 37(3), 409–412.
  4. Farina, A. (2000). Simultaneous measurement of impulse response and distortion with a swept-sine technique. Audio Engineering Society Convention 108.
  5. Scheibler, R., Bezzam, E., & Dokmanić, I. (2018). Pyroomacoustics: A Python package for audio room simulation and array processing algorithms. ICASSP 2018.
  6. EBU Tech 3276. Listening conditions for the assessment of sound programme material.
  7. ITU-R BS.1116. Methods for the subjective assessment of small impairments in audio systems.
  8. BB93 — Acoustic design of schools (UK).
  9. THX Pro Cinema Certification requirements.
¿Prefieres la versión sencilla?

«Por qué tu sala reescribe la música»

Leer el Deep Read