feat(tts): new default tone (1.35/-0.07/-0.30) + collapsible dashboard panel
- Change default voice controls to the user's tuned values: glyph speed 1.35, word_gap -0.07s (-70ms), sentence_gap -0.30s, pitch 0 (env defaults, slider initial values, and the 기본값 reset button all updated). - Make the "봇 목소리(TTS) 조절" dashboard panel collapsible via its header; starts collapsed (▸), expands on click (▾). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -463,9 +463,9 @@ class Dashboard:
|
||||
def _tts_values(self) -> dict:
|
||||
t = self.tts
|
||||
return {
|
||||
"speed": float(getattr(t, "speed", 1.25)),
|
||||
"word_gap": float(getattr(t, "word_gap", 0.25)),
|
||||
"sentence_gap": float(getattr(t, "sentence_gap", 0.75)),
|
||||
"speed": float(getattr(t, "speed", 1.35)),
|
||||
"word_gap": float(getattr(t, "word_gap", -0.07)),
|
||||
"sentence_gap": float(getattr(t, "sentence_gap", -0.30)),
|
||||
"pitch": float(getattr(t, "pitch", 0.0)),
|
||||
}
|
||||
|
||||
@@ -723,6 +723,8 @@ PAGE = r"""<!DOCTYPE html>
|
||||
.demobar b{color:#ffe08a}
|
||||
.sttbox{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:14px 16px;margin:0 0 16px}
|
||||
.sttbox h2{font-size:13px;margin:0 0 10px;font-weight:600;color:var(--fg)}
|
||||
.sttbox h2.collap{cursor:pointer;user-select:none;margin:0}
|
||||
.sttbox h2.collap #ttsCaret{display:inline-block;width:12px;color:var(--muted)}
|
||||
.sttrow{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
|
||||
.btn{background:#173042;border:1px solid #234a63;color:var(--fg);border-radius:10px;padding:8px 14px;font-size:13px;cursor:pointer}
|
||||
.btn:hover{background:#1d3d54}
|
||||
@@ -865,25 +867,27 @@ PAGE = r"""<!DOCTYPE html>
|
||||
<div id="sttres" class="sttres"></div>
|
||||
</section>
|
||||
<section class="sttbox" id="ttsbox" style="display:none">
|
||||
<h2>🔊 봇 목소리(TTS) 조절 · MeloTTS</h2>
|
||||
<div class="ttsgrid">
|
||||
<label>글자 속도 <b id="tvSpeed">1.25x</b>
|
||||
<input type="range" id="tSpeed" min="0.5" max="2.0" step="0.05" value="1.25"></label>
|
||||
<label>단어 간격 <b id="tvWord">250 ms</b>
|
||||
<input type="range" id="tWord" min="-0.2" max="0.5" step="0.01" value="0.25"></label>
|
||||
<label>문장 간격 <b id="tvSent">0.75 s</b>
|
||||
<input type="range" id="tSent" min="-0.5" max="1.5" step="0.05" value="0.75"></label>
|
||||
<label>피치 <b id="tvPitch">0 반음</b>
|
||||
<input type="range" id="tPitch" min="-12" max="12" step="1" value="0"></label>
|
||||
<h2 id="ttsToggle" class="collap"><span id="ttsCaret">▸</span> 🔊 봇 목소리(TTS) 조절 · MeloTTS</h2>
|
||||
<div id="ttsBody" style="display:none">
|
||||
<div class="ttsgrid">
|
||||
<label>글자 속도 <b id="tvSpeed">1.35x</b>
|
||||
<input type="range" id="tSpeed" min="0.5" max="2.0" step="0.05" value="1.35"></label>
|
||||
<label>단어 간격 <b id="tvWord">-70 ms</b>
|
||||
<input type="range" id="tWord" min="-0.2" max="0.5" step="0.01" value="-0.07"></label>
|
||||
<label>문장 간격 <b id="tvSent">-0.30 s</b>
|
||||
<input type="range" id="tSent" min="-0.5" max="1.5" step="0.05" value="-0.3"></label>
|
||||
<label>피치 <b id="tvPitch">0 반음</b>
|
||||
<input type="range" id="tPitch" min="-12" max="12" step="1" value="0"></label>
|
||||
</div>
|
||||
<div class="sttrow">
|
||||
<input id="tText" class="ttstext" placeholder="미리들을 문장" value="안녕하세요, 목소리 미리듣기입니다.">
|
||||
<button id="tPreview" class="btn">▶ 미리듣기</button>
|
||||
<button id="tApply" class="btn">💾 봇에 적용</button>
|
||||
<button id="tReset" class="btn hbtn">기본값</button>
|
||||
<span id="tStat" class="sttstat">슬라이더로 조절 → 미리듣기로 확인 → 봇에 적용하면 다음 답변부터 반영됩니다.</span>
|
||||
</div>
|
||||
<audio id="tAudio" controls style="display:none;margin-top:10px;width:100%"></audio>
|
||||
</div>
|
||||
<div class="sttrow">
|
||||
<input id="tText" class="ttstext" placeholder="미리들을 문장" value="안녕하세요, 목소리 미리듣기입니다.">
|
||||
<button id="tPreview" class="btn">▶ 미리듣기</button>
|
||||
<button id="tApply" class="btn">💾 봇에 적용</button>
|
||||
<button id="tReset" class="btn hbtn">기본값</button>
|
||||
<span id="tStat" class="sttstat">슬라이더로 조절 → 미리듣기로 확인 → 봇에 적용하면 다음 답변부터 반영됩니다.</span>
|
||||
</div>
|
||||
<audio id="tAudio" controls style="display:none;margin-top:10px;width:100%"></audio>
|
||||
</section>
|
||||
<div class="demobar" id="demobar" style="display:none"></div>
|
||||
<div class="comp" id="comp"></div>
|
||||
@@ -1188,6 +1192,11 @@ function ttsSet(s){
|
||||
}
|
||||
async function initTts(){
|
||||
if(ttsInited) return; ttsInited = true;
|
||||
$('ttsToggle').onclick = ()=>{
|
||||
const b=$('ttsBody'), open=b.style.display==='none';
|
||||
b.style.display = open ? 'block' : 'none';
|
||||
$('ttsCaret').textContent = open ? '▾' : '▸';
|
||||
};
|
||||
['tSpeed','tWord','tSent','tPitch'].forEach(id => $(id).addEventListener('input', ttsLabels));
|
||||
$('tPreview').onclick = async ()=>{
|
||||
const text=($('tText').value||'').trim();
|
||||
@@ -1211,7 +1220,7 @@ async function initTts(){
|
||||
else { $('tStat').textContent='적용 실패: '+(j.error||''); }
|
||||
}catch(e){ $('tStat').textContent='적용 오류: '+e; }
|
||||
};
|
||||
$('tReset').onclick = ()=>{ ttsSet({speed:1.25,word_gap:0.25,sentence_gap:0.75,pitch:0});
|
||||
$('tReset').onclick = ()=>{ ttsSet({speed:1.35,word_gap:-0.07,sentence_gap:-0.3,pitch:0});
|
||||
$('tStat').textContent='기본값으로 되돌림 (미리듣기/적용을 눌러 반영).'; };
|
||||
try{
|
||||
const j=await (await fetch('/api/tts/settings')).json();
|
||||
|
||||
Reference in New Issue
Block a user