Acouvero
Baixar
TECHNICAL DOC · v0.5.0

Acústica de salas,
de ponta a ponta — da
medição ao plano.

O Acouvero é uma ferramenta de análise de acústica de salas e planejamento de tratamento para iPhone / iPad. Este documento é para leitores interessados na engenharia acústica ou na implementação do cliente — cobrindo os algoritmos centrais, o sistema de geometria, os métodos de medição, o motor de recomendações e notas de engenharia.

Bandas de oitava
6bandas
Formatos de sala
4geometrias
Reflexões
1–3ordens
§ 01

Visão geral

Entrada: o usuário informa o tamanho / formato / materiais de acabamento da sala, as posições dos alto-falantes e da posição de audição — ou a geometria da sala é medida com a trena em AR (sem necessidade de LiDAR) ou capturada por um escaneamento com LiDAR (RoomPlan).

Saída
  • Localização de pontos de reflexão inicial
  • RT60 (medido + simulado) mais EDT / C50 / C80 / D50 (derivados da RIR simulada)
  • Lista de frequências dos modos da sala
  • Plano de disposição dos painéis (posição, quantidade, SKU do produto)
  • Visualização 3D + mapa de calor da energia das reflexões
  • Exportação de PDF em nível de manual de instalação
  • Medição no dispositivo por varredura ESS / palma (microfone integrado ou microfone de medição USB)
  • Calibração de microfone de medição USB e referência SPL, espectro em tempo real (RTA)
  • Sobreposições de resposta em frequência e médias multiposição, interoperabilidade com REW, PEQ / alinhamento de subwoofer, assistente de IA

Há suporte para salas retangulares, em L, em U e com qualquer polígono simples; as reflexões de primeira ordem e os cálculos de área / contenção usam o polígono real; as reflexões de 2ª/3ª ordem e os modos da sala são aproximados pela caixa delimitadora (ver §9).

§ 02

Modelo acústico

VERSÃO SIMPLES Estes conceitos têm cada um uma explicação simples: o que é o RT60, modos de sala e ondas estacionárias e o método das fontes-imagem.

2.1 Sabine RT60

A clássica fórmula de Sabine:

SABINE · RT60RT60=0.161⋅V∑iSiαi RT_{60} = \frac{0.161 \cdot V}{\sum_i S_i \alpha_i}
VV
Volume da sala (m³); para polígonos, área Shoelace × altura, menos obstáculos como colunas / vigas.
∑iSiαi\sum_i S_i \alpha_i
Área da superfície × coeficiente de absorção por face. Os coeficientes usam 6 bandas de oitava (125 / 250 / 500 / 1k / 2k / 4k Hz).
0.1610.161
= 24·ln(10)/c, com c = 343 m/s (20 °C).

O app traz 4 predefinições de acabamento (cômodo vazio de superfícies duras / acabamento duro típico / ambiente com estofados / ambiente já tratado), cada uma com uma curva de absorção por banda; a estimativa de RT60 em valor único do topo e o orçamento de painéis usam um coeficiente médio de absorção das bandas médias-altas, enquanto a curva Sabine de 6 bandas alimenta a exibição por banda. O RT60 alvo também é uma curva de 6 bandas (não um valor único), em conformidade com normas como EBU Tech 3276 / THX, que permitem uma cauda de reverberação mais longa nas baixas frequências.

2.2 Método das Fontes de Imagem (ISM)

As reflexões de primeira ordem usam espelhamento: espelha-se a fonte em relação a uma parede; a interseção do segmento “fonte espelhada → ouvinte” com a parede é o ponto de reflexão.

  • Sala retangular: espelhar em todos os 6 planos (4 paredes + piso + teto) — forma fechada.
  • Não retangular (PolygonReflectionCalculator): espelha cada segmento de parede de RoomPolygon.walls() e valida o parâmetro s ∈ [0, 1] dentro do segmento (reflexões de piso / teto exigem ainda que o XY da reflexão esteja dentro do polígono); caminhos de primeira ordem também passam por uma verificação de oclusão 2D — qualquer trecho fonte→ponto→ouvinte que cruze outro segmento de parede é descartado.

Reflexões de múltiplas ordens (ordens 1–3) são implementadas pelo MultiOrderReflectionCalculator seguindo a abordagem recursiva do pyroomacoustics:

  1. Enumera todas as sequências de paredes [s₁, …, sₙ], com paredes adjacentes distintas
  2. Iteração da fonte imagem: S₀ = source, Sₖ = mirror(Sₖ₋₁, sₖ)
  3. Traçado reverso a partir do ouvinte: a reta Sₙ → ouvinte cruza sₙ em Pₙ; a reta Sₙ₋₁ → Pₙ cruza sₙ₋₁ em Pₙ₋₁; recursão até o início
  4. Cada interseção deve estar dentro do intervalo válido da parede e com t ∈ (0, 1) no segmento
APROXIMAÇÃO Em salas não retangulares, o multi-ordem usa a aproximação por bounding box (“reflexões fantasma” perto de cantos côncavos). A camada de análise descarta qualquer caminho cujo ponto de reflexão esteja a > 0,3 m de todos os segmentos de parede reais; só os caminhos válidos restantes alimentam a detecção de flutter / slapback.

