1 Commits

Author SHA1 Message Date
b4814d431f feat: ignore own speech
When we detect that Pepper is talking we stop sending audio.

ref: N25B-214
2025-10-27 13:08:57 +01:00
4 changed files with 36 additions and 0 deletions

View File

@@ -21,6 +21,7 @@ class ActuationReceiver(ReceiverBase):
self.create_socket(zmq_context, zmq.SUB, port)
self.socket.setsockopt_string(zmq.SUBSCRIBE, u"") # Causes block if given in options
self._tts_service = None
self._al_memory = None
def _handle_speech(self, message):
text = message.get("data")
@@ -40,10 +41,26 @@ class ActuationReceiver(ReceiverBase):
if not self._tts_service:
self._tts_service = state.qi_session.service("ALTextToSpeech")
if not self._al_memory:
self._al_memory = state.qi_session.service("ALMemory")
# Subscribe to speech end event
self.status_subscriber = self._al_memory.subscriber("ALTextToSpeech/Status") # self because garbage collect
self.status_subscriber.signal.connect(self._on_status_changed)
# Returns instantly. Messages received while speaking will be queued.
qi.async(self._tts_service.say, text)
@staticmethod
def _on_status_changed(value): # value will contain either 'enqueued', 'started' or 'done' depending on the status
"""Callback function for when the speaking status changes. Will change the is_speaking value of the state."""
if "started" in value:
logging.debug("Started speaking.")
state.is_speaking = True
if "done" in value:
logging.debug("Done speaking.")
state.is_speaking = False
def handle_message(self, message):
if message["endpoint"] == "actuate/speech":
self._handle_speech(message)

View File

@@ -57,6 +57,13 @@ class AudioSender(SocketBase):
try:
while not state.exit_event.is_set():
# Don't send audio if Pepper is speaking
if state.is_speaking:
if stream.is_active(): stream.stop_stream()
continue
if stream.is_stopped(): stream.start_stream()
data = stream.read(chunk)
self.socket.send(data)
except IOError as e:

View File

@@ -43,8 +43,19 @@ def main_loop(context):
logging.debug("Starting main loop.")
import schedule
test_speaking_message = {"data": "Hi, my name is Pepper, and this is quite a long message."}
def test_speak():
logging.debug("Testing speech.")
actuation_receiver._handle_speech(test_speaking_message)
schedule.every(10).seconds.do(test_speak)
while True:
if state.exit_event.is_set(): break
schedule.run_pending()
socks = dict(poller.poll(100))
for receiver in receivers:

View File

@@ -18,6 +18,7 @@ class State(object):
self.exit_event = None
self.sockets = [] # type: List[SocketBase]
self.qi_session = None # type: None | ssl.SSLSession
self.is_speaking = False # type: Boolean
def initialize(self):
if self.is_initialized: