| Category: | Chatterbox Clients |
| Author/Contact Info | atcroft |
| Description: | Retrieves data from the Chatterbox (CB) XML ticker, and passes it to a running Festival server instance for output as simulated speech. Uses the LWP::Simple module to retrieve the data, XML::Simple to process the data, and the Festival::Client module to communicate with the Festival server. It uses the epoch time of each comment to determine whether or not it has output a particular line to the Festival server already. Known issues -
Bugs - Aside from the "Known Issues" above, none known yet (the latter being the operative word). Update: 12 Jun 2005 - Found bug in computing $max_retrievals (parentheses were not placed correctly). Code updated with correct version. Update: 12 Jun 2005 - Received a question from demerphq wondering why I had used the epoch value rather than the message_id. The reason was because I wasn't paying attention. Code updated to use message_id rather than epoch. I do appreciate the feedback, demerphq-thank you. (And anyone else seeing anything amiss, please let me know.) |
#!/usr/bin/perl
use strict;
use warnings;
use Festival::Client;
use LWP::Simple;
use XML::Simple;
$| = 1;
# Information for Festival server to connect to
# (undef as port value to use default port)
my %festival_server = (
host => q{localhost},
port => undef,
);
# The following values are in seconds.
# $delay - approximate delay between CB XML Ticker retrievals
# $speech_delay - approximate delay between spoken lines
my $delay = 90;
my $speech_delay = 7;
# $seen - holds the message_id of last message seen
# $max_retrievals - number of times to retrieve CB content
# before exiting (as I did not want to allow the process
# to run forever). This is computed as time to run divided
# by the retrieval delay (both in seconds).
my $seen = 0;
my ($max_retrievals);
{
# Time period to run for. (0d 0h 30m 0s, for testing)
my %to_run = (
days => 0,
hours => 0,
minutes => 30,
seconds => 0,
);
$max_retrievals = int(
(
(
( $to_run{days} * 24 + $to_run{hours} ) * 60 +
$to_run{minutes}
) * 60 + $to_run{seconds}
) / $delay
);
}
# Display CB content and number of messages spoken during
# retrieval period (set true to display)
my $display_messages = 0;
# Setup
my $xs = new XML::Simple;
my $cb_xml_url =
q{http://www.perlmonks.org/index.pl?node_id=207304};
my $fs =
Festival::Client->new( $festival_server{host},
$festival_server{port} )
or die (
qq{Could not connect to Festival server at }
. join (
':',
$festival_server{host},
(
defined(
$festival_server{port}
? $festival_server{port}
: 1314
)
)
)
. qq{: $!\n}
);
my $format = sprintf( qq{(%%0%dd) %%s - %%s: %%s\n},
length($max_retrievals) );
print length($max_retrievals), " ", $max_retrievals, "\n";
while ($max_retrievals) {
my $said = 0;
my $cb_xml = get($cb_xml_url)
or die (qq{Could not retrieve CB XML ticker: $!\n});
my $ref = $xs->XMLin( $cb_xml, ForceArray => [q{message}] )
or die (qq{Could not parse CB XML: $!\n});
# print Data::Dumper->Dump( [ \$ref ], [qw(*ref)] ), "\n";
# Check to see if there are message entries
if ( exists( $ref->{message} ) ) {
# print ref( $ref->{message} ), "\n";
foreach my $message ( @{ $ref->{message} } ) {
if ( $message->{message_id} > $seen ) {
$seen = $message->{message_id};
$fs->say(
join ( qq{\t},
$message->{author}, $message->{text} )
. qq{\n}
);
$said++;
printf $format, $max_retrievals,
scalar localtime $message->{epoch},
$message->{author}, $message->{text}
if ($display_messages);
# I experienced a problem with the content being
# spoken being "lost" if I did not delay between
# sending lines of content. Thus, the delay here.
sleep($speech_delay);
}
}
print qq{Said: $said\n} if ($display_messages);
}
$max_retrievals--;
sleep(
$speech_delay * $said < $delay
? $delay - ( $speech_delay * $said )
: 1
);
}
|
|
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Chatterbox to Festival Server (TTS output)
by planetscape (Chancellor) on Jul 13, 2005 at 04:48 UTC |