2.3 Energia do caminho

Energia de banda larga em função do número de reflexões e da atenuação pela distância:

PATH ENERGYErel=(1−αˉ)N⋅ddirect2dtotal2 E_{rel} = (1 - \bar{\alpha})^N \cdot \frac{d_{direct}^2}{d_{total}^2}
  • α é limitado a [0, 0.99] para que α = 1 não produza log(0) ou pow(negativo, N) = NaN, o que contaminaria todo o caminho
  • A atenuação pela distância segue o espalhamento esférico 1/r²
  • A conversão para dB usa 10·log₁₀ (domínio da energia)

A energia por banda é calculada separadamente para as 6 bandas de oitava (cada uma usando o coeficiente da respectiva banda de finishProfile.absorptionByBand).

2.4 Estimativa de RT60 (medida)

ImpulseResponseEstimator:

  • Filtragem casada: a varredura gravada passa por filtragem inversa (ESS / Farina) e é comprimida em um único impulso; ganho de processamento ≈ 10·log₁₀(T·B) — cerca de +41 dB de SNR efetiva na predefinição de telefone de 3 s, 180 Hz–4 kHz
  • rmsEnvelope: envoltória RMS de janela deslizante
  • Integração reversa de Schroeder: E_back(t) = ∫ₜ^∞ s²(τ) dτ, normalizada com 10·log₁₀ para gerar a curva EDC
  • Regressão linear da inclinação: prefira T30 [−5, −35 dB] conforme o SNR, com fallback para T20 [−5, −25] ou T10 [−5, −15]
  • RT₆₀ = −60 / inclinação

RT60 por banda: sobre as amostras após o filtro casado, passa-banda nos centros de oitava ISO escolhidos conforme a faixa real da varredura (Q = √2) e Schroeder em cada banda.

2.5 Simulação de RIR

SimulatedRIRGenerator transforma os caminhos de reflexão multi-ordem em eventos de impulso discretos gravados em um buffer 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

Some o impulso do som direto e depois execute a integração reversa de Schroeder para extrair EDT / RT60 / C50 / C80 / D50.

Comparação antes / depois Cada caminho de reflexão é atenuado pelos painéis acumulados nas paredes que ele toca, produzindo um RIR “tratado”. A interface alterna entre A/B para mostrar a melhoria de EDT / C50, e o AVAudio faz a convolução de um sinal seco para comparar audivelmente o antes e o depois.

2.6 Modos da sala

Frequências modais de uma sala retangular:

ROOM MODESfnx,ny,nz=c2(nxLx)2+(nyLy)2+(nzLz)2 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}

Classificados por quantos dos índices nₓ, n_y, n_z são não nulos: 1 = axial, 2 = tangencial, 3 = oblíquo.

A enumeração cobre n ≤ 4 por eixo até 300 Hz. Salas não retangulares estimam os modos a partir da caixa delimitadora (modos exatos exigem FEM); isso é indicado explicitamente na interface.

§ 03

Sistema de geometria

3.1 Formatos suportados

  • Retângulo — width × length × height
  • Formato em L — remove um recorte nw × nl em um canto escolhido
  • Formato U — remove um recorte de nw × nl no meio de uma parede escolhida
  • Personalizado — qualquer polígono simples (≥ 3, ≤ 24 vértices)

Todos os formatos não retangulares viram uma lista de vértices em CCW via RoomPolygon.from(shape:, bboxWidth:, bboxLength:). As reflexões de primeira ordem, os cálculos de área / perímetro e de contenção usam esses vértices diretamente; um polígono personalizado inválido (< 3 / > 24 vértices, com autointerseção, área quase nula) degrada silenciosamente para o retângulo delimitador.

3.2 Utilitários de geometria de polígonos

  • Área — fórmula de Shoelace
  • Perímetro — soma dos comprimentos das arestas
  • contains(x, y) — ray-casting com fallback de epsilon na fronteira (evita falsos negativos nos cantos)
  • clamped(point) — retângulos usam o caminho rápido [0, w] × [0, l]; não retângulos usam o verdadeiro [minₓ, maxₓ] × [min_y, max_y] do polygon.boundingBox, testam polygon.contains e fazem busca binária em direção ao centro do bbox se estiver fora
  • walls() — divide o polígono em segmentos de parede classificados pela normal interna (agrupados automaticamente em leftWall / rightWall / frontWall / backWall), permitindo reutilizar o recomendador de painéis da versão retangular
  • PolygonValidator.isSimple — valida um polígono simples sem autointerseção

3.3 Escaneamento com RoomPlan

Usa-se a RoomCaptureSession (API do iOS 16+; no app, o escaneamento exige iOS 17), e o CapturedRoomMapper mapeia o escaneamento para um ScannedRoom (wallSegments + openings + furniture). Mapeamento de coordenadas:

ARKit (x, y, z) → y é vertical App (x, y, z) → z é vertical Extremidades da parede (z=0 piso) App.x = ARKit.x App.y = ARKit.z App.z = 0 Abertura / centro de móvel  App.x = ARKit.x App.y = ARKit.z App.z = ARKit.y

