#!/usr/bin/perl # # Coryright 2004, Dan Rasmussen, Paul Norton, Jon Morgan # # This file is part of Radii: radio's next generation # # Radii 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. # # Radii is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Radii; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # #------------------------------------------------------------------------------ # # Radii: Radio's Next Generation. # # This perl script, designed to run on Linux, is used in conjunction # with system that includes unique hardware and software and software # that is part of most standard Linux distributions. The primary # components are: # # 1. This script which is the center of the radii system. # 2. An external component to send control signals to this script via # RS-232 serial communications port of the system where this perl # script runs. # 3. xmms # 4. setlcd: a program that can be used to control an LCD attaced to a # the parallel port of the system where this perl script runs. # # How this script works: # # 1. It initializes a hash with station data read from an exteranl file. # 2. It initializes serial communications # 3. Wait for serail communications and update xmms, lcd based on input. # # Questions or problems? Please e-mail Dan Rasmussen, dan@retro-tronics.com # #------------------------------------------------------------------------------ use strict; use XML::Simple; use Device::SerialPort; system "stty", '-icanon', system "stty", 'eol', "\001"; my @station; my %radiiStn = (); my %bands = (); my %bandIndex = (); #------------------------------------------------------------------------------- # Initialize bands from an xml file hard coded to stations_short.xml # FIXME: take stations file as an arg. #------------------------------------------------------------------------------- my $file = 'stations_short.xml'; my $xs1 = XML::Simple->new(); my $doc = $xs1->XMLin($file); my $num = 1; my $band; foreach my $key (keys (%{$doc->{station}})) { # print "Key: $key\n"; # print "Band: $doc->{station}->{$key}->{'band'}\n"; # print "URL: $doc->{station}->{$key}->{'url'}\n"; $band = $doc->{station}{$key}{band}; my $url = $doc->{station}{$key}{url}; my $name = $key; $bands{$band} += 1; $radiiStn{$band}{$bands{$band}}{name} = $bands{$band}.":$band: ".$key; $radiiStn{$band}{$bands{$band}}{station} = $url; } my $bandCount = 0; foreach my $bkey (sort keys %bands) { print "Band: $bkey: $bands{$bkey}\n"; # Put a STOP at the end of each band. $bandCount++; $bandIndex{$bandCount} = $bkey; $bands{$bkey} += 1; $radiiStn{$bkey}{$bands{$bkey}}{name} = "STOP"; } $num += 1; print "$num\n"; #------------------------------------------------------------------------------- # Setup serial communications. #------------------------------------------------------------------------------- my $port = new Device::SerialPort("/dev/ttyS0"); $port->baudrate(9600); $port->parity("none"); $port->databits(8); $port->stopbits(1); $port->handshake('none'); $port->write_settings; #------------------------------------------------------------------------------- # Various other initializations. #------------------------------------------------------------------------------- my $choice; my $bIndex = 1; my $curBand = $bandIndex{$bIndex}; my $code = ''; my $oldChoice = 1; my $currentStation = 1; my $oldStation = 1; my $oldBand = 1; my $counter = 0; my @lcdMsg; #------------------------------------------------------------------------------- # Now just wait for and handel input from the sereial port. #------------------------------------------------------------------------------- while ( 1 ) { while (! ($code = $port->input)) { select undef, undef, undef, 0.075; $counter--; if (0 > $counter) { $counter = 0; } if (1 == $counter) { $curBand = $oldBand; @lcdMsg = ("setlcd", $radiiStn{$curBand}{$currentStation}{name}); system(@lcdMsg) == 0 or die "system @station failed: $?"; } } print "processing code: $code\n"; # Handle up message $oldChoice = $choice; if ($code =~ /U/) { print "Processing a U\n"; $choice = $oldChoice - 1; while (! exists $radiiStn{$curBand}{$choice}) { # FIXME: delete last station and we are in trouble! $choice -= 1; if (1 > $choice) { $choice = $bands{$curBand}; } } if (1 > $choice) { $choice = $bands{$curBand}; } $counter = 50; print "Sel: stat[$curBand][$choice][name] = $radiiStn{$curBand}{$choice}{name}\n"; @lcdMsg = ("setlcd", "Sel: $radiiStn{$curBand}{$choice}{name}"); system(@lcdMsg) == 0 or die "system @station failed: $?"; } # Handle down message if ($code =~ /D/) { print "Processing a D\n"; $choice = $oldChoice + 1; while (! exists $radiiStn{$curBand}{$choice}) { # FIXME: delete last station and we are in trouble! $choice += 1; if ($bands{$curBand} < $choice) { $choice = 1; } } if ($bands{$curBand} < $choice) { $choice = 1; } $counter = 50; system("setlcd", "Sel: $radiiStn{$curBand}{$choice}{name}") == 0 or die "Failed to display $radiiStn{$curBand}{$choice}{name}: $?"; } # Handle select message if ($code =~ /S/) { if ($choice eq $currentStation) { $choice = $oldStation; } if ($radiiStn{$curBand}{$choice}{station} =~ /STOP/) { print("Selected STOP\n"); system("/usr/bin/xmms", "-t"); } else { print("Selected station: $radiiStn{$curBand}{$choice}{station}\n"); system("/usr/bin/xmms", "-p", $radiiStn{$curBand}{$choice}{station}); } system("setlcd", $radiiStn{$curBand}{$choice}{name}) == 0 or die "system @station failed: $?"; $counter = 0; $oldStation = $currentStation; $currentStation = $choice; $oldBand = $curBand; } # Handle band down if ($code =~ /d/) { $bIndex++; if ($bIndex > $bandCount) { $bIndex = 1; } $counter = 50; $curBand = $bandIndex{$bIndex}; @lcdMsg = ("setlcd", $curBand.": ".$bands{$curBand}." Stations" ); system(@lcdMsg) == 0 or die "system @station failed: $?"; } # Handle band up if ($code =~ /u/) { $bIndex--; if ($bIndex == 0) { $bIndex = $bandCount; } $counter = 50; $curBand = $bandIndex{$bIndex}; @lcdMsg = ("setlcd", $curBand.": ".$bands{$curBand}." Stations" ); system(@lcdMsg) == 0 or die "system @station failed: $?"; } print "Using choice: $choice\n"; if ('p' eq $choice) { print "Pause/Resume\n"; @station = ("xmms", "-t"); } elsif ('s' eq $choice) { print "Stopped\n"; @station = ("xmms", "-t"); } else { print "$code\n"; } $code = ''; }