win32.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. const childProcess = require('child_process')
  2. const SayPlatformBase = require('./base.js')
  3. const BASE_SPEED = 0 // Unsupported
  4. const COMMAND = 'powershell'
  5. class SayPlatformWin32 extends SayPlatformBase {
  6. constructor () {
  7. super()
  8. this.baseSpeed = BASE_SPEED
  9. }
  10. buildSpeakCommand ({ text, voice, speed }) {
  11. let args = []
  12. let pipedData = ''
  13. let options = {}
  14. let psCommand = `Add-Type -AssemblyName System.speech;$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer;`
  15. if (voice) {
  16. psCommand += `$speak.SelectVoice('${voice}');`
  17. }
  18. if (speed) {
  19. let adjustedSpeed = this.convertSpeed(speed || 1)
  20. psCommand += `$speak.Rate = ${adjustedSpeed};`
  21. }
  22. psCommand += `$speak.Speak([Console]::In.ReadToEnd())`
  23. pipedData += text
  24. args.push(psCommand)
  25. options.shell = true
  26. return { command: COMMAND, args, pipedData, options }
  27. }
  28. buildExportCommand ({ text, voice, speed, filename }) {
  29. let args = []
  30. let pipedData = ''
  31. let options = {}
  32. let psCommand = `Add-Type -AssemblyName System.speech;$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer;`
  33. if (voice) {
  34. psCommand += `$speak.SelectVoice('${voice}');`
  35. }
  36. if (speed) {
  37. let adjustedSpeed = this.convertSpeed(speed || 1)
  38. psCommand += `$speak.Rate = ${adjustedSpeed};`
  39. }
  40. if (!filename) throw new Error('Filename must be provided in export();')
  41. else {
  42. psCommand += `$speak.SetOutputToWaveFile('${filename}');`
  43. }
  44. psCommand += `$speak.Speak([Console]::In.ReadToEnd());$speak.Dispose()`
  45. pipedData += text
  46. args.push(psCommand)
  47. options.shell = true
  48. return { command: COMMAND, args, pipedData, options }
  49. }
  50. runStopCommand () {
  51. this.child.stdin.pause()
  52. childProcess.exec(`taskkill /pid ${this.child.pid} /T /F`)
  53. }
  54. convertSpeed (speed) {
  55. // Overriden to map playback speed (as a ratio) to Window's values (-10 to 10, zero meaning x1.0)
  56. return Math.max(-10, Math.min(Math.round((9.0686 * Math.log(speed)) - 0.1806), 10))
  57. }
  58. getVoices () {
  59. let args = []
  60. let psCommand = 'Add-Type -AssemblyName System.speech;$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer;$speak.GetInstalledVoices() | % {$_.VoiceInfo.Name}'
  61. args.push(psCommand)
  62. return { command: COMMAND, args }
  63. }
  64. }
  65. module.exports = SayPlatformWin32