// ---------- Слоги ---------- function syllabifyIT(w) { const isV = c => 'aeiouàèéìíòóùú'.includes(c.toLowerCase()); const onset = s => /^(str|scr|spr|spl|bl|br|cl|cr|dr|fl|fr|gl|gn|gr|pl|pr|sc|sk|sl|sm|sn|sp|sq|sr|st|sv|tr|ch|gh)/i.test(s); let out = [], syl = '', i = 0; while (i < w.length) { syl += w[i]; if (isV(w[i])) { let j = i + 1, cons = ''; while (j < w.length && !isV(w[j])) cons += w[j++]; if (j < w.length && cons.length > 0) { const k = cons.length === 1 ? 0 : onset(cons.slice(1)) ? 1 : Math.floor(cons.length / 2); syl += cons.slice(0, k); out.push(syl); syl = ''; i += k; } } i++; } if (syl) out.push(syl); return out.join('-'); } function syllabifyPhrase(text) { return text.split(/\s+/).map(syllabifyIT).join(' '); } // ---------- 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; let _currentSylBuf = null; 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); } }