-
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
AVSynthesiser for Mac Engine #350
Conversation
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
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.
Edit
Line 41 in da247c1
'darwin': 'nsss', |
- Change
nsss
toavsynth
and save the change python -m pip install --editable .
python
>>> import pyttsx3
>>> engine = pyttsx3.init()
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 |
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.
Local tests work for me.
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.
>>> 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.
Will |
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
failing on external event loop test. working on a fix.. |
may need ffmpeg for tests mind you. lets see
This reverts commit c2ffcfd.
This test can be added near the top of @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 |
Yeah. This is definitely broken right now. This and cleaning up the espeak stuff is on my priority list |
Co-authored-by: Christian Clauss <[email protected]>
Co-authored-by: Christian Clauss <[email protected]>
Co-authored-by: Christian Clauss <[email protected]>
add avsynth details to rest Co-authored-by: Christian Clauss <[email protected]>
Co-authored-by: Christian Clauss <[email protected]>
may still need to use ruff after this
Co-authored-by: Christian Clauss <[email protected]>
pyttsx3/drivers/avspeech.py
Outdated
print( | ||
f"Finished utterance: {utterance.speechString()}" | ||
) # Debugging: Track each completed utterance |
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.
print( | |
f"Finished utterance: {utterance.speechString()}" | |
) # Debugging: Track each completed utterance | |
# Debugging: Track each completed utterance | |
print(f"Finished utterance: {utterance.speechString()}") |
Run |
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" |
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.
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" |
Co-authored-by: Christian Clauss <[email protected]>
Co-authored-by: Christian Clauss <[email protected]>
Co-authored-by: Christian Clauss <[email protected]>
Where we are up to:
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 |
So this looks ok to me. I just need some brains to figure out how we
#347 #336
I think this is passing all the tests. Its far simpler than nsss and we can do thngs like ssml #121 #287