docs: guide audio localization and live playback

This commit is contained in:
Codex
2026-08-28 16:36:37 +09:00
parent 7cd737429a
commit fd3d98947a
11 changed files with 204 additions and 35 deletions
+49 -5
View File
@@ -1,8 +1,9 @@
# micarrsim # micarrsim
192채널 MEMS 마이크 배열의 배치와 자유음장 DAS 음향 영상을 비교하는 로컬 브라우저 192채널 MEMS 마이크 배열의 배치와 자유음장 DAS 음향 영상을 비교하는 로컬 브라우저
시뮬레이터입니다. Dataset Builder에서 재현 가능한 음향 장면을 만들고 Acoustic Camera에서 시뮬레이터입니다. Dataset Builder에서 녹음 파일·합성 신호와 이동 경로를 포함한 재현 가능한
CPU 또는 WebGPU로 배열 응답, acoustic map과 위치 검출 지표를 계산합니다. 음향 장면을 만들고 Acoustic Camera에서 CPU 또는 WebGPU로 배열 응답, acoustic map과 위치 검출
지표를 계산하거나 이동 장면을 시간축으로 재생합니다.
별도 프로그램이나 패키지를 설치하지 않습니다. 모든 앱과 계산은 이 저장소와 브라우저 안에서 별도 프로그램이나 패키지를 설치하지 않습니다. 모든 앱과 계산은 이 저장소와 브라우저 안에서
실행됩니다. 실행됩니다.
@@ -51,15 +52,26 @@ powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File .\scripts\serve.
실제 완료 시간은 브라우저와 장치에 따라 다릅니다. CPU fallback에서는 WebGPU보다 오래 걸릴 수 실제 완료 시간은 브라우저와 장치에 따라 다릅니다. CPU fallback에서는 WebGPU보다 오래 걸릴 수
있습니다. 있습니다.
### 이동 음원 바로 보기
1. Acoustic Camera에서 **이동 예제**를 누릅니다.
2. **라이브 준비**를 눌러 2 Hz acoustic map을 계산합니다.
3. **재생**을 누르거나 시간 slider를 움직여 음원과 heatmap의 이동을 확인합니다.
이 기능은 trajectory가 있는 합성 Scene의 준정적 시간창 재생입니다. 실제 192채널 마이크 장치에서
들어오는 스트림을 캡처하는 기능은 아닙니다.
## 내 장면으로 전체 흐름 실행하기 ## 내 장면으로 전체 흐름 실행하기
### 1. Dataset Builder에서 Scene 만들기 ### 1. Dataset Builder에서 Scene 만들기
1. 시작 화면에서 **Dataset Builder**를 엽니다. 1. 시작 화면에서 **Dataset Builder**를 엽니다.
2. 선택적으로 배경 이미지와 오디오를 추가합니다. 2. 선택적으로 배경 이미지와 오디오를 추가합니다.
3. 음원을 추가해 canvas 또는 x/y/z 입력으로 위치를 정하고, tone·noise·audio asset과 ambient를 3. 녹음 파일은 **+ 오디오 파일 음원** 한 번으로 asset과 source를 함께 만들 수 있습니다. 합성
설정합니다. 음원은 별도 버튼으로 추가합니다.
4. 상태가 **저장 가능한 장면**이면 **Scene JSON 저장**을 누릅니다. 4. canvas 또는 x/y/z 입력으로 위치를 정하고 tone·noise·audio asset과 ambient를 설정합니다.
5. 움직이는 음원은 **시간에 따라 음원 이동**을 켜고 keyframe과 경로 미리보기 시간을 편집합니다.
6. 상태가 **저장 가능한 장면**이면 **Scene JSON 저장**을 누릅니다.
**Preview WAV 저장**은 source와 ambient를 공간 정보 없이 하나의 mono channel로 합친 청취 **Preview WAV 저장**은 source와 ambient를 공간 정보 없이 하나의 mono channel로 합친 청취
확인용 파일입니다. 192채널 마이크 신호나 beamforming 결과가 아닙니다. 확인용 파일입니다. 192채널 마이크 신호나 beamforming 결과가 아닙니다.
@@ -106,6 +118,31 @@ WebGPU 경로도 신호 합성과 STFT 일부는 CPU에서 수행합니다. grid
100×100은 4배, 200×200은 16배입니다. 처음에는 50×50을 사용하고 해상도가 필요할 때만 높이세요. 100×100은 4배, 200×200은 16배입니다. 처음에는 50×50을 사용하고 해상도가 필요할 때만 높이세요.
실행 시간은 microphone 수, scene 길이, FFT, 대역 폭과 장치에 함께 좌우됩니다. 실행 시간은 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
Result JSON은 계약 버전 `1.0.0`의 `micarrsim.result` 문서입니다. 주요 내용은 다음과 같습니다. Result JSON은 계약 버전 `1.0.0`의 `micarrsim.result` 문서입니다. 주요 내용은 다음과 같습니다.
@@ -117,6 +154,7 @@ Result JSON은 계약 버전 `1.0.0`의 `micarrsim.result` 문서입니다. 주
- 주파수 대역별 선형 power `rawMap`, 표시용 `displayMap`, 검출 `peaks` - 주파수 대역별 선형 power `rawMap`, 표시용 `displayMap`, 검출 `peaks`
- 위치 오차, precision/recall, truth 반경 내 energy, peak-to-sidelobe, main-lobe 폭을 계산하기 - 위치 오차, precision/recall, truth 반경 내 energy, peak-to-sidelobe, main-lobe 폭을 계산하기
위한 평가 파라미터와 `metrics` 위한 평가 파라미터와 `metrics`
- peak별 half-power 공분산과 RMS ellipse를 담은 `beamSpread` (`calibrated: false`)
평가에서 tone source는 tone 주파수가 포함되는 band의 ground truth로만 사용합니다. Audio asset과 평가에서 tone source는 tone 주파수가 포함되는 band의 ground truth로만 사용합니다. Audio asset과
noise source는 스펙트럼을 미리 알 수 없으므로 모든 band의 ground truth로 취급합니다. 이 가정은 noise source는 스펙트럼을 미리 알 수 없으므로 모든 band의 ground truth로 취급합니다. 이 가정은
@@ -143,6 +181,12 @@ Camera의 **비교 배열** 선택으로 두 fixture를 같은 scene과 experime
## 테스트와 benchmark ## 테스트와 benchmark
최상위 폴더에서 자동 서버·headless 브라우저·정리까지 한 번에 실행하려면 다음을 사용합니다.
```bat
test.cmd
```
서버를 실행한 뒤 다음 주소를 브라우저에서 엽니다. 서버를 실행한 뒤 다음 주소를 브라우저에서 엽니다.
- 전체 browser test runner: <http://127.0.0.1:4173/tests/> - 전체 browser test runner: <http://127.0.0.1:4173/tests/>
+28
View File
@@ -15,6 +15,9 @@ Scene과 마이크 배열로 자유음장 microphone signal을 합성하고, STF
3. **기본 예제 실행**을 누릅니다. 3. **기본 예제 실행**을 누릅니다.
4. 완료 후 overlay, 위치 오차와 timing을 확인하고 **Result JSON**을 저장합니다. 4. 완료 후 overlay, 위치 오차와 timing을 확인하고 **Result JSON**을 저장합니다.
이동 장면을 바로 보려면 **이동 예제 → 라이브 준비 → 재생** 순서로 누릅니다. 기본 예제는
24×18 grid와 2 Hz map rate를 사용해 CPU fallback에서도 준비량을 줄였습니다.
## 사용자 입력 불러오기 ## 사용자 입력 불러오기
문서는 다음 순서로 불러오는 것이 안전합니다. 문서는 다음 순서로 불러오는 것이 안전합니다.
@@ -58,10 +61,18 @@ WebGPU가 감지돼도 실제 장치는 실행 시 확인합니다. 계산 중 *
실행 전에 표시됩니다. 현재 후처리는 raw DAS만 지원하며 DAMAS와 CLEAN-SC 항목은 비활성화되어 실행 전에 표시됩니다. 현재 후처리는 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를 선택할 수 있습니다. - acoustic overlay의 투명도와 표시할 band를 선택할 수 있습니다.
- **Ground truth**를 켜면 source 위치와 검출 peak를 비교할 수 있습니다. - **Ground truth**를 켜면 source 위치와 검출 peak를 비교할 수 있습니다.
- **빔 분포**는 peak 주변 half-power lobe의 power 가중 공분산을 1× RMS 점선과 2× RMS 영역으로
표시합니다. 위치 확률, Gaussian 신뢰구간 또는 측정 불확실성 보정값은 아닙니다.
- rectangular와 Fermat spiral preset을 같은 Scene/Experiment에서 연속 실행하면 **배열 비교 기록**에 - rectangular와 Fermat spiral preset을 같은 Scene/Experiment에서 연속 실행하면 **배열 비교 기록**에
backend, timing과 평가 요약이 남습니다. backend, timing과 평가 요약이 남습니다.
- 입력을 바꾼 뒤 화면에 남은 결과는 이전 실행 snapshot이며 UI가 이전 설정 결과임을 표시합니다. - 입력을 바꾼 뒤 화면에 남은 결과는 이전 실행 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
**Result JSON**은 검증을 통과한 `micarrsim.result` 문서만 저장합니다. **Result JSON**은 검증을 통과한 `micarrsim.result` 문서만 저장합니다.
@@ -83,6 +110,7 @@ WebGPU가 감지돼도 실제 장치는 실행 시 확인합니다. 계산 중 *
- `signalStats`: 정규화 전 peak, 적용 scale, clipped sample 수 - `signalStats`: 정규화 전 peak, 적용 scale, clipped sample 수
- `timingMs`: 전체, signal generation과 beamforming 시간 - `timingMs`: 전체, signal generation과 beamforming 시간
- band별 `rawMap` 선형 power, `displayMap`, 검출 `peaks` - band별 `rawMap` 선형 power, `displayMap`, 검출 `peaks`
- 각 peak의 비보정 half-power 공분산과 RMS ellipse인 `beamSpread`
- 평가 설정과 `peakToSidelobeDb`, `energyInsideTruthRatio`, `precision`, `recall`, - 평가 설정과 `peakToSidelobeDb`, `energyInsideTruthRatio`, `precision`, `recall`,
`mainLobeWidthM` `mainLobeWidthM`
+20 -1
View File
@@ -34,6 +34,17 @@ Camera는 사용자가 다시 선택한 파일을 SHA-256으로 계산해 같은
Builder가 내보낸 Scene JSON과 사용한 원본 이미지·오디오는 함께 보관해야 한다. Preview WAV는 Builder가 내보낸 Scene JSON과 사용한 원본 이미지·오디오는 함께 보관해야 한다. Preview WAV는
scene recipe를 mono로 합친 청취 확인용 파일이며 마이크 배열의 192채널 수신 신호가 아니다. 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 정규화 ## 오디오와 map 정규화
`scene.mix.normalization`은 마이크 신호 합성 전에 적용할 오디오 mix 정책이다. `none`은 원래 `scene.mix.normalization`은 마이크 신호 합성 전에 적용할 오디오 mix 정책이다. `none`은 원래
@@ -47,10 +58,18 @@ raw DAS map을 덮어쓰지 않는다.
map은 row-major 배열이다. 첫 행은 `yMax`, 마지막 행은 `yMin`, 각 행은 `xMin`에서 `xMax` map은 row-major 배열이다. 첫 행은 `yMax`, 마지막 행은 `yMin`, 각 행은 `xMin`에서 `xMax`
방향이다. `values.length`는 반드시 `rows × columns`와 같아야 한다. 방향이다. `values.length`는 반드시 `rows × columns`와 같아야 한다.
Experiment의 선택적 `evaluation.detectionThresholdRatio`는 최강 local peak power에 대한 검출
임계 비율이며 `0 < ratio <= 1`이다. 생략된 이전 문서를 Camera에서 열면 기본값 `0.25`를 적용하며,
Experiment JSON을 다시 저장하면 이 값이 명시된다. 값을 낮추면 약한 peak 후보를 포함하지만
sidelobe false positive도 늘 수 있다.
## Result 평가 정보 ## Result 평가 정보
각 band의 `peaks`는 위치와 power 값, 선택적 `sourceId`, `localizationErrorM`, 각 band의 `peaks`는 위치와 power 값, 선택적 `sourceId`, `localizationErrorM`,
`localizationErrorPixels`를 저장한다. `metrics`에는 다음 유한값만 기록한다. `localizationErrorPixels`, `beamSpread`를 저장한다. `beamSpread`는 선택 peak를 포함하는 연결된
half-power 성분의 power 가중 centroid·공분산과 major/minor RMS 반경·각도다. `calibrated`는 현재
항상 `false`이며 확률분포, Gaussian 신뢰구간 또는 통계적 위치 불확실성으로 해석하지 않는다.
`metrics`에는 다음 유한값만 기록한다.
- `peakToSidelobeDb` - `peakToSidelobeDb`
- `energyInsideTruthRatio` - `energyInsideTruthRatio`
+15 -3
View File
@@ -3,7 +3,8 @@
> 구현 상태 · 2026-08-28 > 구현 상태 · 2026-08-28
> >
> 단계 0–4는 완료되어 설치 없는 브라우저 앱, CPU/WebGPU DAS, Builder→Camera asset 재연결, > 단계 0–4는 완료되어 설치 없는 브라우저 앱, CPU/WebGPU DAS, Builder→Camera asset 재연결,
> 배열 비교, 평가·Result 내보내기와 53개 자동 테스트로 검증했다. 단계 5는 향후 고도화 범위다. > 임의 오디오·이동 trajectory, 빔 분포·복수 peak 감도, 라이브 시간축 재생, 배열 비교와
> Result 내보내기를 71개 자동 테스트로 검증했다. 단계 5는 실제 장치·공간 모델 고도화 범위다.
## 1. 목표와 성공 기준 ## 1. 목표와 성공 기준
@@ -133,6 +134,7 @@ flattening이 모델 타당성을 훼손하는지 청취 및 spectrum 통계로
### 단계 2 — Dataset Builder · 완료 ### 단계 2 — Dataset Builder · 완료
- 이미지와 음원 파일 불러오기, 위치·시간·gain 편집, ambient mix와 미리 듣기 - 이미지와 음원 파일 불러오기, 위치·시간·gain 편집, ambient mix와 미리 듣기
- 파일 선택 한 번으로 audio asset source 생성, source별 trajectory keyframe 편집·미리보기
- deterministic seed, clipping 경고, Scene JSON과 mono Preview WAV 내보내기 - deterministic seed, clipping 경고, Scene JSON과 mono Preview WAV 내보내기
- synthetic tone/noise fixture와 로컬 asset manifest 경계 구현 - synthetic tone/noise fixture와 로컬 asset manifest 경계 구현
@@ -151,6 +153,8 @@ flattening이 모델 타당성을 훼손하는지 청취 및 spectrum 통계로
- scene/ground truth/acoustic overlay, 배열 geometry, parameter panel 구현 - scene/ground truth/acoustic overlay, 배열 geometry, parameter panel 구현
- 결과 metric, 실행 환경, 입력 hash와 map 내보내기 - 결과 metric, 실행 환경, 입력 hash와 map 내보내기
- 복수 음원·다중 대역 표시와 실험 preset 비교 - 복수 음원·다중 대역 표시와 실험 preset 비교
- peak별 half-power 공분산/RMS 빔 분포와 재현 가능한 검출 임계값
- sample-aligned 준정적 시간창 분석, bounded map 계획과 이동 장면 재생
완료 조건: 사용자가 코드 수정 없이 배열 JSON 두 개를 같은 장면에서 비교할 수 있다. 완료 조건: 사용자가 코드 수정 없이 배열 JSON 두 개를 같은 장면에서 비교할 수 있다.
@@ -158,6 +162,7 @@ flattening이 모델 타당성을 훼손하는지 청취 및 spectrum 통계로
- 라이선스 검토를 통과한 DCASE/MIMII adapter와 batch workflow 추가 - 라이선스 검토를 통과한 DCASE/MIMII adapter와 batch workflow 추가
- microphone calibration·noise 모델 검토 - microphone calibration·noise 모델 검토
- 실제 192채널 장치의 channel/clock/sample 형식이 정해진 뒤 capture·stream adapter 추가
- 필요 시 DAMAS/CLEAN-SC를 플러그인형 후처리로 추가 - 필요 시 DAMAS/CLEAN-SC를 플러그인형 후처리로 추가
- image-source method 또는 room impulse response 기반 잔향 모듈 추가 - image-source method 또는 room impulse response 기반 잔향 모듈 추가
@@ -167,8 +172,9 @@ flattening이 모델 타당성을 훼손하는지 청취 및 spectrum 통계로
- WebGPU 미지원/장치 한도: 시작 시 capability를 표시하고 CPU fallback 및 grid 상한을 둔다. - WebGPU 미지원/장치 한도: 시작 시 capability를 표시하고 CPU fallback 및 grid 상한을 둔다.
- 좌표·phase 부호 오류: analytic tone test와 배열 대칭성 test를 먼저 만든다. - 좌표·phase 부호 오류: analytic tone test와 배열 대칭성 test를 먼저 만든다.
- 브라우저 메모리: 현재 전체 192채널 signal buffer에 512 MiB 한도를 적용한다. 장시간 입력은 - 브라우저 메모리: snapshot은 전체 192채널 signal buffer에 512 MiB 한도를 적용하고, 이동
향후 chunk/STFT streaming backend로 확장한다. 미리보기는 최대 48개·2,500 points의 짧은 시간창으로 제한한다. 실제 장시간 capture는 향후
chunk/STFT streaming backend로 확장한다.
- 데이터셋 부적합/라이선스: 로컬 asset 계약을 유지하고 synthetic fixture를 기본 test 입력으로 - 데이터셋 부적합/라이선스: 로컬 asset 계약을 유지하고 synthetic fixture를 기본 test 입력으로
쓴다. 실제 데이터 adapter는 단계 5의 라이선스 검토 뒤 추가한다. 쓴다. 실제 데이터 adapter는 단계 5의 라이선스 검토 뒤 추가한다.
- 실제 AC와 simulation gap: 감도, 위상, 위치 오차를 이후 calibration/noise model로 주입 가능하게 한다. - 실제 AC와 simulation gap: 감도, 위상, 위치 오차를 이후 calibration/noise model로 주입 가능하게 한다.
@@ -183,7 +189,13 @@ flattening이 모델 타당성을 훼손하는지 청취 및 spectrum 통계로
- [x] WGSL kernel, CPU/GPU 비교와 50²/100²/200² benchmark - [x] WGSL kernel, CPU/GPU 비교와 50²/100²/200² benchmark
- [x] scene canvas, array view, parameter controls와 Result export - [x] scene canvas, array view, parameter controls와 Result export
- [x] Builder→Camera SHA-256 asset 재연결 왕복 테스트 - [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 - [ ] DCASE/MIMII 라이선스 검토와 adapter
- [ ] 실제 192채널 capture/stream adapter
- [ ] 잔향·calibration·noise model - [ ] 잔향·calibration·noise model
- [ ] DAMAS/CLEAN-SC 후처리 - [ ] DAMAS/CLEAN-SC 후처리
+45 -8
View File
@@ -16,6 +16,7 @@
<a class="guide-brand" href="/">← micarrsim 홈</a> <a class="guide-brand" href="/">← micarrsim 홈</a>
<nav aria-label="문서 목차"> <nav aria-label="문서 목차">
<a href="#quick-start">빠른 시작</a> <a href="#quick-start">빠른 시작</a>
<a href="#moving-live">이동 라이브</a>
<a href="#full-workflow">내 데이터</a> <a href="#full-workflow">내 데이터</a>
<a href="#results">결과 해석</a> <a href="#results">결과 해석</a>
<a href="#troubleshooting">문제 해결</a> <a href="#troubleshooting">문제 해결</a>
@@ -52,16 +53,34 @@
</div> </div>
</section> </section>
<section class="guide-section" id="full-workflow"> <section class="guide-section" id="moving-live">
<div class="section-number">02</div> <div class="section-number">02</div>
<div>
<p class="eyebrow">Moving-source demo</p>
<h2>이동 음원을 바로 재생하기</h2>
<ol class="guide-steps">
<li><a href="/apps/acoustic-camera/">Acoustic Camera</a>에서 <strong>이동 예제</strong>를 누릅니다.</li>
<li><strong>라이브 준비</strong>를 눌러 기본 2 Hz map을 계산합니다.</li>
<li><strong>재생</strong>을 누르거나 시간 slider를 움직입니다.</li>
</ol>
<aside class="callout">
짧은 시간창마다 계산한 heatmap과 trajectory 위치를 보간하는 합성 장면 미리보기입니다.
실제 192채널 마이크 스트림을 녹음하는 기능은 아닙니다.
</aside>
</div>
</section>
<section class="guide-section" id="full-workflow">
<div class="section-number">03</div>
<div> <div>
<p class="eyebrow">5분 전체 흐름</p> <p class="eyebrow">5분 전체 흐름</p>
<h2>내 장면을 만들고 Camera에서 실행하기</h2> <h2>내 장면을 만들고 Camera에서 실행하기</h2>
<ol class="guide-steps"> <ol class="guide-steps">
<li> <li>
<a href="/apps/dataset-builder/">Dataset Builder</a>에서 이미지와 오디오를 <a href="/apps/dataset-builder/">Dataset Builder</a>에서 <strong>+ 오디오 파일 음원</strong>
선택하고 음원 위치, gain, 시간, ambient를 설정합니다. 또는 합성 음원을 추가하고 위치, gain, 시간과 ambient를 설정합니다.
</li> </li>
<li>움직이는 source는 <strong>시간에 따라 음원 이동</strong>을 켜고 keyframe을 편집합니다.</li>
<li><strong>Scene JSON 저장</strong>을 누르고 사용한 원본 파일과 함께 보관합니다.</li> <li><strong>Scene JSON 저장</strong>을 누르고 사용한 원본 파일과 함께 보관합니다.</li>
<li><strong>Scene 저장 후 Camera 열기</strong>를 누릅니다.</li> <li><strong>Scene 저장 후 Camera 열기</strong>를 누릅니다.</li>
<li> <li>
@@ -91,7 +110,7 @@
</section> </section>
<section class="guide-section"> <section class="guide-section">
<div class="section-number">03</div> <div class="section-number">04</div>
<div> <div>
<p class="eyebrow">Compute backend</p> <p class="eyebrow">Compute backend</p>
<h2>속도와 격자 선택</h2> <h2>속도와 격자 선택</h2>
@@ -109,23 +128,33 @@
먼저 50×50을 권장합니다. 100×100은 4배, 200×200은 16배의 scan point를 계산합니다. 먼저 50×50을 권장합니다. 100×100은 4배, 200×200은 16배의 scan point를 계산합니다.
실행 중에는 취소할 수 있으며, 취소하거나 실패해도 이전 완료 결과는 유지됩니다. 실행 중에는 취소할 수 있으며, 취소하거나 실패해도 이전 완료 결과는 유지됩니다.
</p> </p>
<p class="guide-copy">
복수 음원에서 약한 peak가 빠지면 <strong>Peak 검출 임계값</strong>을 기본 25%에서
10–20%로 낮춰 보세요. 약한 후보와 함께 sidelobe 오검출도 늘 수 있으며, main lobe보다
가까운 같은 대역 음원은 conventional DAS에서 하나로 합쳐질 수 있습니다.
</p>
</div> </div>
</section> </section>
<section class="guide-section" id="results"> <section class="guide-section" id="results">
<div class="section-number">04</div> <div class="section-number">05</div>
<div> <div>
<p class="eyebrow">Result JSON</p> <p class="eyebrow">Result JSON</p>
<h2>무엇이 저장되나요?</h2> <h2>무엇이 저장되나요?</h2>
<dl class="result-list"> <dl class="result-list">
<div><dt>rawMap / displayMap</dt><dd>선형 power 원본과 화면 표시용 acoustic map</dd></div> <div><dt>rawMap / displayMap</dt><dd>선형 power 원본과 화면 표시용 acoustic map</dd></div>
<div><dt>peaks</dt><dd>검출 위치, source 매칭, m·pixel 위치 오차</dd></div> <div><dt>peaks</dt><dd>검출 위치, source 매칭, m·pixel 위치 오차</dd></div>
<div><dt>beamSpread</dt><dd>half-power lobe의 power 가중 공분산과 1× RMS ellipse</dd></div>
<div><dt>metrics</dt><dd>energy 비율, precision/recall, sidelobe, main-lobe 폭</dd></div> <div><dt>metrics</dt><dd>energy 비율, precision/recall, sidelobe, main-lobe 폭</dd></div>
<div><dt>evaluation</dt><dd>검출 threshold, 반경, tolerance 등 지표 계산 조건</dd></div> <div><dt>evaluation</dt><dd>검출 threshold, 반경, tolerance 등 지표 계산 조건</dd></div>
<div><dt>timing / environment</dt><dd>backend, grid·scan 범위, 장치 정보와 구간별 시간</dd></div> <div><dt>timing / environment</dt><dd>backend, grid·scan 범위, 장치 정보와 구간별 시간</dd></div>
<div><dt>inputHash</dt><dd>Array·Scene·Experiment 입력을 묶은 SHA-256 재현성 식별자</dd></div> <div><dt>inputHash</dt><dd>Array·Scene·Experiment 입력을 묶은 SHA-256 재현성 식별자</dd></div>
<div><dt>comparison-history</dt><dd>세션의 배열별 시간·위치 오차·PSR 요약을 한 번에 저장</dd></div> <div><dt>comparison-history</dt><dd>세션의 배열별 시간·위치 오차·PSR 요약을 한 번에 저장</dd></div>
</dl> </dl>
<aside class="callout">
화면의 <strong>빔 분포</strong> 1×/2× RMS contour는 acoustic power lobe의 모양입니다.
위치 확률, Gaussian 신뢰구간 또는 보정된 측정 불확실성이 아닙니다.
</aside>
<aside class="callout"> <aside class="callout">
평가는 tone 음원을 해당 주파수 대역이 tone 주파수를 포함할 때만 정답으로 사용합니다. 평가는 tone 음원을 해당 주파수 대역이 tone 주파수를 포함할 때만 정답으로 사용합니다.
noise와 asset 음원은 현재 모든 대역의 정답으로 간주합니다. 녹음 파일의 실제 대역별 noise와 asset 음원은 현재 모든 대역의 정답으로 간주합니다. 녹음 파일의 실제 대역별
@@ -140,7 +169,7 @@
</section> </section>
<section class="guide-section" id="troubleshooting"> <section class="guide-section" id="troubleshooting">
<div class="section-number">05</div> <div class="section-number">06</div>
<div> <div>
<p class="eyebrow">Troubleshooting</p> <p class="eyebrow">Troubleshooting</p>
<h2>막혔을 때 확인할 것</h2> <h2>막혔을 때 확인할 것</h2>
@@ -164,18 +193,26 @@
<summary>WebGPU가 없거나 실행이 너무 느립니다.</summary> <summary>WebGPU가 없거나 실행이 너무 느립니다.</summary>
<p>Backend를 Auto 또는 CPU로 두고 50×50 grid부터 실행하세요. 최신 Chrome/Edge와 그래픽 드라이버도 확인하세요.</p> <p>Backend를 Auto 또는 CPU로 두고 50×50 grid부터 실행하세요. 최신 Chrome/Edge와 그래픽 드라이버도 확인하세요.</p>
</details> </details>
<details>
<summary>두 번째 음원을 찾지 못합니다.</summary>
<p>두 음원이 같은 주파수 대역인지 확인하고 Peak 검출 임계값을 낮추세요. gain 차이, main-lobe 폭보다 짧은 거리, grid 간격과 sidelobe는 threshold만으로 해결되지 않을 수 있습니다.</p>
</details>
<details>
<summary>라이브 준비 버튼이 비활성화됩니다.</summary>
<p>Scene에 시간 순서가 올바른 trajectory keyframe이 두 개 이상 있어야 합니다. Builder에서 시간에 따라 음원 이동을 켜거나 Camera의 이동 예제를 사용하세요.</p>
</details>
</div> </div>
</section> </section>
<section class="guide-section"> <section class="guide-section">
<div class="section-number">06</div> <div class="section-number">07</div>
<div> <div>
<p class="eyebrow">Scope & privacy</p> <p class="eyebrow">Scope & privacy</p>
<h2>현재 모델의 범위</h2> <h2>현재 모델의 범위</h2>
<p class="guide-copy"> <p class="guide-copy">
micarrsim 1.0은 점 음원, 구면 감쇠·분수 지연을 쓰는 자유음장 모델과 conventional micarrsim 1.0은 점 음원, 구면 감쇠·분수 지연을 쓰는 자유음장 모델과 conventional
DAS를 제공합니다. 실내 반사·잔향, 실제 마이크 위치 오차와 비선형성, DAMAS, DAS를 제공합니다. 실내 반사·잔향, 실제 마이크 위치 오차와 비선형성, DAMAS,
CLEAN-SC, DCASE/MIMII 자동 adapter는 현재 범위에 포함되지 않습니다. 결과는 실제 CLEAN-SC, DCASE/MIMII 자동 adapter와 실제 192채널 capture stream은 현재 범위에 포함되지 않습니다. 결과는 실제
장비의 절대 성능 보증이 아니라 같은 조건에서 배열을 비교하는 재현 가능한 기준입니다. 장비의 절대 성능 보증이 아니라 같은 조건에서 배열을 비교하는 재현 가능한 기준입니다.
</p> </p>
<p class="guide-copy"> <p class="guide-copy">
+7 -1
View File
@@ -59,7 +59,7 @@
<span class="launcher-card__number">02</span> <span class="launcher-card__number">02</span>
<div> <div>
<h2>Acoustic Camera</h2> <h2>Acoustic Camera</h2>
<p>배열 응답을 계산하고 주파수 대역별 DAS 결과를 ground truth와 비교합니다.</p> <p>배열 응답과 DAS 결과를 비교하고 이동 음원의 acoustic map을 시간축으로 재생합니다.</p>
</div> </div>
<span class="launcher-card__action">기본 예제로 바로 실행 →</span> <span class="launcher-card__action">기본 예제로 바로 실행 →</span>
</a> </a>
@@ -72,6 +72,12 @@
<p>Acoustic Camera를 열어 <strong>▶ 기본 예제 실행</strong>을 누르고, 완료되면 <strong>Result JSON</strong>을 저장하세요.</p> <p>Acoustic Camera를 열어 <strong>▶ 기본 예제 실행</strong>을 누르고, 완료되면 <strong>Result JSON</strong>을 저장하세요.</p>
<a href="/apps/acoustic-camera/">기본 예제 열기 →</a> <a href="/apps/acoustic-camera/">기본 예제 열기 →</a>
</article> </article>
<article class="quick-start-card">
<p class="eyebrow">이동 음원</p>
<h2>설정 없이 라이브 재생</h2>
<p>Camera에서 <strong>이동 예제 → 라이브 준비 → 재생</strong>만 누르면 됩니다.</p>
<a href="/apps/acoustic-camera/">이동 예제 열기 →</a>
</article>
<article class="quick-start-card"> <article class="quick-start-card">
<p class="eyebrow">내 데이터</p> <p class="eyebrow">내 데이터</p>
<h2>Builder부터 끝까지</h2> <h2>Builder부터 끝까지</h2>
+16
View File
@@ -8,6 +8,22 @@
- radix-2 FFT, Hann STFT와 선택 bin 추출 - radix-2 FFT, Hann STFT와 선택 bin 추출
- scan grid 거리 cache 및 conventional frequency-domain DAS - scan grid 거리 cache 및 conventional frequency-domain DAS
## 이동 음원과 분석 시간창
`sourcePositionAtTime`은 scene 시작 기준의 절대 시각에서 trajectory keyframe 사이를 선형 보간하며,
경로 범위 밖에서는 가장 가까운 끝점 위치를 유지합니다. `sampleQuasiStaticWindow`는 요청 경계를
sample 경계로 올림 정렬하고, 시간창 중앙의 위치에서 이동 음원을 정지한 것으로 근사합니다.
시간창은 활성 source만 잘라 짧은 Scene으로 만들지만 `signalOffsets`에 원래 scene/source의 절대 sample
offset을 보존합니다. 이를 `synthesizeMicrophoneSignals`에 전달하면 각 창을 따로 합성해도 tone phase,
seed 기반 noise index, audio asset 재생 위치와 ambient가 전체 timeline 합성과 연속됩니다.
## Beam spread 의미
Peak의 `beamSpread`는 half-power 연결 성분을 power 가중한 공간 covariance(`covarianceM2`, m²)와 그
RMS 주축 ellipse로 요약한 빔 폭입니다. 가우시안 확률 모델, 위치 확률 또는 신뢰구간으로 보정된 값이
아니며 `calibrated: false`를 유지합니다.
FFT는 `X[k] = Σ x[n] exp(-j2πkn/N)` 규약을 사용합니다. 마이크 신호의 전파 phase FFT는 `X[k] = Σ x[n] exp(-j2πkn/N)` 규약을 사용합니다. 마이크 신호의 전파 phase
`exp(-j2πfr/c)`를 정렬하기 위해 DAS steering은 `exp(+j2πfr/c)`를 곱합니다. 단일 tone의 `exp(-j2πfr/c)`를 정렬하기 위해 DAS steering은 `exp(+j2πfr/c)`를 곱합니다. 단일 tone의
ground-truth 위치에서 peak가 생기는 회귀 테스트로 이 부호를 고정합니다. ground-truth 위치에서 peak가 생기는 회귀 테스트로 이 부호를 고정합니다.
+1 -1
View File
@@ -264,7 +264,7 @@ p {
.quick-start-grid { .quick-start-grid {
display: grid; display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 18px; gap: 18px;
margin-top: 18px; margin-top: 18px;
} }
+3 -3
View File
@@ -5,8 +5,8 @@
JSON Schema Draft 2020-12 형식입니다. JSON Schema Draft 2020-12 형식입니다.
- `array.schema.json`: 배열 크기, 좌표계, 마이크 위치와 선택적 보정값 - `array.schema.json`: 배열 크기, 좌표계, 마이크 위치와 선택적 보정값
- `scene.schema.json`: 재현 가능한 음원 recipe, asset 참조와 ground-truth 위치 - `scene.schema.json`: 재현 가능한 음원 recipe, asset 참조, 정적 위치와 선택적 trajectory
- `experiment.schema.json`: scan plane/grid, 주파수 대역, STFT와 DAS 설정 - `experiment.schema.json`: scan plane/grid, 주파수 대역, STFT/DAS와 peak 검출 임계값
- `result.schema.json`: raw/display/후처리 map, 복수 peak, 실행 timing과 평가 지표 - `result.schema.json`: raw/display/후처리 map, 복수 peak, 비확률 beam spread, timing과 평가 지표
중복 id, Nyquist, 시간 구간과 참조 무결성은 `packages/contracts/validation.js`에서 추가로 검증합니다. 중복 id, Nyquist, 시간 구간과 참조 무결성은 `packages/contracts/validation.js`에서 추가로 검증합니다.
+8 -5
View File
@@ -4,9 +4,11 @@
## 실행 ## 실행
1. 저장소의 `start.cmd`를 실행합니다. 가장 간단한 자동 실행은 저장소 루트의 `test.cmd`입니다. 임시 local server와 headless Edge/Chrome을
2. 최신 Edge 또는 Chrome에서 <http://127.0.0.1:4173/tests/>을 엽니다. 실행하고 전체 browser suite가 끝나면 결과에 맞는 process exit code를 반환합니다.
3. 모든 항목이 끝날 때까지 페이지를 열어 둡니다.
수동 확인은 `start.cmd`를 실행한 뒤 최신 Edge 또는 Chrome에서
<http://127.0.0.1:4173/tests/>을 열고 모든 항목이 끝날 때까지 페이지를 유지합니다.
Unit과 integration test가 같은 페이지에서 실행됩니다. WebGPU 장치 초기화와 192채널 baseline은 Unit과 integration test가 같은 페이지에서 실행됩니다. WebGPU 장치 초기화와 192채널 baseline은
수 초 이상 걸릴 수 있습니다. 페이지 제목과 요약이 `PASS`인지 확인하고 실패 항목의 stack을 수 초 이상 걸릴 수 있습니다. 페이지 제목과 요약이 `PASS`인지 확인하고 실패 항목의 stack을
@@ -19,8 +21,9 @@ Unit과 integration test가 같은 페이지에서 실행됩니다. WebGPU 장
adapter가 없으면 Auto CPU fallback adapter가 없으면 Auto CPU fallback
- `server.test.js`: 숨김 저장소 경로 차단, GET/HEAD 제한과 보안 response headers - `server.test.js`: 숨김 저장소 경로 차단, GET/HEAD 제한과 보안 response headers
- `builder-ui.test.js`: 파일 선택 한 번으로 오디오 음원 생성, 이미지·오디오 연결, canvas 편집, - `builder-ui.test.js`: 파일 선택 한 번으로 오디오 음원 생성, 이미지·오디오 연결, canvas 편집,
Preview WAV/Scene 다운로드, SHA 재연결과 잘못된 import 보존 trajectory keyframe 편집, Preview WAV/Scene 다운로드, SHA 재연결과 잘못된 import 보존
- `camera-ui.test.js`: Dedicated Worker CPU/WebGPU 실행, 취소, Result schema, rectangular/Fermat 비교 - `camera-ui.test.js`: Dedicated Worker CPU/WebGPU 실행, 취소, Result schema, rectangular/Fermat 비교;
이동 예제 로드, 8×8 CPU·2 Hz live map 준비, 복수 frame, scrub, 재생 시간 증가와 일시정지
- `workflow-ui.test.js`: Dataset Builder의 Scene JSON과 원본 assets를 Acoustic Camera에 넘겨 - `workflow-ui.test.js`: Dataset Builder의 Scene JSON과 원본 assets를 Acoustic Camera에 넘겨
Result JSON을 저장하는 end-to-end 흐름 Result JSON을 저장하는 end-to-end 흐름
+12 -8
View File
@@ -5,9 +5,11 @@
## 실행 ## 실행
1. 저장소의 `start.cmd`를 실행합니다. 가장 간단한 자동 실행은 저장소 루트의 `test.cmd`입니다. 임시 local server와 headless Edge/Chrome을
2. 최신 Edge 또는 Chrome에서 <http://127.0.0.1:4173/tests/>을 엽니다. 실행하고 결과에 맞는 process exit code를 반환합니다.
3. 페이지 상단의 통과/실패 합계와 각 테스트 결과를 확인합니다.
수동 확인은 `start.cmd`를 실행한 뒤 최신 Edge 또는 Chrome에서
<http://127.0.0.1:4173/tests/>을 열어 페이지 상단의 통과/실패 합계와 각 결과를 확인합니다.
Unit과 integration module은 같은 browser runner에서 순서대로 실행됩니다. 다시 실행하려면 페이지를 Unit과 integration module은 같은 browser runner에서 순서대로 실행됩니다. 다시 실행하려면 페이지를
새로 고치세요. 다른 포트를 사용했다면 URL의 포트도 바꾸며, `tests/index.html`을 파일로 직접 열면 새로 고치세요. 다른 포트를 사용했다면 URL의 포트도 바꾸며, `tests/index.html`을 파일로 직접 열면
@@ -15,11 +17,13 @@ Unit과 integration module은 같은 browser runner에서 순서대로 실행됩
## 범위 ## 범위
- `contracts.test.js`: Array·Scene·Experiment·Result schema, 관계 검증, 안전한 asset 경로와 fixture - `contracts.test.js`: Array·Scene·Experiment·Result schema, 관계 검증, 안전한 asset 경로와 이동 fixture
- `acoustics.test.js`: seed 재현성, mix/정규화, 자유음장 전파, calibration, STFT와 CPU DAS - `acoustics.test.js`: seed 재현성, 자유음장 전파, trajectory 보간, sample 정렬 시간창과
- `builder.test.js`: Builder scene model, source/asset 조작, 오디오 크기와 WAV 사전 검증 tone/noise/asset 절대 시간 연속성, calibration, STFT와 CPU DAS
- `evaluation.test.js`: local peak, truth matching, 위치 오차, energy, sidelobe와 main-lobe 지표 - `builder.test.js`: Builder scene model, source/asset·trajectory 조작, 오디오 크기와 WAV 사전 검증
- `camera.test.js`: canonical input hash, workload 추정, 거리 이동, Result 생성과 schema 검증 - `evaluation.test.js`: local peak와 검출 감도, truth matching, energy/sidelobe/main-lobe 및 비확률적
beam-spread covariance ellipse
- `camera.test.js`: canonical input hash, workload 추정, 이동 timeline 계획·재생 보간, Result schema 검증
- `webgpu.test.js`: WGSL buffer packing, bin/point batching, 장치 한계와 typed CPU fallback 정책 - `webgpu.test.js`: WGSL buffer packing, bin/point batching, 장치 한계와 typed CPU fallback 정책
WebGPU unit test 대부분은 실제 GPU 없이 planner와 binary layout을 검증합니다. 실제 GPU 수치 일치는 WebGPU unit test 대부분은 실제 GPU 없이 planner와 binary layout을 검증합니다. 실제 GPU 수치 일치는