nateshmbhat / pyttsx3

Offline Text To Speech synthesis for python
Mozilla Public License 2.0
1.99k stars 321 forks source link

Configuring espeak driver on MacOS #311

Open Sirorezka opened 2 months ago

Sirorezka commented 2 months ago

Hello, I have installed and configured pyttsx3 on my macOS. And by default it uses nsss as driver and this setting works fine. However when I change the driver to espeak I'm unable to get any sound from the driver.

So by default you should have the following error on macOS:

'libespeak.so.1' (no such file)

To solve it I have installed espeak from the brew and linked it's libraries to the missing file:

  1. I have installed espeak using homewbew formula. I did also check that espeak works
    
    brew install  espeak

espeak "This is a test"

2. I have created the symlink `libespeak.so.1` to a `libespeak.dlyb` file. As far as I understood the `brew` renamed `.so.1` to `.dlyb`.

ln -s /opt/homebrew/Cellar/espeak/1.48.04_1/lib/libespeak.dylib libespeak.so.1

Now I don't get errors on missing 'libespeak.so.1', but I unfortunately can't hear any voice during execution:

import pyttsx3

engine = pyttsx3.init('espeak', debug=True) voices = engine.getProperty('voices') engine.setProperty('voice',voices[11].id) #English

engine.say('Hello sir, how may I help you, sir.') engine.runAndWait()



So, am I missing something here? Is this solvable?
willwade commented 1 month ago

interesting fix..

I find it at /usr/local/lib/libespeak.dylib

NB: Im on a silicon Mac - and I see /usr/local/lib/libespeak.dylib: Mach-O 64-bit dynamically linked shared library x86_64

So I assume thats the reason this isnt working on a Silicon Mac - its not built for Mac Silicon

I've attempted to fix like this but nay - dead for me https://github.com/willwade/py3-tts/commit/5cee3dd3cfa35385c838b94e6933046a3d1f7d08

Sirorezka commented 1 month ago

Hello, I have investigate a bit more time in the issue and have concluded that my fix doesn't fully solve the issue. It does remove the error about "'libespeak.so.1' ". However unfortunately doesn't allow to generate voice messages with the espeak engine. My guess that the issue is with the calls to the dylib. I.e. some API calls to espeak work (like get list of voices), but main call to the voice generation API doesn't work.

willwade commented 1 month ago

My guess that the issue is with the calls to the dylib. I.e. some API calls to espeak work (like get list of voices), but main call to the voice generation API doesn't work.

Yep. I concur. I think the upstream espeak lib is broken. Or maybe I'm not calling it right.

willwade commented 1 month ago

Related https://github.com/espeak-ng/espeak-ng/issues/982

willwade commented 1 month ago

See also https://github.com/rhasspy/piper/issues/404 it’s

nachoal commented 1 month ago

Hey @Sirorezka were you able to fix the issue of mac not being able to play any sound? I was able to make espeak-ng from my M3 mac and fix the file issues with:

but now when I run espeak 'text' it doesn't work, looking at the stdout it seems to be corrupted:

espeak-ng 'hello world' --stdout
|x=3�@` �nEAe!za^(�q�D� 10�Q    z}n�@Yow@�UUV�|vw~�&Nu� 5CKSXb_ZRMA5)#���������������"$ 
�W<A�/q�+L1BLF^>B.�x���"N1�,l��x�P>�Q�#���                                              E7cWLL[0#���.L��    �)
                                          ,as�,g�mgL �a*Vc�ZqmY���0_-6+���>Y�   ���Q����1��Q��'�IU0�33�
                                                                                                       QaT/yh\�R*�HZ�ijB^��(N%�Vd�z�W0��GV>�B6`9I0L0�S�a����hv
rOL�a�A�����w�g/M�l���P�Xli.K����j�h�yo>Q?�os{�o    S3�&zT�G;}^j�ye�0!@"s5vO_��a�p4�;
                    Sq���NyY���9�@
