say_job(
s,opts) ->job,err
Speak incrementally: a sliced render job
say in slices, for a caller inside an event loop. A long line takes tens
of milliseconds to render. One say call holds the thread that long, so
an audio writer starves and a frame stalls. A job does the same work a
slice at a time.
Each job.step() renders opts.yield_every parameter frames, default 40:
about 200 ms of speech for about 1 ms of work. The knob is the job's
alone; say and synth render whole and ignore it. step returns:
buf, info: done. The final step resamples to opts.rate.false, err: failed. The job is dead.A step after the end returns the same result again. job.done() reports
the end without stepping. The output is the same bytes say(s, opts)
gives.