Os escaneamentos são classificados pela contagem de paredes: exatamente 4 segmentos de parede são tratados diretamente como retângulo; qualquer outro caso passa pelo RectangularRoomSimplifier.polygonShapeFromScan, encadeando os wallSegments em vértices de polígono. Os endpoints do RoomPlan têm erro típico de 3–8 cm; um loop de 12 segmentos pode acumular 5 cm, então o epsilon de fechamento é 12 cm. Se a cadeia não fechar, ele recorre ao bounding box e pede para o usuário escanear de novo.

3.4 Trena AR

Em dispositivos sem LiDAR, o ARTapeMeasureView (uma ARView do RealityKit com world tracking) assume: mire a cruz de mira na parede e toque duas vezes para registrar os pontos inicial / final, passando por largura → comprimento → altura, depois confirme para gerar uma sala retangular — com orientação sobre permissão de câmera e dicas para falha de rastreamento.

3.5 Editor de vértices livres

FreeVertexEditorView permite ao usuário arrastar vértices em um Canvas do SwiftUI:

  • Pressione e segure para excluir (quando o número de vértices > 3, de modo que restem ≥ 3)
  • Cada quadro do arrasto é validado com isSimple; uma nova posição com autointerseção simplesmente não é aplicada (o vértice fica onde está). Tocar em um espaço vazio insere um vértice na aresta mais próxima; há também um editor numérico por vértice e um botão de redefinir para o retângulo delimitador
  • Snap na grade de 0,05 m
  • Uma margem de max(0,5, bbox × 0,2) m fora da bbox permite que o usuário arraste vértices para além da bbox atual (a view pai aumenta automaticamente room.width / length)
§ 04

Zonas de audição e múltiplos ouvintes

AcousticConfiguration.listeners aceita 1..N posições de audição (com 0 ouvintes, uma posição primária padrão é sintetizada com um aviso; com 0 alto-falantes, os templates de caso de uso da §5.2 assumem o controle). A análise executa o método das fontes-imagem uma vez por ouvinte e mescla os pontos de reflexão em um único array (os pontos do ouvinte primário primeiro). O recomendador de painéis acústicos pondera cada parede pelo número de pontos de reflexão (cap = max(6, speakerCount × listenerCount)); vários assentos compartilhando a mesma parede naturalmente a empurram em direção ao teto do orçamento.

Visuais da UI
  • No 3D, os nós de secondary listener usam opacity 0,45 + scale 0,75
  • Na vista superior (RoomPlanView), os pontos de reflexão primários são r=5 em cor cheia, os secundários r=3 com opacidade 0,45
  • A lista de reflexões (RecommendationView) mostra apenas os pontos primários; as posições de audição secundárias recebem uma nota de rodapé “+ N reflexões já contabilizadas no plano”

Reflexões de múltiplas ordens / RIR / mapa de calor ainda são calculados uma única vez para o ouvinte principal (por ouvinte, O(speakers × surfaces³) é pesado demais, e o RIR é uma métrica de ponto único).

§ 05

Motor de recomendação

PanelPlacementRecommender gera [PanelRecommendation], cada item com: posição (parede esquerda / parede direita / teto / parede frontal / parede traseira / canto), quantidade, prioridade (essencial / forte / recomendado / opcional), effectivenessMultiplier, targetReflectionPointId.

5.1 Alocação proporcional (maiores restos)

O antigo add() guloso deixava paredes sem nada: a parede esquerda consumia o orçamento → a parede direita ficava com 0; com orçamentos apertados, o teto / a frente / o fundo também ficavam sem. A nova versão usa o método do maior resto (largest-remainder):

  • Calcular o desejado bruto de cada parede (contagem de pontos de reflexão + profundidade da sala + caso de uso)
  • floor(raw × budget / total) como alocação inicial
  • paredes com raw &gt; 0 recebem pelo menos 1 painel; somente quando o orçamento é menor que o número de paredes com demanda é que as superfícies são zeradas, começando pelas de menor prioridade
  • se a soma &gt; orçamento, corta a partir do menor resto fracionário
  • passagem de simetria esquerda/direita: se raw[0] == raw[1], força alloc[0] == alloc[1]
  • redistribuir qualquer sobra pela maior fração

5.2 Modelos por caso de uso

Sem alto-falantes posicionados, aplicam-se templates específicos por caso de uso:

  • Sala de reunião: teto 35% + parede do fundo 20% + cada parede lateral 12%
  • Podcast: diretamente à frente do microfone 25% + cada lado 18% + teto 20%
  • Estúdio: amortecimento simétrico nas quatro paredes + até 4 armadilhas de graves de canto dentro do orçamento (o verdadeiro desvio de orçamento só acontece no caminho de modos de baixa frequência densos da §5.3)
  • Audição geral: base simétrica + um aviso para adicionar alto-falantes

5.3 Os itens físicos indispensáveis contornam o orçamento

As armadilhas de graves de canto são forçadas a 4 quando os modos de 80–150 Hz são densos, ignorando o limite totalPanel. Motivo: os cantos têm a maior pressão sonora e as armadilhas de graves são ~1,5× mais eficientes ali do que nas paredes — uma necessidade física, não um item de orçamento.

5.4 Ponderação próxima ao ouvinte

Um pós-processamento marca as recomendações de parede a até 1,5 m de um ouvinte como .nearListener, define effectivenessMultiplier ×1,15 e indica no título / motivo que se trata de uma “zona de absorção sensível a curta distância”.

