| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview Base class for Text-to-Speech engines that actually transform | 6 * @fileoverview Base class for Text-to-Speech engines that actually transform |
| 7 * text to speech. | 7 * text to speech. |
| 8 * | 8 * |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 | 24 |
| 25 /** | 25 /** |
| 26 * Default value for TTS properties. | 26 * Default value for TTS properties. |
| 27 * Note that these as well as the subsequent properties might be different | 27 * Note that these as well as the subsequent properties might be different |
| 28 * on different host platforms (like Chrome, Android, etc.). | 28 * on different host platforms (like Chrome, Android, etc.). |
| 29 * @type {{pitch : number, | 29 * @type {{pitch : number, |
| 30 * rate: number, | 30 * rate: number, |
| 31 * volume: number}} | 31 * volume: number}} |
| 32 * @protected | 32 * @protected |
| 33 */ | 33 */ |
| 34 this.propertyDefault = { | 34 this.propertyDefault = {'rate': 0.5, 'pitch': 0.5, 'volume': 0.5}; |
| 35 'rate': 0.5, | |
| 36 'pitch': 0.5, | |
| 37 'volume': 0.5 | |
| 38 }; | |
| 39 | 35 |
| 40 /** | 36 /** |
| 41 * Min value for TTS properties. | 37 * Min value for TTS properties. |
| 42 * @type {{pitch : number, | 38 * @type {{pitch : number, |
| 43 * rate: number, | 39 * rate: number, |
| 44 * volume: number}} | 40 * volume: number}} |
| 45 * @protected | 41 * @protected |
| 46 */ | 42 */ |
| 47 this.propertyMin = { | 43 this.propertyMin = {'rate': 0.0, 'pitch': 0.0, 'volume': 0.0}; |
| 48 'rate': 0.0, | |
| 49 'pitch': 0.0, | |
| 50 'volume': 0.0 | |
| 51 }; | |
| 52 | 44 |
| 53 /** | 45 /** |
| 54 * Max value for TTS properties. | 46 * Max value for TTS properties. |
| 55 * @type {{pitch : number, | 47 * @type {{pitch : number, |
| 56 * rate: number, | 48 * rate: number, |
| 57 * volume: number}} | 49 * volume: number}} |
| 58 * @protected | 50 * @protected |
| 59 */ | 51 */ |
| 60 this.propertyMax = { | 52 this.propertyMax = {'rate': 1.0, 'pitch': 1.0, 'volume': 1.0}; |
| 61 'rate': 1.0, | |
| 62 'pitch': 1.0, | |
| 63 'volume': 1.0 | |
| 64 }; | |
| 65 | 53 |
| 66 /** | 54 /** |
| 67 * Step value for TTS properties. | 55 * Step value for TTS properties. |
| 68 * @type {{pitch : number, | 56 * @type {{pitch : number, |
| 69 * rate: number, | 57 * rate: number, |
| 70 * volume: number}} | 58 * volume: number}} |
| 71 * @protected | 59 * @protected |
| 72 */ | 60 */ |
| 73 this.propertyStep = { | 61 this.propertyStep = {'rate': 0.1, 'pitch': 0.1, 'volume': 0.1}; |
| 74 'rate': 0.1, | |
| 75 'pitch': 0.1, | |
| 76 'volume': 0.1 | |
| 77 }; | |
| 78 | 62 |
| 79 | 63 |
| 80 /** @private */ | 64 /** @private */ |
| 81 | 65 |
| 82 if (cvox.AbstractTts.pronunciationDictionaryRegexp_ == undefined) { | 66 if (cvox.AbstractTts.pronunciationDictionaryRegexp_ == undefined) { |
| 83 // Create an expression that matches all words in the pronunciation | 67 // Create an expression that matches all words in the pronunciation |
| 84 // dictionary on word boundaries, ignoring case. | 68 // dictionary on word boundaries, ignoring case. |
| 85 var words = []; | 69 var words = []; |
| 86 for (var word in cvox.AbstractTts.PRONUNCIATION_DICTIONARY) { | 70 for (var word in cvox.AbstractTts.PRONUNCIATION_DICTIONARY) { |
| 87 words.push(word); | 71 words.push(word); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 117 }; | 101 }; |
| 118 | 102 |
| 119 | 103 |
| 120 /** @override */ | 104 /** @override */ |
| 121 cvox.AbstractTts.prototype.isSpeaking = function() { | 105 cvox.AbstractTts.prototype.isSpeaking = function() { |
| 122 return false; | 106 return false; |
| 123 }; | 107 }; |
| 124 | 108 |
| 125 | 109 |
| 126 /** @override */ | 110 /** @override */ |
| 127 cvox.AbstractTts.prototype.stop = function() { | 111 cvox.AbstractTts.prototype.stop = function() {}; |
| 128 }; | |
| 129 | 112 |
| 130 | 113 |
| 131 /** @override */ | 114 /** @override */ |
| 132 cvox.AbstractTts.prototype.addCapturingEventListener = function(listener) { }; | 115 cvox.AbstractTts.prototype.addCapturingEventListener = function(listener) {}; |
| 133 | 116 |
| 134 | 117 |
| 135 /** @override */ | 118 /** @override */ |
| 136 cvox.AbstractTts.prototype.increaseOrDecreaseProperty = | 119 cvox.AbstractTts.prototype.increaseOrDecreaseProperty = function( |
| 137 function(propertyName, increase) { | 120 propertyName, increase) { |
| 138 var min = this.propertyMin[propertyName]; | 121 var min = this.propertyMin[propertyName]; |
| 139 var max = this.propertyMax[propertyName]; | 122 var max = this.propertyMax[propertyName]; |
| 140 var step = this.propertyStep[propertyName]; | 123 var step = this.propertyStep[propertyName]; |
| 141 var current = this.ttsProperties[propertyName]; | 124 var current = this.ttsProperties[propertyName]; |
| 142 current = increase ? current + step : current - step; | 125 current = increase ? current + step : current - step; |
| 143 this.ttsProperties[propertyName] = Math.max(Math.min(current, max), min); | 126 this.ttsProperties[propertyName] = Math.max(Math.min(current, max), min); |
| 144 }; | 127 }; |
| 145 | 128 |
| 146 /** | 129 /** |
| 147 * Converts an engine property value to a percentage from 0.00 to 1.00. | 130 * Converts an engine property value to a percentage from 0.00 to 1.00. |
| 148 * @param {string} property The property to convert. | 131 * @param {string} property The property to convert. |
| 149 * @return {?number} The percentage of the property. | 132 * @return {?number} The percentage of the property. |
| 150 */ | 133 */ |
| 151 cvox.AbstractTts.prototype.propertyToPercentage = function(property) { | 134 cvox.AbstractTts.prototype.propertyToPercentage = function(property) { |
| 152 return (this.ttsProperties[property] - this.propertyMin[property]) / | 135 return (this.ttsProperties[property] - this.propertyMin[property]) / |
| 153 Math.abs(this.propertyMax[property] - this.propertyMin[property]); | 136 Math.abs(this.propertyMax[property] - this.propertyMin[property]); |
| 154 }; | 137 }; |
| 155 | 138 |
| 156 /** | 139 /** |
| 157 * Merges the given properties with the default ones. Always returns a | 140 * Merges the given properties with the default ones. Always returns a |
| 158 * new object, so that you can safely modify the result of mergeProperties | 141 * new object, so that you can safely modify the result of mergeProperties |
| 159 * without worrying that you're modifying an object used elsewhere. | 142 * without worrying that you're modifying an object used elsewhere. |
| 160 * @param {Object=} properties The properties to merge with the current ones. | 143 * @param {Object=} properties The properties to merge with the current ones. |
| 161 * @return {Object} The merged properties. | 144 * @return {Object} The merged properties. |
| 162 * @protected | 145 * @protected |
| 163 */ | 146 */ |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 * @param {string} text A text string to be spoken. | 209 * @param {string} text A text string to be spoken. |
| 227 * @param {Object= } properties Out parameter populated with how to speak the | 210 * @param {Object= } properties Out parameter populated with how to speak the |
| 228 * string. | 211 * string. |
| 229 * @return {string} The text formatted in a way that will sound better by | 212 * @return {string} The text formatted in a way that will sound better by |
| 230 * most speech engines. | 213 * most speech engines. |
| 231 * @protected | 214 * @protected |
| 232 */ | 215 */ |
| 233 cvox.AbstractTts.prototype.preprocess = function(text, properties) { | 216 cvox.AbstractTts.prototype.preprocess = function(text, properties) { |
| 234 if (text.length == 1 && text >= 'A' && text <= 'Z') { | 217 if (text.length == 1 && text >= 'A' && text <= 'Z') { |
| 235 for (var prop in cvox.AbstractTts.PERSONALITY_CAPITAL) | 218 for (var prop in cvox.AbstractTts.PERSONALITY_CAPITAL) |
| 236 properties[prop] = cvox.AbstractTts.PERSONALITY_CAPITAL[prop]; | 219 properties[prop] = cvox.AbstractTts.PERSONALITY_CAPITAL[prop]; |
| 237 } | 220 } |
| 238 | 221 |
| 239 // Substitute all symbols in the substitution dictionary. This is pretty | 222 // Substitute all symbols in the substitution dictionary. This is pretty |
| 240 // efficient because we use a single regexp that matches all symbols | 223 // efficient because we use a single regexp that matches all symbols |
| 241 // simultaneously. | 224 // simultaneously. |
| 242 text = text.replace( | 225 text = text.replace( |
| 243 cvox.AbstractTts.substitutionDictionaryRegexp_, | 226 cvox.AbstractTts.substitutionDictionaryRegexp_, function(symbol) { |
| 244 function(symbol) { | |
| 245 return ' ' + cvox.AbstractTts.SUBSTITUTION_DICTIONARY[symbol] + ' '; | 227 return ' ' + cvox.AbstractTts.SUBSTITUTION_DICTIONARY[symbol] + ' '; |
| 246 }); | 228 }); |
| 247 | 229 |
| 248 // Handle single characters that we want to make sure we pronounce. | 230 // Handle single characters that we want to make sure we pronounce. |
| 249 if (text.length == 1) { | 231 if (text.length == 1) { |
| 250 return cvox.AbstractTts.CHARACTER_DICTIONARY[text] ? | 232 return cvox.AbstractTts.CHARACTER_DICTIONARY[text] ? |
| 251 (new goog.i18n.MessageFormat(Msgs.getMsg( | 233 (new goog.i18n.MessageFormat( |
| 252 cvox.AbstractTts.CHARACTER_DICTIONARY[text]))) | 234 Msgs.getMsg(cvox.AbstractTts.CHARACTER_DICTIONARY[text]))) |
| 253 .format({'COUNT': 1}) : | 235 .format({'COUNT': 1}) : |
| 254 text.toUpperCase(); | 236 text.toUpperCase(); |
| 255 } | 237 } |
| 256 | 238 |
| 257 // Substitute all words in the pronunciation dictionary. This is pretty | 239 // Substitute all words in the pronunciation dictionary. This is pretty |
| 258 // efficient because we use a single regexp that matches all words | 240 // efficient because we use a single regexp that matches all words |
| 259 // simultaneously, and it calls a function with each match, which we can | 241 // simultaneously, and it calls a function with each match, which we can |
| 260 // use to look up the replacement in our dictionary. | 242 // use to look up the replacement in our dictionary. |
| 261 text = text.replace( | 243 text = text.replace( |
| 262 cvox.AbstractTts.pronunciationDictionaryRegexp_, | 244 cvox.AbstractTts.pronunciationDictionaryRegexp_, function(word) { |
| 263 function(word) { | |
| 264 return cvox.AbstractTts.PRONUNCIATION_DICTIONARY[word.toLowerCase()]; | 245 return cvox.AbstractTts.PRONUNCIATION_DICTIONARY[word.toLowerCase()]; |
| 265 }); | 246 }); |
| 266 | 247 |
| 267 // Expand all repeated characters. | 248 // Expand all repeated characters. |
| 268 text = text.replace( | 249 text = text.replace( |
| 269 cvox.AbstractTts.repetitionRegexp_, cvox.AbstractTts.repetitionReplace_); | 250 cvox.AbstractTts.repetitionRegexp_, cvox.AbstractTts.repetitionReplace_); |
| 270 | 251 |
| 271 return text; | 252 return text; |
| 272 }; | 253 }; |
| 273 | 254 |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 'angularjs': 'angular j s', | 442 'angularjs': 'angular j s', |
| 462 'bcc': 'B C C', | 443 'bcc': 'B C C', |
| 463 'cc': 'C C', | 444 'cc': 'C C', |
| 464 'chromevox': 'chrome vox', | 445 'chromevox': 'chrome vox', |
| 465 'cr48': 'C R 48', | 446 'cr48': 'C R 48', |
| 466 'ctrl': 'control', | 447 'ctrl': 'control', |
| 467 'doubleclick': 'double-click', | 448 'doubleclick': 'double-click', |
| 468 'gmail': 'gee mail', | 449 'gmail': 'gee mail', |
| 469 'gtalk': 'gee talk', | 450 'gtalk': 'gee talk', |
| 470 'http': 'H T T P', | 451 'http': 'H T T P', |
| 471 'https' : 'H T T P S', | 452 'https': 'H T T P S', |
| 472 'igoogle': 'eye google', | 453 'igoogle': 'eye google', |
| 473 'pagerank': 'page-rank', | 454 'pagerank': 'page-rank', |
| 474 'username': 'user-name', | 455 'username': 'user-name', |
| 475 'www': 'W W W', | 456 'www': 'W W W', |
| 476 'youtube': 'you tube' | 457 'youtube': 'you tube' |
| 477 }; | 458 }; |
| 478 | 459 |
| 479 | 460 |
| 480 /** | 461 /** |
| 481 * Pronunciation dictionary regexp. | 462 * Pronunciation dictionary regexp. |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 | 537 |
| 557 /** | 538 /** |
| 558 * Constructs a description of a repeated character. Use as a param to | 539 * Constructs a description of a repeated character. Use as a param to |
| 559 * string.replace. | 540 * string.replace. |
| 560 * @param {string} match The matching string. | 541 * @param {string} match The matching string. |
| 561 * @return {string} The description. | 542 * @return {string} The description. |
| 562 * @private | 543 * @private |
| 563 */ | 544 */ |
| 564 cvox.AbstractTts.repetitionReplace_ = function(match) { | 545 cvox.AbstractTts.repetitionReplace_ = function(match) { |
| 565 var count = match.length; | 546 var count = match.length; |
| 566 return ' ' + (new goog.i18n.MessageFormat(Msgs.getMsg( | 547 return ' ' + |
| 567 cvox.AbstractTts.CHARACTER_DICTIONARY[match[0]]))) | 548 (new goog.i18n.MessageFormat( |
| 568 .format({'COUNT': count}) + ' '; | 549 Msgs.getMsg(cvox.AbstractTts.CHARACTER_DICTIONARY[match[0]]))) |
| 550 .format({'COUNT': count}) + |
| 551 ' '; |
| 569 }; | 552 }; |
| 570 | 553 |
| 571 | 554 |
| 572 /** | 555 /** |
| 573 * @override | 556 * @override |
| 574 */ | 557 */ |
| 575 cvox.AbstractTts.prototype.getDefaultProperty = function(property) { | 558 cvox.AbstractTts.prototype.getDefaultProperty = function(property) { |
| 576 return this.propertyDefault[property]; | 559 return this.propertyDefault[property]; |
| 577 }; | 560 }; |
| 578 | 561 |
| 579 | 562 |
| 580 /** @override */ | 563 /** @override */ |
| 581 cvox.AbstractTts.prototype.toggleSpeechOnOrOff = function() { | 564 cvox.AbstractTts.prototype.toggleSpeechOnOrOff = function() { |
| 582 return true; | 565 return true; |
| 583 }; | 566 }; |
| OLD | NEW |