Listening and Talking to your Linux Box

25 Jan 2008

Traditional ways in which our computer applications 'talks' to us is by displaying lines of text or may be images or animations/videos. Apart from the occasional beep/alert sounds, the normal computer applications try to communicate to the user only visually. I wanted to go a few steps ahead and write some applications that would literally 'talk' to the user.

A tool that could translate text to speech was what i needed and i found a brilliant open source tool called Festival.

Installing Festival

sudo apt-get install festival

sudo apt-get install festvox-don

Turn on your speakers and try the following :

$ echo "Hello World" | festival --tts

Its so simple..!

Festival and the Shell

Festival when combined with the capabilities of the powerful Unix Shell gives awesome results.

$ cat filename.txt | festival --tts

$ man festival | festival --tts

$ echo "Hello $(whoami), $(who | wc -l) people are logged into $(hostname) now" | festival --tts Festival and Ruby

I wouldn't be satifisfied with anything unless i mix it with Ruby..!

Laptop lid program

A program that says "come back soon" when you close your laptop's lid, and says "Welcome back" when you open it back.

Linux's elegant /proc interface provides an easy way to sense closing and opening of laptop lid.

Try "cat /proc/acpi/button/lid/LID/state"

My ruby script polls this file for 'state' change, and uses festival to speak out the corresponding message, whenever lid is opened/closed.

Festival and IM

I couldn't stop before i tried using Festival with my Instant messenger programs :)

Idea was to make the IM programs read the received messages aloud, rather than me having to read it. It was fairly straight forward.

Voice chat

The Reverse process : Reading data from PC's microphone

I wanted to read raw sound data from my laptop's microphone and dump it into a disk file. In other words, i wanted to write a sound recording program.

In Linux systems, PC's soundcard is represented by /dev/dsp (or /dev/dsp or /dev/sound). Reading from /dev/dsp, we will get raw audio data from the 'line-in' or the 'built-in microphone'. We can dump raw digital audio data to /dev/dsp and it will be played on the speakers.

The sound input circuitry of the soundcard is an Analog to Digital Converter (ADC), which digitize the analog audio signals.

Programming the soundcard's ADC

The ADC has a few parameters which needs to be set before reading data from it, namely Sampling Rate and Sample Size.

  • Sampling rate decides the number of samples to be taken from the analog input per second.
  • Sample size is the precision with which each of these samples needs to be saved in digital format(to be precise, its the number of bits used per sample of data)
Ioctl() system call is used to set these paramters after opening "/dev/dsp". Ruby has a wrapper for ioctl(), but it dint work satisfactorily. So I used my all time favorite, the mighty C.

Recorder Program

You can compile the program using

cc record.c -o recorder

Then run it as

./recorder

It starts recording and records 10 seconds of audio (duration can be changed by editing the DURATION parameter in the code) and saves at sound.pcm in the current directory.

We cant use the usual media players to play it since its raw digital data. But we can simply dump into the "/dev/dsp" !!

cat sound.pcm > /dev/dsp

Its a demonstration of the beauty and power of the Unix architecture.

Necessary data for programming the soundcard were obtained from here and here