§ 06

Medição

VERSÃO SIMPLES Estes três tópicos têm cada um uma página em linguagem simples: medição por varredura, o teste da palma e como escolher microfone de medição.

6.1 Varredura ESS

Varredura logarítmica ESS (método de Farina): quatro predefinições + personalizada, durações de 3 / 6 / 12 s:

  • Teste rápido no telefone: 180 Hz–4 kHz na saída integrada, 75 Hz–4 kHz na saída externa (única predefinição que permite o alto-falante integrado)
  • Graves / subwoofer: 15–300 Hz (requer saída externa)
  • Faixa completa: 20 Hz–20 kHz (requer saída externa)
  • Personalizada: limites livres dentro de 10 Hz–20 kHz cobrindo pelo menos uma oitava (requer saída externa)
  • Filtro inverso (makeInverseSweep) = reversão temporal + um envelope de amplitude de +6 dB/oitava (crescente com a frequência, para compensar o espectro rosa do ESS)
  • Gravação via AVAudioRecorder em Linear PCM sem perdas (16 bits mono .caf, faixa dinâmica de ~96 dB — codecs perceptuais não têm lugar na medição de impulso; a taxa de amostragem segue a sessão de áudio — 44,1 kHz no microfone integrado, os 48 kHz nativos em microfones de medição USB)
  • Leitura de volta → filtro casado → analyzeImpulse

O sinal de reprodução, a varredura inversa e a análise compartilham uma única configuração, com a frequência máxima limitada pela taxa de amostragem real; as predefinições de graves / faixa completa / personalizada se recusam a iniciar sem saída externa. As bandas de oitava do RT60 são escolhidas conforme a faixa real da varredura; a faixa de uma predefinição é a configuração do estímulo — a faixa confiável ainda depende do alto-falante, do microfone e da qualidade da medição.

Alinhamento de taxa de amostragem O WAV de varredura, a varredura inversa e a gravação são todos gerados na taxa de amostragem real da sessão de áudio (makeInverseSweep(sampleRate:) é parametrizado) — a filtragem casada está sempre ativa, tanto a 44,1 kHz no microfone integrado quanto a 48 kHz em microfones de medição USB.

6.2 Impulso de palma

Sem reprodução — o usuário bate uma palma forte dentro de uma janela de 1 s; são gravados 4,5 s no total (~3,5 s de cauda). O sinal vai direto para analyzeImpulse (não precisa de filtragem casada; uma palma já é um impulso estreito). Isso cobre a banda de oitava de 125 Hz, que a predefinição de telefone (a partir de 180 Hz) não alcança.

6.3 Medido vs simulado

MeasuredVsSimulatedCard obtém o RT60 medido mais recente do projeto e mostra o desvio em relação ao RT60 simulado da geometria atual:

< 15%modelo e medição concordam
15–30%certa divergência (possivelmente móveis / materiais não modelados)
> 30%grande divergência — verifique novamente a geometria / os materiais

6.4 Ruído ambiente & calibração

AmbientNoiseEstimator grava 3 s de silêncio (aparando 100 ms em cada extremidade) para o ruído de fundo da sala: média de banda larga / pico em dBFS, mais uma classificação de silêncio em 5 níveis (o dBFS é apenas relativo até uma calibração de SPL, depois da qual passa a ser exibido dB SPL). A calibração de latência de campo próximo reutiliza a mesma varredura ESS: segure o telefone a até 30 cm do alto-falante, meça o atraso do início da gravação até o pico do impulso (incluindo um pre-roll proposital de 250 ms), idealmente em 2–3 execuções — uma dispersão das últimas 3 leituras abaixo de 5 ms indica confiança alta; abaixo de 20 ms, média. A latência fica vinculada à rota atual de entrada + saída e se autoinvalida quando qualquer uma das duas muda; as medições de campo distante mostram o atraso de propagação já com ela subtraída.

6.5 Referência de tempo e qualidade da medição

  • Referência de tempo acústica: um chirp precede a varredura como âncora temporal, redetectado a cada medição; em caso de falha na detecção, há fallback com indicação explícita da confiança de fase — sem alegar alinhamento absoluto entre medições.
  • Desvio de relógio: estima a diferença de relógio entre os caminhos de reprodução e gravação e a corrige quando as condições permitem.
  • Referência de loopback elétrico: interfaces USB com múltiplas entradas podem usar um segundo canal como referência de loopback; quando as condições não são atendidas, há fallback para a referência acústica. A rota do assistente de reprodução para Mac não usa o loopback elétrico local.
  • Campos de qualidade: cada registro guarda a SNR, o piso de ruído, o status de clipping, o deslocamento temporal do IR, a entrada real e a taxa de amostragem disponíveis; o que não puder ser determinado fica vazio, nunca é inventado.
  • Tratamento de clipping: uma varredura com clipping detectado é invalidada com aviso para refazer a medição; registros de palma são marcados e sinalizados.
  • Comparação simulação / medição: a medição mais recente da sala é comparada lado a lado com o RT60 da simulação geométrica para avaliar o ajuste do modelo (limites em 6.3).

6.6 Microfones de medição USB e roteamento de saída

