Mar 26

As a follow-on to our implementation of text to speech (TTS) announcements of weather conditions and alerts over our home ceiling speakers, we thought it would be useful to feed caller ID name from our home phone line into the TTS system. My mobile phone has a similar feature where it verbally announces known callers. It was surprising to me, but the feature on my mobile is pretty useful: when I am busy and I get a call from a known caller, I can make a decision to pick up without needing to touch the phone.

Some of you probably view home land lines as old tech as compared to the use of mobile phones and voice over IP (VOIP) solutions, but we still get some calls on our land line. Besides, the feature was pretty easy to implement because we already had most of the key components in place:

  • Home Linux server
  • Audio amplifier connecting home server to ceiling speakers
  • Cepstral TTS software

All we had to do was to connect an analog modem to our home server, set up the free Network Caller ID (ncid) software to trigger the TTS software and start enjoying this new feature.

In addition to voice announcement of caller ID names, we have desktop pop-up notifications that display the caller ID name and number. This is done via an extension to the core ncid software. Here’s what an incoming call looks like on one of our Macs:

Callerd ID pop up on Mac OS X

Dial-up Modem

Since I had previously recycled all of our older serial port analog dial-up modems, the modem is the one component we needed to buy for this solution. We ended up buying the Zoom 3095 USB modem. We installed the Linuxant driver for this Conexant chipset modem on our Ubuntu 8.04-based server and the system recognized the device:

[10599829.334557] usbcore: deregistering interface driver cdc_acm
[10599836.615583] usbcore: registered new interface driver dcgusbdcp
[10599836.618441] /c/builds/200910221327/dgcmodem-1.11/modules/mod_dgcusbdcp.c: dgcusbdcp_probe: adding union descriptor for cdc_acm
[10599837.298316] cdc_acm 1-1:2.0: ttyACM0: USB ACM device
[10599837.301785] usbcore: registered new interface driver cdc_acm
[10599837.301824] /build/buildd/linux-2.6.24/drivers/usb/class/cdc-acm.c: v0.25:USB Abstract Control Model driver for USB modems and ISDN adapters

And output from lsusb:

# lsusb
Bus 004 Device 001: ID 0000:0000  
Bus 003 Device 001: ID 0000:0000  
Bus 002 Device 001: ID 0000:0000  
Bus 001 Device 007: ID 0803:3095 Zoom Telephonics, Inc.
Bus 001 Device 005: ID 06cd:012a Keyspan USA-49Wlc serial adapter
Bus 001 Device 001: ID 0000:0000

I had originally crossed my fingers and hoped that the built-in drivers on Ubuntu 8.04 would work, but they did not. That led me to take the Linuxant route. Here are the original errors:

[10598899.847464] usb 1-1: new full speed USB device using uhci_hcd and address 6
[10598902.460191] usb 1-1: configuration #1 chosen from 2 choices
[10598902.768025] /build/buildd/linux-2.6.24/drivers/usb/class/cdc-acm.c: Zero length descriptor references
[10598902.768038]
[10598902.768127] cdc_acm: probe of 1-1:1.0 failed with error -22
[10598902.768168] usbcore: registered new interface driver cdc_acm
[10598902.768182] /build/buildd/linux-2.6.24/drivers/usb/class/cdc-acm.c: v0.25:USB Abstract Control Model driver for USB modems and ISDN adapters

Network Caller ID Software

Initial installation of the ncid software was a pain due to some dependency hell issues with the existing Ubuntu 8.04 packages. Once I tackled those issues, the software was easy to set up and test. (I probably should have taken the compile the source tar ball route, but I prefer to install binary packages whenever feasible). The basic problem with the ncid .deb packages was that they called for slightly older versions of dependencies that I had on my Ubuntu system. Since I suspected that the exact versions didn’t matter that much, I ignored the installation errors encountered while installing the ncid packages.

On our Ubuntu server, I installed the ncid, ncid-client and ncid-speak packages. The former contains the ncidd daemon that monitors the phone line via the modem while the latter enables you to get notified whenever a call and caller ID information is received. On our Mac OS X desktops, I installed the ncid-pop .dmg file to enable a Growl-based desktop notification of caller ID information.

After package installation I had to configure the ncidd daemon to start automatically as described at the bottom of the installation instructions for Ubuntu.

Since /dev/modem was already aliased to /dev/ttyACM0, I was able to use the test instructions in the CID test document to perform a simple test by starting the software and making a call. Everything worked fine on the first try!

# ncidd -Dv3
Started: 03/31/2010 20:40:37
Server: ncidd (NCID) 0.76
Verbose level: 3
ncidd logfile: /var/log/ncidd.log
Processed config file: /etc/ncid/ncidd.conf
Configured to send 'cidlog' to clients.
Configured to send 'cidinfo' to clients.
Processed alias file: /etc/ncid/ncidd.alias
CID logfile: /var/log/cidcall.log
CID logfile maximum size: 110000 bytes
Data logfile: /var/log/ciddata.log
Telephone Line Identifier: -
TTY port opened: /dev/ttyACM0
TTY port speed: 19200
TTY lock file: /var/lock/LCK..ttyACM0
TTY port control signals enabled
CallerID from AT Modem and maybe Gateway
AT Z S0=0 E1 V1 Q0
OK
Try 1 to init modem: return = 0.
Modem initialized.
AT+VCID=1
OK
Modem set for CallerID.
Network Port: 3333
Not using PID file, there was no '-P' option.
Client 6 connected, sent call log: /var/log/cidcall.log
Client 7 connected, sent call log: /var/log/cidcall.log
Client 8 connected, sent call log: /var/log/cidcall.log

