docs: connect the array builder workflow
This commit is contained in:
@@ -2,9 +2,9 @@
|
||||
|
||||
192채널 MEMS 마이크 배열의 배치와 자유음장·저비용 실내 근사에서 DAS·DAS-PHAT·GCC-PHAT
|
||||
위치 추정을 비교하는 로컬 브라우저
|
||||
시뮬레이터입니다. Dataset Builder에서 녹음 파일·합성 신호와 이동 경로를 포함한 재현 가능한
|
||||
음향 장면을 만들고 Acoustic Camera에서 CPU 또는 WebGPU로 배열 응답, acoustic map과 위치 검출
|
||||
지표를 계산하거나 이동 장면을 시간축으로 재생합니다.
|
||||
시뮬레이터입니다. Array Builder에서 마이크 배치를 설계하고, Dataset Builder에서 녹음 파일·합성
|
||||
신호와 이동 경로를 포함한 재현 가능한 음향 장면을 만든 뒤, Acoustic Camera에서 CPU 또는
|
||||
WebGPU로 배열 응답, acoustic map과 위치 검출 지표를 계산하거나 이동 장면을 시간축으로 재생합니다.
|
||||
|
||||
별도 프로그램이나 패키지를 설치하지 않습니다. 모든 앱과 계산은 이 저장소와 브라우저 안에서
|
||||
실행됩니다.
|
||||
@@ -58,8 +58,8 @@ powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File .\scripts\serve.
|
||||
|
||||
### 화면 폭 조절
|
||||
|
||||
데스크톱에서는 Dataset Builder의 오른쪽 설정 패널과 Acoustic Camera의 왼쪽 설정 패널 경계를
|
||||
드래그해 넓힐 수 있습니다. 경계선에 키보드 초점을 두면 `←`/`→`로 16px씩,
|
||||
데스크톱에서는 Array Builder와 Acoustic Camera의 왼쪽 설정 패널, Dataset Builder의 오른쪽 설정
|
||||
패널 경계를 드래그해 넓힐 수 있습니다. 경계선에 키보드 초점을 두면 `←`/`→`로 16px씩,
|
||||
`Shift`와 함께 누르면 64px씩 조절됩니다. `Home`/`End`는 최소·최대
|
||||
폭, `Enter` 또는 더블클릭은 기본 폭으로 되돌립니다.
|
||||
|
||||
@@ -77,7 +77,25 @@ powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File .\scripts\serve.
|
||||
|
||||
## 내 장면으로 전체 흐름 실행하기
|
||||
|
||||
### 1. Dataset Builder에서 Scene 만들기
|
||||
### 1. Array Builder에서 마이크 배열 만들기 (선택)
|
||||
|
||||
1. 시작 화면에서 **Array Builder**를 엽니다.
|
||||
2. aperture 너비·높이와 프리셋을 배치할 **생성 경계**(사각형 또는 타원)를 정합니다.
|
||||
3. **격자**, **선형**, **원형**, **Fermat 나선**, **균일 랜덤** 중 하나로 배치합니다. 랜덤은
|
||||
seed로 같은 좌표를 재현하며, 최소 간격과 경계 여백도 지정할 수 있습니다.
|
||||
4. **추가** 도구로 canvas에 마이크를 놓고, 선택한 점을 드래그하거나 x/y/z 입력으로 수정합니다.
|
||||
목록에서는 삭제와 채널 순서 변경도 할 수 있습니다.
|
||||
5. 상태가 **Array JSON 저장 가능**이면 **Array JSON 저장**을 누릅니다.
|
||||
|
||||
불러온 Array의 `sensitivityDb`, `phaseOffsetDeg`, `frequencyResponse` 보정 정보는 마이크 위치·ID나
|
||||
채널 순서를 편집해도 보존됩니다. 프리셋 생성은 마이크 목록 전체를 새로 만드는 작업이므로 기존
|
||||
채널별 보정값도 교체됩니다.
|
||||
|
||||
생성 경계 형상, 프리셋 종류, random seed와 최소 간격은 편집을 돕는 설정이며 표준 Array JSON에
|
||||
저장되지 않습니다. 저장되는 것은 aperture 너비·높이와 최종 마이크 좌표·순서 및 채널별 보정값입니다.
|
||||
자세한 사용법은 [`apps/array-builder/README.md`](apps/array-builder/README.md)를 참고하세요.
|
||||
|
||||
### 2. Dataset Builder에서 Scene 만들기
|
||||
|
||||
1. 시작 화면에서 **Dataset Builder**를 엽니다.
|
||||
2. 선택적으로 배경 이미지와 오디오를 추가합니다.
|
||||
@@ -90,12 +108,12 @@ powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File .\scripts\serve.
|
||||
**Preview WAV 저장**은 source와 ambient를 공간 정보 없이 하나의 mono channel로 합친 청취
|
||||
확인용 파일입니다. 192채널 마이크 신호나 beamforming 결과가 아닙니다.
|
||||
|
||||
### 2. Acoustic Camera에서 실행하기
|
||||
### 3. Acoustic Camera에서 실행하기
|
||||
|
||||
1. 홈으로 돌아가 **Acoustic Camera**를 엽니다.
|
||||
2. 다음 순서로 입력합니다: **Scene → Array → Experiment → Assets**.
|
||||
3. **Scene**에서 Builder가 저장한 `.scene.json`을 선택합니다.
|
||||
4. 기본 배열을 사용하지 않을 때만 **Array**에서 `.array.json`을 선택합니다.
|
||||
4. 기본 배열을 사용하지 않을 때는 **Array**에서 Array Builder가 저장한 `.array.json`을 선택합니다.
|
||||
5. 별도 실험 문서를 사용할 때만 **Experiment**에서 `.experiment.json`을 선택합니다.
|
||||
6. Scene에 이미지나 audio asset이 있다면 **Assets**에서 Builder에 사용했던 원본 파일을 다시
|
||||
선택합니다. 여러 파일을 한 번에 선택할 수 있습니다.
|
||||
@@ -248,6 +266,7 @@ DAMAS와 CLEAN-SC는 구현하지 않습니다.
|
||||
Camera의 **배열 선택**에서 8개 fixture를 바로 불러와 같은 Scene/Experiment로 연속 실행할 수 있습니다.
|
||||
저채널·대형 배열의 grating lobe나 compact 배열의 넓은 main lobe는 배치 trade-off를 관찰하기 위한
|
||||
의도된 예제 특성입니다.
|
||||
새 배치를 직접 만들려면 [Array Builder](apps/array-builder/README.md)를 사용하세요. 저장소 fixture의
|
||||
상세한 생성법은 [`assets/array-geometries/README.md`](assets/array-geometries/README.md)를 참고하세요.
|
||||
|
||||
## 테스트와 benchmark
|
||||
@@ -273,6 +292,7 @@ test.cmd
|
||||
- [`docs/data-contracts.md`](docs/data-contracts.md): Array·Scene·Experiment·Result 계약
|
||||
- [`docs/acoustic-model.md`](docs/acoustic-model.md): 마이크 응답과 자유음장·shoebox 희소 근사
|
||||
- [`docs/realtime-porting.md`](docs/realtime-porting.md): 실측 다채널 위치추정 API 포팅
|
||||
- [`apps/array-builder/README.md`](apps/array-builder/README.md): 배열 생성·직접 편집과 Camera 전달
|
||||
- [`schemas/README.md`](schemas/README.md): JSON Schema 구성
|
||||
- [`docs/execution-plan.md`](docs/execution-plan.md): 구현 단계와 기술 결정
|
||||
- [`goal.md`](goal.md): 프로젝트 목표
|
||||
@@ -283,7 +303,7 @@ test.cmd
|
||||
## 디렉터리 구조
|
||||
|
||||
```text
|
||||
apps/ Dataset Builder와 Acoustic Camera UI
|
||||
apps/ Array Builder, Dataset Builder와 Acoustic Camera UI
|
||||
assets/ 마이크 배열과 synthetic Scene/Experiment fixture
|
||||
benchmarks/ 현재 브라우저에서 실행하는 WebGPU scaling 측정
|
||||
docs/ 사용자 안내, 데이터 계약, 실행 계획과 기준 실측
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
</div>
|
||||
|
||||
<div class="array-card">
|
||||
<div class="array-heading"><div><span class="compact-label">MIC ARRAY</span><h3 id="array-title">배열</h3></div><strong id="microphone-count">— ch</strong></div>
|
||||
<div class="array-heading"><div><span class="compact-label">MIC ARRAY</span><h3 id="array-title">배열</h3><a class="builder-link" href="/apps/array-builder/">Array Builder에서 만들기 →</a></div><strong id="microphone-count">— ch</strong></div>
|
||||
<label class="field">
|
||||
<span>배열 선택</span>
|
||||
<select id="array-preset">
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
# Array Builder
|
||||
|
||||
Array Builder는 `micarrsim.array` JSON을 브라우저에서 만드는 마이크 배열 편집기입니다. aperture
|
||||
크기와 생성 경계를 정한 뒤 프리셋으로 시작하거나 마이크를 직접 추가·이동해 Acoustic Camera의
|
||||
배열 입력으로 사용할 수 있습니다.
|
||||
|
||||
## 열기
|
||||
|
||||
저장소 루트에서 `start.cmd`를 실행하고 시작 화면의 **Array Builder**를 선택합니다. 서버가 이미
|
||||
실행 중이면 <http://127.0.0.1:4173/apps/array-builder/>를 직접 열 수 있습니다. HTML module을
|
||||
사용하므로 파일을 탐색기에서 직접 열지 마세요.
|
||||
|
||||
## 가장 짧은 사용 순서
|
||||
|
||||
1. **크기와 형상**에서 aperture 너비·높이와 생성 경계를 정합니다.
|
||||
2. 프리셋을 고르고 **현재 배열을 프리셋으로 교체**를 누릅니다.
|
||||
3. canvas와 마이크 목록에서 좌표와 채널 순서를 다듬습니다.
|
||||
4. 상태가 **Array JSON 저장 가능**인지 확인하고 **Array JSON 저장**을 누릅니다.
|
||||
5. Acoustic Camera를 열어 **Array** 입력에서 저장한 `.array.json`을 선택합니다.
|
||||
|
||||
## 크기와 생성 경계
|
||||
|
||||
- **너비·높이:** Array JSON의 `aperture.width`와 `aperture.height`이며 단위는 m입니다.
|
||||
- **사각형:** 너비와 높이의 직사각형 안에 preset을 배치합니다.
|
||||
- **타원:** 같은 너비와 높이를 지름으로 하는 타원 안에 preset을 배치합니다.
|
||||
- **좌표 중앙 정렬:** 현재 마이크의 무게중심을 원점으로 이동합니다.
|
||||
- **좌표에 크기 맞춤:** 현재 좌표가 들어가도록 aperture를 조절합니다.
|
||||
- **경계 밖 마이크를 안으로 이동:** 선택한 생성 경계 안으로 좌표를 제한합니다.
|
||||
|
||||
aperture 크기를 입력하는 것만으로 기존 좌표가 자동 확대·축소되지는 않습니다. 크기를 줄인 뒤
|
||||
경계 밖 좌표가 생겼다면 검증 메시지를 보고 크기를 다시 맞추거나 clamp 작업을 사용하세요.
|
||||
|
||||
## 프리셋
|
||||
|
||||
| 방식 | 설정 | 배치 |
|
||||
| --- | --- | --- |
|
||||
| 격자 | 행·열, 경계 여백 | 아래 행부터 위로, 각 행은 왼쪽에서 오른쪽으로 생성 |
|
||||
| 선형 | 마이크 수, x/y 축 | 선택한 중심축을 따라 일정 간격으로 생성 |
|
||||
| 원형 | 마이크 수 | 사각 경계는 사각 둘레, 타원 경계는 타원 둘레에 균일 배치 |
|
||||
| 나선 | 마이크 수 | golden angle을 사용하는 결정론적 Fermat 나선 |
|
||||
| 균일 랜덤 | 마이크 수, seed, 최소 간격 | 경계 내부에 seed로 재현되는 좌표 생성 |
|
||||
|
||||
**경계 여백**은 preset 좌표를 aperture 가장자리에서 안쪽으로 띄웁니다. 랜덤 배열은 요청한 최소
|
||||
간격을 만족하는 배치를 제한된 횟수 안에 찾지 못하면 현재 배열을 바꾸지 않고 오류를 표시합니다.
|
||||
같은 크기·형상·수·seed·간격을 사용하면 같은 랜덤 좌표가 생성됩니다.
|
||||
|
||||
프리셋 생성은 현재 마이크 목록 전체를 교체합니다. 필요한 기존 좌표나 채널 보정이 있다면 먼저
|
||||
Array JSON을 저장하세요.
|
||||
|
||||
## 직접 편집
|
||||
|
||||
- **선택 도구 (`V`):** 마이크 점을 선택하고 드래그해 x/y를 바꿉니다.
|
||||
- **추가 도구 (`A`):** 빈 canvas를 클릭해 새 마이크를 만듭니다.
|
||||
- **좌표 필드:** 선택한 마이크의 ID와 x/y/z를 숫자로 정확히 입력합니다.
|
||||
- **삭제:** 목록이나 canvas에서 선택한 뒤 **선택 마이크 삭제** 또는 `Delete`를 사용합니다.
|
||||
- **순서:** **채널 앞으로/뒤로**로 `microphones` 배열의 채널 순서를 바꿉니다.
|
||||
- **미세 이동:** 방향키로 이동하고 `Shift`를 함께 누르면 10배 거리로 이동합니다.
|
||||
- **스냅:** 격자 스냅 간격은 화면에서 mm 단위로 입력합니다.
|
||||
- **실행 취소:** `Ctrl+Z`, 다시 실행은 `Ctrl+Shift+Z`입니다.
|
||||
|
||||
확대·축소와 화면 맞춤은 보기만 바꾸며 저장 좌표에는 영향을 주지 않습니다.
|
||||
|
||||
## 보정값 보존
|
||||
|
||||
선택한 채널의 `sensitivityDb`와 `phaseOffsetDeg`는 보정값 펼침 영역에서 편집할 수 있습니다. 기존
|
||||
Array JSON을 불러왔을 때 마이크에 `frequencyResponse`가 있으면 응답점 수를 표시하며, 위치·ID,
|
||||
채널 순서나 배열 메타데이터를 편집해도 그 curve를 그대로 보존합니다.
|
||||
|
||||
프리셋으로 마이크 목록을 교체하면 새 채널이 만들어지므로 이전 채널의 sensitivity, phase와
|
||||
frequency response도 함께 제거됩니다.
|
||||
|
||||
## Array JSON에 저장되는 것
|
||||
|
||||
저장 파일은 계약 버전 `1.0.0`의 `micarrsim.array` 문서입니다.
|
||||
|
||||
- Array ID, 이름과 선택적 설명
|
||||
- m 단위 aperture 너비·높이
|
||||
- 오른손 좌표계와 순서가 있는 마이크 ID·`[x, y, z]`
|
||||
- 채널별 선택적 sensitivity, phase와 frequency-response curve
|
||||
|
||||
생성 경계의 사각형/타원 선택, 프리셋 종류, 행·열, random seed·최소 간격·경계 여백, snap과
|
||||
zoom은 편집기 설정입니다. 표준 Array JSON에는 저장되지 않으며 Camera는 최종 aperture와 실제
|
||||
마이크 좌표·순서를 사용합니다.
|
||||
|
||||
## Camera로 전달하기
|
||||
|
||||
1. Array Builder에서 **Array JSON 저장**을 누릅니다.
|
||||
2. 헤더의 **Camera 열기** 또는 홈의 Acoustic Camera를 엽니다.
|
||||
3. 입력 준비의 **Array**에서 저장한 파일을 선택합니다.
|
||||
4. 채널 수와 aperture 요약을 확인한 뒤 Scene과 Experiment를 준비해 실행합니다.
|
||||
|
||||
Experiment를 별도 파일로 가져올 때는 그 문서의 `arrayId`가 방금 불러온 Array ID와 같아야 합니다.
|
||||
Camera에서 배열 선택이 **불러온 Array JSON**으로 바뀌고 입력 검증이 통과했는지 확인하세요.
|
||||
|
||||
## 검증과 제한
|
||||
|
||||
- 마이크는 1개 이상 1,024개 이하입니다.
|
||||
- Array ID는 영문 소문자나 숫자로 시작하며 소문자·숫자·점·밑줄·하이픈만 허용합니다.
|
||||
- 마이크 ID는 비어 있을 수 없고 배열 안에서 고유해야 합니다.
|
||||
- 좌표는 유한한 수여야 합니다. x/y가 현재 생성 경계와 aperture를 벗어나면 저장 가능한 경고로
|
||||
표시되므로, 의도한 배치인지 확인하거나 clamp 작업을 사용하세요.
|
||||
- 마이크 두 개가 같은 x/y/z 좌표를 공유할 수 없습니다.
|
||||
- 저장되지 않은 변경이 있으면 페이지를 닫을 때 브라우저가 확인합니다.
|
||||
|
||||
JSON 구조 자체는 [`../../schemas/array.schema.json`](../../schemas/array.schema.json), 공통 계약은
|
||||
[`../../docs/data-contracts.md`](../../docs/data-contracts.md), 배열 예제는
|
||||
[`../../assets/array-geometries/README.md`](../../assets/array-geometries/README.md)를 참고하세요.
|
||||
@@ -1026,7 +1026,7 @@ body[data-array-tool="add"] #array-canvas,
|
||||
}
|
||||
}
|
||||
|
||||
@container array-controls (max-width: 330px) {
|
||||
@container array-controls (max-width: 340px) {
|
||||
.preset-grid,
|
||||
.button-grid,
|
||||
.calibration-fields {
|
||||
|
||||
+36
-10
@@ -17,6 +17,7 @@
|
||||
<nav aria-label="문서 목차">
|
||||
<a href="#quick-start">빠른 시작</a>
|
||||
<a href="#moving-live">이동 라이브</a>
|
||||
<a href="#array-builder">배열 만들기</a>
|
||||
<a href="#full-workflow">내 데이터</a>
|
||||
<a href="#acoustic-model">환경·실측</a>
|
||||
<a href="#results">결과 해석</a>
|
||||
@@ -28,7 +29,7 @@
|
||||
<section class="guide-hero">
|
||||
<h1>micarrsim 사용 설명서</h1>
|
||||
<p>
|
||||
<code>start.cmd</code>로 열고, 장면을 실행하고, 결과를 저장하는 순서만 먼저 확인하세요.
|
||||
<code>start.cmd</code>로 열고, 배열과 장면을 준비하고, 결과를 저장하는 순서만 먼저 확인하세요.
|
||||
입력과 계산은 로컬 브라우저에서 처리됩니다.
|
||||
</p>
|
||||
</section>
|
||||
@@ -70,8 +71,31 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="guide-section" id="full-workflow">
|
||||
<section class="guide-section" id="array-builder">
|
||||
<div class="section-number">03</div>
|
||||
<div>
|
||||
<p class="eyebrow">Microphone geometry</p>
|
||||
<h2>내 마이크 배열 만들기</h2>
|
||||
<ol class="guide-steps">
|
||||
<li><a href="/apps/array-builder/">Array Builder</a>에서 aperture 너비·높이와 사각형 또는 타원 생성 경계를 정합니다.</li>
|
||||
<li>격자·선형·원형·Fermat 나선·균일 랜덤 중 하나를 고릅니다. 랜덤은 seed와 최소 간격으로 재현성과 채널 간 거리를 제어합니다.</li>
|
||||
<li>canvas의 <strong>추가</strong> 도구로 마이크를 놓고, 점을 드래그하거나 x/y/z 필드로 좌표를 수정합니다.</li>
|
||||
<li>목록에서 마이크를 삭제하거나 채널 순서를 바꾸고, 상태가 <strong>Array JSON 저장 가능</strong>이면 저장합니다.</li>
|
||||
<li><a href="/apps/acoustic-camera/">Acoustic Camera</a>의 <strong>Array</strong> 입력에서 저장한 파일을 선택합니다.</li>
|
||||
</ol>
|
||||
<aside class="callout">
|
||||
가져온 채널의 sensitivity, phase와 frequency-response 보정은 위치·순서 편집 중 보존됩니다.
|
||||
다만 프리셋으로 마이크 목록을 교체하면 기존 채널별 보정도 교체됩니다.
|
||||
</aside>
|
||||
<aside class="callout callout--important">
|
||||
생성 경계 형상, 프리셋 종류, seed와 최소 간격은 편집기 설정이라 표준 Array JSON에
|
||||
저장되지 않습니다. Camera가 사용하는 것은 저장된 aperture와 최종 마이크 좌표·순서입니다.
|
||||
</aside>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="guide-section" id="full-workflow">
|
||||
<div class="section-number">04</div>
|
||||
<div>
|
||||
<p class="eyebrow">5분 전체 흐름</p>
|
||||
<h2>내 장면을 만들고 Camera에서 실행하기</h2>
|
||||
@@ -85,7 +109,8 @@
|
||||
<li><strong>Scene 저장 후 Camera 열기</strong>를 누릅니다.</li>
|
||||
<li>
|
||||
Camera에서 파일을 <strong>Scene → Array → Experiment → Assets</strong> 순서로
|
||||
가져옵니다. 내 Array/Experiment가 없다면 내장 기본값을 그대로 둡니다.
|
||||
가져옵니다. Array Builder에서 저장한 파일이 있다면 Array 단계에서 선택하고,
|
||||
내 Array/Experiment가 없다면 내장 기본값을 그대로 둡니다.
|
||||
</li>
|
||||
<li>
|
||||
Assets에서 Builder에 사용한 원본 이미지와 오디오를 한 번에 다시 선택합니다.
|
||||
@@ -96,7 +121,7 @@
|
||||
|
||||
<aside class="callout">
|
||||
데스크톱에서는 설정과 작업 영역 사이의 선을 드래그하거나 방향키로 패널 폭을 조절할
|
||||
수 있습니다. <kbd>Enter</kbd> 또는 더블클릭하면 기본 폭으로 돌아갑니다. 폭은 Builder와
|
||||
수 있습니다. <kbd>Enter</kbd> 또는 더블클릭하면 기본 폭으로 돌아갑니다. 폭은 각 Builder와
|
||||
Camera별로 이 브라우저에 저장되며, 좁은 화면에서는 두 영역이 자동으로 위아래로
|
||||
배치됩니다.
|
||||
</aside>
|
||||
@@ -117,7 +142,7 @@
|
||||
</section>
|
||||
|
||||
<section class="guide-section">
|
||||
<div class="section-number">04</div>
|
||||
<div class="section-number">05</div>
|
||||
<div>
|
||||
<p class="eyebrow">Localization & compute</p>
|
||||
<h2>알고리즘, 속도와 격자 선택</h2>
|
||||
@@ -166,7 +191,7 @@
|
||||
</section>
|
||||
|
||||
<section class="guide-section" id="acoustic-model">
|
||||
<div class="section-number">05</div>
|
||||
<div class="section-number">06</div>
|
||||
<div>
|
||||
<p class="eyebrow">Acoustics & measured input</p>
|
||||
<h2>환경과 마이크 응답 선택</h2>
|
||||
@@ -188,7 +213,7 @@
|
||||
</section>
|
||||
|
||||
<section class="guide-section" id="results">
|
||||
<div class="section-number">06</div>
|
||||
<div class="section-number">07</div>
|
||||
<div>
|
||||
<p class="eyebrow">Result JSON</p>
|
||||
<h2>무엇이 저장되나요?</h2>
|
||||
@@ -228,7 +253,7 @@
|
||||
</section>
|
||||
|
||||
<section class="guide-section" id="troubleshooting">
|
||||
<div class="section-number">07</div>
|
||||
<div class="section-number">08</div>
|
||||
<div>
|
||||
<p class="eyebrow">Troubleshooting</p>
|
||||
<h2>막혔을 때 확인할 것</h2>
|
||||
@@ -268,7 +293,7 @@
|
||||
</section>
|
||||
|
||||
<section class="guide-section">
|
||||
<div class="section-number">08</div>
|
||||
<div class="section-number">09</div>
|
||||
<div>
|
||||
<p class="eyebrow">Scope & privacy</p>
|
||||
<h2>현재 모델의 범위</h2>
|
||||
@@ -289,7 +314,8 @@
|
||||
|
||||
<section class="reference-grid" aria-label="상세 문서">
|
||||
<a href="/README.md"><strong>전체 README</strong><span>설치·실행·구조·제약</span></a>
|
||||
<a href="/apps/dataset-builder/README.md"><strong>Builder 설명서</strong><span>source·ambient·Preview WAV</span></a>
|
||||
<a href="/apps/array-builder/README.md"><strong>Array Builder 설명서</strong><span>마이크 배치·프리셋·JSON</span></a>
|
||||
<a href="/apps/dataset-builder/README.md"><strong>Dataset Builder 설명서</strong><span>source·ambient·Preview WAV</span></a>
|
||||
<a href="/apps/acoustic-camera/README.md"><strong>Camera 설명서</strong><span>backend·결과·비교</span></a>
|
||||
<a href="/docs/acoustic-model.md"><strong>음향 모델</strong><span>마이크 응답·반사·산란·회절</span></a>
|
||||
<a href="/docs/realtime-porting.md"><strong>실측 포팅</strong><span>block·streaming 위치추정 API</span></a>
|
||||
|
||||
+15
-3
@@ -24,7 +24,7 @@
|
||||
<section class="landing-intro" aria-labelledby="landing-title">
|
||||
<p class="eyebrow">Microphone array workbench</p>
|
||||
<h1 id="landing-title">무엇을 하시겠어요?</h1>
|
||||
<p>배열 위치추정을 바로 실행하거나, 평가에 사용할 음원 장면을 먼저 만드세요.</p>
|
||||
<p>배열을 설계하거나 음원 장면을 만든 뒤, 위치추정 결과를 바로 비교하세요.</p>
|
||||
</section>
|
||||
|
||||
<section class="launcher-grid" aria-label="작업 선택">
|
||||
@@ -47,19 +47,31 @@
|
||||
</div>
|
||||
<span class="launcher-card__action">새 Scene 만들기 →</span>
|
||||
</a>
|
||||
|
||||
<a class="launcher-card" href="/apps/array-builder/">
|
||||
<span class="launcher-card__number" aria-hidden="true">03</span>
|
||||
<div>
|
||||
<p class="launcher-card__kicker">마이크 배치 설계</p>
|
||||
<h2>Array Builder</h2>
|
||||
<p>크기와 생성 경계를 정하고, 프리셋 또는 직접 편집으로 마이크 배열을 만듭니다.</p>
|
||||
</div>
|
||||
<span class="launcher-card__action">새 Array 만들기 →</span>
|
||||
</a>
|
||||
</section>
|
||||
|
||||
<details class="workflow-disclosure">
|
||||
<summary>내 파일로 분석하는 순서</summary>
|
||||
<ol class="workflow-list">
|
||||
<li><strong>Array 제작 (선택)</strong><span>크기와 마이크 좌표를 설계해 JSON 저장</span></li>
|
||||
<li><strong>Scene 제작</strong><span>Builder에서 음원과 위치 지정</span></li>
|
||||
<li><strong>파일 보관</strong><span>Scene JSON과 원본 파일을 함께 보관</span></li>
|
||||
<li><strong>Camera 입력</strong><span>Scene, 배열, 원본 파일 선택</span></li>
|
||||
<li><strong>결과 저장</strong><span>위치 map과 지표를 Result JSON으로 저장</span></li>
|
||||
</ol>
|
||||
<p class="workflow-note">
|
||||
Scene JSON에는 원본 파일이 포함되지 않습니다. 다시 열 때 같은 파일을 선택하면 SHA-256으로
|
||||
확인해 연결합니다. <a href="/docs/#asset-reconnect">자세히 보기</a>
|
||||
Array Builder가 저장한 JSON은 Camera의 Array 입력에서 바로 선택할 수 있습니다. Scene JSON에는
|
||||
원본 파일이 포함되지 않으므로 다시 열 때 같은 파일을 SHA-256으로 확인해 연결합니다.
|
||||
<a href="/docs/#asset-reconnect">자세히 보기</a>
|
||||
</p>
|
||||
</details>
|
||||
</main>
|
||||
|
||||
@@ -514,6 +514,7 @@ body.is-resizing-pane * {
|
||||
}
|
||||
|
||||
.landing-shell .launcher-grid {
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
gap: 16px;
|
||||
margin-top: 28px;
|
||||
}
|
||||
@@ -582,6 +583,7 @@ body.is-resizing-pane * {
|
||||
}
|
||||
|
||||
.workflow-disclosure .workflow-list {
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||
margin: 16px 0 12px;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ async function digestHex(blob) {
|
||||
return [...new Uint8Array(digest)].map((value) => value.toString(16).padStart(2, "0")).join("");
|
||||
}
|
||||
|
||||
test("시작 화면과 Dataset Builder가 작업 우선순위 및 390px 레이아웃을 유지한다", async () => {
|
||||
test("시작 화면이 세 앱 진입점과 390px 레이아웃을 유지한다", async () => {
|
||||
const landingFrame = document.createElement("iframe");
|
||||
landingFrame.src = "/";
|
||||
landingFrame.style.cssText = "position:fixed;left:-20000px;top:0;width:390px;height:900px;border:0";
|
||||
@@ -49,9 +49,12 @@ test("시작 화면과 Dataset Builder가 작업 우선순위 및 390px 레이
|
||||
try {
|
||||
const landingDocument = landingFrame.contentDocument;
|
||||
const launchers = [...landingDocument.querySelectorAll(".launcher-card")];
|
||||
assertEqual(launchers.length, 2, "landing exposes only two primary tasks");
|
||||
assertEqual(launchers.length, 3, "landing exposes three primary tasks");
|
||||
assert(launchers[0].textContent.includes("Acoustic Camera"), "analysis is the first landing task");
|
||||
assert(launchers[1].textContent.includes("Dataset Builder"), "scene authoring is the second landing task");
|
||||
const launcherPaths = new Set(launchers.map((launcher) => launcher.getAttribute("href")));
|
||||
assert(launcherPaths.has("/apps/dataset-builder/"), "landing links to Dataset Builder");
|
||||
assert(launcherPaths.has("/apps/array-builder/"), "landing links to Array Builder");
|
||||
assert(launcherPaths.has("/apps/acoustic-camera/"), "landing links to Acoustic Camera");
|
||||
assert(!landingDocument.querySelector(".workflow-disclosure").open, "file workflow starts collapsed");
|
||||
assert(!landingDocument.querySelector('a[href="/docs/execution-plan.md"]'), "developer plan is absent from landing");
|
||||
assert(
|
||||
|
||||
@@ -35,6 +35,23 @@ const LAYOUT_CASES = [
|
||||
homePanelWidth: 320,
|
||||
homeGridTracks: 1,
|
||||
},
|
||||
{
|
||||
label: "Array Builder",
|
||||
path: "/apps/array-builder/",
|
||||
panelSide: "start",
|
||||
storageKey: "micarrsim.array-builder.control-panel-width",
|
||||
defaultPanelWidth: 420,
|
||||
layoutId: "array-builder-layout",
|
||||
panelId: "array-builder-controls",
|
||||
workspaceId: "array-builder-workspace",
|
||||
handleId: "array-builder-split-handle",
|
||||
canvasSelector: ".array-canvas-card",
|
||||
representativeSelectors: ["#array-name", "#generate-preset-button"],
|
||||
adaptiveGridSelector: ".preset-grid",
|
||||
defaultGridTracks: 2,
|
||||
homePanelWidth: 360,
|
||||
homeGridTracks: 1,
|
||||
},
|
||||
];
|
||||
|
||||
let mountSequence = 0;
|
||||
|
||||
Reference in New Issue
Block a user