-
Notifications
You must be signed in to change notification settings - Fork 346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Espeak - event loop and recurrent say calls fix #363
base: master
Are you sure you want to change the base?
Conversation
NB I used test code of this @cclauss I'm not sure now how accurate this is to our pytest code.. import pyttsx3
from pyinstrument import Profiler
import time
# Initialize the pyttsx3 engine
engine = pyttsx3.init("espeak")
# Set up event listeners for debugging
def on_start(name):
print(f"[DEBUG] Started utterance: {name}")
print(f"Started utterance: {name}")
def on_word(name, location, length):
print(f"Word: {name} at {location} with length {length}")
# Interrupt the utterance if location is above a threshold to simulate test_interrupting_utterance
if location > 10:
print("Interrupting utterance by calling endLoop...")
engine.stop() # Directly call endLoop instead of stop
def on_end(name, completed):
print(f"Finished utterance: {name}, completed: {completed}")
# Connect the listeners
# engine.connect("started-utterance", on_start)
# engine.connect("started-word", on_word)
# engine.connect("finished-utterance", on_end)
# Demo for test_interrupting_utterance
def demo_interrupting_utterance():
print("\nRunning demo_interrupting_utterance...")
engine.say("The quick brown fox jumped over the lazy dog.")
engine.runAndWait()
# Demo for test_external_event_loop
def demo_external_event_loop():
print("\nRunning demo_external_event_loop...")
def external_loop():
# Simulate external loop iterations
for _ in range(5):
engine.iterate() # Process engine events
time.sleep(0.5) # Adjust timing as needed
engine.say("The quick brown fox jumped over the lazy dog.")
engine.startLoop(False) # Start loop without blocking
external_loop()
print("Calling endLoop from external demo...")
engine.endLoop() # End the event loop explicitly
# Demo for testing multiple `say` calls followed by `runAndWait`
def demo_multiple_say_calls():
print("\nRunning demo_multiple_say_calls...")
engine.say("The first sentence.")
engine.runAndWait() # Should speak "The first sentence."
print("Calling say after the first runAndWait()...")
engine.say("The second sentence follows immediately.")
engine.runAndWait() # Should speak "The second sentence follows immediately."
print("Calling say after the second runAndWait()...")
engine.say("Finally, the third sentence is spoken.")
engine.runAndWait() # Should speak "Finally, the third sentence is spoken."
# Run demos
demo_interrupting_utterance()
# Initialize the profiler
profiler = Profiler()
# Start profiling for the external event loop demo
profiler.start()
# Run the external event loop demo
demo_external_event_loop()
# Stop profiling
profiler.stop()
# Print the profiling report
profiler.print()
# Run the multiple `say` calls demo
demo_multiple_say_calls() |
Co-authored-by: Christian Clauss <cclauss@me.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
.github/workflows/python_publish.yml
Outdated
@@ -30,7 +30,7 @@ jobs: | |||
runs-on: ${{ matrix.os }} | |||
steps: | |||
- if: runner.os == 'Linux' | |||
run: sudo apt-get update -q -q && sudo apt-get install --yes espeak-ng libespeak1 | |||
run: sudo apt-get update -q -q && sudo apt-get install --yes espeak-ng libespeak1 alsa-utils |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
run: sudo apt-get update -q -q && sudo apt-get install --yes espeak-ng libespeak1 alsa-utils | |
run: sudo apt-get update -q -q && sudo apt-get install --yes alsa-utils espeak-ng libespeak1 |
modprobe: FATAL: Module snd-dummy not found in directory /lib/modules/6.5.0-1025-azure ??? |
Maybe skip the tests AFTER tests/test_pyttsx3.py::test_changing_volume PASSED if $CI is defined. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the logger
@@ -7,12 +10,12 @@ | |||
from tempfile import NamedTemporaryFile | |||
import logging | |||
|
|||
logger = logging.getLogger(__name__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! Now we need to use logger
instead of logger
below.
Co-authored-by: Christian Clauss <cclauss@me.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do not merge with failing tests.
No worries! I wont! |
So this fixes
it now has its own internal queue - which seems crazy since driver has a queue but it just was not easy making use of it
I feel this should be ok since sapi and mac dont really make use of the driver queue..
In time this whole library needs better reactoring around queues. Its really horrible to get your head around.
@cclauss - can you run this through your tests - it is an attempt to fix the external event loop
Its got a lot of debug lines in it ..
If it basically works i'll remove these.