Broadcasting text to speech with Python
### Background ###
As a busy father there are times during the day when I can not be glued to the computer, but am free to listen to something on headphones (ie doing dishes, cleaning the garage etc). Sometimes I listen to podcasts - but sometimes I'm out of interesting ones. I've recently been working on learning Django and wanted to be able to lurk on the IRC channel more. Its not something that I always want to have front and center on my screen, but would be interested in listening in on as if it were a conversation. So I thought: "I wonder if I can use the built-in OS X text to speech engine and broadcast that over streaming MP3 to my iPhone". So began a saturday project during the kid's nap, with some tweaks over the next several evenings.
The result is several pieces that can be used separately or together:
* a basic IRC bot (basically taken from a python irc library)
* a method of taking a set of strings, converting them to spoken text and then pushing them out as streaming MP3
While I developed the latter to work in service of the former, the basic technique could be used with any number of text sources - such as tailing logs etc, there is some interesting potential.
### The pieces ###
For the IRC bits, I mainly rely on the irclib and ircbot modules from this [Python project] [irclib]
To speak the text locally is relatively straightforward, just calling the "say" command line tool.
Putting the rest of the pieces together assumes you are running Leopard, as it has more the of the libraries required. All of these libraries compiled fine on Leopard using the standard
sudo make install
Here are the bits needed for the broadcast part of this to run:
For converting the spoken text to MP3 you need the [LAME library][lame]
To broadcast this mp3, you need access to a icecast or shoutcast server. To get your own running on Leopard you need to first install the [libogg and libvorbis][vorbis] (maybe just one or the other is needed, but easy enough to do both)
You then need the icecast program itself, plus the libshout library and its Python binding all from [icecast.org][icecast]
This may seem like a lot, but if you are familiar with the above 3 step process - it goes smoothly.
### Installation and Usage ###
Assuming you now have all the libraries and the icecast binary installed, the only other tool you need is the short shell script txt2mp3 that takes text as input and spits out mp3 data as output. Place this somewhere on your shell path ie /usr/local/bin/
There are then 2 python scripts (and a shared python module), one just speaks the IRC traffic locally (localspeak.py), the other will broadcast it to an icecast server (icecastbot.py). Both will require some configuration of variables to point to your icecast server so as to match the settings in your iceast.xml configuration file, as well as IRC settings using a unique nick for the IRC bot.
The two mp3 files are used by the streaming script and should be in the same directory as it.
To kill the bot, /msg the bot on IRC the text 'die', given that this is threaded, there is not an easy way to kill it from the terminal (I'm sure there is a way to write the python code to handle this better, but I don't know it)
Be sure to set the voice on your computer to use "Alex" its the highest quality one, and makes conversation much more intelligible. I've included a minimal "pronounce dict" dictionary - will need adding to.
### Random notes ###
* You can get some really weird results if you mix MP3s of different bit/sample rates
* My threading code isn't the most bombproof. I'm not using a lock, but am relying on the deque data type to be "thread safe" internally as the docs imply.
* Compiling Unix'y' stuff on OS X has gotten way better than it used to by!
* If you can't get the locally speaking version working, don't even try the broadcast version
* My current favorite iPhone client for listening to streams is Wunder Radio
### License ###
Copyright (c) 2009 Preston Holmes
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
[irclib]:http://python-irclib.sourceforge.net/ "Python IRC Library"