57 lines
1.7 KiB
JavaScript
57 lines
1.7 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;
|
|
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); }
|
|
}
|