O seletor de entrada da página de medição lista o microfone integrado e entradas USB class-compliant (ex.: miniDSP UMIK-1 / UMIK-2); um listener de routeChangeNotification retorna ao microfone integrado quando o externo desaparece. As taxas de gravação e da varredura seguem a sessão (UMIK-1 = 48 kHz). Arquivos .txt de calibração de frequência no estilo REW / UMIK são importados diretamente (interpretando Sens Factor e o número de série, interpolação no domínio de frequência logarítmica; o arquivo de 90° é recomendado para medição de salas). A calibração é vinculada ao UID da porta de entrada — ao trocar para uma entrada incompatível, a calibração anterior não é aplicada.

Calibração única de referência SPL: encaixe um calibrador de nível sonoro (padrão 94 dB @ 1 kHz) sobre o microfone, o app amostra 3 s de nível para derivar o deslocamento dBFS → SPL; dB SPL só é exibido quando a entrada corresponde e existe uma calibração SPL — caso contrário, as leituras permanecem em dBFS. Instantâneo de calibração no momento da medição: novos registros de varredura / palma salvam a curva de calibração, o nome, o número de série, o Sens Factor, o offset de SPL e o UID de entrada vigentes naquele momento — substituir, limpar ou revincular a calibração depois não altera as leituras desses registros; o detalhe da medição, a prévia da resposta em frequência após a janela de IR, a exportação de texto da resposta e o PDF usam o mesmo instantâneo salvo. A calibração em si é persistida por UID da porta de entrada em ~/Library/Application Support/mic_calibration.json.

A reprodução passa pelo seletor de rota do sistema (um wrapper de AVRoutePickerView, colocado nos cards de varredura / calibração de campo próximo); a sessão libera AirPlay / Bluetooth A2DP / HFP para que os tons de teste toquem por alto-falantes externos, e volta para o alto-falante do aparelho quando nenhum está conectado. A entrada de gravação fica sempre explicitamente fixada na escolha do usuário (microfone USB ou integrado), para que o microfone de um dispositivo Bluetooth não roube a entrada no meio da reprodução e contamine a medição. Assistente de reprodução para Mac: descobre o AcouveroMacSpeaker na LAN via Bonjour, transfere primeiro o WAV da varredura para o Mac e depois envia o comando de reprodução, enquanto o iPhone grava — para rotas de saída de Mac que não conseguem hospedar diretamente o áudio da sessão de medição (essa rota não usa o loopback elétrico local).

6.7 Interoperabilidade com REW e arquivos

  • Importação / exportação de texto de resposta em frequência: compatível com delimitadores comuns, linhas de comentário, notação científica e formatos decimais, validando o eixo de frequências na importação; arquivos sem coluna de fase não geram dados de fase.
  • Exportação ciente da calibração: exporta dB SPL quando existe um instantâneo válido de calibração SPL, dBFS caso contrário — o cabeçalho rotula a unidade honestamente.
  • Importação de áudio de IR: há suporte para respostas ao impulso WAV / AIFF; arquivos multicanal exigem escolha explícita do canal.
  • Análise de varredura offline: exporte o arquivo de estímulo para reprodução externa e, após importar a gravação, é preciso informar as frequências inicial / final e a duração antes da deconvolução — os parâmetros da varredura nunca são adivinhados.
  • Exportação de áudio para compartilhamento: IRs ou gravações brutas disponíveis podem ser compartilhados como WAV.
  • Os resultados importados podem ser arquivados e fluir para os gráficos, sobreposições e análises aplicáveis; a admissão em um grupo de medição depende do tipo de dado e do escopo de confiança. Arquivos de projeto REW .mdat não são lidos no momento.
§ 07

Gráficos e análise de medição

A página de detalhes da medição mostra gráficos conforme os dados que cada registro realmente possui — curvas ausentes nunca são fabricadas; os gráficos suportam modo claro / escuro, Dynamic Type e resumos de acessibilidade.

  • RT60: gráfico de barras por banda de oitava com linha-alvo e cores de status.
  • Decaimento de Schroeder: curva EDC com o intervalo de ajuste T20.
  • Resposta em frequência: eixo logarítmico, suavização por oitava e leitura por cursor; exibida em dB SPL enquanto o instantâneo de calibração for válido.
  • Resposta ao impulso: forma de onda com marcadores de zero temporal e de pico; amplitude relativa ao pico.
  • Fase: vistas wrapped / unwrapped, inversão de polaridade, ajuste fino do zero temporal e indicação de confiança da referência.
  • Atraso de grupo: atraso de grupo na banda válida, com análise opcional de fase mínima / fase em excesso.
  • Janelamento de IR: referência de pico ou t=0, larguras esquerda / direita independentes, retangular / Hann / Tukey / Blackman; respostas original e janelada em prévia lado a lado — janelamento e ajuste de fase afetam apenas a prévia, nunca a medição armazenada.
  • Espectrograma: decaimento tempo-frequência do IR, com intervalo de tempo e faixa dinâmica ajustáveis.
  • Cascata e RT60 Decay: visualização do decaimento de graves, comprimento de janela / tempo / faixa dinâmica ajustáveis; ajustes de qualidade insuficiente não são exibidos.
  • Espectro em tempo real (RTA): exibição de 1/1–1/24 de oitava, ponderação A / C / Z, resposta instantânea / Fast / Slow, retenção e limpeza de picos, nível global, nível de pico e frequência dominante.
  • O RTA usa a calibração da entrada correspondente e é rotulado dBFS até existir uma calibração SPL; é mutuamente exclusivo com as medições formais (entrar libera o monitor de nível da página de medição, fechar o restaura), e callbacks antigos nunca sobrescrevem o estado novo após parar ou trocar de entrada.
