Say time

This morning, I read on Hacker News that, “You’ll be more productive if your computer announces the time.” The link was to a click-baity article on a number of “productivity hacks,” the first of which was, “Have your computer announce the time.” As is often the case, this article comes from a world that contains only two kinds of computers. “Here’s how to do it on a Mac, and here are instructions for Windows users.”

My machine runs Linux, so I wondered how I might have it announce the time.

It’s easy to get the current time with GNU date

$ date
Sun Sep  6 14:31:30 EDT 2015

and to synthesize some simple text with espeak

$ echo "Hello, world!" | espeak

so a first pass at a solution might be

$ date | espeak

But that’s not very satisfying. A human knows what that string means, but espeak just reads it off as is, “sun sep six…”

Time::Human

Turns out CPAN already contains a Perl module which does exactly what we need: Time::Human.

$ perl -MTime::Human -E 'say "The time is now ", humanize(localtime)'
The time is now a little after half past two in the afternoon

That string is much more suitable for piping to espeak!

$ perl -MTime::Human -E 'say "The time is now ", humanize(localtime)' | espeak

Not bad!

Festival

Espeak sounds okay, but perhaps we can do better. There’s another synthesizer called Festival, which sounds a little smoother. And there’s even a lite version, written in C.

$ sudo apt-get install flite
$ perl -MTime::Human -E 'say "The time is now ", humanize(localtime)' | flite

Flite has a number of voices from which to choose. The one that seems to sound the best for this is awb_time

$ perl -MTime::Human -E 'say "The time is now ", humanize(localtime)' | flite -voice awb_time

Nice!

Cron

Now, how to get it to say the time automatically every hour? Cron. I edit my personal crontab file with

crontab -e

and add an entry like so

0 * * * * /usr/bin/perl -MTime::Human -E 'say "The time is now ", humanize(localtime)' | flite -voice awb_time

That will invoke that one-liner at the top of every hour.

Normally, I use plenv to install Perl in my own space, so I installed Time::Human with

cpanm Time::Human

To get the cron job to work with /usr/bin/perl, I had to install Time::Human against the system Perl with

sudo apt-get install libtime-human-perl

Now my system tells me the time every hour on the hour! We’ll see if that helps my productivity.

Random voice

Here’s a little Perl script I wrote to choose from all of flite’s voices randomly

#!/usr/bin/env perl

use v5.20;
use warnings;
use Time::Human;

my $time_string = "The time is now " . humanize(localtime);

die "$time_string\n" if @ARGV;

my $voices = `flite -lv`;

my @voices = split ' ', $voices =~ s/^Voices available: //r;

my $voice = $voices[rand @voices];

system "flite -voice $voice -t '$time_string'";

I didn’t end up using it because I thought the awb_time voice sounded better and I wanted to use it all the time.

Advertisements
Say time

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s