Published
Edited
Oct 22, 2020
Insert cell
html`<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>`
Insert cell
md`# TTS`
Insert cell
viewof language = select({
title: "Language",
description: "Pleasse select your target language.",
options: [],
//value: "Moe"
})
Insert cell
html`<input name="input" id="pitch" type="range" min="0.1" max="10" step="0.1" value="1.0">`
Insert cell
html`<input name="input" id="rate" type="range" min="0.1" max="2" step="0.1" value="1.0">`
Insert cell
viewof g1 = textarea({
title: "Your Great American Novel",
placeholder: "Insert story here...",
spellcheck: true,
width: "100%",
rows: 10,
submit: "Publish"
})
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
{
var synth = window.speechSynthesis;

var inputForm = document.querySelector('form');
var inputTxt = document.querySelector('textarea');
console.log(inputForm)
var voiceSelect = document.querySelector('select');

var pitch = document.querySelector('#pitch');
//var pitchValue = document.querySelector('.pitch-value');
var rate = document.querySelector('#rate');
//var rateValue = document.querySelector('.rate-value');
console.log(pitch,pitch.value)

var voices = [];

function populateVoiceList() {
voices = synth.getVoices();

for(let i = 0; i < voices.length ; i++) {
var option = document.createElement('option');
option.textContent = voices[i].name + ' (' + voices[i].lang + ')';
if(voices[i].default) {
option.textContent += ' -- DEFAULT';
}

option.setAttribute('data-lang', voices[i].lang);
option.setAttribute('data-name', voices[i].name);
voiceSelect.appendChild(option);
}
}

populateVoiceList();
if (speechSynthesis.onvoiceschanged !== undefined) {
speechSynthesis.onvoiceschanged = populateVoiceList;
}

inputForm.onchange = function(event) {
event.preventDefault();
console.log(event)

var utterThis = new SpeechSynthesisUtterance(inputTxt.value);
var selectedOption = voiceSelect.selectedOptions[0].getAttribute('data-name');
for(let i = 0; i < voices.length ; i++) {
if(voices[i].name === selectedOption) {
utterThis.voice = voices[i];
}
}
console.log(pitch,pitch.value)
utterThis.volume = 0.5
utterThis.lang = utterThis.voice.lang
utterThis.pitch = 1.0 //parseFloat(pitch.value);
utterThis.rate = 1.0 //parseFloat(rate.value);
console.log(utterThis);
synth.speak(utterThis);

inputTxt.blur();
}
}
Insert cell
import {button, select, textarea, slider} from "@jashkenas/inputs"
Insert cell
d3 = require("d3")
Insert cell
Speech = require('https://bundle.run/speak-tts@2.0.8')
Insert cell
_init()
Insert cell
function _init() {
const speech = new Speech.default();
speech
.init({
volume: 0.5,
lang: "en-GB",
rate: 1,
pitch: 1,
//'voice':'Google UK English Male',
//'splitSentences': false,
listeners: {
onvoiceschanged: voices => {
console.log("Voices changed", voices);
}
}
})
.then(data => {
console.log("Speech is ready", data);
//_addVoicesList(data.voices);
//_prepareSpeakButton(speech);
})
.catch(e => {
console.error("An error occured while initializing : ", e);
});
const text = speech.hasBrowserSupport()
? "Hurray, your browser supports speech synthesis"
: "Your browser does NOT support speech synthesis. Try using Chrome of Safari instead !";
//document.getElementById("support").innerHTML = text;
console.log(text)
}
Insert cell
html`<div id="mathfield1" style=" font-size: 32px; margin: 3em; padding: 8px; border-radius: 8px; border: 1px solid rgba(0, 0, 0, .3); box-shadow: 0 0 8px rgba(0, 0, 0, .2); --hue: 53 !important; --caret: red !important;" >e^{i\pi} + 1 = 0</div>`
Insert cell
html`<div id="output"></div>`
Insert cell
{
let el = document.getElementById('mathfield1')
let mf1 = MathLive.makeMathField( el, { smartMode: true,virtualKeyboardMode: "manual",speechEngine: "local" });
el.addEventListener('input',(ev) => { // `ev.target` is an instance of `MathfieldElement` console.log(ev.target.value);
try {
console.log("input ev",ev, ev.target)
console.log(ev.target.getValue(), ev.target.getValue("json"));
const ast = MathLive.latexToAST(ev.target.getValue());
document.getElementById(
'output'
).innerHTML = JSON.stringify(
//mathJsonToMathjs(ast, {}).eval()
);
//document.getElementById('output').innerHTML = JSON.stringify(ast);
} catch (e) {
document.getElementById('output').innerHTML = '😕';
}
});
}
Insert cell
MathLive = require('mathlive@0.58.0/dist/mathlive.js')
Insert cell
mathjs = require('mathjs@7.5.1/dist/math.js')
Insert cell
function mathJsonToMathjs(mathJson, config) {
let result;
if (mathJson === undefined) return undefined;

if (
typeof mathJson === 'number' ||
mathJson.num !== undefined
) {
let n =
typeof mathJson === 'number'
? mathJson
: mathJson.num;

// Convert to BigNum if required
if (config.number === 'BigNumber')
n = window.math.bignumber(n);

result = new window.math.expression.node.ConstantNode(
n
);

// Apply the superscript as an operation
result = applySuperscriptAsPower(
result,
mathJson,
config
);
} else if (
typeof mathJson === 'string' ||
mathJson.sym !== undefined
) {
const BUILT_IN_CONSTANTS = {
π: window.math.pi,
τ: window.math.tau, // GREEK SMALL LETTER TAU
: window.math.e, // ℯ SCRIPT SMALL E
: window.math.e, // ⅇ DOUBLE-STRUCK ITALIC SMALL E
e: window.math.e,
ϕ: window.math.phi, // GREEK SMALL LETTER PHI
ⅈ: window.math.i, // ⅈ DOUBLE-STRUCK ITALIC SMALL I
ⅉ: window.math.i, // ⅉ DOUBLE-STRUCK ITALIC SMALL J
i: window.math.i, //
};
const symbol =
typeof mathJson === 'string'
? mathJson
: mathJson.sym;
if (BUILT_IN_CONSTANTS[symbol]) {
result = new window.math.expression.node.ConstantNode(
BUILT_IN_CONSTANTS[symbol]
);
} else {
result = new window.math.expression.node.SymbolNode(
MASTON.asSymbol(mathJson)
);
}
result = applySuperscriptAsPower(
result,
mathJson,
config
);
} else if (mathJson.op !== undefined) {
if (
mathJson.lhs !== undefined &&
mathJson.rhs !== undefined
) {
const OPERATOR_FUNCTIONS = {
'+': 'add',
'-': 'subtract',
'*': 'multiply',
'/': 'divide',
// '.*': 'dotMultiply',
// './': 'dotDivide',
'%': 'mod',
mod: 'mod',
};
const args = [
mathJsonToMathjs(mathJson.lhs, config),
mathJsonToMathjs(mathJson.rhs, config),
];
result = new window.math.expression.node.OperatorNode(
mathJson.op,
OPERATOR_FUNCTIONS[mathJson.op],
args
);
} else if (mathJson.rhs !== undefined) {
const UNARY_OPERATOR_FUNCTIONS = {
'-': 'unaryMinus',
'+': 'unaryPlus',
// '~': 'bitNot',
// 'not': 'not'
};
result = new window.math.expression.node.OperatorNode(
mathJson.op,
UNARY_OPERATOR_FUNCTIONS[mathJson.op],
[mathJsonToMathjs(mathJson.rhs, config)]
);
}
} else if (mathJson.fn) {
if (
mathJson.fn === 'log' ||
(mathJson.fn === 'ln' &&
mathJson.fn.sub !== undefined)
) {
result = new window.math.expression.node.FunctionNode(
'log',
getMathjsArgsWithSub(mathJson, config)
);
} else if (mathJson.fn === 'lb') {
const args = getMathjsArgs(mathJson, config);
args.push(
new window.math.expression.node.ConstantNode(
window.math.bignumber(2)
)
);
result = new window.math.expression.node.FunctionNode(
'log',
args
);
} else if (mathJson.fn === 'lg') {
result = new window.math.expression.node.FunctionNode(
new window.math.expression.node.SymbolNode(
'log10'
),
getMathjsArgs(mathJson, config)
);
} else {
const fnName =
{
'+': 'add',
'-': 'subtract',
'*': 'multiply',
'/': 'divide',
randomReal: 'random',
randomInteger: 'randomInt',
Gamma: 'gamma',
Re: 're',
Im: 'im',
binom: 'composition',
ucorner: 'ceil',
lcorner: 'floor',
arccos: 'acos',
arcsin: 'asin',
arctan: 'atan',
arcosh: 'acosh',
arsinh: ' asinh',
}[mathJson.fn] || mathJson.fn;

result = new window.math.expression.node.FunctionNode(
fnName,
getMathjsArgs(mathJson, config)
);
}
} else if (mathJson.group) {
result = applySuperscriptAsPower(
mathJsonToMathjs(mathJson.group, config),
mathJson,
config
);
}

return result;
}
Insert cell
function applySuperscriptAsPower(mjs, mathJson, config) {
let result = mjs;
if (
typeof mathJson === 'object' &&
mathJson.sup !== undefined
) {
result = new window.math.expression.node.FunctionNode(
'pow',
[result, mathJsonToMathjs(mathJson.sup, config)]
);
}
return result;
}



Insert cell
function getMathjsArgsWithSub(mathJson, config) {
const result = getMathjsArgs(mathJson, config);
if (mathJson.sub !== undefined) {
result.push(mathJsonToMathjs(mathJson.sub, config));
}

return result;
}
Insert cell
function getMathjsArgs(mathJson, config) {
let result = [];
if (Array.isArray(mathJson.arg)) {
for (
let index = 0;
index < mathJson.arg.length;
index++
) {
result.push(
mathJsonToMathjs(mathJson.arg[index], config)
);
}
} else {
result = [mathJsonToMathjs(mathJson.arg, config)];
}
return result;
}

Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more