feat: add physically explicit narrowband MUSIC

This commit is contained in:
2026-08-29 12:40:48 +09:00
parent 044be3cf92
commit 11fee76280
40 changed files with 6473 additions and 275 deletions
+61 -8
View File
@@ -227,6 +227,54 @@ band는 주기적으로 같은 phase를 만드는 lag가 많아 여러 위치가
해결하지는 않는다. 단일 reference 방식은 모든 마이크 쌍을 쓰는 GCC보다 계산량이 작지만 pair
중복성과 고장 마이크에 대한 강건성도 작다.
### Narrowband MUSIC (`music`)
현재 CPU MUSIC은 [Schmidt의 noise-subspace 방법](https://doi.org/10.1109/TAP.1986.1143830)을
근거리 구면파 direct-path manifold에 적용한다. 근거리 source localization의 관련 문헌은
[Huang–Barkat](https://doi.org/10.1109/8.86917)이다. 보정된 snapshot
`x(t)`로 mean subtraction 없는 sample covariance를 만든다.
```text
R = (1/T) Σ_t x(t) x(t)ᴴ
R v_j = λ_j v_j, λ_0 ≥ ... ≥ λ_(M-1)
q(p) = Σ_(j=K)^(M-1) |v_jᴴ a(p)|² / (a(p)ᴴ a(p))
```
`q`는 noise projection fraction이고 optimum은 minimum이다. UI/evaluation은 표준
pseudospectrum `P=1/q`를 scan 안에서 `P/Pmax`로 표시한다. `q_min>0`이면 이는
`q_min/q(p)`이고, `q_min=0`이면 정확한 zero 위치만 1로 표시한다. flat `q`는 모두 1로
표시하되 위치 peak는 만들지 않는다. `q`, `P`와 `P/Pmax`는 확률·posterior·confidence 또는
신뢰구간이 아니다.
Experiment band는 `Fs/N` grid에 놓인 아날로그 carrier 가설을 정확히 하나만 포함한다.
`f_a`를 그 center, signed ADC alias의 orientation을 `η = sign(f_s)`라 하면 공간 위상의
크기는 analog carrier `f_a`를 유지하고 `η`만 alias inversion 방향으로 사용한다.
```text
a_m(p) = H_m,residual(f_a) / max(r_m(p), d_min)
× exp[-j η 2π f_a (r_m(p)-r_0(p))/c + j φ_m,residual(f_a)]
```
`f_s<0`인 alias inversion에서는 positive-bin STFT coefficient, sensitivity/response 보정과
전체 complex manifold가 baseband 가설의 켤레 방향이 된다. microphone frequency response는
관측 bin이 아니라 사용자가 지정한 `f_a`에서 평가한다. 이 가설은 Experiment에서 오며 Scene
source frequency·position truth는 covariance, K 선택이나 scan에 사용하지 않는다. 같은 ADC
bin의 다른 alias order는 별도 band로 명시해야 하고 자동 선택하지 않는다. 정확한 DC와 Nyquist는
실수 sequence에 독립 quadrature가 없어 거부한다.
K는 사용자가 고정하거나 [Wax–Kailath AIC/MDL](https://doi.org/10.1109/TASSP.1985.1164557)로
선택한다. AIC/MDL은 비중첩 complete snapshot, `T>M`, roundoff보다 엄격히 큰 noise eigenvalue가
필요하고 IID complex Gaussian snapshot, spatially white noise, 창 동안 일정한 source 수를
가정한다. 비중첩 자체는 통계적 독립성의 증명이 아니며 criterion은 확률이나 confidence가 아니다.
가정/수치 조건이 깨지면 typed `MUSIC_UNAVAILABLE` 오류를 내고 fixed K로 fallback하지 않는다.
같은 주파수의 coherent source는 signal covariance rank를 잃을 수 있다. eigengap이 수치 audit
bound보다 작으면 subspace를 임의 분할하지 않는다. diagonal loading, eigenvalue floor, spatial
smoothing, band 간 association·평균·maximum fusion은 없다. 배열의 spatial alias/grating lobe,
동률과 flat objective도 결과를 좋게 보이도록 제거하지 않는다.
[Wax–Shan–Kailath broadband eigenstructure 방법](https://doi.org/10.1109/TASSP.1984.1164400)은
알려진 별도 알고리즘이지만 현재 구현하지 않았다.
## 샘플링, Nyquist와 alias
Scene의 `sampleRate`는 모든 마이크가 동시에 동작하는 이상적 real-valued ADC의 sampling rate다.
@@ -269,16 +317,19 @@ alias-equivalent band ID를 보존한다. 같은 `adcBinSetKey`를 가진 band
`-Fs/2` endpoint는 두 관측이나 두 FFT bin이 아니라 같은 phase-degenerate Nyquist
sample을 양쪽 zone에서 표현한 것이다.
같은 이유로 위치 추정기의 선택적 microphone-response 역보정도 관측 ADC bin에서 평가한다. Forward
tone 합성은 원 analog 주파수의 응답을 사용하므로, Nyquist 위 carrier를 알고 보정하는 별도
alias-aware 알고리즘처럼 동작하지 않는다. 이 차이 역시 감추지 않는 현재 알고리즘의 결과다.
같은 이유로 DAS·DAS-PHAT·GCC-PHAT의 선택적 microphone-response 역보정은 관측 ADC bin에서
평가한다. Forward tone 합성은 원 analog 주파수의 응답을 사용하므로 이 세 알고리즘은 Nyquist 위
carrier를 아는 alias-aware 알고리즘처럼 동작하지 않는다. MUSIC만 예외로, 사용자가 band에
명시한 단일 아날로그 FFT-grid 가설에서 response와 signed complex manifold를 계산한다. 이는
Scene truth를 읽거나 가능한 alias order를 자동 탐색하는 것이 아니다.
서로 다른 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를 고르지 않는다.
않고 Result에 `aliasOrderResolution: not-attempted`로 기록한다. MUSIC은 band 하나에 사용자가
고른 가설 하나만 계산해 `configured-single-hypothesis`로 기록하며, 후보 중 승자를 고르지 않는다.
여러 order를 비교하려면 각각 독립 band로 명시해야 한다.
audio asset과 noise는 이미 sampling된 baseband 신호로 취급하므로 파일에 없는 Nyquist 위 analog
spectrum을 만들어 내지 않는다.
@@ -361,9 +412,11 @@ Result `signalStats`에는 다음 선택 필드가 들어간다.
같은 입력과 seed에서 환경 preset만 바꿨다면 이 값과 위치 오차·precision/recall·PSR을 함께
비교할 수 있다.
Result 최상위 `algorithm`은 실제 실행한 `das`, `das-phat` 또는 `gcc-phat`를 기록한다. band의
`rawMap.scale`은 DAS에서 `power`, 두 PHAT 방식에서 `score`다. peak 정규화된 `displayMap`은
시각 비교용일 뿐 어느 scale도 확률분포나 신뢰구간으로 바꾸지 않는다.
Result 최상위 `algorithm`은 실제 실행한 `das`, `das-phat`, `gcc-phat` 또는 `music`을 기록한다.
band의 `rawMap.scale`은 DAS에서 `power`, 두 PHAT 방식에서 `score`, MUSIC에서
`noise-projection`이다. MUSIC Result는 `musicModel`과 band별 `musicDiagnostics`에 아날로그
가설, alias inversion, covariance/EVD audit와 K 선택 가정을 기록한다. 표시 변환은 어느 scale도
확률분포나 신뢰구간으로 바꾸지 않는다.
## 정확도 범위와 제외 사항