def background_thread_func(self): bytes_sent=ctypes.c_int16() out_buffer=ctypes.create_string_buffer(OUT_BUFFER_SIZE) bytes_received=ctypes.c_int16() data_type=ctypes.c_int16() while True: data, index = self.queue.get() if data is None: break synthIndexReached.notify(synth=self, index=index) remaining=len(data)+1 while remaining and self.isSpeaking: self.dll.pico_putTextUtf8(self.pico_engine, data, remaining, ctypes.byref(bytes_sent)) remaining-=bytes_sent.value data=data[bytes_sent.value:] status=PICO_STEP_BUSY buf=BytesIO() while self.isSpeaking and status==PICO_STEP_BUSY: status=self.dll.pico_getData(self.pico_engine, out_buffer, OUT_BUFFER_SIZE, ctypes.byref(bytes_received), ctypes.byref(data_type)) if status==PICO_STEP_BUSY: buf.write(ctypes.string_at(out_buffer, bytes_received.value)) if buf.tell() >= 4096: self.player.feed(buf.getvalue()) buf.seek(0) buf.truncate(0) else: if buf.tell(): self.player.feed(buf.getvalue()) synthDoneSpeaking.notify(synth=self) self.player.idle() if not self.isSpeaking: #stop requested during playback self.dll.pico_resetEngine(self.pico_engine,0) self.lastIndex=None self.queue.task_done()
def Bookmark(self, streamNum, pos, bookmark, bookmarkId): synth = self.synthRef() if synth is None: log.debugWarning( "Called Bookmark method on SapiSink while driver is dead") return synthIndexReached.notify(synth=synth, index=bookmarkId)
def run(self): try: self.wavePlayer = nvwave.WavePlayer( channels=1, samplesPerSec=self.sampleRate, bitsPerSample=16, outputDevice=config.conf["speech"]["outputDevice"]) self.synthEvent = threading.Event() finally: self.initializeEvent.set() while self.keepAlive: self.synthEvent.wait() self.synthEvent.clear() lastIndex = None while self.keepAlive: data = self.speechPlayer.synthesize(8192) if self.isSpeaking and data: indexNum = self.speechPlayer.getLastIndex() self.wavePlayer.feed( ctypes.string_at(data, data.length * 2), onDone=lambda indexNum=indexNum: synthIndexReached. notify(synth=self.synthRef(), index=indexNum) if indexNum >= 0 else False) lastIndex = indexNum else: indexNum = self.speechPlayer.getLastIndex() if indexNum > 0 and indexNum != lastIndex: synthIndexReached.notify(synth=self.synthRef(), index=indexNum) self.wavePlayer.idle() synthDoneSpeaking.notify(synth=self.synthRef()) break self.initializeEvent.set()
def ITTSBufNotifySink_BookMark(self, this, qTimeStamp, dwMarkNum): synth = self.synthRef() if synth is None: log.debugWarning("Called ITTSBufNotifySink_BookMark method on ITTSBufNotifySink while driver is dead") return synthIndexReached.notify(synth=synth, index=dwMarkNum) if synth._finalIndex == dwMarkNum: synth._finalIndex = None synthDoneSpeaking.notify(synth=synth)
def _callback(self, bytes, len, markers): if len == 0: # The C++ code will log an error with details. log.debugWarning("ocSpeech_speak failed!") self._processQueue() return # This gets called in a background thread. stream = io.BytesIO(ctypes.string_at(bytes, len)) wav = wave.open(stream, "r") self._maybeInitPlayer(wav) data = wav.readframes(wav.getnframes()) if markers: markers = markers.split('|') else: markers = [] prevPos = 0 # Push audio up to each marker so we can sync the audio with the markers. for marker in markers: if self._wasCancelled: break name, pos = marker.split(':') index = int(name) pos = int(pos) # pos is a time offset in 100-nanosecond units. # Convert this to a byte offset. # Order the equation so we don't have to do floating point. pos = pos * self._bytesPerSec // HUNDRED_NS_PER_SEC # Push audio up to this marker. self._player.feed(data[prevPos:pos], onDone=lambda index=index: synthIndexReached.notify(synth=self, index=index)) prevPos = pos if self._wasCancelled: if isDebugForSynthDriver(): log.debug("Cancelled, stopped pushing audio") else: self._player.feed(data[prevPos:]) if isDebugForSynthDriver(): log.debug("Done pushing audio") self._processQueue()
def _onIndexReached(self, index): synthIndexReached.notify(synth=self, index=index) def _onDoneSpeaking(self): synthDoneSpeaking.notify(synth=self)
def _onIndexReached(self, index): synthIndexReached.notify(synth=self, index=index)
def ITTSBufNotifySink_BookMark(self, this, qTimeStamp, dwMarkNum): synthIndexReached.notify(synth=self._synthDriver,index=dwMarkNum) if self._synthDriver._finalIndex==dwMarkNum: self._synthDriver._finalIndex=None synthDoneSpeaking.notify(synth=self._synthDriver)
def _onIndexReached(self, index): if index is not None: synthIndexReached.notify(synth=self, index=index) else: synthDoneSpeaking.notify(synth=self)