184 lines
12 KiB
HTML
184 lines
12 KiB
HTML
<div class="section-head">
|
||
<span class="section-icon"><span class="mdi mdi-microphone-variant"></span></span>
|
||
<div class="section-title">
|
||
<h2>Clone a Voice</h2>
|
||
<p>Capture 3–20 seconds of clean speech, trim it, name it, then save it as a reusable voice clone.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Audio source — integrated tabs (record / upload / link) -->
|
||
<div class="tab-content" id="tab-source">
|
||
<div class="clone-tabbox">
|
||
<div class="clone-src-picker" id="clone-src-picker" role="tablist">
|
||
<button class="clone-src-tab active" data-src="mic" role="tab"><span class="mdi mdi-microphone"></span> Microphone</button>
|
||
<button class="clone-src-tab" data-src="file" role="tab"><span class="mdi mdi-file-music-outline"></span> Upload file</button>
|
||
<button class="clone-src-tab" data-src="url" role="tab"><span class="mdi mdi-link-variant"></span> URL / YouTube</button>
|
||
</div>
|
||
<div class="clone-srcpanel">
|
||
|
||
<!-- Microphone -->
|
||
<div class="clone-src-card" id="clone-src-mic" data-src="mic">
|
||
<p class="clone-src-intro"><span class="mdi mdi-microphone"></span> Record a fresh sample with live input-level monitoring.</p>
|
||
<div class="field" style="max-width:320px">
|
||
<label for="clone-your-name">Voice name</label>
|
||
<input type="text" id="clone-your-name" placeholder="e.g. Anna" spellcheck="false" autocomplete="off">
|
||
<p class="note">Sets the voice name and is dropped into the sentence below.</p>
|
||
</div>
|
||
<div class="sample-read-box" style="margin-top:12px">
|
||
<div class="sample-head">
|
||
<label for="clone-sample-lang">Read this aloud</label>
|
||
<select id="clone-sample-lang">
|
||
<option value="EN">English</option>
|
||
<option value="DE">Deutsch</option>
|
||
<option value="IT">Italiano</option>
|
||
<option value="ES">Español</option>
|
||
<option value="FR">Français</option>
|
||
<option value="PT">Português</option>
|
||
<option value="NL">Nederlands</option>
|
||
<option value="PL">Polski</option>
|
||
</select>
|
||
</div>
|
||
<textarea class="sample-sentence" id="clone-sample-text" aria-label="Sample sentence to read aloud" spellcheck="true">Hello! My name is Sam, and this is my voice. I can speak softly or with great strength. The crisp winter air, warm firelight, and the gentle sound of rain — these are the things I love. Can you hear how clearly I speak?</textarea>
|
||
<p class="note" style="margin-top:6px"><span class="mdi mdi-pencil-outline"></span> Edit the sentence freely before recording.</p>
|
||
</div>
|
||
<div class="btn-row" style="margin-top:12px">
|
||
<button class="btn-secondary" id="clone-monitor-btn"><span class="mdi mdi-waveform"></span> Check level</button>
|
||
<button class="btn-secondary" id="clone-monitor-stop" disabled>Stop monitor</button>
|
||
<button class="btn-red" id="rec-start-btn"><span class="mdi mdi-record-circle-outline"></span> Record</button>
|
||
<button class="btn-secondary" id="rec-stop-btn" disabled><span class="mdi mdi-stop-circle-outline"></span> Stop</button>
|
||
<div id="rec-indicator"><div id="rec-dot"></div><span id="rec-time">0:00</span></div>
|
||
</div>
|
||
<div class="mic-monitor-box" id="clone-monitor-box" style="margin-top:10px">
|
||
<div class="mic-monitor-head">
|
||
<span>Input level</span>
|
||
<span class="meter-readout" id="clone-db-readout">-∞ dB</span>
|
||
</div>
|
||
<div class="mic-meter" id="clone-mic-meter" aria-hidden="true"></div>
|
||
<canvas id="clone-live-wave" class="mic-live-wave" width="300" height="48" aria-hidden="true"></canvas>
|
||
<div class="mic-gain-row">
|
||
<label for="clone-mic-gain">Mic gain</label>
|
||
<input id="clone-mic-gain" type="range" min="0" max="2" step="0.05" value="1">
|
||
<span class="mic-gain-value" id="clone-mic-gain-value">1.00x</span>
|
||
</div>
|
||
<div class="note" style="margin-top:4px">Best peaks: −18 to −9 dB. Never red.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Upload file -->
|
||
<div class="clone-src-card" id="clone-src-file" data-src="file" hidden>
|
||
<p class="clone-src-intro"><span class="mdi mdi-file-music-outline"></span> Drop an audio or video file, or click to browse.</p>
|
||
<div id="drop-zone">
|
||
<strong>Drop an audio / video file here</strong>
|
||
<span>WAV · MP3 · OGG · FLAC · M4A · MP4 · MKV · WEBM</span>
|
||
<span style="margin-top:10px;font-size:12px;color:var(--subtext)">or click to browse</span>
|
||
<input type="file" id="file-input" accept=".wav,.mp3,.ogg,.opus,.flac,.m4a,.mp4,.mkv,.webm,.mov,.avi,audio/*,video/*">
|
||
</div>
|
||
</div>
|
||
|
||
<!-- URL / YouTube -->
|
||
<div class="clone-src-card" id="clone-src-url" data-src="url" hidden>
|
||
<p class="clone-src-intro"><span class="mdi mdi-link-variant"></span> Paste a direct audio link or a YouTube URL to grab the audio.</p>
|
||
<div class="url-row">
|
||
<input type="text" id="yt-url" placeholder="https://www.youtube.com/watch?v=...">
|
||
<button class="btn-primary" id="yt-btn">Download</button>
|
||
</div>
|
||
<div id="yt-progress"></div>
|
||
</div>
|
||
|
||
</div><!-- /clone-srcpanel -->
|
||
</div><!-- /clone-tabbox -->
|
||
|
||
<!-- Trim (appears once audio is loaded) -->
|
||
<div class="card" id="waveform-card" style="display:none">
|
||
<h2><span class="mdi mdi-content-cut"></span> Trim your sample</h2>
|
||
<p class="card-subtitle">Select the best 3–20 s of clean speech from the waveform.</p>
|
||
<div id="waveform-wrap"><div id="waveform"></div></div>
|
||
<div class="time-row">
|
||
<label>Start (s) <input type="number" id="trim-start" value="0" min="0" step="0.1"></label>
|
||
<label>End (s) <input type="number" id="trim-end" value="0" min="0" step="0.1"></label>
|
||
<span id="trim-duration" class="dur-ok">0.0 s</span>
|
||
</div>
|
||
<div class="btn-row">
|
||
<button class="btn-primary" id="trim-btn">Confirm trim → Name & Save</button>
|
||
<button class="btn-secondary" id="auto-trim-btn">Auto trim</button>
|
||
<button class="btn-secondary" id="play-btn"><span class="mdi mdi-play"></span> Play</button>
|
||
<button class="btn-secondary" id="play-selection-btn"><span class="mdi mdi-play"></span> Play selection</button>
|
||
</div>
|
||
</div>
|
||
</div><!-- /tab-source -->
|
||
|
||
<!-- Name, transcribe, preview & save -->
|
||
<div class="tab-content" id="tab-save">
|
||
<div class="card">
|
||
<h2><span class="mdi mdi-account-voice"></span> Name your voice</h2>
|
||
<p class="card-subtitle">Choose language & gender and type a name — the ID builds automatically (e.g. <code>EN_F_Anna</code>). You can also type a custom ID.</p>
|
||
<div class="clone-id-row">
|
||
<div class="field">
|
||
<label for="lang-select">Language</label>
|
||
<select id="lang-select" aria-label="Voice language">
|
||
<option>EN</option><option>DE</option><option>ZH</option><option>FR</option>
|
||
<option>ES</option><option>JA</option><option>KO</option><option>IT</option>
|
||
<option>PT</option><option>RU</option><option>AR</option><option>PL</option>
|
||
<option>NL</option><option>SV</option><option>TR</option><option>HI</option>
|
||
</select>
|
||
</div>
|
||
<div class="field">
|
||
<label for="gender-select">Gender</label>
|
||
<select id="gender-select" aria-label="Voice gender">
|
||
<option value="F">F — Female</option>
|
||
<option value="M">M — Male</option>
|
||
<option value="N">N — Neutral</option>
|
||
</select>
|
||
</div>
|
||
<div class="field" style="flex:1;min-width:140px">
|
||
<label>Name (no spaces)</label>
|
||
<input type="text" id="name-input" placeholder="Anna">
|
||
</div>
|
||
<button class="btn-secondary" id="helper-apply-btn" hidden>Apply →</button>
|
||
</div>
|
||
<div class="field" style="margin-top:14px">
|
||
<label for="voice-id-input">Final voice ID</label>
|
||
<div class="voice-id-row">
|
||
<input type="text" id="voice-id-input" placeholder="e.g. EN_F_Anna or MyCustomVoice" spellcheck="false">
|
||
</div>
|
||
<div id="voice-id-hint" class="note" style="min-height:1.2em"></div>
|
||
</div>
|
||
</div>
|
||
<div class="card">
|
||
<h2><span class="mdi mdi-message-text-outline"></span> Reference transcript</h2>
|
||
<p class="card-subtitle">The exact words spoken in the audio — type them or auto-transcribe.</p>
|
||
<div class="engine-setup-row" style="padding:10px 12px; margin-bottom:12px">
|
||
<div class="engine-setup-col no-border" style="flex:1">
|
||
<label class="engine-setup-label"><span class="mdi mdi-microphone"></span> Speech to Text <a href="#" class="engine-setup-link" onclick="navTo('s-llms'); navEnginesCat('stt'); return false;" title="Configure Speech to Text settings"><span class="mdi mdi-cog-outline"></span></a></label>
|
||
<div class="engine-setup-controls">
|
||
<select id="clone-stt-backend" aria-label="Speech-to-text recognition engine"><option value="configured">Configured Whisper/STT</option></select>
|
||
<button class="btn-secondary" id="clone-refresh-stt-btn" type="button"><span class="mdi mdi-refresh"></span></button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="btn-row">
|
||
<button class="btn-secondary" id="transcribe-btn"><span class="mdi mdi-message-text-outline"></span> Auto-transcribe</button>
|
||
<span id="transcribe-status" style="font-size:13px;color:var(--subtext)"></span>
|
||
</div>
|
||
<textarea id="transcript-area" placeholder="Type or auto-transcribe the spoken text…"></textarea>
|
||
</div>
|
||
<div class="card">
|
||
<h2><span class="mdi mdi-play-circle-outline"></span> Preview</h2>
|
||
<p class="card-subtitle">Listen to the trimmed audio before saving.</p>
|
||
<audio id="trim-audio" controls style="display:none"></audio>
|
||
<p id="no-audio-hint" class="note">No audio yet — record or load a sample above, or use Voice Design.</p>
|
||
</div>
|
||
<div class="card">
|
||
<h2><span class="mdi mdi-content-save-outline"></span> Save to library</h2>
|
||
<p class="card-subtitle">Write the cloned voice to your active voices folder.</p>
|
||
<div class="btn-row" style="align-items:center;gap:12px">
|
||
<button class="btn-green" id="save-btn"><span class="mdi mdi-memory"></span> Save to Voice Library</button>
|
||
<label class="chunk-toggle-label" style="font-size:12px;gap:5px" title="Save automatically once audio, ID and transcript are all ready (re-saves when you change details)">
|
||
<input type="checkbox" id="clone-autosave-toggle" checked>
|
||
<span>Auto-save when ready</span>
|
||
</label>
|
||
</div>
|
||
<div id="save-result" class="note" style="display:none"></div>
|
||
</div>
|
||
</div><!-- /tab-save -->
|