How to get espeak to continuously speak stdout piped from netcat

espeaknetcatraspberry pitext to speech

I have a Raspberry pi 3 that I want to use as a sort of PA system, using espeak to announce stuff piped from netcat, which is getting input from a remote server. On the pi, I initiate the listener like so:

nc -lk 7777 | espeak

and on the remote remote machine (a Macbook pro for testing purposes) I issue

echo "hello world" | nc raspberrypi 7777

It speaks the first thing I send, but if I try sending more stuff, it won't output speech, and there's no text written to the terminal, either. It's as if espeak has stopped, even though netcat is still running.

I've tried initiating the listener without a pipe, so that it just puts stdout on the terminal, and I can spam the echo | nc command from the Mac and have all of it appear as expected on the pi.

I've tried googling a solution, and there's stuff about continuously feeding the stdout from an nc listener to a data file, but I can't see anything relating to espeak specifically.

I've also tried piping nc to other commands like tee and logsave, and they behave as I expect, continuously writing the output of nc to a file.

UPDATE

I noted in a comment below that I was able to get the setup mentioned above to work swimmingly with my beefy desktop running Linux Mint as the listener and an almost-as-beefy server box running Ubuntu server as the client sending the echoes. This made me think that something about the Pi, not nc, was to blame. My suspicion is that it has something to do with the Pi's audio, so I've tried a few things:

  • Streaming an mp3 radio station over wifi through both HDMI and the 3.5 mm jack using mplayer resulted in massive stuttering, although I could kind of make out what was going on. Trying it over ethernet yielded the same result.

  • Using mplayer to play a locally stored mp3 file over HDMI also resulted in the same stuttering.

  • using aplay to play the same mp3 over HDMI produced loud white noise.

I also tried espeak in interactive mode, and the same problem manifests. It says the first line I type, but ignores all subsequent lines. Sometimes, while messing with nc as above, it'll rapidly spit out all the lines I've tried feeding it at once.

Best Answer

I tried netcat -lk on my pi jessie with the 3 different versions of netcat, but they either dont support -k, or the server ending up in a busy loop after the first connection:

$ strace nc -l -k -p 7777 </dev/null | espeak --stdout >/dev/null
poll([{fd=0, events=POLLIN}, {fd=-1}], 2, -1) = 1 ([{fd=0, revents=POLLNVAL}])

I suggest you use socat which worked for me. Here's the equivalent line:

socat -u TCP4-LISTEN:7777,reuseaddr,fork - | espeak
Related Question