ssml_renderer.js 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.SsmlRenderer = void 0;
  4. const engine_js_1 = require("../common/engine.js");
  5. const EngineConst = require("../common/engine_const.js");
  6. const xml_renderer_js_1 = require("./xml_renderer.js");
  7. class SsmlRenderer extends xml_renderer_js_1.XmlRenderer {
  8. finalize(str) {
  9. return ('<?xml version="1.0"?><speak version="1.1"' +
  10. ' xmlns="http://www.w3.org/2001/10/synthesis"' +
  11. ` xml:lang="${engine_js_1.Engine.getInstance().locale}">` +
  12. '<prosody rate="' +
  13. engine_js_1.Engine.getInstance().getRate() +
  14. '%">' +
  15. this.separator +
  16. str +
  17. this.separator +
  18. '</prosody></speak>');
  19. }
  20. pause(pause) {
  21. return ('<break ' +
  22. 'time="' +
  23. this.pauseValue(pause[EngineConst.personalityProps.PAUSE]) +
  24. 'ms"/>');
  25. }
  26. prosodyElement(attr, value) {
  27. value = Math.floor(this.applyScaleFunction(value));
  28. const valueStr = value < 0 ? value.toString() : '+' + value.toString();
  29. return ('<prosody ' +
  30. attr.toLowerCase() +
  31. '="' +
  32. valueStr +
  33. (attr === EngineConst.personalityProps.VOLUME ? '>' : '%">'));
  34. }
  35. closeTag(_tag) {
  36. return '</prosody>';
  37. }
  38. markup(descrs) {
  39. SsmlRenderer.MARKS = {};
  40. return super.markup(descrs);
  41. }
  42. merge(spans) {
  43. const result = [];
  44. let lastMark = '';
  45. for (let i = 0; i < spans.length; i++) {
  46. const span = spans[i];
  47. if (this.isEmptySpan(span))
  48. continue;
  49. const kind = SsmlRenderer.MARK_KIND ? span.attributes['kind'] : '';
  50. const id = engine_js_1.Engine.getInstance().automark
  51. ? span.attributes['id']
  52. : engine_js_1.Engine.getInstance().mark
  53. ? span.attributes['extid']
  54. : '';
  55. if (id &&
  56. id !== lastMark &&
  57. !(SsmlRenderer.MARK_ONCE && SsmlRenderer.MARKS[id])) {
  58. result.push(kind ? `<mark name="${id}" kind="${kind}"/>` : `<mark name="${id}"/>`);
  59. lastMark = id;
  60. SsmlRenderer.MARKS[id] = true;
  61. }
  62. if (engine_js_1.Engine.getInstance().character &&
  63. span.speech.length === 1 &&
  64. span.speech.match(/[a-zA-Z]/)) {
  65. result.push('<say-as interpret-as="' +
  66. SsmlRenderer.CHARACTER_ATTR +
  67. '">' +
  68. span.speech +
  69. '</say-as>');
  70. }
  71. else {
  72. result.push(span.speech);
  73. }
  74. }
  75. return result.join(this.separator);
  76. }
  77. isEmptySpan(span) {
  78. const sep = span.attributes['separator'];
  79. return span.speech.match(/^\s*$/) && (!sep || sep.match(/^\s*$/));
  80. }
  81. }
  82. exports.SsmlRenderer = SsmlRenderer;
  83. SsmlRenderer.MARK_ONCE = false;
  84. SsmlRenderer.MARK_KIND = true;
  85. SsmlRenderer.CHARACTER_ATTR = 'character';
  86. SsmlRenderer.MARKS = {};