(�;T<�(%
       F����Y#�2�(-f{l����IX<l`�Z�,H�11�FVI�#17~��<�X��T7�e��x]
'�X��>7
DJ�_z   �13&@
             yx25DQ�tAw=�,-��|����)J�L  '�u�G%d2/P #!�!L$���-Rg*uGres<����X4�)U�fIh$$�&a��  �cc��J##A������
nachoal commented 1 month ago

So this seems to be an issue with portaudio, I was able to hear something when piping the output to a wav file: espeak-ng "Hello, world" --stdout > hello.wav I'm just gonna call it a day and change code to use this through a wrapper, let me know if you are able to make it work directly 😅

willwade commented 1 month ago

Short answer - no. I haven’t got it to work. That sounds promising. That output. Is that not the bytestream? So it wouldn’t be readable like that anyway? Tried piping it to portaudio eg https://github.com/espeak-ng/espeak-ng/blob/master/docs/guide.md#problems-with-pcaudiolib (Nb. I’ve assumed you’ve looked into this more than me and figured it’s using portaudio on Mac rather than another library)

One thing for anyone following this riveting discussion (!) is that on the Mac there are two common ways to skip building from source and installing. It might be worth anyone commenting here (including me!) to detail which method they are using.

  1. Homebrew. https://formulae.brew.sh/formula/espeak#default note it installs fine and seems to work. But - note it's using the old sourceforge repo code. A lot has changed. You really want the ng build https://formulae.brew.sh/formula/espeak-ng#default but this isn't working 2 MacPorts. https://ports.macports.org/port/espeak-ng/details/ - note the paths are different for these two

im away for a couple of weeks. I’ll dig more into this when I’m back.

dspasyuk commented 1 month ago

Anyone tried this script here: https://github.com/dspasyuk/llama.cui/blob/main/piper_install_mac.sh I have tested it on M2 Mac. Piper is integrated with Llama.cui.

willwade commented 1 month ago

Anyone tried this script here: https://github.com/dspasyuk/llama.cui/blob/main/piper_install_mac.sh I have tested it on M2 Mac. Piper is integrated with Llama.cui.

I think the key thing really here is this.

i``` f ! grep -qxF 'export DYLD_LIBRARY_PATH=/opt/homebrew/Cellar/espeak-ng/1.51/lib/:$DYLD_LIBRARY_PATH' ~/.zprofile; then echo 'export DYLD_LIBRARY_PATH=/opt/homebrew/Cellar/espeak-ng/1.51/lib/:$DYLD_LIBRARY_PATH' >> ~/.zprofile fi

Sirorezka commented 1 month ago

So this seems to be an issue with portaudio, I was able to hear something when piping the output to a wav file: espeak-ng "Hello, world" --stdout > hello.wav I'm just gonna call it a day and change code to use this through a wrapper, let me know if you are able to make it work directly 😅

I would consider piping everything to any exisiting system audio player. For example to afplay:

f=`mktemp` &&  espeak-ng "Hello, world" --stdout > "${f}" && afplay ${f}
willwade commented 3 weeks ago

Ok. Fixed this.

Read https://github.com/thevickypedia/py3-tts/issues/4 and https://github.com/thevickypedia/py3-tts/pull/6

The reason it doesn't play is that there is no code for it to actually play on Mac. There is a line to use aplay- which is Linux only. On Mac and windows we then need our own inbullt methods (Nb. Espeak DLL doesn't play audio. The command line does but this py library uses the dll).

See solution at https://github.com/willwade/py3-tts/blob/37bde65234c55ad0b59c58d454e50e325f645d13/pyttsx3/drivers/espeak.py#L182

note: there are a lot of discussions above and in other places about the dll not working at all. I think this is because the homebrew build isn't built right for silicon. So if you are using Apple silicon build it from scratch (and I mean the dependencies too). It's honestly easy and painless - just follow the docs in espeak docs

update I have this fully working on Mac & Windows now