8000 Espeak - event loop and recurrent say calls fix by willwade · Pull Request #363 · nateshmbhat/pyttsx3 · GitHub
[go: up one dir, main page]

Skip to content
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

Open
wants to merge 42 commits into
base: master
Choose a base branch
from

Conversation

willwade
Copy link
Collaborator
@willwade willwade commented Nov 4, 2024

So this fixes

  • External Event Loop in espeak
  • Calling say multiple times and then runAndWait

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.

@willwade willwade changed the title DRAFT attempt at fixing event loop DRAFT attempt at fixing event loop in espeak Nov 4, 2024
@willwade
Copy link
Collaborator Author
willwade commented Nov 4, 2024

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()

@willwade willwade changed the title DRAFT attempt at fixing event loop in espeak Espeak - event loop and recurrent say calls fix Nov 4, 2024
@@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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

@cclauss
Copy link
Contributor
cclauss commented Nov 13, 2024

modprobe: FATAL: Module snd-dummy not found in directory /lib/modules/6.5.0-1025-azure

???

@cclauss
Copy link
Contributor
cclauss commented Nov 13, 2024

Maybe skip the tests AFTER tests/test_pyttsx3.py::test_changing_volume PASSED if $CI is defined.

Copy link
Contributor
@cclauss cclauss left a 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__)
Copy link
Contributor

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.

willwade and others added 11 commits November 15, 2024 16:00
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>
Copy link
Contributor
@cclauss cclauss left a 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.

@willwade
Copy link
Collaborator Author

Please do not merge with failing tests.

No worries! I wont!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0