Files
lang/js/syllables.js

71 lines
2.2 KiB
JavaScript

// ---------- Слоги ----------
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;
async function getAudioCtx() {
if (!_audioCtx) _audioCtx = new (window.AudioContext || window.webkitAudioContext)();
if (_audioCtx.state === 'suspended') await _audioCtx.resume();
return _audioCtx;
}
let _currentBlob = null;
let _currentSylBuf = null;
async function playSyllable(sylIdx, total) {
if (!_currentBlob) return;
try {
const ctx = await getAudioCtx();
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) {}
}
// Проигрывание слога из истории (загрузка blob из IndexedDB)
async function playHistorySyl(recId, sylIdx, total) {
try {
const db = await openRecDB();
const tx = db.transaction('recs', 'readonly');
const store = tx.objectStore('recs');
const rec = await new Promise(r => { const req = store.get(recId); req.onsuccess = () => r(req.result); });
if (!rec?.blob) return;
_currentBlob = rec.blob;
_currentSylBuf = null;
await playSyllable(sylIdx, total);
} catch(e) {}
}