UNPKG

@ztiknl/sara

Version:

Sentient Artificial Responsive Agent

204 lines (191 loc) 6.21 kB
// set start vars var voiceactive = false; var api_id; var api_file; var vo_language; var vo_voice; var vo_gender; // process config.json file loadconfig(); // Imports the Google Cloud client library const textToSpeech = require('@google-cloud/text-to-speech'); // Import other required libraries const fs = require('fs'); const util = require('util'); const sfx = require('./sfx.js') // include colored responses module const response = require('./response.js'); module.exports = { start: async function() { if (voiceactive == false) { response.conlog('voice', 'speech synthesis activated', 'info'); voiceactive = true; var result = 'I am able to speak now'; return result; } else { response.conlog('voice', 'speech synthesis was already activated', 'info'); var result = 'I am already able to speak'; return result; } }, list: async function(language) { if(language) { if (language == 'french') { language = 'fr'; } if (language == 'dutch') { language = 'nl'; } if (language == 'german') { language = 'de'; } if (language == 'english') { language = 'en'; } } else { var language = vo_language; } const client = new textToSpeech.TextToSpeechClient({ projectId: api_id, keyFilename: api_file }) const result = await client.listVoices({'languageCode': language}); console.log(result[0]['voices']); console.log(result[0]['voices'].length) if (result[0]['voices'].length < 1) { var rslt = 'There are no voices available'; } else { var rslt = 'There are '+result[0]['voices'].length+' voices available'; var i = 0; while (i < result[0]['voices'].length) { response.conlog('voice', result[0]['voices'][i]['languageCodes']+':\n\t'+result[0]['voices'][i]['ssmlGender']+'\n\tName: '+result[0]['voices'][i]['name']+'\n\tSample rate: '+result[0]['voices'][i]['naturalSampleRateHertz']+'\n', 'output'); i++; } } return rslt; }, synthesize: async function(sentence, language) { if (language) { if (language == 'french') { vo_language = 'fr-FR'; if (vo_gender == 'FEMALE') { vo_voice = 'fr-FR-Wavenet-C'; } else { vo_voice = 'fr-FR-Wavenet-D'; } } if (language == 'dutch') { vo_language = 'nl-NL'; if (vo_gender == 'FEMALE') { vo_voice = 'nl-NL-Wavenet-D'; } else { vo_voice = 'nl-NL-Wavenet-C'; } } if (language == 'german') { vo_language = 'de-DE'; if (vo_gender == 'FEMALE') { vo_voice = 'de-DE-Wavenet-C'; } else { vo_voice = 'de-DE-Wavenet-B'; } } if (language == 'english') { vo_language = 'en-GB'; if (vo_gender == 'FEMALE') { vo_voice = 'en-GB-Wavenet-C'; } else { vo_voice = 'en-GB-Wavenet-B'; } } } if (voiceactive == true) { sentence = module.exports.vocalize(String(sentence)); const client = new textToSpeech.TextToSpeechClient({ projectId: api_id, keyFilename: api_file }) const request = { input: {ssml: sentence}, voice: {languageCode: vo_language, name: vo_voice, ssmlGender: vo_gender}, audioConfig: {audioEncoding: 'LINEAR16'}, }; const [result] = await client.synthesizeSpeech(request); const writeFile = util.promisify(fs.writeFile); await writeFile('resources/voice/output.wav', result.audioContent, 'binary'); sfx.output('voice'); if (language) { loadconfig(); } return; } }, vocalize: function(sentence) { sentence = sentence.replace(/\n/gi, "<break time=\'750ms\'/>\n"); sentence = sentence.replace(/,/gi, "<break time=\'500ms\'/>\n"); sentence = sentence.replace(/:/gi, "<break time=\'500ms\'/>\n"); sentence = sentence.replace(/;/gi, "<break time=\'500ms\'/>\n"); sentence = sentence.replace(/\(/gi, "<break time=\'500ms\'/>\n"); sentence = sentence.replace(/\)/gi, "<break time=\'500ms\'/>\n"); sentence = sentence.replace(/ZTiK.nl/gi, "Stick N L"); sentence = sentence.replace(/ZTiKnl/gi, "Stick N L"); sentence = sentence.replace(/ZTiK/gi, "Stick"); sentence = sentence.replace(/SARA/gi, "Sarah"); sentence = sentence.replace(/S.A.R.A./gi, "Sarah"); sentence = sentence.replace(/S.A.R.A/gi, "Sarah"); sentence = '<speak><break time=\'250ms\'/>'+sentence+'</speak>'; return sentence; }, silence: async function() { await sfx.quiet(); var result = '...'; return result; }, stop: async function() { if (voiceactive == true) { response.conlog('voice', 'speech synthesis deactivated', 'info'); voiceactive = false; var result = 'I am no longer able to speak'; return result; } else { response.conlog('voice', 'speech synthesis was already deactivated', 'info'); var result = 'I am already unable to speak'; return result; } }, status: function() { return voiceactive; } } function loadconfig() { const fs = require('fs') const path = './config.json' try { if (fs.existsSync(path)) { var configfile = require('./config.json'); if (configfile['google cloud'] != null) { api_id = configfile['google cloud']['projectid']; api_file = configfile['google cloud']['file']; } else { api_id = 'sara-245106'; api_file = './resources/apikeys/googlecloud.json'; } if (configfile['voiceoptions']['language'] != null) { vo_language = configfile['voiceoptions']['language']; } else { vo_language = 'en-US'; } if (configfile['voiceoptions']['voice'] != null) { vo_voice = configfile['voiceoptions']['voice']; } else { vo_voice = 'en-GB-Wavenet-C'; } if (configfile['voiceoptions']['gender'] != null) { vo_gender = configfile['voiceoptions']['gender']; } else { vo_gender = 'FEMALE'; } } } catch(err) { } }