mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-10-31 05:35:35 +00:00
Adding IPA output to emscripten js library and demo
This commit is contained in:
@@ -52,6 +52,12 @@
|
||||
display: block;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
#ipaarea {
|
||||
width: 100%;
|
||||
height: 8rem;
|
||||
display: block;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
p.gh {
|
||||
color: #333;
|
||||
text-align: right;
|
||||
@@ -100,6 +106,7 @@
|
||||
<h1>espeakng.js 1.49.1 Demo</h1>
|
||||
<form>
|
||||
<textarea id="texttospeak">Call me Ishmael. Some years ago --- never mind how long precisely --- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world. It is a way I have of driving off the spleen and regulating the circulation.</textarea>
|
||||
<textarea readonly="true" placeholder="IPA" id="ipaarea"></textarea>
|
||||
<div class="speecharg">
|
||||
<label for="pitch">Pitch</label><input id="pitch" type="range" value="50" min="0" max="100" /><button type="button" aria-label="Reset pitch" title="Reset pitch" onclick="resetPitch();">↶</button>
|
||||
</div>
|
||||
@@ -110,7 +117,7 @@
|
||||
<label for="voice">Voice</label><select id="voice"></select><button type="button" aria-label="Reset voice" title="Reset voice" onclick="resetVoice();">↶</button>
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<button type="button" onmousedown="speak();">Speak</button>
|
||||
<button type="button" onmousedown="speakAndIpa();">Speak</button>
|
||||
<button type="button" onmousedown="stop();">Stop</button>
|
||||
</div>
|
||||
<p class="gh"><a href="https://github.com/eeejay/espeak/tree/emscripten">Original Code for eSpeak: Eitan Isaacson</a></p>
|
||||
|
||||
@@ -50,6 +50,35 @@ public:
|
||||
espeak_SetSynthCallback(NULL);
|
||||
}
|
||||
|
||||
int synth_ipa_(const char* aText, const char* virtualFileName) {
|
||||
|
||||
/* phoneme_mode
|
||||
bit 1: 0=eSpeak's ascii phoneme names, 1= International Phonetic Alphabet (as UTF-8 characters).
|
||||
bit 7: use (bits 8-23) as a tie within multi-letter phonemes names
|
||||
bits 8-23: separator character, between phoneme names
|
||||
*/
|
||||
|
||||
espeak_SetSynthCallback(NULL);
|
||||
|
||||
int phoneme_options = (1 << 1); // Use IPA
|
||||
int use_custom_phoneme_separator = (0 << 7);
|
||||
int phonemes_separator = ' '; // Use a default value
|
||||
|
||||
int phoneme_conf = phoneme_options | (phonemes_separator << 8);
|
||||
|
||||
FILE* f_phonemes_out = fopen(virtualFileName,"wb");
|
||||
if(!f_phonemes_out)
|
||||
return -1;
|
||||
|
||||
//espeak_ng_InitializeOutput(ENOUTPUT_MODE_SYNCHRONOUS, 0, NULL);
|
||||
espeak_SetPhonemeTrace(phoneme_conf, f_phonemes_out);
|
||||
espeak_Synth(aText, 0, 0, POS_CHARACTER, 0, 0, NULL, NULL);
|
||||
espeak_SetPhonemeTrace(0, NULL);
|
||||
fclose(f_phonemes_out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
long set_voice(
|
||||
const char* aName,
|
||||
const char* aLang=NULL,
|
||||
|
||||
@@ -52,6 +52,7 @@ interface espeak_EVENT {
|
||||
interface eSpeakNGWorker {
|
||||
void eSpeakNGWorker();
|
||||
void synth_(DOMString aText, VoidPtr aCallback);
|
||||
long synth_ipa_(DOMString aText, DOMString virtualFileName);
|
||||
long getSizeOfEventStruct_();
|
||||
long set_voice(DOMString aName, DOMString aLang, optional octet gender=0, optional octet age=0, optional octet aVariant=0);
|
||||
[Const] attribute espeak_VOICE[] voices;
|
||||
|
||||
+27
-3
@@ -179,10 +179,12 @@ function speak() {
|
||||
pusher.connect(ctx.destination);
|
||||
console.log(' Creating pusher... done');
|
||||
|
||||
var user_text = document.getElementById('texttospeak').value;
|
||||
|
||||
// actual synthesis
|
||||
console.log(' Calling synthesize...');
|
||||
tts.synthesize(
|
||||
document.getElementById('texttospeak').value,
|
||||
user_text,
|
||||
function cb(samples, events) {
|
||||
//console.log(' Inside synt cb');
|
||||
if (!samples) {
|
||||
@@ -203,11 +205,32 @@ function speak() {
|
||||
//console.log(' Leaving synt cb');
|
||||
} // end of function cb
|
||||
); // end of tts.synthesize()
|
||||
console.log(' Calling synthesize... done');
|
||||
|
||||
console.log(' Calling synthesize... done');
|
||||
console.log('Leaving speak()');
|
||||
|
||||
} // end of speak()
|
||||
|
||||
function ipa() {
|
||||
|
||||
console.log("Synthesizing ipa ... ");
|
||||
var ts = new Date();
|
||||
var user_text = document.getElementById('texttospeak').value;
|
||||
|
||||
//user_text = user_text.repeat(50);
|
||||
|
||||
tts.set_voice(document.getElementById('voice').value);
|
||||
tts.synthesize_ipa(user_text, function(result) {
|
||||
var te = new Date();
|
||||
document.getElementById('ipaarea').value = result.ipa;
|
||||
console.log("Ipa synthesis done in " + (te-ts) + " ms.")
|
||||
});
|
||||
}
|
||||
|
||||
function speakAndIpa() {
|
||||
speak();
|
||||
ipa();
|
||||
}
|
||||
|
||||
function resetPitch() {
|
||||
document.getElementById('pitch').value = 50;
|
||||
}
|
||||
@@ -254,5 +277,6 @@ function initializeDemo() {
|
||||
console.log('Leaving cb1');
|
||||
} // end of function cb1
|
||||
);
|
||||
|
||||
console.log('Creating eSpeakNG instance... done');
|
||||
}
|
||||
|
||||
@@ -63,7 +63,8 @@ for (var method of [
|
||||
'set_rate',
|
||||
'set_pitch',
|
||||
'set_voice',
|
||||
'synthesize'
|
||||
'synthesize',
|
||||
'synthesize_ipa'
|
||||
]) {
|
||||
eSpeakNG.prototype[method] = _createAsyncMethod(method);
|
||||
}
|
||||
|
||||
@@ -93,6 +93,28 @@ eSpeakNGWorker.prototype.synthesize = function (aText, aCallback) {
|
||||
Runtime.removeFunction(fp);
|
||||
};
|
||||
|
||||
eSpeakNGWorker.prototype.synthesize_ipa = function (aText, aCallback) {
|
||||
|
||||
// Use a unique temp file for the worker. Avoid collisions, just in case.
|
||||
var ipaVirtualFileName = "espeak-ng-ipa-tmp-" + Math.random().toString().substring(2);
|
||||
|
||||
var res = "";
|
||||
var code = this.synth_ipa_(aText, ipaVirtualFileName);
|
||||
|
||||
if(code == 0)
|
||||
res = FS.readFile(ipaVirtualFileName, { encoding: 'utf8' })
|
||||
|
||||
// Clean up the tmp file
|
||||
FS.unlink(ipaVirtualFileName);
|
||||
|
||||
var ret = {
|
||||
code: code,
|
||||
ipa: res
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
// Make this a worker
|
||||
|
||||
if (typeof WorkerGlobalScope !== 'undefined') {
|
||||
@@ -104,6 +126,7 @@ if (typeof WorkerGlobalScope !== 'undefined') {
|
||||
});
|
||||
|
||||
onmessage = function(e) {
|
||||
|
||||
if (!worker) {
|
||||
throw 'eSpeakNGWorker worker not initialized';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user