3

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.

2

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
  • Thanks. I'll give that a try. I was able to get my above setup to work on my desktop and another remote server, so I think it has to do with espeak on the pi. I know TTS takes some horsepower, especially if you want it responsive. – user2368261 Apr 29 '16 at 1:09
  • 1
    If you have netcat-openbsd on a non-Debian-derived Linux, the endless loop may be due to netcat not handling POLLHUP when the reader (or writer, in this case) goes away. See bugzilla.redhat.com/show_bug.cgi?id=156835 and anonscm.debian.org/cgit/collab-maint/netcat-openbsd.git/tree/…. Using one of the other netcat variants, or socat as you recommend, does the trick. – zackse Apr 29 '16 at 1:24
  • I should have mentioned the pi is running raspbian. – user2368261 Apr 29 '16 at 22:56
0

A reinstall of Raspbian seems to have solved the issue. I think I installed something during an earlier project that interfered with Alsa.

Espeak is now responsive in both regular interactive mode and when piping stuff in from netcat. However, it will start breaking up after about 5 or 10 seconds of audio, but I don't think that will be a problem for me since it'll only be reading off short messages. This problem has been mentioned on some other forums as well. Here's a link to a post on the raspberypi.org forums about this topic, and it seems I was right about the pi's audio being flaky. Basically the solution mentioned in the link that works for me is to force espeak to output the speech to stdout rather than the audio card, then pipe that to aplay.

espeak --stdout <text> | aplay -q

This works perfectly when piping stuff in through netcat as well.

0

Assuming you don't require nc, you can use the -c feature of ncat. You may have to get it though, and since you are using raspbian, use this to get it:

apt-get install nmap --no-install-recommends

There are a lot of uneeded files with nmap, so this should get you ncat.

To set up the server you want, run this:

ncat -l 7777 -k -c "espeak"

To connect (note that you can use any nc variation):

ncat [your host ip] 7777

What -c does in ncat is run a command when a client connects, and send the command's stdout to the client, and recieve the stdin from the client. This allows you to remotely execute the espeak command.

Another easier thing to do is just use ssh, which is what I did in your situation. You should be able to enable the ssh server on your pi using raspi-config, or do it the hard way.

You also note audio problems, which I also had with my pi. It all comes down to alsa being stupid, and I think I remember not being able to fix it until I reburnt raspbian to my sd card. Having an inadiquate power supply can also make the audio stutter, which I fixed by turning the volume down to a point where it didn't sound bad, and used an amplified speaker to make it louder. Worked like a charm!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.