docs: add quick start and user guides

This commit is contained in:
Codex
2026-08-28 12:47:57 +09:00
parent 3317a03d1a
commit 513de2b51f
16 changed files with 1148 additions and 65 deletions
+90 -1
View File
@@ -1,3 +1,92 @@
# Acoustic Camera
scene과 마이크 배열을 불러와 자유음장 전파, WGSL DAS 빔포밍, overlay 및 평가를 수행하는 앱입니다.
Scene과 마이크 배열로 자유음장 microphone signal을 합성하고, STFT와 conventional DAS를 통해
주파수 대역별 acoustic map과 ground-truth 평가 지표를 만드는 브라우저 앱입니다.
## 열기와 기본 예제
저장소의 `start.cmd`를 실행한 뒤 시작 화면에서 **Acoustic Camera**를 선택하거나
<http://127.0.0.1:4173/apps/acoustic-camera/>을 엽니다. `index.html`을 직접 열지 마세요.
가장 빠른 확인 방법은 다음과 같습니다.
1. 기본 fixture가 준비될 때까지 기다립니다.
2. 192채널 rectangular 배열, single-tone scene과 50×50 grid를 그대로 둡니다.
3. **기본 예제 실행**을 누릅니다.
4. 완료 후 overlay, 위치 오차와 timing을 확인하고 **Result JSON**을 저장합니다.
## 사용자 입력 불러오기
문서는 다음 순서로 불러오는 것이 안전합니다.
1. **Scene**: `.scene.json`
2. **Array**: 선택 사항인 `.array.json`; 또는 **비교 배열** preset 사용
3. **Experiment**: 선택 사항인 `.experiment.json`
4. **Assets**: Scene이 참조하는 원본 이미지와 오디오
Scene을 불러오면 현재 Experiment의 `sceneId`와 scan plane을 Scene에 맞추고 기존 asset 연결을
해제합니다. Array를 불러오면 현재 Experiment의 `arrayId`를 맞춥니다. 별도 Experiment는 현재
Scene과 Array를 참조해야 하므로 마지막에 불러오세요.
Scene JSON에는 원본 파일 byte가 없습니다. **Assets**에서 Builder에 사용한 파일을 다시 선택하면
Camera가 SHA-256을 계산해 manifest에 연결합니다. 같은 이름이라도 내용이 바뀌면 거절됩니다.
브라우저를 다시 열거나 Scene을 바꿀 때도 재선택해야 합니다.
- asset 한 파일: 최대 128 MiB
- 연결된 asset 합계: 최대 512 MiB
- decode되어 메모리에 유지되는 오디오 합계: 최대 192 MiB
파일은 외부로 업로드되지 않고 브라우저 메모리에서만 처리됩니다.
## Backend 선택
- **Auto (GPU→CPU)**: 권장. WebGPU를 먼저 시도하고 adapter/device 부재나 지원되는 장치 한계가
있으면 CPU로 계속합니다.
- **WebGPU 강제**: GPU만 사용하며 운용 오류가 나도 CPU로 fallback하지 않습니다.
- **CPU 강제**: CPU 수치 기준이나 WebGPU가 없는 환경에서 사용합니다.
WebGPU가 감지돼도 실제 장치는 실행 시 확인합니다. 계산 중 **계산 취소**를 누르면 Worker를
종료하며, 이미 완료된 이전 결과가 있으면 그대로 남습니다.
## Grid, STFT와 대역
50×50은 2,500 points입니다. 이를 1로 보면 100×100은 4배, 200×200은 16배 points를 계산합니다.
처음에는 50×50을 권장합니다. 실행량은 microphone 수, scene 길이, FFT/hop과 선택 band의 bin
수에도 비례하므로 실제 시간 배율은 장치마다 다릅니다.
각 band는 id, 최소/최대 Hz와 overlay 색을 가집니다. Nyquist를 넘거나 겹치는 id 등 계약 오류는
실행 전에 표시됩니다. 현재 후처리는 raw DAS만 지원하며 DAMAS와 CLEAN-SC 항목은 비활성화되어
있습니다.
## 화면과 배열 비교
- acoustic overlay의 투명도와 표시할 band를 선택할 수 있습니다.
- **Ground truth**를 켜면 source 위치와 검출 peak를 비교할 수 있습니다.
- rectangular와 Fermat spiral preset을 같은 Scene/Experiment에서 연속 실행하면 **배열 비교 기록**에
backend, timing과 평가 요약이 남습니다.
- 입력을 바꾼 뒤 화면에 남은 결과는 이전 실행 snapshot이며 UI가 이전 설정 결과임을 표시합니다.
## Result JSON
**Result JSON**은 검증을 통과한 `micarrsim.result` 문서만 저장합니다.
- `experimentId`, `arrayId`, `sceneId`, `createdAt`, 실제 `backend`
- 실행 입력 전체의 canonical SHA-256인 `inputHash`
- `signalStats`: 정규화 전 peak, 적용 scale, clipped sample 수
- `timingMs`: 전체, signal generation과 beamforming 시간
- band별 `rawMap` 선형 power, `displayMap`, 검출 `peaks`
- 평가 설정과 `peakToSidelobeDb`, `energyInsideTruthRatio`, `precision`, `recall`,
`mainLobeWidthM`
Tone source는 그 주파수가 band 범위 안에 있을 때만 해당 band의 ground truth입니다. Audio asset과
noise source는 스펙트럼을 사전에 판별하지 않으므로 모든 band의 ground truth로 평가합니다. Source
z가 scan z와 다르면 평면에 투영한 x/y를 사용하므로 UI 경고와 위치 오차를 함께 해석하세요.
## 해석 한계
신호 모델은 직접 경로와 거리 감쇠를 사용하는 자유음장입니다. 반사, 잔향, 회절, 차폐, 바람,
센서 비선형과 장착 구조는 포함하지 않습니다. 배열 JSON의 sensitivity/phase calibration은 적용하지만
결과는 상대 배열 비교와 알고리즘 검증용이며 실측 인증을 대신하지 않습니다.
WebGPU 성능을 별도로 측정하려면 서버 실행 후
<http://127.0.0.1:4173/benchmarks/webgpu-scaling.html>을 여세요.
+8 -5
View File
@@ -31,11 +31,14 @@
<h1 id="workspace-title">음향 장면</h1>
<p class="workspace-meta" id="scene-meta">장면을 불러오고 있습니다.</p>
</div>
<div class="workspace-tools" aria-label="입력 파일">
<label class="button button--ghost file-button">Scene<input id="scene-input" type="file" accept="application/json,.json" /></label>
<label class="button button--ghost file-button">Array<input id="array-input" type="file" accept="application/json,.json" /></label>
<label class="button button--ghost file-button">Experiment<input id="experiment-input" type="file" accept="application/json,.json" /></label>
<label class="button button--ghost file-button">Assets<input id="asset-input" type="file" accept="audio/*,image/*,.wav,.flac,.mp3,.ogg,.m4a,.png,.jpg,.jpeg,.webp,.svg" multiple /></label>
<div class="workspace-import">
<div class="workspace-tools" aria-label="입력 파일">
<label class="button button--ghost file-button" title="1. Scene JSON을 먼저 선택하세요.">Scene<input id="scene-input" type="file" accept="application/json,.json" /></label>
<label class="button button--ghost file-button" title="2. 사용자 배열이 있을 때 Array JSON을 선택하세요.">Array<input id="array-input" type="file" accept="application/json,.json" /></label>
<label class="button button--ghost file-button" title="3. 현재 Scene과 Array를 참조하는 Experiment JSON을 선택하세요.">Experiment<input id="experiment-input" type="file" accept="application/json,.json" /></label>
<label class="button button--ghost file-button" title="4. Scene에 사용한 원본 파일을 다시 선택하세요.">Assets<input id="asset-input" type="file" accept="audio/*,image/*,.wav,.flac,.mp3,.ogg,.m4a,.png,.jpg,.jpeg,.webp,.svg" multiple /></label>
</div>
<p class="import-order">권장 순서 · Scene → Array → Experiment → Assets</p>
</div>
</div>
+3
View File
@@ -17,7 +17,9 @@
.workspace-heading .eyebrow, .section-heading .eyebrow, .array-heading .eyebrow { margin-bottom: 7px; }
.workspace-heading h1 { margin-bottom: 4px; font-size: clamp(1.9rem, 4vw, 3.2rem); letter-spacing: -.055em; }
.workspace-meta, .section-copy { margin: 0; color: var(--muted); font-size: .76rem; line-height: 1.55; }
.workspace-import { display: grid; gap: 7px; justify-items: end; }
.workspace-tools { justify-content: flex-end; }
.import-order { margin: 0; color: var(--muted); font-size: .64rem; }
.scene-canvas-card { position: relative; overflow: hidden; min-height: 520px; border: 1px solid var(--line); border-radius: 22px; background: #07110f; box-shadow: var(--shadow); }
#scene-canvas { display: block; width: 100%; height: clamp(520px, 64vh, 760px); }
.canvas-message { position: absolute; top: 32px; left: 50%; display: grid; width: min(440px, calc(100% - 48px)); gap: 6px; color: var(--muted); text-align: center; pointer-events: none; transform: translateX(-50%); }
@@ -109,6 +111,7 @@
.camera-header, .workspace-heading { align-items: stretch; }
.camera-header { position: static; display: flex; flex-direction: column; }
.header-status, .header-actions, .workspace-tools { justify-content: flex-start; width: 100%; }
.workspace-import { justify-items: start; }
.header-actions .button, .workspace-tools .button { flex: 1 1 calc(50% - 5px); }
.scene-workspace { padding: 18px; }
.workspace-heading { flex-direction: column; }
+63 -1
View File
@@ -1,3 +1,65 @@
# Dataset Builder
음원, ambient audio, 이미지상의 위치를 조합해 scene audio와 ground truth manifest를 만드는 앱입니다.
이미지 평면에 source ground truth를 배치하고 tone, noise, 로컬 audio asset과 ambient를 조합해
재현 가능한 `micarrsim.scene` JSON을 만드는 브라우저 앱입니다.
## 열기
저장소의 `start.cmd`를 실행한 뒤 시작 화면에서 **Dataset Builder**를 선택하거나
<http://127.0.0.1:4173/apps/dataset-builder/>을 엽니다. `index.html`을 직접 열면 module과 Worker가
동작하지 않습니다.
## 기본 사용법
1. **배경 이미지**를 선택하거나 이미지 없이 grid를 사용합니다.
2. **오디오 추가**로 source 또는 ambient에 사용할 파일을 연결합니다.
3. **+ 음원 추가**를 누르고 카드를 선택한 뒤 canvas를 클릭하거나 x/y/z를 입력합니다.
4. source 종류를 설정합니다.
- `Tone`: 주파수와 위상을 갖는 합성 정현파
- `Noise`: seed로 재현되는 white 또는 pink noise
- `Audio asset`: 선택한 파일의 channel을 사용하며 짧은 파일은 반복 가능
5. 필요하면 ambient 종류와 gain을 설정합니다.
6. 검증 카드가 **저장 가능한 장면**이면 **Scene JSON 저장**을 누릅니다.
길이, sample rate, 음속, seed와 mix 정규화도 Scene JSON에 저장됩니다. 이미지가 있으면 표시
평면의 x/y 범위, z와 image pixel 크기가 ground truth 좌표 변환에 사용됩니다.
## 미리 듣기와 Preview WAV
**미리 듣기**는 현재 mix를 브라우저에서 재생합니다. **Preview WAV 저장**은 모든 source와
ambient를 공간 정보 없이 합친 mono PCM16 확인용 파일입니다. 마이크별 전파 지연이 적용된
192채널 녹음이나 acoustic-camera 결과가 아닙니다.
클리핑이 예상되면 저장 전에 경고합니다. 출력이 너무 크면 scene 길이 또는 sample rate를 줄이거나
source gain과 mix 정규화를 조절하세요.
## Scene JSON과 assets
Scene JSON은 오디오·이미지 원본을 포함하지 않고 asset manifest만 기록합니다. 각 descriptor에는
id, 종류, 파일명과 SHA-256이 들어갑니다.
- 파일 한 개는 최대 128 MiB, 연결 파일 합계는 최대 512 MiB입니다.
- decode된 오디오의 합계는 최대 192 MiB입니다.
- Scene을 다시 불러오면 브라우저 권한이 없으므로 원본 이미지와 오디오를 다시 선택해야 합니다.
- 같은 이름의 파일도 SHA-256이 manifest와 다르면 기존 asset으로 연결되지 않습니다.
- 사용 중인 asset은 먼저 source, ambient 또는 image 참조를 바꾼 뒤 제거할 수 있습니다.
원본 파일은 외부로 업로드되지 않고 브라우저 메모리에서만 처리됩니다. 단, JSON에는 파일명이
남을 수 있으므로 공유 전에 확인하세요.
## Acoustic Camera로 넘기기
1. Scene JSON과 사용한 원본 assets를 함께 보관합니다.
2. Acoustic Camera에서 **Scene**으로 JSON을 선택합니다.
3. 사용자 문서가 있다면 **Array**, **Experiment** 순서로 선택합니다.
4. **Assets**에서 원본 이미지와 오디오를 다시 선택해 SHA-256 연결 상태를 확인합니다.
5. 검증이 통과하면 시뮬레이션을 실행합니다.
안전한 전체 import 순서는 **Scene → Array → Experiment → Assets**입니다. 자세한 계산과 Result
설명은 [`../acoustic-camera/README.md`](../acoustic-camera/README.md)를 참고하세요.
## 모델 범위
Builder의 mix는 재현 가능한 source recipe와 위치 ground truth를 만드는 단계입니다. 자유음장 전파,
마이크 calibration과 DAS는 Acoustic Camera에서 수행합니다. 실제 방의 반사·잔향·차폐를 Builder가
추정하지 않습니다.