Função do app · 08

Gerador

Três sinais de teste — senoide, sweep logarítmico e ruído rosa — sintetizados com exatidão em vez de aproximação por tabela ou grade de frequências.

Como usar no app

Onde encontrar

Aba Gerador. O segmentado Tipo no topo escolhe entre Senoide, Sweep e Ruído Rosa.

Exemplo de uso: tunar um sistema com ruído rosa e o RTA

  1. Escolha Ruído Rosa, ajuste o Nível a uns 40–50% e toque em Tocar.
  2. Vá para a aba RTA, Modo "Curva", fração 1/3 de oitava — o ruído rosa deve aparecer como uma linha reta se o compensador de largura de banda estiver desligado.
  3. Ajuste a EQ do sistema até a curva medida ficar o mais parecida possível com a curva-alvo escolhida (ver Curvas-Alvo).

Exemplo de uso: gerar um tom de referência para calibrar outro equipamento

  1. Escolha Senoide e digite 1000 Hz no campo de Frequência (a referência mais comum para calibração).
  2. Ajuste o Nível conforme necessário e toque em Tocar.
  3. Alimente o equipamento sendo calibrado por uma saída de linha, não pelo alto-falante do aparelho — o card "Precisão da geração" lembra disso para medições confiáveis.

Senoide

Sweep

No app, o sweep é uma ferramenta manual: toque em Tocar e observe o RTA (ou um analisador externo) enquanto ele varre. Ele não alimenta a função de transferência do Spectra — essa mede H1/coerência ao vivo sobre qualquer programa de áudio, sem precisar de sweep.

Ruído rosa

Sem controles além do slider de Nível, comum aos três tipos.

Card "Precisão da geração"

Mostra a frequência realmente sintetizada (Senoide) ou a taxa de amostragem de saída em uso (Sweep/Ruído Rosa). Se o oscilador e o nó de saída estiverem em taxas diferentes — o que só deveria acontecer em cenários anômalos de troca de rota —, um aviso aparece: "O oscilador e a saída estão em taxas diferentes — a frequência sai desafinada. Reinicie o áudio." O card também lembra que a síntese digital é exata, mas a caixa/sala/EQ depois do alto-falante não são corrigidos pelo app — para medição de precisão, use uma saída de linha ou interface externa em vez do alto-falante do aparelho.

O gerador continua tocando ao trocar de aba (não é parado ao sair da tela do Gerador), mas é interrompido automaticamente se o app for para segundo plano.

O canal e a rota de saída (alto-falante, fone, AirPlay, Bluetooth) são escolhidos em Ajustes › I/O — "Canal (saída)" (só aparece com mais de um canal disponível) e "Rota de saída".

A partir daqui Como cada sinal é sintetizado por dentro — fórmulas e a origem de cada técnica. Não é preciso entender nada disso para usar o app.

Senoide de fase contínua

O SineOscillator acumula fase em precisão dupla (Double), o que permite mudar a frequência amostra a amostra — essencial para o sweep — sem cliques de descontinuidade entre buffers:

Acumulador de fase
$$ x[n] = A \cdot \sin(\phi_n) \qquad\qquad \phi_{n+1} = \big(\phi_n + \tfrac{2\pi f_n}{f_s}\big) \bmod 2\pi $$

A 48 kHz, o incremento de fase para 20 Hz é de apenas ~0,0026 rad, e a precisão dupla mantém isso com erro da ordem de 1e-19 — a fase não deriva mesmo em sessões longas, graças ao wrap exato para [0, 2π) a cada amostra.

Bug corrigido: taxa de amostragem errada Até a v0.9.0, o oscilador era criado com a taxa que o AVAudioSession reportava antes de a sessão ser configurada, enquanto o nó de saída acabava montado com a taxa real. Quando divergiam — no Simulator, ou depois de trocar rota de áudio no aparelho — toda frequência saía escalada pela razão entre as duas: 1 kHz virava 918,75 Hz com o oscilador assumindo 48 kHz e o nó rodando a 44,1 kHz. O oscilador agora acompanha a taxa real do nó, e a tela mostra a taxa em uso.

Sweep logarítmico (ESS)

De 20 Hz a 20 kHz, tempo igual por oitava (ao contrário de um sweep linear, que gasta o mesmo tempo por Hz) — a forma padrão de exponential sine sweep usada em medição de resposta em frequência de salas e alto-falantes3:

Frequência instantânea do sweep
$$ f(t) = f_{\text{início}} \cdot \left(\frac{f_{\text{fim}}}{f_{\text{início}}}\right)^{t/T} \qquad t \in [0, T] $$

Propriedade característica, testada: o ponto médio no tempo (t = T/2) cai exatamente na média geométrica dos extremos (√(f_início · f_fim)).

No Spectra o sweep é uma ferramenta de geração de sinal de teste — para varrer um sistema manualmente enquanto se observa o RTA ou um analisador externo. A função de transferência do app não depende dele: ela mede em tempo real sobre qualquer programa de áudio, sem precisar sincronizar captura com um sweep.

Ruído rosa

−3 dB por oitava, sintetizado a partir de ruído branco pelo filtro IIR de 3 polos "econômico" de Paul Kellett4 — não o método Voss-McCartney, e sim três estágios em paralelo:

Filtro de Kellett (3 polos)
$$ \begin{aligned} b_0 &\leftarrow 0{,}99765\,b_0 + w \cdot 0{,}0990460 \\ b_1 &\leftarrow 0{,}96300\,b_1 + w \cdot 0{,}2965164 \\ b_2 &\leftarrow 0{,}57000\,b_2 + w \cdot 1{,}0526913 \\ \text{saída} &= 0{,}11 \cdot A \cdot (b_0+b_1+b_2+0{,}1848\,w) \end{aligned} $$

onde w é uma amostra de ruído branco em [−1, 1] e 0,11 é o fator de escala empírico da implementação original de Kellett.

A fonte de ruído branco usada é um xorshift32 (três operações bit a bit), não o gerador criptográfico do sistema (Float.random(in:)/arc4random_buf) — trocado na revisão v0.12.0 porque o gerador criptográfico pode fazer chamada de sistema, e isso rodava 48 mil vezes por segundo dentro do callback de áudio em tempo real, onde qualquer chamada que possa travar é proibida.

Sincronização com a taxa real

O GeneratorEngine orquestra os três tipos atrás de uma única chamada de render, com sampleRate atualizado sempre que o formato de saída do AVAudioEngine é (re)estabelecido — nunca divergindo da taxa real do nó, pela mesma razão descrita acima para o oscilador de senoide.