feat: add physically explicit narrowband MUSIC
This commit is contained in:
@@ -83,6 +83,7 @@ Portable plan은 top-level `algorithm`으로 위치 추정기를 선택한다.
|
||||
| `das` | frequency-domain delay-and-sum | `power` | CPU |
|
||||
| `das-phat` | phase-only spectrum을 steering하는 DAS | `score` | CPU |
|
||||
| `gcc-phat` | 한 reference mic에 대한 `M-1`개 GCC-PHAT 지연 scan | `score` | CPU only |
|
||||
| `music` | 표준 좁은대역 Schmidt noise-subspace scan | `noise-projection` | CPU only |
|
||||
|
||||
같은 array·scan·band·STFT로 알고리즘을 비교할 때도 알고리즘마다 별도 plan을 만든다.
|
||||
|
||||
@@ -103,6 +104,14 @@ const gccPhatPlan = createLocalizationPlan({
|
||||
algorithm: "gcc-phat",
|
||||
phatFloorRatio: 1e-6,
|
||||
});
|
||||
|
||||
const musicPlan = createLocalizationPlan({
|
||||
...commonConfig,
|
||||
algorithm: "music",
|
||||
normalization: "none",
|
||||
musicSourceCountMethod: "fixed",
|
||||
musicSourceCount: 1,
|
||||
});
|
||||
```
|
||||
|
||||
`phatRelativeFloor`는 DAS-PHAT의 channel spectrum 정규화 floor이고, `phatFloorRatio`는
|
||||
@@ -151,7 +160,7 @@ const plan = createLocalizationPlan({
|
||||
{ id: "machine", minHz: 900, maxHz: 1100, color: "#65f2bf" },
|
||||
],
|
||||
stft: { fftSize: 512, hopSize: 256 },
|
||||
algorithm: "das", // "das" | "das-phat" | "gcc-phat"
|
||||
algorithm: "das", // "das" | "das-phat" | "gcc-phat" | "music"
|
||||
speedOfSound: 343,
|
||||
normalization: "peak",
|
||||
compensateFrequencyResponse: true,
|
||||
@@ -174,7 +183,7 @@ const plan = createLocalizationPlan({
|
||||
- scan의 `columns`와 `rows`는 양의 정수
|
||||
- `speedOfSound`는 양수
|
||||
- `normalization`은 `peak` 또는 `none`
|
||||
- `algorithm`은 `das`, `das-phat`, `gcc-phat` 중 하나
|
||||
- `algorithm`은 `das`, `das-phat`, `gcc-phat`, `music` 중 하나
|
||||
- `phatRelativeFloor`와 `phatFloorRatio`는 지정한 경우 0–1
|
||||
- `maxCompensationDb`는 0–120 dB
|
||||
- `peakDetection.thresholdRatio`는 0–1,
|
||||
@@ -186,7 +195,29 @@ const plan = createLocalizationPlan({
|
||||
STFT·correlation workspace를 유지한다. 같은 계획으로 두 분석을 동시에 실행하지 말고 worker마다
|
||||
별도 계획을 만든다. Array·scan·band·STFT·알고리즘을 바꾸면 새 계획을 만들어야 한다.
|
||||
Portable plan의 generic cache는 `plan.analysisPlan`이며 기존 호출자를 위해 DAS 계열에는
|
||||
`plan.dasPlan`, GCC-PHAT에는 `plan.gccPhatPlan` alias도 제공한다.
|
||||
`plan.dasPlan`, GCC-PHAT에는 `plan.gccPhatPlan`, MUSIC에는 `plan.musicPlan` alias도 제공한다.
|
||||
|
||||
### MUSIC 포팅 경계
|
||||
|
||||
MUSIC raw `q = ||E_n^H a||²/(a^H a)`는 작은 값이 좋은 noise projection이다. 표시용
|
||||
`P/Pmax = q_min/q`도 확률·신뢰도·Gaussian 신뢰구간이 아니며, raw q 보존을 위해
|
||||
`normalization: "none"`만 허용한다.
|
||||
|
||||
band마다 사용자가 지정한 analog FFT-grid 가설 하나와 접힌 positive ADC bin 하나만 사용한다.
|
||||
Scene carrier/위치 truth는 읽지 않는다. analog carrier `f_a`의 공간 위상을 alias orientation
|
||||
`η`로 `exp[-j η 2π f_a Δr/c]`에 적용하며, inversion이면 calibration과 steering을 포함한
|
||||
전체 complex manifold를 켤레화한다. 정확한 DC/Nyquist는 quadrature-degenerate라 거절한다.
|
||||
|
||||
Fixed K는 `1..M-1`이다. Wax–Kailath MDL/AIC는 complete non-overlapping frame, `T > M`,
|
||||
strict-positive noise eigenvalue, IID complex Gaussian snapshot·spatially white noise·고정 K를
|
||||
가정한다. non-overlap은 독립성의 증명이 아니다. 조건 불충족과 식별 불가능한 partition은
|
||||
`MusicUnavailableError` (`code: "MUSIC_UNAVAILABLE"`)이며 fixed fallback은 없다.
|
||||
diagonal loading, floor, spatial smoothing, multibin/wideband fusion도 없다. grating lobe,
|
||||
동률과 coherent rank deficiency를 결과가 좋아 보이도록 제거하지 않는다.
|
||||
|
||||
계획은 allocation 전에 typed working bytes, FFT butterfly, covariance complex accumulation,
|
||||
Jacobi pair update와 projection MAC 상한을 검사한다. 이 CPU cap은 메모리·응답성 보호 장치이지
|
||||
realtime 보장이 아니므로 `processingTimeMs`와 streaming deadline 통계를 대상 장치에서 측정한다.
|
||||
|
||||
portable 계획의 기본 scan point batch는 DAS 계열 256개, GCC-PHAT 4,096개이고 STFT transform
|
||||
batch는 128개다. GCC-PHAT cross-spectrum은 16,384 operation 단위로도 양보한다. 각 batch 경계에서
|
||||
|
||||
Reference in New Issue
Block a user