172 lines
11 KiB
HTML
172 lines
11 KiB
HTML
<!doctype html>
|
||
<html lang="ko">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<meta name="description" content="micarrsim 음향 장면 및 ground truth 생성기" />
|
||
<title>Dataset Builder · micarrsim</title>
|
||
<link rel="stylesheet" href="/packages/ui/app-shell.css" />
|
||
<link rel="stylesheet" href="/apps/dataset-builder/styles.css" />
|
||
</head>
|
||
<body>
|
||
<div class="app-shell builder-shell">
|
||
<header class="app-header builder-header">
|
||
<a class="app-brand" href="/">
|
||
<strong>micarrsim</strong>
|
||
<span>Dataset Builder</span>
|
||
</a>
|
||
<div class="header-actions">
|
||
<button class="button button--ghost" id="preview-button" type="button">▶ 미리 듣기</button>
|
||
<button class="button button--ghost" id="wav-button" type="button" title="공간정보 없이 모든 음원을 합친 mono 확인용 WAV입니다.">Preview WAV 저장</button>
|
||
<button class="button button--primary" id="export-button" type="button">Scene JSON 저장</button>
|
||
<a class="button button--ghost" href="/apps/acoustic-camera/">Scene 저장 후 Camera 열기 →</a>
|
||
</div>
|
||
</header>
|
||
|
||
<main class="builder-layout">
|
||
<section class="scene-workspace" aria-label="장면 편집 화면">
|
||
<div class="workspace-heading">
|
||
<div>
|
||
<p class="eyebrow">Ground-truth canvas</p>
|
||
<h1 id="workspace-title">음향 장면</h1>
|
||
</div>
|
||
<div class="workspace-tools">
|
||
<label class="button button--ghost file-button">
|
||
배경 이미지
|
||
<input id="image-input" type="file" accept="image/*" />
|
||
</label>
|
||
<button class="button button--danger is-hidden" id="remove-image-button" type="button">이미지 해제</button>
|
||
<label class="button button--ghost file-button">
|
||
원본 오디오 연결
|
||
<input id="audio-input" type="file" accept="audio/*,.wav,.flac,.mp3,.ogg,.m4a" multiple />
|
||
</label>
|
||
<label class="button button--ghost file-button">
|
||
Scene 불러오기
|
||
<input id="scene-input" type="file" accept="application/json,.json" />
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="canvas-card">
|
||
<canvas id="scene-canvas" aria-label="이미지 평면과 음원 ground truth"></canvas>
|
||
<div class="canvas-empty" id="canvas-empty">
|
||
<strong>이미지를 추가하거나 grid를 그대로 사용하세요.</strong>
|
||
<span>선택한 음원을 옮기려면 canvas를 클릭하세요.</span>
|
||
</div>
|
||
<div class="canvas-badge" id="canvas-badge">x −0.60…0.60 m · y −0.45…0.45 m</div>
|
||
</div>
|
||
|
||
<div class="source-strip-heading">
|
||
<div>
|
||
<h2>음원 ground truth</h2>
|
||
<p>파일 음원은 선택 즉시 생성됩니다. 카드를 선택한 뒤 canvas를 클릭해 위치를 지정하세요.</p>
|
||
</div>
|
||
<div class="source-actions">
|
||
<button class="button button--ghost" id="add-source-button" type="button">+ 합성 음원</button>
|
||
<label class="button button--primary file-button">
|
||
+ 오디오 파일 음원
|
||
<input id="audio-source-input" type="file" accept="audio/*,.wav,.flac,.mp3,.ogg,.m4a" multiple />
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<div class="source-strip" id="source-list" aria-label="음원 목록"></div>
|
||
|
||
<section class="asset-shelf">
|
||
<div>
|
||
<h2>로컬 assets</h2>
|
||
<p>원본은 업로드되지 않고 브라우저에서만 처리됩니다. PCM WAV를 권장하며, 다른 codec 지원은 환경에 따라 다릅니다.<br />Scene을 다시 불러온 뒤에는 위의 <strong>원본 오디오 연결</strong>에서 같은 파일을 선택하세요.</p>
|
||
</div>
|
||
<div class="asset-list" id="asset-list"></div>
|
||
</section>
|
||
</section>
|
||
|
||
<aside class="control-panel" aria-label="장면 파라미터">
|
||
<div class="runtime-line">
|
||
<span class="status-chip status-chip--neutral" data-runtime-status>런타임 확인 중…</span>
|
||
<span class="save-state" id="save-state">기본 장면</span>
|
||
</div>
|
||
|
||
<section class="control-section">
|
||
<div class="section-title"><span>01</span><h2>장면</h2></div>
|
||
<label class="field field--wide">
|
||
<span>이름</span>
|
||
<input id="scene-name" type="text" maxlength="120" />
|
||
</label>
|
||
<label class="field field--wide">
|
||
<span>Scene ID</span>
|
||
<input id="scene-id" type="text" maxlength="120" pattern="[a-z0-9][a-z0-9._-]*" />
|
||
</label>
|
||
<div class="field-grid">
|
||
<label class="field"><span>길이 (s)</span><input id="scene-duration" type="number" min="0.05" max="300" step="0.05" /></label>
|
||
<label class="field"><span>Sample rate</span><input id="sample-rate" type="number" min="8000" max="192000" step="1" /></label>
|
||
<label class="field"><span>음속 (m/s)</span><input id="speed-of-sound" type="number" min="250" max="400" step="0.1" /></label>
|
||
<label class="field"><span>Seed</span><input id="scene-seed" type="number" min="0" max="4294967295" step="1" /></label>
|
||
<label class="field"><span>Mix 정규화</span><select id="mix-normalization"><option value="none">없음</option><option value="peak">Peak</option></select></label>
|
||
<label class="field"><span>Target peak</span><input id="target-peak" type="number" min="0.01" max="1" step="0.01" /></label>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="control-section">
|
||
<div class="section-title"><span>02</span><h2>표시 평면</h2></div>
|
||
<div class="field-grid field-grid--compact">
|
||
<label class="field"><span>x min</span><input id="plane-x-min" type="number" step="0.05" /></label>
|
||
<label class="field"><span>x max</span><input id="plane-x-max" type="number" step="0.05" /></label>
|
||
<label class="field"><span>y min</span><input id="plane-y-min" type="number" step="0.05" /></label>
|
||
<label class="field"><span>y max</span><input id="plane-y-max" type="number" step="0.05" /></label>
|
||
<label class="field"><span>plane z (m)</span><input id="plane-z" type="number" min="0.01" step="0.1" /></label>
|
||
</div>
|
||
<p class="section-note">x/y는 편집 화면 범위이며, 배경 이미지가 있을 때 image plane으로 JSON에 저장됩니다.</p>
|
||
</section>
|
||
|
||
<section class="control-section" id="source-editor-section">
|
||
<div class="section-title"><span>03</span><h2>선택 음원</h2></div>
|
||
<div id="no-source-message" class="inline-note">음원을 선택하세요.</div>
|
||
<div id="source-fields">
|
||
<label class="field field--wide"><span>이름</span><input id="source-name" type="text" maxlength="120" /></label>
|
||
<div class="field-grid field-grid--three">
|
||
<label class="field"><span>x (m)</span><input id="source-x" type="number" step="0.01" /></label>
|
||
<label class="field"><span>y (m)</span><input id="source-y" type="number" step="0.01" /></label>
|
||
<label class="field"><span>거리 z (m)</span><input id="source-z" type="number" min="0.01" step="0.1" /></label>
|
||
</div>
|
||
<div class="field-grid field-grid--three">
|
||
<label class="field"><span>Gain (dB)</span><input id="source-gain" type="number" min="-120" max="24" step="1" /></label>
|
||
<label class="field"><span>시작 (s)</span><input id="source-start" type="number" min="0" step="0.01" /></label>
|
||
<label class="field"><span>길이 (s)</span><input id="source-duration" type="number" min="0.01" step="0.01" /></label>
|
||
</div>
|
||
<label class="field field--wide"><span>신호 종류</span><select id="source-type"><option value="tone">Tone</option><option value="noise">Noise</option><option value="asset">Audio asset</option></select></label>
|
||
<div id="tone-fields"><label class="field field--wide"><span>주파수 (Hz)</span><input id="tone-frequency" type="number" min="1" step="1" /></label></div>
|
||
<div id="noise-fields"><label class="field field--wide"><span>Noise color</span><select id="noise-color"><option value="white">White</option><option value="pink">Pink</option></select></label></div>
|
||
<div id="asset-fields">
|
||
<label class="field field--wide"><span>Audio asset</span><select id="source-asset"></select></label>
|
||
<div class="field-grid">
|
||
<label class="field"><span>Channel</span><input id="source-channel" type="number" min="0" max="255" step="1" /></label>
|
||
<label class="check-field"><input id="source-loop" type="checkbox" /><span>짧은 파일 반복</span></label>
|
||
</div>
|
||
</div>
|
||
<button class="button button--danger button--full" id="remove-source-button" type="button">선택 음원 삭제</button>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="control-section">
|
||
<div class="section-title"><span>04</span><h2>Ambient</h2></div>
|
||
<label class="field field--wide"><span>종류</span><select id="ambient-type"><option value="none">없음</option><option value="white">White noise</option><option value="pink">Pink noise</option><option value="asset">Audio asset</option></select></label>
|
||
<label class="field field--wide" id="ambient-asset-field"><span>Audio asset</span><select id="ambient-asset"></select></label>
|
||
<div class="field-grid" id="ambient-asset-options">
|
||
<label class="field"><span>Channel</span><input id="ambient-channel" type="number" min="0" max="255" step="1" /></label>
|
||
<label class="check-field"><input id="ambient-loop" type="checkbox" /><span>짧은 파일 반복</span></label>
|
||
</div>
|
||
<label class="field field--wide"><span>Gain (dB)</span><input id="ambient-gain" type="number" min="-120" max="24" step="1" /></label>
|
||
</section>
|
||
|
||
<section class="validation-card" aria-live="polite">
|
||
<div class="validation-dot" id="validation-dot"></div>
|
||
<div><strong id="validation-title">검증 대기</strong><p id="validation-message">장면을 준비하고 있습니다.</p></div>
|
||
</section>
|
||
</aside>
|
||
</main>
|
||
</div>
|
||
<script type="module" src="/packages/ui/runtime-status.js"></script>
|
||
<script type="module" src="/apps/dataset-builder/main.js"></script>
|
||
</body>
|
||
</html>
|