Requisitos de dados · DATA GATING Fase, atraso de grupo e janelamento exigem uma varredura e dados de IR qualificados; quando a referência de tempo é insuficiente, a interface a chama explicitamente de fase relativa — sem alegar alinhamento absoluto confiável entre medições. O RTA ainda não tem registro de SPL de longo prazo.
§ 08

Histórico, médias multiposição e sobreposições

  • Arquivo V2: as medições guardam metadados, a gravação bruta / sidecar de IR disponível e os dados de análise; registros antigos continuam compatíveis em modo somente leitura, sem fabricar os dados brutos ausentes.
  • Gestão do histórico: ver e apagar medições por sala, abrir detalhes ou escolher registros para análises posteriores.
  • Comparação antes / depois: escolha dois registros para comparar RT60 global e por banda, respostas sobrepostas e diferenças nas bandas válidas.
  • Sobreposição de 2–6 respostas: suavização de 1/3–1/48 de oitava, exibir / ocultar por curva, predefinições de faixa completa / graves; níveis sem alinhar, zerados na banda média ou alinhados à primeira curva, com deslocamentos na legenda; dados de origem intactos, e registros que não podem ser sobrepostos explicam o motivo.
  • Grupos de medição: os registros carregam rótulo de posição, pesos e etapa antes / depois; crie um grupo a partir do histórico, entre em um, ou meça uma nova posição diretamente em um grupo.
  • Médias multiposição: média aritmética em dB, média de potência RMS e — com referência de tempo confiável e espectros complexos — média complexa vetorial; mostra a curva média, as curvas membro e a faixa espacial min / max por frequência.
  • Comparação de grupos: compara as respostas médias, as faixas espaciais e os RT60 médios de dois grupos, concluindo sobre a consistência espacial.
Limites · BOUNDARIES As médias e comparações de grupos usam atualmente dB relativos; a média vetorial entre taxas de amostragem ainda não é suportada. As sobreposições usam predefinições de faixa — ainda sem zoom por gestos, sobreposições de fase / cascata / decaimento, nem exportação em PDF das sobreposições.
§ 09

PEQ e alinhamento de subwoofer

VERSÃO SIMPLES Estes dois tópicos têm cada um uma página em linguagem simples: EQ paramétrico e alinhamento do subwoofer.

9.1 Ajuste de alvo PEQ

  • Curva-alvo parametrizada: nível-alvo, reforço de graves, inclinação de agudos e banda de ajuste.
  • Restrições de filtros: quantidade de filtros, reforço / corte máximo e faixa de Q.
  • Previsão e justificativa: medição, alvo, respostas dos filtros e resultado previsto em um mesmo gráfico, com métricas de melhoria e justificativa filtro a filtro.
  • Exclusão de quedas profundas: quedas profundas causadas por cancelamento acústico são excluídas automaticamente, evitando grandes reforços sobre um nulo.
  • Exportação: texto Generic, Equalizer APO, coeficientes miniDSP e YAML do CamillaDSP — apenas cálculo e exportação de ajustes; nada é gravado diretamente nos dispositivos.

Ainda não há editor manual de filtros, biblioteca de alvos nem arquivamento de resultados de EQ.

9.2 Alinhamento de duas vias e multi-subwoofer

  • Alinhamento de duas vias: escolha uma medição da caixa de referência e uma do subwoofer ajustável, preveja a soma complexa e resolva atraso, ganho e polaridade; a curva somada é mostrada antes e depois do alinhamento.
  • Multi-sub, multiassento: 1–4 subwoofers com medições independentes escolhidas por assento × fonte; otimize para todos os assentos, limite pelo pior assento ou otimize explicitamente apenas o assento principal.
  • Resultados e compartilhamento: ajustes por sub, melhoria por assento, métricas médias e de pior caso, com ajustes compartilháveis como texto.
  • Requisitos de dados: registros sem configuração de varredura, referência de tempo confiável ou IR listam o motivo da indisponibilidade em vez de serem excluídos silenciosamente.

Os resultados multiassento são atualmente uma tabela numérica sem sobreposição de curvas somadas por assento; o alinhamento é uma previsão que deve ser verificada medindo novamente após aplicar os ajustes; misturar fontes em taxas de amostragem diferentes ainda precisa de validação.

§ 10

Assistente acústico de IA

