Apr 23200612:00 AM CDT

Creating an RSS Speaking Alarm Clock

Categories: Tweaks, Windows
  1. Install Additional Voices (optional)
    1. First install Microsoft Reader
    2. Then install the Reader TTS package
  2. Install Perl
  3. Download nmake
  4. Install XML-RSS perl module
  5. Download the following perl script (rss2html5.pl), which is a modification of rss2html.pl
    	#!/usr/bin/perl -w
    	# rss2html - converts an RSS file to HTML
    	# It take one argument, either a file on the local system,
    	# or an HTTP URL like http://slashdot.org/slashdot.rdf
    	# by Jonathan Eisenzopf. v1.0 19990901
    	# Copyright (c) 1999 Jupitermedia Corp. All Rights Reserved.
    	# See http://www.webreference.com/perl for more information
    	#
    	# This program is free software; you can redistribute it and/or modify
    	# it under the terms of the GNU General Public License as published by
    	# the Free Software Foundation; either version 2 of the License, or
    	# (at your option) any later version.
    
    	# INCLUDES
    	use strict;
    	use XML::RSS;
    	use LWP::Simple;
    	
    	# Declare variables
    	my $content;
    	my $file;
    	
    	# MAIN
    	# check for command-line argument
    	die "Usage: rss2html.pl (<RSS file> | <URL>)\n" unless @ARGV == 1;
    	
    	# get the command-line argument
    	my $arg = shift;
    	
    	# create new instance of XML::RSS
    	my $rss = new XML::RSS;
    	
    	# argument is a URL
    	if ($arg=~ /http:/i) {
    	    $content = get($arg);
    	    die "Could not retrieve $arg" unless $content;
    	    # parse the RSS content
    	    $rss->parse($content);
    	
    	# argument is a file
    	} else {
    	    $file = $arg;
    	    die "File \"$file\" does't exist.\n" unless -e $file;
    	    # parse the RSS file
    	    $rss->parsefile($file);
    	}
    	
    	# print the HTML channel
    	&print_html($rss);
    	
    	# SUBROUTINES
    	sub print_html {
    	    my $rss = shift;
    	    print <<HTML;
    	HTML
    	
    	    # print the channel items
    	    my $i = 0;
    	    foreach my $item (@{$rss->{'items'}})
    	    {
    	      next unless defined($item->{'title'});
    	      print "$item->{'title'}... ... ... ... ...\n";
    	      if($i==4){
    	         last;   
    	      }
    	       $i = $i + 1;
    	    }
    	
    	    # if there's a copyright element
    	    if ($rss->{'channel'}->{'copyright'}) {
    	   print <<HTML;
    	<p><sub>$rss->{'channel'}->{'copyright'}</sub></p>
    	HTML
    	    }
    	
    	    print <<HTML;
    	HTML
    	}
    
  6. Download the following TextToWave.vbs
    	'Drop a plain text file on this script, and it will create an
    	'identically-named WAV file (except for the file extension!).
    	'The default audio format is set in the script with the constant
    	'AUDIO_FORMAT, or you may supply a format as a number from
    	'4 to 68. The audio format number is supplied as an OPTIONAL
    	'second argument to this script.
    	'
    	'Common formats: 8 (8KHz 8-bit mono), 16 (16KHz 8-bit mono),
    	'35 (44KHz 16-bit Stereo), 65 (GSM 8KHz), 66 (GSM 11KHz)
    	
    	Option Explicit
    	dim tts, fs, ts, ss, strFile, strText, blnError, lngFormat
    	Const ForReading = 1
    	Const SSFMCreateForWrite = 3
    	Const AUDIO_FORMAT = 65 'Please refer to the SAFT function for value description
    	
    	   'Check argument count
    	   If WScript.Arguments.Count = 0 Then
    	      MsgBox "Drop a text file on this script and I'll convert it into a WAV sound file."
    	      WScript.Quit 1
    	   End If
    	   'Make sure the argument is a file
    	   Set fs = CreateObject("Scripting.FileSystemObject")
    	   strFile = WScript.Arguments(0)
    	   strFile = Trim(strFile)
    	   If strFile = "" Then
    	      MsgBox "I can't read nothing! Give me the name of a text file."
    	      WScript.Quit 1
    	   End If
    	   If InStr(strFile, "\\") <> 1 And InStr(strFile, ":\") <> 2 Then
    	      strFile = fs.GetAbsolutePathName(fs.BuildPath(fs.GetFolder(".").Path, strFile))
    	   End If
    	   If Not fs.FileExists(strFile) Then
    	      MsgBox "I can't locate a file named """ & WScript.Arguments(0) & """. Try using a fully-qualified path and file name."
    	      WScript.Quit 1
    	   End If
    	   'Is there an optional second argument for the audio format?
    	   If WScript.Arguments.Count > 1 Then
    	      lngFormat = WScript.Arguments(1)
    	      If Not IsNumeric(lngFormat) Then
    	         MsgBox "The second argument, if supplied, must be a NUMBER. Yours wasn't!"
    	         WScript.Quit 1
    	      End If
    	      lngFormat = Int(Abs(lngFormat)) - 1
    	   Else
    	      lngFormat = AUDIO_FORMAT - 1
    	   End If
    	   'Get the SAPI 5text-to-voice engine.
    	   Set tts = Nothing
    	   Set tts = CreateObject("Sapi.SpVoice")
    	   If tts Is Nothing Then
    	      InputBox "You don't have SAPI 5! Please hop on the internet, download, and install the Microsoft SAPI 5 speech development kit from here:", "Error", "http://download.microsoft.com/download/speechSDK/SDK/5.1/WXP/EN-US/speechsdk51.exe"
    	      WScript.Quit 1
    	   End If
    	   'Read the file
    	   Status "Reading text file"
    	   Set ts = fs.OpenTextFile(WScript.Arguments(0), ForReading, True)
    	   strText = ts.ReadAll
    	   ts.Close
    	   Set ts = Nothing
    	   'Generate a file name for the output WAV file
    	   strFile = Left(strFile, InStrRev(strFile, ".")) & "wav"
    	   'Check to see that chosen audio format is supported
    	   Err.Clear
    	   blnError = True
    	   On Error Resume Next
    	   Do While blnError
    	      lngFormat = lngFormat + 1
    	      If fs.FileExists(strFile) Then fs.DeleteFile strFile
    	      Set ss = CreateObject("Sapi.SpFileStream")
    	      ss.Format.Type = lngFormat
    	      ss.Open strFile, SSFMCreateForWrite, False
    	      Set tts.AudioOutputStream = ss
    	      Err.Clear
    	      If Err.Number = 0 Then
    	         Status "USING:  Format " & lngFormat & " (" & SAFT(lngFormat) & ")"
    	         blnError = False
    	      Else
    	         Status "FAILED: Format " & lngFormat & " (" & SAFT(lngFormat) & ")"
    	         Set tts.AudioOutputStream = Nothing
    	         ss.Close
    	         Set ss = Nothing
    	         blnError = True
    	      End If
    	   Loop
    	   'Convert text to WAV!
    	   Status "Converting to WAV"
    	   tts.Speak strText
    	   'Clean up
    	   ss.Close
    	   Set ss = Nothing
    	   Set tts = Nothing
    	
    	Sub Status(strMessage)
    	   If Lcase(Right(Wscript.FullName, 12)) = "\cscript.exe" Then
    	      Wscript.Echo strMessage
    	   End If
    	End Sub
    	
    	Function SAFT(lngSpeechAudioFormatType)
    	'Returns a text description of the format type
    	'Values from SpeechLib.SpeechAudioFormatType
    	Dim strSAFT, lngSAFT
    	   'Preserve input variable
    	   lngSAFT = lngSpeechAudioFormatType
    	   'Stop bad input
    	   If Not IsNumeric(lngSAFT) Then
    	      SAFT = "Unknown"
    	      Exit Function
    	   End If
    	   If lngSAFT < 4 Or lngSAFT > 68 Then
    	      SAFT = "Unknown"
    	      Exit Function
    	   End If
    	   'NORMAL for values between 0 and 39
    	   'stereo = add 1
    	   '16-bit = add 2
    	   '8KHz = 4
    	   '11KHz = 8
    	   '12KHz = 12
    	   '16KHz = 16
    	   '22KHz = 20
    	   '24KHz = 24
    	   '32KHz = 28
    	   '44KHz = 32
    	   '48KHz = 36
    	   If lngSAFT < 40 Then
    	      lngSAFT = lngSAFT - 4 'Offset so it starts at zero
    	      strSAFT = Split("8 11 12 16 22 24 32 44 48")(lngSAFT \ 4) & "KHz"
    	      strSAFT = strSAFT & " "
    	      strSAFT = strSAFT & Split("8 16")((lngSAFT And 2) \ 2) & "bit"
    	      strSAFT = strSAFT & " "
    	      strSAFT = strSAFT & Split("Mono Stereo")(lngSAFT And 1)
    	   End If
    	   'TrueSpeech_8kHz1BitMono = 40
    	   If lngSAFT = 40 Then
    	      strSAFT = "TrueSpeech 8KHz 1bit Mono"
    	   End If
    	   'stereo = add 1 to below values
    	   'CCITT_ALaw for values between 41 and 48
    	   '8KHz = 41
    	   '11KHz = 43
    	   '22KHz = 45
    	   '44KHz = 47
    	   'CCITT_uLaw for values between 49 and 56
    	   '8KHz = 49
    	   '11KHz = 51
    	   '22KHz = 53
    	   '44KHz = 55
    	   'ADPCM for values between 57 and 64
    	   '8KHz = 57
    	   '11KHz = 59
    	   '22KHz = 61
    	   '44KHz = 63
    	   If ((lngSAFT > 40) And (lngSAFT < 65)) Then
    	      lngSAFT = lngSAFT - 41 'Offset so it starts at zero
    	      strSAFT = Split("CCITT_ALaw CCITT_uLaw ADPCM")(lngSAFT \ 8)
    	      strSAFT = strSAFT & " "
    	      strSAFT = strSAFT & Split("8 11 22 44")((lngSAFT \ 2) And 3) & "KHz"
    	      strSAFT = strSAFT & " "
    	      strSAFT = strSAFT & Split("Mono Stereo")(lngSAFT And 1)
    	   End If
    	   'GSM_610 for values between 65 and 68 (no stereo)
    	   '8KHz = 65
    	   '11KHz = 66
    	   '22KHz = 67
    	   '44KHz = 68
    	   If lngSAFT > 64 Then
    	      Select Case lngSAFT
    	         Case 65
    	            strSAFT = "GSM_610 8KHz Mono"
    	         Case 66
    	            strSAFT = "GSM_610 11KHz Mono"
    	         Case 67
    	            strSAFT = "GSM_610 22KHz Mono"
    	         Case 68
    	            strSAFT = "GSM_610 44KHz Mono"
    	         Case Else
    	            strSAFT = "Unknown"
    	      End Select
    	   End If
    	   'Return the value
    	   SAFT = strSAFT
    	End Function
    
  7. Create the following batch script:
    	echo "Good Morning Your-Name-Goes-Here... ... ... ..." >> alarm.txt
    	echo "Top 5 stories from Dig this morning are:... ..." >> alarm.txt
    	perl rss2html5.pl http://www.digg.com/rss/index.xml >> alarm.txt
    	
    	echo "Top 5 stories from Slash Dot this morning are:... ..." >> alarm.txt
    	perl rss2html5.pl http://rss.slashdot.org/Slashdot/slashdot >> alarm.txt
    	
    	echo "Top 5 stories from Boing Boing are:... ..." >> alarm.txt
    	perl rss2html5.pl http://feeds.feedburner.com/boingboing/iBag >> alarm.txt
    	
    	echo "... ... Have a nice day!... ... ... ... ... ... ... ... ..." >> alarm.txt
    	
    	del alarm.wav
    	TextToWave.vbs alarm.txt 35
    	del alarm.txt
    	start alarm.m3u
    
    (Replace RSS feeds as you so desire)
  8. Create the alarm.m3u playlist file pointing to your wake-up-song and alarm.wav using the following example:
    
    	#EXTM3U
    	#EXTINF:30,B-52's - Love Shack
    	love_shack.mp3
    	#EXTINF:81,alarm
    	alarm.wav
    
  9. Schedule the batch script using the AT command[7].
    Example:
    AT 07:30 /EVERY:m,t,w,th,f c:\alarm\alarm.bat

Links:
Festival: http://cstr.ed.ac.uk/projects/festival
Linux Distors: http://linux.org/dist