RING
CIDINFO: *LINE*-*RING*1*

DATE = 0331

TIME = 2040

NAME = KAMPMEIER CHRIS

NMBR = 6363469885
CID: *DATE*03312010*TIME*2040*LINE*-*NMBR*6363469885*MESG*NONE*NAME*KAMPMEIER CHRIS*

RING
CIDINFO: *LINE*-*RING*2*

RING
CIDINFO: *LINE*-*RING*3*

CIDINFO: *LINE*-*RING*0*

Main Problem: Computer Answering Calls

The main problem we encountered during initial testing was that the home server would occasionally answer incoming calls as if it was a fax system. Not good at all. It turned out that the alias of /dev/modem to the actual device was causing some other application on our Linux system to compete with ncidd. After removing the /dev/modem alias and modifying /etc/ncid/ncidd.conf to use the device /dev/ttyACM0, this auto answer issue went away.

Follow-up: A month or so after setting up ncid, I noticed that one again the home server periodically attempted to answer incoming calls. To my surprise, the good ole /dev/modem symlink had magically reappeared. Digging a bit deeper, it turns out that under /etc/udev/rules.d/ a file 00-dgc.rules contains a setting to establish this symlink. I commented out the line to avoid the symlink from reappearing in the future and restarted udev:

 sudo /etc/init.d/udev restart

Announcing Caller ID Name

There’s an ncid-speak module that is by default wired to use the Festival TTS engine to announce caller ID information. Since we’re using Cepstral rather than Festival for our TTS engine, I simply copied and modified the /etc/init.d/ncid-speak startup/shutdown script to execute a custom script that invokes the Cepstral swift command line interface. The modified portion of the new ncid-swift file looks like this:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          ncid-swift
# Required-Start:    $local_fs $remote_fs
# Required-Stop:     $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      S 0 1 6
# Short-Description: NCID Client using the swift TTS engine
# Description:       NCID client using the swift TTS engine
### END INIT INFO

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/usr/sbin:/usr/bin:/sbin:/bin
DESC="Network Caller ID Swift TTS Client"
NAME=ncid
MODULE=ncid-swift
DAEMON=/usr/bin/$NAME
PIDFILE=/var/run/$MODULE.pid
SCRIPTNAME=/etc/init.d/$MODULE

ConfigDir=/etc/ncid
ConfigFile=$ConfigDir/ncidmodules.conf

DAEMON_ARGS="--no-gui -p $PIDFILE -C -P /home/automate/bin/callerid"
...

The key change was made to the DAEMON_ARGS line. Basically, this script will run the ncid client which will in turn execute the callerid script whenever a call is received. The callerid script performs a bit of pre-processing on the caller ID name text and executes the Cepstral TTS swift command line interface:

#!/usr/bin/perl

$lockfile = '/tmp/lock.callerid';
$beep = '/home/automate/audio/beep-1.wav';

if (!-e $lockfile) {
    `/usr/bin/touch $lockfile`;
    my $text = "<audio src='$beep'><break time='1s'/><prosody volume='+20%' rate='.90'>";

    my @userinput = <STDIN>;
    my $name = $userinput[3];
    $name =~ s/\s/\<break strength='weak'\/>/g;
    $text = $text . "Caller: " . $name . "<break strength='strong'/>";
    $text =~ s/KAMPMEIER/ \<phoneme ph='k ae1 m p m ay1 er0'>Kampmeier<\/phoneme>/g;
    $text =~ s/PEIFFER/ \<phoneme ph='p ay1 f er0'>Peiffer<\/phoneme>/g;

    `/usr/bin/aoss /usr/local/bin/swift "$text"`;
    `/bin/rm $lockfile`;
}

In the future, I should more closely examine the ncid-speak module source to see if I can contribute back a Cepstral extension to it rather than using my slight clone of the speak module.

Displaying Caller ID on Mac OS X Desktops

As mentioned earlier, we installed the ncid-pop.dmg file on our Mac OS X systems. In the ncid download page, scroll down and expand the ncid-pop folder and expand the latest version.

We first installed the latest version of the Growl desktop notification app for Mac OS X. We chose to receive notifications via the Growl interface because it much better looking and configurable than the klunky NCIDpop notification pop-up window. After you install Growl, go to Growl under System Preferences and ensure that the Start Growl at login option is checked.

Drag the NCIDpop app to Applications and start it. As a one-time configuration step, you’ll need to specify the name of the system running ncidd. In our case, this is simply the host name “home-server”.

To make the caller ID notifications persistent on your desktop, set the the NDICpop application’s Notifications Stay on Screen setting to Always rather than Application Decides. Otherwise, the notification disappears rather quickly from the desktop.

To ensure that NCIDpop starts automatically, you can add it to each user’s Login Items within their account settings under System preferences. You’ll need to start the NCIDpop under each user’s account and set the server and Growl option for notification. You’ll also need to go into the Growl settings for the NCIDpop app and modify the Stay On Screen setting as mentioned above.

Next Steps

The ncid-page module enables you to send caller ID information via email and/or text messages to your mobile phone. This feature might be useful in that it would alert us as to when someone had tried to reach us at home.

One Response to “Announcing Caller ID Over Home Speakers”

  1. [...] year I hacked away at some scripts to report on current weather conditions and to announce caller ID information through our home ceiling speakers.  I had also hacked away at an initial script to poll the US [...]

Leave a Reply

preload preload preload