Skip to content

Commit

Permalink
breaking changes. fix #5 and #6
Browse files Browse the repository at this point in the history
  • Loading branch information
YerkoPalma committed Nov 27, 2017
1 parent c623df6 commit 8d851b2
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 73 deletions.
21 changes: 17 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ var choo = require('choo')
var html = require('choo/html')

var app = choo()
app.use(require('choo-tts'))
app.use(require('choo-tts')())
app.route('/', mainView)
app.mount('body')

Expand Down Expand Up @@ -76,7 +76,7 @@ function speech (state, emitter) {
})
}

// later in yout view
// later in your view
function view (state, emit) {
return html`<body>
<button onclick="${regularSpeech}">regular speech</button>
Expand Down Expand Up @@ -108,8 +108,21 @@ with every speech, but you can set this for a specific speech, if you set an `id
property to the object passed to the speak event.

## API
### `tts = require('choo-tts')`
Load the plugin and populate a `tts` object to the state.
### `plugin = tts([opts])`
The plugin accept an options object and return the plugin. The `opts` object
can have the following properties:

- `voice`: A string with the name of the voice to be selected as `selectedVoice`.
if not set, or not found, will use the browser default voice.
- `rate`: The speed of the utterance to be spoken, can be a value
from 0.1 to 10, defaults to 1.
- `pitch`: The pitch of the utterance to be spoken, can be a value from 0
to 2, defaults to 1.
- `volume`: The volume of the utterance to be spoken, can be a value from 0
to 1, defaults to 0.5.

If everything goes right, then the plugin will populate a `tts` object to the
state.

- `tts.state`: Get the state of text-to-speech object. Can be any of the
following strings: `PAUSED`, `PENDING`, `SPEAKING` or `READY`.
Expand Down
4 changes: 2 additions & 2 deletions example.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ var choo = require('choo')
var html = require('choo/html')

var app = choo()
app.use(require('.'))
app.use(require('.')())
app.use(speech)
app.route('/', mainView)
app.mount('body')
Expand Down Expand Up @@ -45,6 +45,6 @@ function speech (state, emitter) {
})
emitter.on('tts:speech-end', function ({ event, id }) {
window.alert(`speech took ${event.elapsedTime} ms`)
if (id === 'special') window.alert('Tha was special!')
if (id === 'special') window.alert('That was special!')
})
}
139 changes: 72 additions & 67 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,75 +14,80 @@ var events = tts.events = {
ERROR: 'tts:error'
}

