From bd042be61cce1eb25aa762845b705e06c5e291a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Fri, 22 May 2026 18:31:56 +0400 Subject: [PATCH] =?UTF-8?q?v63:=20=D0=BA=D0=BB=D0=B8=D0=BA=D0=B0=D0=B1?= =?UTF-8?q?=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5=20=D1=81=D0=BB=D0=BE=D0=B3?= =?UTF-8?q?=D0=B8=20=E2=80=94=20=D0=BF=D1=80=D0=BE=D0=B8=D0=B3=D1=80=D1=8B?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D1=81=D0=B5=D0=B3=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=D0=BE=D0=B2=20=D0=B0=D1=83=D0=B4=D0=B8=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 4497c31..b8f5b4b 100644 --- a/index.html +++ b/index.html @@ -53,9 +53,38 @@ let mediaRecorder, audioChunks = [], userAudioBlob = null, ttsText = ''; let isRecording = false, isAnalyzing = false, micAnalyser = null, micAnimId = null; let recordStartTime = 0, recordDuration = 0; // ---------- Версия ---------- -const VERSION = 'v62'; +const VERSION = 'v63'; document.getElementById('ver').textContent = VERSION; +// ---------- AudioContext для проигрывания слогов ---------- +let _audioCtx = null; +function getAudioCtx() { + if (!_audioCtx) _audioCtx = new (window.AudioContext || window.webkitAudioContext)(); + if (_audioCtx.state === 'suspended') _audioCtx.resume(); + return _audioCtx; +} + +let _currentBlob = null; // blob для проигрывания слогов +let _currentSylBuf = null; // декодированный AudioBuffer + +async function playSyllable(sylIdx, total) { + if (!_currentBlob) return; + const ctx = getAudioCtx(); + try { + if (!_currentSylBuf) { + const ab = await _currentBlob.arrayBuffer(); + _currentSylBuf = await ctx.decodeAudioData(ab); + } + const dur = _currentSylBuf.duration; + const start = (dur / total) * sylIdx; + const len = dur / total; + const src = ctx.createBufferSource(); + src.buffer = _currentSylBuf; + src.connect(ctx.destination); + src.start(0, start, len); + } catch(e) { console.log('playSyllable ERR', e); } +} + // ---------- Перевод на русский (Groq) ---------- async function translateToRussian(text) { if (!GROQ_API_KEY) return; @@ -266,6 +295,24 @@ async function doCompare(blob, originalText, duration) { '� Артикуляция: ' + phon.voiceClarity + '%' + ''; + // Слоги — кликабельные для прослушивания фрагментов + _currentBlob = blob; + _currentSylBuf = null; + const sy = syllabifyIT(originalText); + if (sy && sy.includes('-')) { + const syls = sy.split('-'); + const sylHTML = '
' + + syls.map((s, i) => + '' + s + '' + ).join('·') + + '
'; + document.getElementById('diff').innerHTML += sylHTML; + } + setStatus('Готово.'); isAnalyzing = false; return whisperResult.text || '';