Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

Talking Winamp RF remote control

by OzzyOsbourne (Chaplain)
on Jan 25, 2002 at 05:51 UTC ( [id://141403] : CUFP . print w/replies, xml ) Need Help??

So you have a universal RF X10 remote (UR47A - comes with activehome and other starter kits) and a firecracker serial receiver on your PC, and you know that the Boom2000 software to control Winamp, well, bites. What can you do?

Run the following script. It stays open as you issue commands. It not only will do the typical play, stop, FF, rew, thing, but it can:

  • fade in/out,
  • toggle the shuffle,
  • toggle the repeat,
  • raise the volume, and
  • change the balance
, but it will also speak the title of the song and the time remaining over your speakers via the Microsoft TTS engine (which I find really useful when listening to unknown artists on internet radio while in different room from the PC).

If you want to change the button asignments, you will need a serial port watching program like SerialWatcher to read the codes that come in. Then just make changes to the button_codes hash.

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: Winam +p 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 ser +ial 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$s +erial_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 secon +ds"; $voice->Speak($info, 1); while ($voice->IsSpeaking()) { sleep 1; } return; }

Update (7/26/04): This code also works with MediaMonkey.


Replies are listed 'Best First'.
Re: Talking Winamp RF remote control
by jbisbee (Pilgrim) on Jan 25, 2002 at 19:32 UTC
    I have X10 stuff to do this (I paid like $15 with all the coupons I had), but since then, I've gone completely Windowsless. I'm think I'm going to see if I can mimic the the functionality under Linux with XMMS. Heck it's even possible to do the voice with festival.

    I'm gonna do a little research, but like most things, someone probably has already do it. :)


Re: Talking Winamp RF remote control
by mdog (Pilgrim) on Jan 31, 2002 at 21:47 UTC
    Damn! I thought I was a geek when I wrote a script to replace X10's Active Home software (which also sucks ass) but you outgeeked me! Their dusk/dawn feature for it never worked.

    This is really cool -- I plan on implementing it at home when I get a chance!

    Thanks for releasing it!