UNPKG

mmir-lib

Version:

MMIR (Mobile Multimodal Interaction and Relay) library

242 lines (205 loc) 6.95 kB
/** * Media Module: Implementation for Text-To-Speech via MARY TTS * * @requires CSP for accessing the MARY TTS server, e.g. for default server URL "media-src http://mary.dfki.de:59125/" or "default-src http://mary.dfki.de:59125/" * NOTE if you have configured a different server URL, then that one needs to be enabled via CSP * * @class MaryWebAudioTTSImpl * @memberOf mmir.env.media * @hideconstructor * */ define(['mmirf/mediaManager', 'mmirf/configurationManager', 'mmirf/languageManager', 'mmirf/util/loadFile'], function(mediaManager, config, lang, load){ /** * @readonly * @inner * @default "ttsMary" * @memberOf mmir.env.media.MaryWebAudioTTSImpl# */ var _pluginName = 'ttsMary'; /** * @readonly * @inner * @default "http://mary.dfki.de:59125/" * @memberOf mmir.env.media.MaryWebAudioTTSImpl# */ var _defaultServerPath = 'http://mary.dfki.de:59125/'; return function createMaryTTSImpl(_defaultLogger){ /** * separator char for language- / country-code (specific to TTS service) * * @memberOf mmir.env.media.MaryWebAudioTTSImpl# * @private */ var _langSeparator = void(0); /** @memberOf mmir.env.media.MaryWebAudioTTSImpl# * @private */ var _getLangParam; /** @memberOf mmir.env.media.MaryWebAudioTTSImpl# * @private */ var _getVoiceParam; /** * HELPER retrieve language setting and apply impl. specific corrections/adjustments * (i.e. deal with MARY specific quirks for language/country codes) * * @memberOf mmir.env.media.MaryWebAudioTTSImpl# * @private */ var _getFixedLang = function(options){ var locale = _getLangParam(options, _langSeparator); return lang.fixLang('mary', locale); }; /** * HELPER parse raw voice information * @param {String} str the raw line decribing the voice (as returned from service) * @memberOf mmir.env.media.MaryWebAudioTTSImpl# * @private */ var _toVoiceDetails = function(str){ var infos = str? str.trim().split(/\s/) : []; return { name: infos[0], language: infos[1], gender: /^(fe)?male$/i.test(infos[2])? infos[2].toLowerCase() : 'unknown', local: false } }; /** * HELPER create filter-function for voice depending on language and/or gender * @param {VoiceOptions} options for listing voices: * options.language: the language code (may include country code) * @memberOf mmir.env.media.MaryWebAudioTTSImpl# * @private */ var _createVoiceFilter = function(options){ var reLang = null, reStr = null; if(options.language){ var parts = options.language.split(/[-_]/); reStr = '^'+parts[0]; if(parts[1]){ reStr += '[-_]'+parts[1]+'$'; } reLang = new RegExp(reStr, 'i'); } var reName = null; var reGender = null; if(options.details){ reStr = options.details.name; if(reStr){ reName = new RegExp('^'+reStr+'$', 'i'); } reStr = options.details.gender; if(reStr){ reGender = new RegExp('^'+reStr+'$', 'i'); } } return function(voice){ return (!reLang || reLang.test(voice.language)) && (!reName || reName.test(voice.name)) && (!reGender || reGender.test(voice.gender)); } }; /** @memberOf mmir.env.media.MaryWebAudioTTSImpl# * @private */ var generateTTSURL = function(text, options){ text = encodeURIComponent(text); var lang = _getFixedLang(options); var voice = _getVoiceParam(options); var voiceParamStr = voice? '&VOICE='+voice : ''; return config.get([_pluginName, "baseUrl"], _defaultServerPath) +'process?INPUT_TYPE=TEXT&OUTPUT_TYPE=AUDIO&INPUT_TEXT=' + text + '&LOCALE='+lang + voiceParamStr + '&AUDIO=WAVE_FILE'; }; /** @memberOf mmir.env.media.MaryWebAudioTTSImpl# * @private */ var createAudio = function(sentence, options, onend, onerror, oninit){ return mediaManager.getURLAsAudio( generateTTSURL(sentence, options), onend, onerror, oninit ); }; /** @memberOf mmir.env.media.MaryWebAudioTTSImpl# * @requires CrossDomain and CSP: allow access to baseUrl (default: "http://mary.dfki.de:59125/") * @private */ var getList = function(type, callback, onerror){ var url = config.get([_pluginName, "baseUrl"], _defaultServerPath) + (type === 'voice'? 'voices' : 'locales'); load({ url: url, dataType: 'text', success: function(data){ // console.log(data) callback && callback(data? data.trim().split(/\r?\n/) : []); }, error: onerror }); }; /** @memberOf mmir.env.media.MaryWebAudioTTSImpl# * @requires CrossDomain and CSP: allow access to baseUrl (default: "http://mary.dfki.de:59125/") * @see mmir.MediaManager#getSpeechLanguages * @private */ var getLanguageList = function(callback, onerror){ getList('language', callback, onerror); }; /** @memberOf mmir.env.media.MaryWebAudioTTSImpl# * @requires CrossDomain and CSP: allow access to baseUrl (default: "http://mary.dfki.de:59125/") * @see mmir.MediaManager#getVoices * @private */ var getVoiceList = function(options, callback, onerror){ getList('voice', function(list){ var voices = list.map(function(raw){ return _toVoiceDetails(raw);}); var isFilter = options && (options.language || (options.details && (options.details.name || options.details.gender))); var filteredList = !isFilter? voices : voices.filter(_createVoiceFilter(options)); var isDetails = options && options.details; callback && callback(isDetails? filteredList : filteredList.map(function(v){ return v.name;})); }, onerror); }; /** @memberOf mmir.env.media.MaryWebAudioTTSImpl# */ return { /** * @public * @memberOf mmir.env.media.MaryWebAudioTTSImpl.prototype */ getPluginName: function(){ return _pluginName; }, /** * @public * @memberOf mmir.env.media.MaryWebAudioTTSImpl.prototype */ getCreateAudioFunc: function(){ return createAudio; }, /** * @public * @memberOf mmir.env.media.MaryWebAudioTTSImpl.prototype */ getLanguageListFunc: function(){ return getLanguageList; }, /** * @public * @memberOf mmir.env.media.MaryWebAudioTTSImpl.prototype */ getVoiceListFunc: function(){ return getVoiceList; }, /** * @public * @memberOf mmir.env.media.MaryWebAudioTTSImpl.prototype */ setLangParamFunc: function(getLangParamFunc){ _getLangParam = getLangParamFunc; }, /** * @public * @memberOf mmir.env.media.MaryWebAudioTTSImpl.prototype */ setVoiceParamFunc: function(getVoiceParamFunc){ _getVoiceParam = getVoiceParamFunc; } };//END: return { ... };//END: createMaryTTSImpl(defaultLogger){... });