function tts (state, emitter) {
var synth = window.speechSynthesis
try {
if (!synth) throw new Error('tts:error - speechSynthesis not supported')
// set default values
state.tts = {}
state.tts.pitch = 1
state.tts.rate = 1
state.tts.volume = 0.5
// readonly state
Object.defineProperty(state.tts, 'state', {
get: function () {
// check state
return synth.paused ? 'PAUSED' : synth.pending ? 'PENDING' : synth.speaking ? 'SPEAKING' : 'READY'
}
})
Object.defineProperty(state.tts, 'voices', {
get: function () {
return synth.getVoices()
}
})
state.tts.selectedVoice = state.tts.voices.filter(voice => voice.default)[0]
function tts (opts) {
opts = opts || {}
return function (state, emitter) {
var synth = window.speechSynthesis
try {
if (!synth) throw new Error('tts:error - speechSynthesis not supported')
// set default values
state.tts = {}
state.tts.pitch = opts.pitch || 1
state.tts.rate = opts.rate || 1
state.tts.volume = opts.volume || 0.5
// readonly state
Object.defineProperty(state.tts, 'state', {
get: function () {
// check state
return synth.paused ? 'PAUSED' : synth.pending ? 'PENDING' : synth.speaking ? 'SPEAKING' : 'READY'
}
})
Object.defineProperty(state.tts, 'voices', {
get: function () {
return synth.getVoices()
}
})
state.tts.selectedVoice = state.tts.voices.filter(voice => opts.voice ? voice.name === opts.voice : voice.default)[0]
// if the voice name defined in options wasn't found
state.tts.selectedVoice = state.tts.selectedVoice || state.tts.voices.filter(voice => voice.default)[0]

emitter.on(events.SPEAK, speech => {
var utterance = null
var speechId
// if a string is passed, use values from the state
if (typeof speech === 'string') {
utterance = new SpeechSynthesisUtterance(speech)
utterance.voice = state.tts.selectedVoice
utterance.pitch = state.tts.pitch
utterance.rate = state.tts.rate
utterance.volume = state.tts.volume
} else if (typeof speech === 'object') {
var opts = Object.assign(state.tts, speech)
utterance = new SpeechSynthesisUtterance(speech.text)
utterance.voice = state.tts.selectedVoice
utterance.pitch = opts.pitch
utterance.rate = opts.rate
utterance.volume = opts.volume
speechId = opts.id
}
synth.speak(utterance)
utterance.onstart = function (event) {
emitter.emit(events.SPEECH_START, { event, id: speechId })
}
utterance.onend = function (event) {
emitter.emit(events.SPEECH_END, { event, id: speechId })
}
utterance.onboundary = function (event) {
emitter.emit(events.SPEECH_BOUNDARY, { event, id: speechId })
emitter.on(events.SPEAK, speech => {
var utterance = null
var speechId
// if a string is passed, use values from the state
if (typeof speech === 'string') {
utterance = new SpeechSynthesisUtterance(speech)
utterance.voice = state.tts.selectedVoice
utterance.pitch = state.tts.pitch
utterance.rate = state.tts.rate
utterance.volume = state.tts.volume
} else if (typeof speech === 'object') {
var customOpts = Object.assign(state.tts, speech)
utterance = new SpeechSynthesisUtterance(speech.text)
utterance.voice = state.tts.selectedVoice
utterance.pitch = customOpts.pitch
utterance.rate = customOpts.rate
utterance.volume = customOpts.volume
speechId = customOpts.id
}
synth.speak(utterance)
utterance.onstart = function (event) {
emitter.emit(events.SPEECH_START, { event, id: speechId })
}
utterance.onend = function (event) {
emitter.emit(events.SPEECH_END, { event, id: speechId })
}
utterance.onboundary = function (event) {
emitter.emit(events.SPEECH_BOUNDARY, { event, id: speechId })
}
})
emitter.on(events.CANCEL, synth.cancel)
emitter.on(events.PAUSE, synth.pause)
emitter.on(events.RESUME, synth.resume)
synth.onvoiceschanged = function () {
state.tts.voices = synth.getVoices()
emitter.emit(events.VOICES_CHANGED)
}
})
emitter.on(events.CANCEL, synth.cancel)
emitter.on(events.PAUSE, synth.pause)
emitter.on(events.RESUME, synth.resume)
synth.onvoiceschanged = function () {
state.tts.voices = synth.getVoices()
emitter.emit(events.VOICES_CHANGED)
emitter.on(events.SET_VOICE, voiceName => {
if (!state.tts.voices) throw new Error('tts: Voices array no set yet, can\'t set voice')
var voice = state.tts.voices.filter(v => {
return v.name === voiceName
})[0]
if (!voice) throw new Error('tts: Voice ' + voiceName + ' not found')
state.tts.selectedVoice = voice
})
} catch (e) {
emitter.emit(events.ERROR, e)
}
emitter.on(events.SET_VOICE, voiceName => {
if (!state.tts.voices) throw new Error('tts: Voices array no set yet, can\'t set voice')
var voice = state.tts.voices.filter(v => {
return v.name === voiceName
})[0]
if (!voice) throw new Error('tts: Voice ' + voiceName + ' not found')
state.tts.selectedVoice = voice
})
} catch (e) {
emitter.emit(events.ERROR, e)
}
}
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@
"choo": "^6.6.0",
"snazzy": "^7.0.0",
"standard": "^10.0.3"
},
"dependencies": {
"speech-synthesis-recorder": "^1.0.0"
}
}

0 comments on commit 8d851b2

Please sign in to comment.