From fd3d98947aa2314786242c9c4e1401d33ce14b3f Mon Sep 17 00:00:00 2001 From: Codex Date: Fri, 28 Aug 2026 16:36:37 +0900 Subject: [PATCH] docs: guide audio localization and live playback --- README.md | 54 ++++++++++++++++++++++++++++--- apps/acoustic-camera/README.md | 28 ++++++++++++++++ docs/data-contracts.md | 21 +++++++++++- docs/execution-plan.md | 18 +++++++++-- docs/index.html | 53 +++++++++++++++++++++++++----- index.html | 8 ++++- packages/acoustics-core/README.md | 16 +++++++++ packages/ui/app-shell.css | 2 +- schemas/README.md | 6 ++-- tests/integration/README.md | 13 +++++--- tests/unit/README.md | 20 +++++++----- 11 files changed, 204 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index ee2efd8..b24a7dc 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # micarrsim 192채널 MEMS 마이크 배열의 배치와 자유음장 DAS 음향 영상을 비교하는 로컬 브라우저 -시뮬레이터입니다. Dataset Builder에서 재현 가능한 음향 장면을 만들고 Acoustic Camera에서 -CPU 또는 WebGPU로 배열 응답, acoustic map과 위치 검출 지표를 계산합니다. +시뮬레이터입니다. Dataset Builder에서 녹음 파일·합성 신호와 이동 경로를 포함한 재현 가능한 +음향 장면을 만들고 Acoustic Camera에서 CPU 또는 WebGPU로 배열 응답, acoustic map과 위치 검출 +지표를 계산하거나 이동 장면을 시간축으로 재생합니다. 별도 프로그램이나 패키지를 설치하지 않습니다. 모든 앱과 계산은 이 저장소와 브라우저 안에서 실행됩니다. @@ -51,15 +52,26 @@ powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File .\scripts\serve. 실제 완료 시간은 브라우저와 장치에 따라 다릅니다. CPU fallback에서는 WebGPU보다 오래 걸릴 수 있습니다. +### 이동 음원 바로 보기 + +1. Acoustic Camera에서 **이동 예제**를 누릅니다. +2. **라이브 준비**를 눌러 2 Hz acoustic map을 계산합니다. +3. **재생**을 누르거나 시간 slider를 움직여 음원과 heatmap의 이동을 확인합니다. + +이 기능은 trajectory가 있는 합성 Scene의 준정적 시간창 재생입니다. 실제 192채널 마이크 장치에서 +들어오는 스트림을 캡처하는 기능은 아닙니다. + ## 내 장면으로 전체 흐름 실행하기 ### 1. Dataset Builder에서 Scene 만들기 1. 시작 화면에서 **Dataset Builder**를 엽니다. 2. 선택적으로 배경 이미지와 오디오를 추가합니다. -3. 음원을 추가해 canvas 또는 x/y/z 입력으로 위치를 정하고, tone·noise·audio asset과 ambient를 - 설정합니다. -4. 상태가 **저장 가능한 장면**이면 **Scene JSON 저장**을 누릅니다. +3. 녹음 파일은 **+ 오디오 파일 음원** 한 번으로 asset과 source를 함께 만들 수 있습니다. 합성 + 음원은 별도 버튼으로 추가합니다. +4. canvas 또는 x/y/z 입력으로 위치를 정하고 tone·noise·audio asset과 ambient를 설정합니다. +5. 움직이는 음원은 **시간에 따라 음원 이동**을 켜고 keyframe과 경로 미리보기 시간을 편집합니다. +6. 상태가 **저장 가능한 장면**이면 **Scene JSON 저장**을 누릅니다. **Preview WAV 저장**은 source와 ambient를 공간 정보 없이 하나의 mono channel로 합친 청취 확인용 파일입니다. 192채널 마이크 신호나 beamforming 결과가 아닙니다. @@ -106,6 +118,31 @@ WebGPU 경로도 신호 합성과 STFT 일부는 CPU에서 수행합니다. grid 100×100은 4배, 200×200은 16배입니다. 처음에는 50×50을 사용하고 해상도가 필요할 때만 높이세요. 실행 시간은 microphone 수, scene 길이, FFT, 대역 폭과 장치에 함께 좌우됩니다. +## 위치 추정, 빔 분포와 복수 음원 + +DAS 출력은 각 scan point의 상대 acoustic power map이며 위치 확률분포가 아닙니다. Camera는 map의 +local peak를 위치 후보로 표시합니다. **빔 분포**를 켜면 각 peak의 연결된 half-power lobe에 대해 +power 가중 공분산을 계산해 1× RMS 점선과 2× RMS 영역을 그립니다. Gaussian의 등고선처럼 보일 수 +있지만 통계적으로 보정된 Gaussian, 신뢰구간 또는 발생 확률은 아닙니다. + +복수 음원은 각각 별도 local peak가 남을 만큼 공간적으로 분리되고 선택 대역에 에너지가 있어야 +검출됩니다. **Peak 검출 임계값 (%)**은 최강 peak 대비 후보의 최소 power입니다. 기본 25%에서 약한 +두 번째 음원이 빠지면 10–20%로 낮출 수 있지만 sidelobe 오검출도 늘어납니다. 서로 같은 대역에서 +main lobe보다 가깝거나 gain 차이가 큰 음원은 conventional DAS의 물리·알고리즘 한계 때문에 +threshold만으로 분리되지 않을 수 있습니다. + +## 이동 음원 라이브의 동작 + +Builder의 trajectory는 Scene 시작 기준 절대 시간의 keyframe 사이를 직선 보간합니다. Camera는 +장면을 sample 경계에 맞춘 짧은 시간창으로 나누고, 각 창 중앙의 음원 위치에서 tone 위상, noise +index와 audio asset 재생 위치가 이어지도록 신호를 합성합니다. 계산된 map 사이에서는 heatmap을 +보간하고 ground-truth 위치는 연속 보간합니다. + +- Map rate: 초당 분석 map 목표 수. 높을수록 움직임이 세밀하지만 준비 시간이 늘 수 있습니다. +- 라이브 미리보기 상한: 48 maps, map당 최대 2,500 scan points +- 모델: 준정적 위치 변화이며 Doppler와 창 내부의 연속 전파 경로 변화는 포함하지 않음 +- 실제 장치: 물리 192채널 capture/stream gateway는 하드웨어 형식이 정해진 뒤 별도 adapter가 필요 + ## Result JSON Result JSON은 계약 버전 `1.0.0`의 `micarrsim.result` 문서입니다. 주요 내용은 다음과 같습니다. @@ -117,6 +154,7 @@ Result JSON은 계약 버전 `1.0.0`의 `micarrsim.result` 문서입니다. 주 - 주파수 대역별 선형 power `rawMap`, 표시용 `displayMap`, 검출 `peaks` - 위치 오차, precision/recall, truth 반경 내 energy, peak-to-sidelobe, main-lobe 폭을 계산하기 위한 평가 파라미터와 `metrics` +- peak별 half-power 공분산과 RMS ellipse를 담은 `beamSpread` (`calibrated: false`) 평가에서 tone source는 tone 주파수가 포함되는 band의 ground truth로만 사용합니다. Audio asset과 noise source는 스펙트럼을 미리 알 수 없으므로 모든 band의 ground truth로 취급합니다. 이 가정은 @@ -143,6 +181,12 @@ Camera의 **비교 배열** 선택으로 두 fixture를 같은 scene과 experime ## 테스트와 benchmark +최상위 폴더에서 자동 서버·headless 브라우저·정리까지 한 번에 실행하려면 다음을 사용합니다. + +```bat +test.cmd +``` + 서버를 실행한 뒤 다음 주소를 브라우저에서 엽니다. - 전체 browser test runner: diff --git a/apps/acoustic-camera/README.md b/apps/acoustic-camera/README.md index 7c513cc..d4d807b 100644 --- a/apps/acoustic-camera/README.md +++ b/apps/acoustic-camera/README.md @@ -15,6 +15,9 @@ Scene과 마이크 배열로 자유음장 microphone signal을 합성하고, STF 3. **기본 예제 실행**을 누릅니다. 4. 완료 후 overlay, 위치 오차와 timing을 확인하고 **Result JSON**을 저장합니다. +이동 장면을 바로 보려면 **이동 예제 → 라이브 준비 → 재생** 순서로 누릅니다. 기본 예제는 +24×18 grid와 2 Hz map rate를 사용해 CPU fallback에서도 준비량을 줄였습니다. + ## 사용자 입력 불러오기 문서는 다음 순서로 불러오는 것이 안전합니다. @@ -58,10 +61,18 @@ WebGPU가 감지돼도 실제 장치는 실행 시 확인합니다. 계산 중 * 실행 전에 표시됩니다. 현재 후처리는 raw DAS만 지원하며 DAMAS와 CLEAN-SC 항목은 비활성화되어 있습니다. +**Peak 검출 임계값 (%)**은 최강 local peak의 power에 대한 상대 임계값이며 Experiment JSON에 +저장됩니다. 기본 25%에서 약한 두 번째 음원이 빠지면 10–20%로 낮추세요. 낮은 값은 더 약한 후보를 +살리는 대신 sidelobe를 음원으로 잘못 고를 가능성도 높입니다. 같은 대역의 두 음원이 main lobe +폭보다 가깝다면 grid만 키우거나 threshold를 낮춰도 conventional DAS map에서 하나로 합쳐질 수 +있습니다. + ## 화면과 배열 비교 - acoustic overlay의 투명도와 표시할 band를 선택할 수 있습니다. - **Ground truth**를 켜면 source 위치와 검출 peak를 비교할 수 있습니다. +- **빔 분포**는 peak 주변 half-power lobe의 power 가중 공분산을 1× RMS 점선과 2× RMS 영역으로 + 표시합니다. 위치 확률, Gaussian 신뢰구간 또는 측정 불확실성 보정값은 아닙니다. - rectangular와 Fermat spiral preset을 같은 Scene/Experiment에서 연속 실행하면 **배열 비교 기록**에 backend, timing과 평가 요약이 남습니다. - 입력을 바꾼 뒤 화면에 남은 결과는 이전 실행 snapshot이며 UI가 이전 설정 결과임을 표시합니다. @@ -74,6 +85,22 @@ WebGPU가 감지돼도 실제 장치는 실행 시 확인합니다. 계산 중 * 않고 새 실행을 시작하면 교체 여부를 확인하며, 미저장 항목이나 실행 중 계산이 있는 상태에서 페이지를 닫으면 브라우저가 한 번 더 확인합니다. +## 이동 음원 라이브 + +Scene source에 두 개 이상의 `trajectory` keyframe이 있으면 **라이브 준비**가 활성화됩니다. +Builder에서는 **시간에 따라 음원 이동**과 경로 미리보기 slider로 이 데이터를 만들 수 있습니다. + +1. Map rate와 backend를 선택합니다. 처음에는 2 Hz와 Auto를 권장합니다. +2. **라이브 준비**를 누릅니다. 현재 입력 snapshot을 최대 48개, map당 최대 2,500 points의 짧은 + 분석창으로 계산합니다. +3. **재생** 또는 시간 slider로 이동합니다. Heatmap은 이웃한 acoustic map 사이를 보간하고 + source 위치는 keyframe 사이를 연속 보간합니다. + +각 시간창은 sample 경계에 맞추며 tone 위상, 결정적 noise index와 audio asset의 재생 위치를 원래 +Scene 시간에 이어 붙입니다. 한 창 안에서는 중앙 시각의 위치를 고정하는 준정적 근사이므로 Doppler, +창 내부 연속 경로 변화와 실제 마이크 스트림은 지원하지 않습니다. 실제 192채널 장치를 연결하려면 +장치의 channel 순서, sample 형식, clock와 전송 API에 맞춘 capture adapter가 별도로 필요합니다. + ## Result JSON **Result JSON**은 검증을 통과한 `micarrsim.result` 문서만 저장합니다. @@ -83,6 +110,7 @@ WebGPU가 감지돼도 실제 장치는 실행 시 확인합니다. 계산 중 * - `signalStats`: 정규화 전 peak, 적용 scale, clipped sample 수 - `timingMs`: 전체, signal generation과 beamforming 시간 - band별 `rawMap` 선형 power, `displayMap`, 검출 `peaks` +- 각 peak의 비보정 half-power 공분산과 RMS ellipse인 `beamSpread` - 평가 설정과 `peakToSidelobeDb`, `energyInsideTruthRatio`, `precision`, `recall`, `mainLobeWidthM` diff --git a/docs/data-contracts.md b/docs/data-contracts.md index b21d4f5..f4e15f5 100644 --- a/docs/data-contracts.md +++ b/docs/data-contracts.md @@ -34,6 +34,17 @@ Camera는 사용자가 다시 선택한 파일을 SHA-256으로 계산해 같은 Builder가 내보낸 Scene JSON과 사용한 원본 이미지·오디오는 함께 보관해야 한다. Preview WAV는 scene recipe를 mono로 합친 청취 확인용 파일이며 마이크 배열의 192채널 수신 신호가 아니다. +## 이동 음원 trajectory + +Scene source의 선택적 `trajectory`는 2–4,096개의 `{ time, position }` keyframe 배열이다. `time`은 +Scene 시작 기준 절대 초이며 0 이상 `scene.duration` 이하에서 엄격히 증가해야 한다. `position`은 +정적 source와 같은 `[x, y, z]` m 좌표다. keyframe 사이 위치는 선형 보간하며, 첫 keyframe은 +호환용 `source.position`과 같은 시작 위치로 Builder가 유지한다. + +Camera 라이브 미리보기는 sample 경계에 맞춘 시간창 중앙에서 trajectory 위치를 평가한다. 짧은 +창으로 Scene 시간을 다시 기준화해도 tone 위상, noise sample index와 audio asset 재생 위치는 원래 +절대 시간에 이어진다. 이는 준정적 근사이며 Doppler를 계약하지 않는다. + ## 오디오와 map 정규화 `scene.mix.normalization`은 마이크 신호 합성 전에 적용할 오디오 mix 정책이다. `none`은 원래 @@ -47,10 +58,18 @@ raw DAS map을 덮어쓰지 않는다. map은 row-major 배열이다. 첫 행은 `yMax`, 마지막 행은 `yMin`, 각 행은 `xMin`에서 `xMax` 방향이다. `values.length`는 반드시 `rows × columns`와 같아야 한다. +Experiment의 선택적 `evaluation.detectionThresholdRatio`는 최강 local peak power에 대한 검출 +임계 비율이며 `0 < ratio <= 1`이다. 생략된 이전 문서를 Camera에서 열면 기본값 `0.25`를 적용하며, +Experiment JSON을 다시 저장하면 이 값이 명시된다. 값을 낮추면 약한 peak 후보를 포함하지만 +sidelobe false positive도 늘 수 있다. + ## Result 평가 정보 각 band의 `peaks`는 위치와 power 값, 선택적 `sourceId`, `localizationErrorM`, -`localizationErrorPixels`를 저장한다. `metrics`에는 다음 유한값만 기록한다. +`localizationErrorPixels`, `beamSpread`를 저장한다. `beamSpread`는 선택 peak를 포함하는 연결된 +half-power 성분의 power 가중 centroid·공분산과 major/minor RMS 반경·각도다. `calibrated`는 현재 +항상 `false`이며 확률분포, Gaussian 신뢰구간 또는 통계적 위치 불확실성으로 해석하지 않는다. +`metrics`에는 다음 유한값만 기록한다. - `peakToSidelobeDb` - `energyInsideTruthRatio` diff --git a/docs/execution-plan.md b/docs/execution-plan.md index 7eab0fa..3b1df55 100644 --- a/docs/execution-plan.md +++ b/docs/execution-plan.md @@ -3,7 +3,8 @@ > 구현 상태 · 2026-08-28 > > 단계 0–4는 완료되어 설치 없는 브라우저 앱, CPU/WebGPU DAS, Builder→Camera asset 재연결, -> 배열 비교, 평가·Result 내보내기와 53개 자동 테스트로 검증했다. 단계 5는 향후 고도화 범위다. +> 임의 오디오·이동 trajectory, 빔 분포·복수 peak 감도, 라이브 시간축 재생, 배열 비교와 +> Result 내보내기를 71개 자동 테스트로 검증했다. 단계 5는 실제 장치·공간 모델 고도화 범위다. ## 1. 목표와 성공 기준 @@ -133,6 +134,7 @@ flattening이 모델 타당성을 훼손하는지 청취 및 spectrum 통계로 ### 단계 2 — Dataset Builder · 완료 - 이미지와 음원 파일 불러오기, 위치·시간·gain 편집, ambient mix와 미리 듣기 +- 파일 선택 한 번으로 audio asset source 생성, source별 trajectory keyframe 편집·미리보기 - deterministic seed, clipping 경고, Scene JSON과 mono Preview WAV 내보내기 - synthetic tone/noise fixture와 로컬 asset manifest 경계 구현 @@ -151,6 +153,8 @@ flattening이 모델 타당성을 훼손하는지 청취 및 spectrum 통계로 - scene/ground truth/acoustic overlay, 배열 geometry, parameter panel 구현 - 결과 metric, 실행 환경, 입력 hash와 map 내보내기 - 복수 음원·다중 대역 표시와 실험 preset 비교 +- peak별 half-power 공분산/RMS 빔 분포와 재현 가능한 검출 임계값 +- sample-aligned 준정적 시간창 분석, bounded map 계획과 이동 장면 재생 완료 조건: 사용자가 코드 수정 없이 배열 JSON 두 개를 같은 장면에서 비교할 수 있다. @@ -158,6 +162,7 @@ flattening이 모델 타당성을 훼손하는지 청취 및 spectrum 통계로 - 라이선스 검토를 통과한 DCASE/MIMII adapter와 batch workflow 추가 - microphone calibration·noise 모델 검토 +- 실제 192채널 장치의 channel/clock/sample 형식이 정해진 뒤 capture·stream adapter 추가 - 필요 시 DAMAS/CLEAN-SC를 플러그인형 후처리로 추가 - image-source method 또는 room impulse response 기반 잔향 모듈 추가 @@ -167,8 +172,9 @@ flattening이 모델 타당성을 훼손하는지 청취 및 spectrum 통계로 - WebGPU 미지원/장치 한도: 시작 시 capability를 표시하고 CPU fallback 및 grid 상한을 둔다. - 좌표·phase 부호 오류: analytic tone test와 배열 대칭성 test를 먼저 만든다. -- 브라우저 메모리: 현재 전체 192채널 signal buffer에 512 MiB 한도를 적용한다. 장시간 입력은 - 향후 chunk/STFT streaming backend로 확장한다. +- 브라우저 메모리: snapshot은 전체 192채널 signal buffer에 512 MiB 한도를 적용하고, 이동 + 미리보기는 최대 48개·2,500 points의 짧은 시간창으로 제한한다. 실제 장시간 capture는 향후 + chunk/STFT streaming backend로 확장한다. - 데이터셋 부적합/라이선스: 로컬 asset 계약을 유지하고 synthetic fixture를 기본 test 입력으로 쓴다. 실제 데이터 adapter는 단계 5의 라이선스 검토 뒤 추가한다. - 실제 AC와 simulation gap: 감도, 위상, 위치 오차를 이후 calibration/noise model로 주입 가능하게 한다. @@ -183,7 +189,13 @@ flattening이 모델 타당성을 훼손하는지 청취 및 spectrum 통계로 - [x] WGSL kernel, CPU/GPU 비교와 50²/100²/200² benchmark - [x] scene canvas, array view, parameter controls와 Result export - [x] Builder→Camera SHA-256 asset 재연결 왕복 테스트 +- [x] 임의 오디오 source 원클릭 생성과 codec 안내 +- [x] 이동 trajectory 계약·편집·시간창 합성·Camera 라이브 재생 +- [x] 비확률 beam spread RMS contour와 Result export +- [x] 복수 음원용 Experiment peak 검출 감도 +- [x] `test.cmd` one-command headless browser 검증 - [ ] DCASE/MIMII 라이선스 검토와 adapter +- [ ] 실제 192채널 capture/stream adapter - [ ] 잔향·calibration·noise model - [ ] DAMAS/CLEAN-SC 후처리 diff --git a/docs/index.html b/docs/index.html index 4ab3894..5358043 100644 --- a/docs/index.html +++ b/docs/index.html @@ -16,6 +16,7 @@ ← micarrsim 홈