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

AVSynthesiser for Mac Engine #350

Merged
merged 60 commits into from
Nov 13, 2024
Merged

AVSynthesiser for Mac Engine #350

merged 60 commits into from
Nov 13, 2024

Conversation

willwade
Copy link
Collaborator

So this looks ok to me. I just need some brains to figure out how we

  • Add to test suite
  • Checking docs
  • Double checking code and making sure tests work

#347 #336

I think this is passing all the tests. Its far simpler than nsss and we can do thngs like ssml #121 #287

nateshmbhat#347 nateshmbhat#336

I think this is passing all the tests. Its far simpler than nsss and we can do thngs like ssml nateshmbhat#121 nateshmbhat#287
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.

Edit

'darwin': 'nsss',

  1. Change nsss to avsynth and save the change
  2. python -m pip install --editable .
  3. python
>>> import pyttsx3
>>> engine = pyttsx3.init()

@willwade
Copy link
Collaborator Author

Yeah. Slightly nervous of this. I need to make sure all tests are good and stuff like voices are the same. Don't want to break legacy code

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.

Local tests work for me.

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.

>>> engine=pyttsx3.init('nsss')
>>> engine.say("This is a test")
>>> engine.runAndWait()  # This works and the REPL does not quit.
>>> engine=pyttsx3.init('avsynth')
>>> engine.say("This is a test")
>>> engine.runAndWait()  # This works but the REPL quits which is a BUG.

@cclauss
Copy link
Contributor

cclauss commented Oct 27, 2024

Will avsynth work on iOS?

@willwade
Copy link
Collaborator Author

Will avsynth work on iOS?

well "technically" it should.. but no idea how you get all of python etc working on ios like this..

hard to see with black changes but basically " if not self._busy and hasattr(self, "_queue"):" in setBusy

cant see why this would break other engines.. famous last words
@willwade
Copy link
Collaborator Author

failing on external event loop test. working on a fix..

may need ffmpeg for tests mind you. lets see
@cclauss
Copy link
Contributor

cclauss commented Nov 2, 2024

This test can be added near the top of tests/test_pyttsx3.py before the other tests mess with the engine. The test passes for me but unfortunately, I hear no utterences.

@pytest.mark.skipif(sys.platform not in ("darwin", "ios"), reason="Testing only on macOS and iOS")
def test_apple_avsynth_voices(engine):
    import platform

    macos_version, _, macos_hardware = platform.mac_ver()
    print(f"{sys.platform = }, {macos_version = } on {macos_hardware = }")
    print(list(pyttsx3._activeEngines))
    print(engine)
    # assert str(engine) == "avsynth", "Expected engine name to be avsynth on macOS and iOS"
    voice = engine.getProperty("voice")
    # On macOS v14.x, the default nsss voice is com.apple.voice.compact.en-US.Samantha.
    # ON macOS v15.x, the default nsss voice is "".
    # ON macOS v15.x, the default avsynth voice is None.

    assert voice in (None, "", "com.apple.voice.compact.en-US.Samantha"), (
        f"Expected default voice {voice} to be com.apple.voice.compact.en-US.Samantha"
    )
    voices = engine.getProperty("voices")
    # On macOS v14.x, nsss has 143 voices.
    # On macOS v15.x, nsss has 176 voices
    print(f"On macOS v{macos_version}, {engine} has {len(voices) = } voices.")
    assert len(voices) in (176, 143), "Expected 176 or 143 voices on macOS and iOS"
    # print("\n".join(voice.id for voice in voices))
    en_us_voices = [voice for voice in voices if voice.id.startswith("com.apple.eloquence.en-US.")]
    assert len(en_us_voices) == 8, "Expected 8 com.apple.eloquence.en-US voices on macOS and iOS"
    names = []
    for _voice in en_us_voices:
        engine.setProperty("voice", _voice.id)
        name = _voice.id.split(".")[-1]
        names.append(name)
        engine.say(f"{name} says hello.")
    name_str = ", ".join(names)
    assert name_str == "Eddy, Flo, Grandma, Grandpa, Reed, Rocko, Sandy, Shelley"
    print(f"({name_str})", end=" ", flush=True)
    engine.runAndWait()
    engine.setProperty("voice", voice)  # Reset voice to original value

@willwade
Copy link
Collaborator Author

willwade commented Nov 2, 2024

Yeah. This is definitely broken right now. This and cleaning up the espeak stuff is on my priority list

willwade and others added 9 commits November 3, 2024 19:03
Co-authored-by: Christian Clauss <[email protected]>
Comment on lines 95 to 97
print(
f"Finished utterance: {utterance.speechString()}"
) # Debugging: Track each completed utterance
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
print(
f"Finished utterance: {utterance.speechString()}"
) # Debugging: Track each completed utterance
# Debugging: Track each completed utterance
print(f"Finished utterance: {utterance.speechString()}")

@cclauss
Copy link
Contributor

cclauss commented Nov 13, 2024

Run pre-commit run --all-files to fix the pre-commit error.

Comment on lines +55 to +59
assert voice in (
None,
"",
"com.apple.voice.compact.en-US.Samantha",
), f"Expected default voice {voice} to be com.apple.voice.compact.en-US.Samantha"
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
assert voice in (
None,
"",
"com.apple.voice.compact.en-US.Samantha",
), f"Expected default voice {voice} to be com.apple.voice.compact.en-US.Samantha"
if voice:
assert (
voice == "com.apple.voice.compact.en-US.Samantha",
), f"Expected default voice {voice} to be com.apple.voice.compact.en-US.Samantha"

@willwade
Copy link
Collaborator Author

Where we are up to:

  • say and runandwait does nothing
    but if you say and say twice - it will work

I have something wrong with queuing

eg

# Initialize the pyttsx3 engine
engine = pyttsx3.init("avspeech")

def demo_play_simple(): 
    print("\nRunning demo_play_simple...")
    engine.say("Playing a simple message")
    engine.runAndWait()
    
    # 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.")

    print("Calling say after the first runAndWait()...")
    engine.say("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."

demo_play_simple()
# Run the multiple `say` calls demo
demo_multiple_say_calls()

You will hear some of the sentences but not the final one. Its all out of sync

@willwade willwade merged commit 43509f4 into nateshmbhat:master Nov 13, 2024
7 of 10 checks passed
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