A barra de ferramentas do histórico de medições oferece uma entrada de chat que usa a própria chave de API da Anthropic do usuário (guardada no Keychain do aparelho); o assistente envia à Anthropic a conversa e os dados de ferramentas necessários para cada requisição, e os custos de API ficam por conta da conta do usuário.

  • Interface de conversa: respostas em streaming, status de execução de ferramentas, parar e limpar, estimativa de uso / custo.
  • Leitura de dados de medição: listar registros, resumos e respostas parciais, e comparar medições.
  • Ferramentas de cálculo: invoca exatamente os mesmos algoritmos de recomendação de PEQ e alinhamento de subwoofer da interface manual.
  • Avaliação de sala e layout: lista salas, lê posições de caixas / ouvinte e modos, e prevê — em uma cópia do projeto — o efeito de mover equipamentos ou mudar o perfil de absorção; projetos salvos nunca são reescritos.
  • Medição somente após confirmação: a IA propõe a finalidade e as salas candidatas e só inicia a varredura após a confirmação do usuário; recusar ou parar cancela a solicitação.
  • Configurações de medição compartilhadas: a IA e a medição manual reutilizam o mesmo espaço de trabalho, herdando entrada, assistente de reprodução para Mac, faixa / duração da varredura, atraso e loopback; a página de chat mostra nível / progresso ao vivo com cancelamento e, ao terminar, restaura o contexto original de sala e grupo de medição.
  • Restauração de sessão: uma sessão atual é salva e restaurável, marcando na restauração a execução de ferramenta interrompida; limpar a sessão apaga também o histórico e o uso.
Limites · BOUNDARIES Ainda não há lista de múltiplas sessões nem modelo local de reserva; a ferramenta de layout não suporta adicionar / remover equipamentos, alterações de painéis especificadas nem previsão a partir da calibração medida. O caminho com chave de API real e o loop de áudio no dispositivo ainda estão pendentes de aceitação.
§ 11

Visualização e saída

11.1 Visualização 3D

Room3DController renderiza com SceneKit: paredes / piso / teto / nós de alto-falantes (cabinet fino + accent tick + channel pill) / ouvinte (FE glyph + drop stem) / obstáculos (SCNBox translúcido) / painéis recomendados (mockups de painéis por parede) / segmentos de caminho de reflexão de múltiplas ordens / sobreposição de mapa de calor de energia de reflexão.

DESIGN · DESENHO TÉCNICO A aparência é um “estilo de desenho técnico” (arestas hairline, iluminação constante, sem PBR), deliberadamente distinta do 3D fotorrealista.

11.2 Mapa de calor de energia de reflexão

O ReflectionEnergyMapGenerator acumula a energia de cada caminho de múltiplas ordens na grade uCells × vCells da parede atingida (padrão 12×6). Um mapa de energia por parede, sobreposto em 3D como uma camada de cor de energia (azul → ciano → verde → amarelo → vermelho).

EnergyHeatmapRenderer transforma a grade em uma UIImage: células em estilo de blocos de 16 px cada (sem interpolação entre as células, mantendo as bordas da grade legíveis; a suavização na parede vem da filtragem bilinear de textura do SceneKit) + um degradê personalizado de 5 paradas (azul → ciano → verde → amarelo → vermelho) + alfa mapeado linearmente de 0,20 a 0,85 conforme a posição da energia em uma escala fixa de −30…0 dB (−∞ totalmente transparente).

11.3 Prévia da convolução RIR

RIRPreviewPlayer usa AVAudioEngine + AVAudioPlayerNode para convolver um sinal seco sintetizado proceduralmente (corda dedilhada / sequência de palmas / fala semelhante a vogais — sem amostras embutidas) com a RIR simulada e reproduzi-lo, para que os usuários ouçam a diferença entre “sem tratamento” e “com tratamento”.

A convolução no domínio do tempo RIRConvolver.convolve(dry:rir:) é O(N × M) direta (N = amostras do sinal dry, M = amostras do RIR), normalizada pelo pico em 0,9 para evitar clipping.

11.4 Manual de instalação em PDF

ReportExporter renderiza um PDF A4 (595 × 842 pt) via UIGraphicsPDFRenderer:

  • Visão geral da sala + captura 3D
  • Gráfico de barras de RT60 em 6 bandas: estimativa de Sabine vs. alvo, com valores medidos sobrepostos quando houver dados
  • Tabela de pontos de reflexão + tabela de modos + resumo de riscos
  • Tabela de painéis recomendados (a BOM da lista de compras é exibida no app, não no PDF)
  • Quando há dados de medição, são adicionados gráficos de RT60 / EDC / resposta em frequência / espectrograma / cascata / fase e um resumo de média multiposição; a unidade da resposta usa o instantâneo de calibração salvo no momento da medição (rotulado honestamente como dB SPL ou dBFS)
  • Fonte Geist + fallback PingFangSC (cascadeList do CoreText, para o CJK não renderizar como □□□)

11.5 Persistência de projetos

ProjectStore (um actor) grava ~/Library/Application Support/Acouvero/projects.json: [RoomProject], cada um contendo o Room completo + speakers + listeners + recommendations + panelCountOverrides. No primeiro lançamento, os dados migram automaticamente do diretório legado FindEcho/ (FindEcho é o codinome interno anterior à mudança de nome, mantido deliberadamente nos símbolos do código).

MeasurementStore (um actor) grava ~/Library/Application Support/Acouvero/measurements.json: [MeasurementResult], vinculado a um projeto pelo roomId.

Ambos usam recuperação de decodificação em nível de elemento (um wrapper Throwable<T>) — um registro corrompido não derruba a lista inteira.

