use strict; use Win32::SerialPort qw(:STAT); use Win32::GUI; use Win32::OLE; use constant WM_USER => 1024; my ($count,$data,$Port,$serial_data); my ($voice,$winampHandle); my %button_codes=( '1110111000111000'=>{ action=>'Previous', type=>WM_COMMAND, value1=>40044, value2=>0, }, '1110111010111000'=>{ action=>'Next', type=>WM_COMMAND, value1=>40048, value2=>0, }, '1110111010110000'=>{ action=>'Play', type=>WM_COMMAND, value1=>40045, value2=>0, }, '1110111001110010'=>{ action=>'Pause', type=>WM_COMMAND, value1=>40046, value2=>0, }, '1110111001110000'=>{ action=>'Stop', type=>WM_COMMAND, value1=>40047, value2=>0, }, '1110111011001001'=>{ action=>'Fadeout', type=>WM_COMMAND, value1=>40147, value2=>0, }, '1110111001000000'=>{ action=>'Fast_for5', type=>WM_COMMAND, value1=>40148, value2=>0, }, '1110111011000000'=>{ action=>'Fast_rewind5', type=>WM_COMMAND, value1=>40144, value2=>0, }, '1110111011010101'=>{ action=>'Raise_vol', type=>WM_COMMAND, value1=>40058, value2=>0, }, '1110111011010011'=>{ action=>'Lower_vol', type=>WM_COMMAND, value1=>40059, value2=>0, }, '1110111011110010'=>{ action=>'Toggle_Repeat', type=>WM_COMMAND, value1=>40022, value2=>0, }, '1110111010111010'=>{ action=>'Toggle_Shuffle', type=>WM_COMMAND, value1=>40023, value2=>0, }, '1110111010100000'=>{ action=>'Mute', type=>WM_USER, value1=>0, value2=>122, }, '1110111001010010'=>{ action=>'Balance_Ctr', type=>WM_USER, value1=>0, value2=>123, }, '1110111011010001'=>{ action=>'Balance_Rt', type=>WM_USER, value1=>127, value2=>123, }, '1110111011010010'=>{ action=>'Balance_Lt', type=>WM_USER, value1=>-127, value2=>123, }, '1110111011010110'=>{ action=>'Get_Info', type=>'', value1=>'', value2=>'', } ); ##### MAIN SUBS ##### &Init_Voice() &Call_WAmp(); &Open_Serial(); &Get_Data(); &Close_Serial(); ##### MAIN SUBS ##### sub Call_WAmp(){ $winampHandle = Win32::GUI::FindWindow("Winamp v1.x", ""); if ($winampHandle){return $winampHandle;}else{die "Stopping: Winamp Not running\n";} return $winampHandle; } sub Open_Serial{ # Prep and open the serial port $Port = new Win32::SerialPort("COM2"); $Port->baudrate(9600); $Port->parity("none"); $Port->databits(8); $Port->stopbits(1); $Port->handshake("none"); $Port->rts_active(1); $Port->binary(1); $Port->write_settings || undef $Port; die "Can't change Device_Control_Block: $^E\n" unless ($Port); } sub Get_Data{ # Gets the data bits from the serial port and puts into $data do{ my $serial_data; ($count, $serial_data) = $Port->read( 40 );#read data from serial port if ( $count>4 and defined $serial_data ) { my @bytes= split(//, $serial_data); my $header=unpack("B16",join('',$bytes[0],$bytes[1])); $data=unpack("B16",join('',$bytes[2],$bytes[3])); if ($button_codes{$data}{type}=='Get_Info'){ &Talk(); } Win32::GUI::SendMessage($winampHandle,$button_codes{$data}{type},$button_codes{$data}{value1},$button_codes{$data}{value2}); my $footer=unpack("B8",$bytes[4]); print "code:\t $button_codes{$data}{type}, $button_codes{$data}{value1},$button_codes{$data}{value2}\ncount:\t$count\ndata:\t$serial_data\nheader:\t$header\ndata:\t$data\nfooter:\t$footer\n"; #select(undef, undef, undef, 1); }else{ select(undef, undef, undef, 1);#Wait 1 seconds } }until($data==1110111011110000); } sub Close_Serial{ $Port->close || die "failed to close"; undef $Port; print "bye"; } sub Init_Voice{ $voice = Win32::OLE->new("Speech.VoiceText") or die("TTS failed"); $voice->Register("", "$0"); $voice->{Enabled} = 1; # optional $voice->{Speed}=150; return $voice; } sub Talk{ my $windowname=Win32::GUI::Text($winampHandle); $windowname=~s/\s+//g; $windowname=~s/\d+.//g; my ($artist,$title)=split(/-/,$windowname); my $totaltime=Win32::GUI::SendMessage( $winampHandle, WM_USER, 1, 105 ); my $minutes=int($totaltime/60); my $seconds=($totaltime-((int($totaltime/60))*60)); my $info = "$title by $artist, $minutes minutes and $seconds seconds"; $voice->Speak($info, 1); while ($voice->IsSpeaking()) { sleep 1; } return; }