fix: expose physical aliasing and delayed arrivals

This commit is contained in:
2026-08-29 10:21:33 +09:00
parent e048ccbadc
commit de0053eae3
38 changed files with 3086 additions and 214 deletions
+97
View File
@@ -82,6 +82,38 @@ Scene JSON의 사용자 설정 예는 다음과 같다.
하며 occluder id는 중복될 수 없다. 사용자 설정에서도 마이크 좌표가 room 안에 놓이도록 구성해야
1차 반사가 생성된다.
## 라이브 창의 전파 지연과 이동 근사
라이브 frame의 출력 sample 구간을 `[S, E)`, 현재 quasi-static geometry에서 모든
source–microphone 희소 경로의 최대 지연을 `Dmax`라 하자. 합성기는 다음 순서로 frame을 만든다.
1. source trajectory를 출력 창 중앙 시각에서 한 번 샘플링한다.
2. `R = max(0, S - ceil(Dmax × sampleRate))`부터 `E`까지의 tone, noise와 asset 방사 신호를
원래 Scene 절대 sample index로 생성한다.
3. 이 pre-roll buffer에 direct, reflection, scattering, diffraction과 diffuse 경로를 적용한다.
4. 전파가 끝난 뒤 `[S, E)`만 crop하여 localizer에 넘긴다.
따라서 source가 `S` 전에 멈췄더라도 그 직접음·반사음·diffuse tail이 창 안에 도착하면 보존된다.
analytic tone뿐 아니라 deterministic noise index와 asset 재생 위치도 원래 절대 시간축을 유지한다.
`synthesis.windowing`과 live frame의 `signalStats.windowing`은 render/output sample, pre-roll,
최대 지연, geometry와 Doppler 정책을 기록한다.
source별 `sourceArrivals`는 각 midpoint path의 half-open 도착 sample 구간이 출력과 겹치는지와
겹친 path kind를 기록한다. live ground-truth 평가는 emission midpoint가 아니라
`arrivingSourceIds`를 사용하므로, 이미 멈춘 source의 tail을 false positive로 잘못 세지 않는다.
이 ID 집합은 위치 추정이 끝난 뒤 평가에만 쓰며 raw channel, STFT, steering이나 peak 검출에는
입력하지 않는다.
다만 이는 moving wave equation 해법이 아니다. pre-roll 방사 시각의 retarded source 위치를 다시
구하지 않고 전체 render buffer에서 창 중앙 위치와 그 위치의 경로를 고정한다. 창 안의 연속 이동,
Doppler, 시간에 따라 변하는 reflection geometry도 모델링하지 않는다. 움직임이 경로 지연에 비해
크다면 frame 길이를 줄여 quasi-static 오차를 드러내고 수렴성을 확인해야 한다.
sampled asset/noise의 fractional delay와 microphone response는 zero-padded block FFT 전달함수다.
pre-roll은 현재 희소 **전파 경로**의 최대 지연을 보존하지만, 측정된 주파수 응답에서 무한하거나
임의 길이의 causal analog impulse response state를 복원하지 않는다. 또한 Scene이
`mix.normalization: peak`이면 live 합성은 각 출력 crop의 peak로 scale을 계산하므로 frame 간
절대 진폭 비교에는 `normalization: none`을 사용해야 한다.
## Camera 환경 preset과 비용
Camera의 **고급 설정 → 음향 환경**은 현재 geometry 전체가 들어가도록 room을 자동 추론하고 다음
@@ -184,6 +216,66 @@ band는 주기적으로 같은 phase를 만드는 lag가 많아 여러 위치가
해결하지는 않는다. 단일 reference 방식은 모든 마이크 쌍을 쓰는 GCC보다 계산량이 작지만 pair
중복성과 고장 마이크에 대한 강건성도 작다.
## 샘플링, Nyquist와 alias
Scene의 `sampleRate`는 모든 마이크가 동시에 동작하는 이상적 real-valued ADC의 sampling rate다.
현재 모델에는 analog anti-alias filter가 없다. 따라서 tone 주파수는 Nyquist를 넘어도 허용되며,
관측 주파수는 다음 signed baseband 주파수로 접힌다. 정확한 Nyquist tie는 `+Fs/2`로
표준화하지만 `+Fs/2`와 `-Fs/2`는 같은 real sample sequence다.
```text
f_wrapped = f_analog mod Fs, 0 <= f_wrapped < Fs
f_signed = f_wrapped if f_wrapped <= Fs/2
f_wrapped - Fs otherwise
f_adc = |f_signed|
```
`f_signed < 0`이면 one-sided positive spectrum이 반전된다. 정확히 DC나 Nyquist에 접힌 tone은
quadrature 정보가 소실되는 퇴화점이다. Camera는 이를 오류로 숨기지 않고 source 요약, band legend와
Result `signalStats.sampling`에 원 주파수·signed ADC 주파수·반전 여부와 DC/Nyquist
위상 퇴화 여부를 기록한다.
공간 전파는 alias 주파수로 바꾸지 않는다. 합성기는 각 path의 원래 analog 주파수
`2π f_analog τ`로 지연 위상과 해당 주파수의 microphone response를 적용한 뒤 ADC 시각에서
sampling한다. 이 순서를 뒤집으면 fractional path delay의 센서 간 위상이 틀리므로, tone은
mic/path별 analytic phasor와 시작·종료 event로 합성한다.
Experiment band도 Nyquist 위 값을 허용한다. 요청 주파수 구간의 모든 등가 one-sided real-FFT
bin **center**를 접어 선택하며, 일부 alias 후보를 골라 버리지 않는다. 이 선택은 brick-wall
대역 필터가 아니다. 유한 Hann window의 off-grid leakage는 인접 bin에도 남는다. 현재
DAS·DAS-PHAT는 양의 ADC bin 주파수로 구면 steering하고, GCC-PHAT는 선택 bin으로 제한한
기하 lag correlation을 수행한다. 어느 쪽도 원래 alias order를 이용해 결과가 좋아지도록
보정하지 않는다.
따라서 초과 주파수에서 peak가 틀어지거나 grating lobe·동률 peak가 나타나는 것이 정상적인 설계
결과일 수 있다. Result의 band별 `frequencyObservation`은 1-based Nyquist zone별 연속 fold
segment, 반전·alias order, 실제 ADC bin center, 연속/FFT-grid many-to-one 여부와
alias-equivalent band ID를 보존한다. 같은 `adcBinSetKey`를 가진 band는 독립 관측이 아니다.
정확한 Nyquist 경계에서 `+Fs/2`와 `-Fs/2`는 실수 sampling sequence가 동일하다.
단일 주파수 provenance는 이를 `+Fs/2`로 canonicalize하지만, `foldSegments`의
`signedAdcStartHz`/`signedAdcEndHz`는 각 zone을 따라가는 방향을 보존하므로 반전 zone
시작점이 `-Fs/2`로 나타날 수 있다. 경계를 가로지르는 두 segment의 `+Fs/2`와
`-Fs/2` endpoint는 두 관측이나 두 FFT bin이 아니라 같은 phase-degenerate Nyquist
sample을 양쪽 zone에서 표현한 것이다.
같은 이유로 위치 추정기의 선택적 microphone-response 역보정도 관측 ADC bin에서 평가한다. Forward
tone 합성은 원 analog 주파수의 응답을 사용하므로, Nyquist 위 carrier를 알고 보정하는 별도
alias-aware 알고리즘처럼 동작하지 않는다. 이 차이 역시 감추지 않는 현재 알고리즘의 결과다.
서로 다른 analog tone이 같은 ADC bin으로 접히면 **단일 channel의 시간 sample만으로는**
원 주파수를 구별할 수 없다. 그러나 이 합성기는 원 analog 파장의 센서 간 위상을 보존하므로,
충분히 촘촘하고 보정된 다채널 array에는 carrier order를 판별할 공간 위상 증거가 남을 수 있다.
현재 DAS·DAS-PHAT·GCC-PHAT는 carrier hypothesis를 열거하는 알고리즘이 아니므로 이를 복원하지
않고 Result에 `aliasOrderResolution: not-attempted`로 기록한다. 이 기능을 추가하려면 검증된
array-processing 방법과 별도 alias-order 평가가 필요하며, 임의 규칙으로 peak를 고르지 않는다.
audio asset과 noise는 이미 sampling된 baseband 신호로 취급하므로 파일에 없는 Nyquist 위 analog
spectrum을 만들어 내지 않는다.
Tone과 band의 현재 검증 범위는 0–1 MHz다. 이는 Nyquist 제한이 아니라 JavaScript
IEEE-754 위상 정밀도, 마이크 응답 계약과 현재 희소 경로 모델을 함께 검증한 수치 범위다.
더 높은 carrier가 필요하면 단순히 상한을 제거하지 말고 phase reduction과 microphone model을
그 범위에서 다시 검증해야 한다.
## 마이크 주파수 응답
각 마이크에는 2–64개의 측정점을 지정할 수 있다. `frequencyHz`는 0–1,000,000 Hz에서
@@ -212,6 +304,11 @@ band는 주기적으로 같은 phase를 만드는 lag가 많아 여러 위치가
합성기는 알고리즘과 무관하게 sensitivity, 정적 phase offset과 frequency-response curve를 수신
channel에 적용한다. 위치 추정에서의 역보정은 알고리즘별로 다르다.
Tone에는 원 analog carrier에서 보간한 하나의 complex response를 정상상태 phasor로 적용한다.
따라서 지속 sinusoid의 gain/phase 비교에는 맞지만, hard-gated 시작·종료에서 실제 analog
마이크 필터가 만드는 ringing이나 frequency-dependent transient까지 계산하는 full LTI filter
모델은 아니다. 이 근사를 ADC를 포함한 완전한 하드웨어 시뮬레이션으로 해석하지 않는다.
- DAS는 sensitivity 역 gain과 정적 phase를 항상 보정한다. `compensateFrequencyResponse`를
생략하거나 `true`로 두면 response의 역 gain과 phase도 보정한다. 응답 notch의 무제한 gain
boost는 noise까지 키울 수 있으므로 `maxCompensationDb`로 제한하며 기본값은 24 dB, 허용 범위는