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
+44 -9
View File
@@ -53,6 +53,9 @@ powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File .\scripts\serve.
같은 입력에서 **위치 추정 알고리즘**만 DAS-PHAT으로 바꿔 다시 실행하면 아래 비교 기록에 두 결과가
나란히 남습니다. GCC-PHAT은 광대역 입력에서 비교하세요.
MUSIC을 바로 확인하려면 현재 장면 제목 옆 **MUSIC 빠른 예제**를 누른 뒤
**▶ Snapshot 실행**만 누르면 됩니다. 12채널·1.125 kHz 단일-bin·Fixed K=1 설정이 함께 열립니다.
실제 완료 시간은 브라우저와 장치에 따라 다릅니다. CPU fallback에서는 WebGPU보다 오래 걸릴 수
있습니다.
@@ -114,7 +117,8 @@ powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File .\scripts\serve.
1. 홈으로 돌아가 **Acoustic Camera**를 엽니다.
2. 권장 순서인 **Scene → Array → Experiment → Assets**로 입력합니다. Experiment는 어느
시점에 열어도 모든 분석 대역을 유지하고 현재 Scene·Array에 자동으로 연결됩니다.
시점에 열어도 모든 분석 대역과 원래의 `sceneId`/`arrayId` provenance label을 유지하며,
실행에는 현재 열린 Scene·Array가 사용됩니다.
3. **Scene**에서 Builder가 저장한 `.scene.json`을 선택합니다.
4. 기본 배열을 사용하지 않을 때는 **Array**에서 Array Builder가 저장한 `.array.json`을 선택합니다.
5. 별도 실험 문서를 사용할 때만 **Experiment**에서 `.experiment.json`을 선택합니다.
@@ -123,9 +127,9 @@ powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File .\scripts\serve.
7. 입력 검증이 통과하면 위치 추정 알고리즘, backend와 scan grid를 정하고 실행합니다.
8. 완료 후 **Result JSON**을 저장합니다.
Experiment를 불러오면 Camera가 먼저 문서 자체의 계약을 검사한 뒤 `sceneId`와 `arrayId`를
현재 열린 Scene·Array에 자동으로 연결합니다. 가져온 `frequencyBands`와 나머지 분석 설정은
보존됩니다. 재연결한 문서는 현재 입력을 기준으로 관계 검증을 다시 수행합니다. Nyquist 위 tone과
Experiment를 불러오면 Camera가 먼저 문서 자체의 계약을 검사하고 가져온 `sceneId`,
`arrayId`, `frequencyBands`와 나머지 분석 설정을 그대로 보존합니다. 두 ID가 현재 입력과
달라도 거부하지 않으며, Result의 ID와 hash에는 실제 실행에 사용한 Scene·Array를 기록합니다. Nyquist 위 tone과
band는 오류가 아니라 ideal ADC alias 실험으로 허용되며, 원 주파수와 실제 ADC FFT range가 UI와
Result에 함께 기록됩니다. 잘못된 범위·scan·asset 같은 실제 오류는 그대로 거부됩니다. Scene을
다시 불러오면 이전 asset 연결은 해제됩니다.
@@ -133,7 +137,7 @@ Result에 함께 기록됩니다. 잘못된 범위·scan·asset 같은 실제
Camera 안의 **Builder 새 탭** 링크는 편집 중인 Experiment와 분석 대역을 원래 Camera 탭에
유지합니다. Builder에서 JSON을 저장한 뒤 새 Camera를 다시 열지 말고 원래 Camera 탭으로 돌아와
Scene 또는 Array를 선택하세요. 같은 Camera 페이지에서 Scene을 교체하면 scan 영역과
`sceneId`만 맞추며 기존 `frequencyBands`는 보존합니다.
plane을 새 Scene에 맞추되 Experiment의 provenance ID와 기존 `frequencyBands`는 보존합니다.
Camera에서 수정한 Scene·Experiment, 완료 Result와 전체 배열 비교 기록은 각각 JSON으로 저장할 수
있습니다. 저장하지 않은 항목이나 실행 중 계산이 있으면 페이지를 닫을 때 브라우저가 확인합니다.
@@ -157,6 +161,7 @@ SHA-256 manifest를 저장합니다. 브라우저는 새 페이지나 세션에
| DAS | 상대 acoustic power | CPU, WebGPU | 가장 단순한 기준선. 채널 gain과 알려진 마이크 응답을 보정합니다. |
| DAS-PHAT | 무차원 score | CPU, WebGPU | 마이크별 진폭을 버리고 위상 정합을 비교해 gain·반사에 더 강건할 수 있습니다. |
| GCC-PHAT | 무차원 score | CPU | 한 reference와 나머지 마이크의 TDOA 상관을 사용합니다. 광대역이 필요하며 협대역에서는 주기적 모호성이 큽니다. |
| MUSIC | noise-subspace projection `q` | CPU | [Schmidt narrowband MUSIC](https://doi.org/10.1109/TAP.1986.1143830)의 근거리 구면파 구현입니다. band마다 아날로그 FFT-grid carrier 가설 하나와 source 수를 지정해야 합니다. |
- **Auto (GPU→CPU)**: 권장값입니다. WebGPU adapter나 device를 사용할 수 없거나 지원되는 장치
한계를 넘으면 CPU로 계속합니다.
@@ -164,9 +169,21 @@ SHA-256 manifest를 저장합니다. 브라우저는 새 페이지나 세션에
오류를 표시합니다.
- **CPU 강제**: 비교와 호환성 확인을 위해 선택한 알고리즘의 CPU 구현을 사용합니다.
GCC-PHAT은 현재 CPU 전용이므로 선택하면 Auto 또는 CPU만 사용할 수 있습니다. Camera는 각 band가
GCC-PHAT과 MUSIC은 현재 CPU 전용이므로 선택하면 Auto 또는 CPU만 사용할 수 있습니다. Camera는 각 band가
8개 미만의 FFT bin을 포함하면 협대역 경고를 표시합니다.
MUSIC의 원시 값은
`q(r)=Σ|E_nᴴa(r)|²/(a(r)ᴴa(r))`이며 작은 값이 더 좋은 위치 가설입니다. Camera가 표시·peak
검출에 쓰는 `P/Pmax`는 `P=1/q`를 scan 안에서 다시 0–1로 나타낸 값일 뿐, `q`와 `P/Pmax`
모두 위치 확률·posterior·confidence 또는 신뢰구간이 아닙니다. `q=0`인 이상적 pole, 동일
최솟값 tie와 완전히 평평한 map은 큰 유한값으로 조작하지 않고 별도로 처리합니다.
`musicSourceCountMethod`은 사용자가 지정한 `fixed` K 또는
[Wax–Kailath AIC/MDL](https://doi.org/10.1109/TASSP.1985.1164557)입니다. AIC/MDL은
비중첩 frame, `T>M`, 양의 noise eigenvalue 외에도 IID complex Gaussian snapshot,
spatially white noise와 창 동안 일정한 source 수를 **가정**합니다. 비중첩은 통계적 독립성의
증명이 아니며 criterion score 역시 확률이나 confidence가 아닙니다.
WebGPU 경로도 신호 합성과 STFT 일부는 CPU에서 수행합니다. grid의 point 수는 50×50을 1로 보면
100×100은 4배, 200×200은 16배입니다. 처음에는 50×50을 사용하고 해상도가 필요할 때만 높이세요.
실행 시간은 microphone 수, scene 길이, FFT, 대역 폭과 장치에 함께 좌우됩니다.
@@ -217,6 +234,21 @@ scan 범위나 마이크 수 때문에 값이 단순히 커지는 현상은 막
main lobe보다 가깝거나 gain 차이가 큰 음원은 conventional DAS의 물리·알고리즘 한계 때문에
threshold만으로 분리되지 않을 수 있습니다.
MUSIC band는 FFT spacing에 맞는 사용자가 지정한 아날로그 carrier 가설을 정확히 하나만 포함해야
합니다. Nyquist 위 가설도 허용되며 signed ADC alias가 음수이면 positive-bin coefficient,
마이크 calibration과 전체 complex 근거리 manifold를 켤레 방향으로 사용합니다. 공간 위상의
크기는 접힌 ADC 주파수가 아니라 analog carrier `f_a`이고 alias 부호는 orientation만 정합니다. 이는 Scene의
실제 tone을 조회해 정답 alias order를 고르는 기능이 아닙니다. 가설은 Experiment band에서만
오고 Scene truth는 위치추정에 사용되지 않습니다. 같은 ADC bin의 다른 alias order는 별도 band로
직접 만들어 비교해야 하며 자동 선택·평균·maximum fusion은 없습니다. DC와 정확한 Nyquist bin은
실수 sampling에서 quadrature가 퇴화하므로 거부됩니다.
표준 narrowband MUSIC은 coherent한 같은-frequency source에서 covariance rank가 줄어드는 현상을
고치지 않습니다. 현재 구현에는 diagonal loading, spatial smoothing, 임의 wideband/multiband
fusion이 없고, [Wax–Shan–Kailath broadband eigenstructure 방법](https://doi.org/10.1109/TASSP.1984.1164400)도
구현하지 않았습니다. grating lobe와 동일 최솟값은 배열 설계 결과로 그대로 남고, signal/noise
subspace가 수치적으로 식별되지 않으면 `MUSIC_UNAVAILABLE`로 실패합니다.
## 이동 음원 라이브의 동작
Builder의 trajectory는 Scene 시작 기준 절대 시간의 keyframe 사이를 직선 보간합니다. Camera는
@@ -243,7 +275,9 @@ channel/clock/transport adapter만 별도로 연결합니다. 실시간 여부
Result JSON은 계약 버전 `1.1.0`의 `micarrsim.result` 문서입니다. Array·Scene·Experiment는
`1.0.0`을 유지합니다. 주요 내용은 다음과 같습니다.
- 실행한 `experimentId`, `arrayId`, `sceneId`, 실제 `algorithm`·`backend`와 생성 시각
- 실행한 `experimentId`, `arrayId`, `sceneId`, 실제 `algorithm`·`backend`와 생성 시각. 이 ID들은
provenance label이며 물리 호환성 판정값이 아닙니다. Camera는 가져온 Experiment를 현재
Scene·Array에 연결한 뒤 Result에 실제 실행 ID와 hash를 기록합니다.
- Array·Scene·Experiment의 canonical SHA-256인 `inputHash`
- 정규화 전 peak, 적용 scale, clipping 수와 음향 모델·희소 경로 수를 담은 `signalStats`
- 원 tone→signed ADC alias, DC/Nyquist 퇴화와 anti-alias filter 부재를 담은 필수 sampling provenance
@@ -268,8 +302,9 @@ source는 임의 spectrum threshold를 만들지 않고 모든 band의 ground tr
음향 모델은 직접 경로의 자유음장과 1차 반사·scattering·occluder 회절·RT60 tail을 제한된
경로로 계산하는 shoebox 근사를 제공합니다. 파동 방정식, 고차 반사, 재질별 주파수 의존 흡음,
복잡한 mesh 회절, 바람, Doppler, 마이크 self-noise·비선형, ADC quantization·nonlinearity와
channel clock jitter·drift는 모델링하지 않습니다. 위치 추정기는 DAS, DAS-PHAT와 CPU GCC-PHAT를 제공하지만 full-pair SRP-PHAT, MUSIC,
DAMAS와 CLEAN-SC는 구현하지 않습니다.
channel clock jitter·drift는 모델링하지 않습니다. 위치 추정기는 DAS, DAS-PHAT, CPU GCC-PHAT와
CPU narrowband MUSIC을 제공하지만 full-pair SRP-PHAT, wideband MUSIC, DAMAS와 CLEAN-SC는
구현하지 않습니다.
따라서 결과는 배열·grid·대역의 상대 비교와 소프트웨어 검증용이며, 현장 성능 인증이나 안전
판단을 대신하지 않습니다.