MicCalibrationStore grava ~/Library/Application Support/mic_calibration.json (raiz do diretório, sem subdiretório): a curva de calibração do REW + offset de SPL, vinculada ao UID da porta de entrada — trocar de entrada exige uma nova importação / calibração.

§ 12

Notas de engenharia

12.1 SwiftUI + @Observable

A ViewModel (FindEchoViewModel) usa a macro @Observable do Swift 5.9 — os campos de estado são observados diretamente, sem Combine. Os resultados da AcousticAnalysis são armazenados em cache por meio de uma comparação 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
}

12.2 Isolamento de actors

ProjectStore e MeasurementStore são actors, serializando a lógica de IO / assíncrona de forma natural; RoomPlanService é uma classe @MainActor. Os chamadores da UI usam async / await, então a thread principal nunca é bloqueada por IO de disco.

12.3 Ciclo de vida do AVAudio

AudioSessionManager centraliza a categoria da sessão (.playback para a prévia do RIR, .playAndRecord para a medição). A proteção contra interrupções cobre os dois caminhos: no lado da medição, um InterruptionMonitor dentro de AudioMeasurementService observa AVAudioSession.interruptionNotification — uma ligação / Siri durante uma varredura, palma ou medição de ruído ambiente descarta o resultado com um erro; no lado da prévia, RIRPreviewPlayer também observa, parando automaticamente o nó do player e limpando isPlaying. Uma mudança de rota de áudio no meio da medição também invalida a execução.

12.4 Cancelamento de Task

A reprodução da convolução é uma tarefa em segundo plano; toques rápidos no botão disparam pendingPlayTask?.cancel() mais uma dupla verificação de Task.isCancelled para evitar escritas fora de ordem na MainActor.

12.5 Cobertura de testes

AllShapesAndUseCasesTests usa o framework Swift Testing para rodar a matriz completa — cada formato × cada caso de uso (um único ouvinte; os alto-falantes são um par estéreo ou um único central por caso de uso) — verificando:

  • analysis.reflectionPaths.count >= 1
  • analysis.warnings inclui a nota de aproximação para salas não retangulares
  • o total de painéis recomendados é não negativo (totalPanelCount ≥ 0; sem asserção de correspondência com o orçamento)
  • polígonos personalizados que se autointersectam fazem fallback com segurança (sem crash, degradando para um retângulo)
  • vértices &lt; 3 e outros fallbacks de casos de borda

12.6 Plataforma e localização

Destino de implantação iOS 17.0, iPhone + iPad; zero dependências de terceiros (sem pacotes SPM / CocoaPods) — apenas frameworks do sistema (SwiftUI / SceneKit / ARKit / RoomPlan / AVFoundation / Accelerate). A localização usa um catálogo .xcstrings: chinês como idioma de origem, mais English / Français / Deutsch / Español / Português (Brasil) — 6 idiomas no total, alternáveis no app ou seguindo o sistema.

§ 13

Limitações conhecidas

  1. Multi-ordem em salas não retangulares usa a caixa delimitadora — o risco de flutter / slapback de 2ª/3ª ordem perto de cantos côncavos pode sair impreciso. Os pontos de primeira ordem em si usam o polígono real.
  2. Os modos da sala em salas não retangulares são estimados a partir do bounding box — modos exatos exigem FEM.
  3. Medição com o microfone integrado do iPhone — não calibrado; resposta de frequência / sensibilidade não plana. A confiança é sempre marcada como .low, usada como referência cruzada com a estimativa geométrica. Com um microfone de medição USB (miniDSP UMIK-1 / UMIK-2) e o arquivo de calibração do REW carregado, os níveis por banda são corrigidos pela curva de calibração; uma calibração de referência única de 94 dB SPL então exibe os níveis ambiente e de medição como dB SPL absolutos (somente dBFS até lá).
  4. Hipótese de fonte única do ISM — ignora a difração da caixa, a diretividade da corneta e outras características de alto-falantes reais.
  5. Sem modelagem de armadilhas de graves — problemas abaixo de 80 Hz ficam fora do modelo de Sabine e precisam de tratamento dedicado para baixas frequências.
  6. Precisão da varredura AR — os endpoints do RoomPlan erram tipicamente 3-8 cm; um loop de 12 segmentos pode acumular mais de 5 cm. A espessura das paredes não é modelada.
  7. Limites do escopo de análise — a média complexa vetorial entre taxas de amostragem ainda não é suportada; os resultados de alinhamento multiassento são atualmente uma tabela numérica, sem sobreposição de curvas somadas por assento; as sobreposições de resposta ainda não entram no relatório PDF.
  8. Ferramentas profissionais ainda não implementadas — sem registro de SPL de longo prazo, inteligibilidade STI ou medição de distorção (THD); impedância / Thiele-Small e API REST também estão ausentes.
  9. Aceitação em dispositivo pendente — o caminho real de API do assistente de IA (streaming com chave real / medição confirmada / arquivamento de gravações) e a cadeia completa de microfones UMIK em hardware real (incluindo o UMIK-2 a 96 kHz) ainda precisam de aceitação; passar no simulador não comprova o loop de áudio no dispositivo.
§ 14

Referências

  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.
Quer a versão em linguagem simples?

“Por que a sua sala reescreve a música que você ouve”

Leia o Deep Read