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

SoundOff Program (eg. for Pandora Radio)

by liverpole (Monsignor)
on Dec 04, 2011 at 18:17 UTC ( [id://941745]=CUFP: print w/replies, xml ) Need Help??

When I listen to soft jazz on Pandora Radio at work, I like to mute the volume when the advertising starts so I can concentrate on what I'm doing.

The problem is, when I'm in the middle of a software task I often forget to unmute the volume, so a period of time goes by before I realize I'm still "listening" to the radio.

This simple app is my lazy way to avoid having to turn on the volume again. I can click on the big green On/Off button (or type "Enter") and the speaker volume goes off for a preset time (15-seconds by default; typically long enough for most ads), and then automatically unmutes when the interval expires.

There's a volume control slider, as well as the capability to disable the timer altogether, making the unmute operation manual instead.

The program works on Windows, and requires installation of the perl/Tk module and Win32::Sound.

Though it's pretty straightforward, you can always click on 'F1' for help.

Edit:  I discovered there's a bug in Win32::Sound, whereby setting the volume disables the right speaker. I've edited the code to add the workaround, change tabs to spaces, and remove a couple of focusNext perl/Tk calls which were unnecessary.

#!/usr/bin/perl -w ############### ## Libraries ## ############### use strict; use warnings; use Tk; use Tk::Font; use Tk::Photo; use Tk::ROText; use Tk::DialogBox; use Win32::Sound; ################## ## User-defined ## ################## my $prog_title = "SoundOff v1.0 -- Dec. 2011 by John C. Norton"; my $min_mute = 5; my $dflt_mute = 15; # GUI Look & Feel my $a_timer_bg = [ '#ffafef', '#ffbf7f' ]; my $a_timer_txt = [ 'Timer Inactive (Esc)', 'Timer Active (Esc)' ]; my $bg_button = '#afcfff'; my $bg_label = '#ffbf7f'; my $bg_meter = '#ffdf3f'; my $bg_help = '#cfff9f'; my $fo_slider = 'Lucida Sans:9/*'; my $fo_button = 'Comic Sans MS:10*'; my $fo_label = 'Arial:10*'; my $fo_help = 'Lucida Sans:8'; my $a_can_geo = [ 128, 256 ]; my $a_meter_x = [ 48, 90 ]; my $a_meter_y = [ 32, 220 ]; my $a_bg_meter = [ '#ffffcf', '#ff3f3f' ]; my $a_btn_geo = [ 280, 317, 3 ]; my $a_on_off_geo = [ 280, 317, 3 ]; my $h_on_xpm = { '0' => '#7fcf7f', '2' => '#000000', '1' => '#87f7 +17' }; my $h_off_xpm = { '0' => '#ffbf7f', '2' => '#000000', '1' => '#ff3f +3f' }; ############# ## Globals ## ############# my $volume = '100'; my $b_resume = 1; my $b_mute = 0; my $c_tick = 0; my $mute_time = my $resume = $dflt_mute; my ($btn_on, $btn_off, $cv_meter, $id_meter, $id_text, $mute_ent, $c_t +imer); ################## ## Main Program ## ################## create_gui(); ################# ## Subroutines ## ################# sub create_gui { my $mw = new MainWindow(-title => $prog_title); my $fr1 = frame($mw, '^0x'); # Help, Master Volume, Quit my $fr2 = frame($mw, '^1b'); # Main frame my $fr3 = frame($fr2, '<0b'); # Large On/Off button my $fr4 = frame($fr2, '<1b'); # Timer Active, Mute Time, Meter main_options($fr1); $btn_on = sound_on_button($fr3); $btn_off = sound_off_button($fr3); $c_timer = togglebtn($fr4, \$b_resume, $a_timer_txt, $a_timer_bg) +; lbl_entry($fr4, 'Mute Time', \$mute_time); resume_meter($fr4); my $c_idle = sub { ($b_mute and $b_resume and $c_tick) and $c_tick +->(1) }; $mw->repeat(1000 => $c_idle); MainLoop; } sub main_options { my ($w) = @_; my $mw = $w->toplevel; my $fr1 = frame($w, '<0bg1'); my $fr2 = frame($w, '<1xg1'); my $fr3 = frame($w, '>0bg1'); my $b1 = button($fr1, 'Help (F1)', '<1b'); my $b2 = button($fr3, 'Quit (^Q)', '<1b'); volume_slider($fr2); $b1->configure(-command => sub { give_help($mw) }); $b2->configure(-command => sub { exit }); $mw->bind("<F1>" => sub { $b1->invoke }); $mw->bind("<Control-q>" => sub { $b2->invoke }); $mw->bind("<Return>" => sub { toggle_mute() }); $mw->bind("<KeyPress-Left>" => sub { adjust_mute_time(-5) }); $mw->bind("<KeyPress-Right>" => sub { adjust_mute_time(5) }); $mw->bind("<KeyPress-Down>" => sub { adjust_volume('-') }); $mw->bind("<KeyPress-Up>" => sub { adjust_volume('+') }); $mw->bind("<Escape>" => sub { $c_timer->() }); } sub resume_meter { my ($w) = @_; $cv_meter = $w->Canvas(-bg => 'gray', -takefocus => 0); $cv_meter->configure(-width => $a_can_geo->[0]); $cv_meter->configure(-height => $a_can_geo->[1]); my ($x0, $x1, $y0, $y1) = ( @$a_meter_x, @$a_meter_y ); my @rect = ( $x0, $y0, $x1, $y1, -fill => $a_bg_meter->[0] ); $cv_meter->createRectangle(@rect); packit($cv_meter, '1bg2'); } sub volume_slider { my ($w) = @_; my $a_vol = [ '-orient' => 'horizontal', -label => '~ Master Volum +e ~' ]; my $vol = $w->Scale(@$a_vol, -variable => \$volume, -bg => $bg_m +eter); $vol->configure(-command => [ \&adjust_volume, '*' ]); $vol->configure(-takefocus => 0, -font => create_font($w, $fo_slid +er)); packit($vol, '<1b'); } sub adjust_mute_time { my ($incr) = @_; $mute_time =~ s/\D//g; $mute_time ||= $dflt_mute; ($incr eq '*') and $incr = 0; $mute_time += $incr; ($mute_time < $min_mute) and $mute_time = $min_mute; return $mute_time; } sub button { my ($w, $text, $pack) = @_; my $btn = $w->Button(-bg => $bg_button, -text => $text, -takefocu +s => 0); $btn->configure(-font => create_font($w, $fo_button)); return packit($btn, $pack || '<'); } sub create_font { my ($w, $font_spec) = @_; my $weight = ($font_spec =~ s/[*]//)? 'bold': 'normal'; my $slant = ($font_spec =~ s:[/]::)? 'italic': 'roman'; my ($fam, $size, $bold) = $font_spec =~ /(.+):(\d+)([*])?$/; my $mw = $w->toplevel; my @args = ( -weight => $weight, -slant => $slant ); my $font = $mw->Font(-family => $fam, -size => $size, @args); return $font; } sub lbl_entry { my ($w, $label, $s_var) = @_; my $frm = frame($w, '0xg2'); my $lbl = $frm->Label(-bg => $bg_label, -text => $label); $lbl->configure(-font => create_font($w, $fo_label)); $mute_ent = $frm->Entry(-width => 1, -justify => 'center'); my $c_validate = sub { return ($_[0] =~ /^\d*$/)? 1: 0 }; $mute_ent->configure(-textvar => $s_var); $mute_ent->configure(-validate => 'all', -validatecommand => $c_va +lidate); $lbl->pack($mute_ent, -side => 'left'); $mute_ent->pack(-expand => 1, -fill => 'both'); $mute_ent->focus; $mute_ent->selectionRange(0, 15); } sub togglebtn { my ($w, $s_var, $a_text, $a_bg) = @_; my $frm = frame($w, '0xg2'); my $btn = $frm->Button(); my $c_toggle = sub { my $text = $a_text->[$$s_var = 1 - $$s_var]; my $bg = $a_bg->[$$s_var]; $btn->configure(-text => $text, -bg => $bg); }; $btn->configure(-text => $a_text->[$$s_var], -bg => $a_bg->[$$s_va +r]); $btn->configure(-command => $c_toggle, -takefocus => 0); $btn->configure(-font => create_font($w, $fo_button)); packit($btn, '1b'); return $c_toggle; } sub frame { my ($w, $pack, $bg) = @_; my $frm = $w->Frame; ($bg || "") and $frm->configure(-bg => $bg); return packit($frm, $pack); } sub packit { my ($w, $pack) = @_; $pack ||= '^0n'; my $h_sides = {qw{ < left > right ^ top v bottom}}; my $h_fill = {qw{n none b both x x y y }}; my $h_rel = {qw{ - flat g groove r ridge s solid ^ raised v sunk +en }}; my $side = ($pack =~ s/^([<v^>])//)? $h_sides->{$1}: 'top'; my $b_exp = ($pack =~ s/^([01])//)? $1: 0; my $fill = ($pack =~ s/^([nbxy])//)? $h_fill->{$1}: 'none'; my $rel = ($pack =~ s/^([-grs^v])//)? $h_rel->{$1}: ''; my $bw = ($pack =~ s/^(\d+)//)? $1: 2; $rel and $w->configure(-relief => $rel, -borderwidth => $bw); $w->pack(-expand => $b_exp || 0, -fill => $fill, -side => $side); } sub toggle_mute { my ($btn) = @_; return ($b_mute = 1 - $b_mute)? mute_on(): mute_off(); } sub mute_on { adjust_volume(0); $btn_on->packForget; $btn_off->pack; $resume = my $curr_mute = adjust_mute_time(0); $b_mute = 1; $c_tick = sub { my ($nsecs) = @_; $resume -= $nsecs; ($resume <= 0) and return mute_off(); my $pcnt = (100 * $resume / $curr_mute); meter_level($pcnt); meter_label($resume); }; $c_tick->(0); } sub mute_off { $resume = $mute_time || $dflt_mute; $btn_on->pack; $btn_off->packForget; meter_level(0); meter_label('On'); $b_mute = $c_tick = 0; adjust_volume('*'); } sub meter_level { my ($pcnt) = @_; $pcnt = 100 - $pcnt; my ($x0, $x1, $y0, $y1) = ( @$a_meter_x, @$a_meter_y ); $y0 += ($pcnt * ($y1 - $y0)) / 100; my @rect = ( $x0, $y0, $x1, $y1, -fill => $a_bg_meter->[1] ); $id_meter and $cv_meter->delete($id_meter); $id_meter = $cv_meter->createRectangle(@rect); } sub meter_label { my ($text) = @_; my ($x0, $x1, $y0, $y1) = ( @$a_meter_x, @$a_meter_y ); my ($textx, $texty) = (($x0 + $x1) / 2, $y1 + 4); my @args = ( $textx, $texty, -anchor => 'n', -text => $text); $id_text and $cv_meter->delete($id_text); $id_text = $cv_meter->createText(@args); } sub adjust_volume { my ($vol) = @_; ($vol eq '*') and $vol = $volume; ($vol eq '-') and $vol = ($volume > 0)? --$volume: $volume; ($vol eq '+') and $vol = ($volume < 100)? ++$volume: $volume; if (0 == $vol or !$b_mute) { my $val = int(65535 * $vol / 100) & 0x0000ffff; Win32::Sound::Volume(($val << 16) | $val); } } sub create_xpm { my ($a_geo, $h_xpm, $data) = @_; my ($w, $h, $nsyms) = @$a_geo; my ($lb, $rb) = (chr(123), chr(125)); # Don't mess up '%' i +n vim # Create XPM header my $xpm = qq{ :/* XPM */ :static char *xpm[] = $lb :"$w $h $nsyms 1", }; # Fill in XPM color symbols foreach my $key (keys %$h_xpm) { my $line = sprintf "%s c %s", $key, $h_xpm->{$key}; $xpm .= qq{\n\t\t:"$line",}; } $xpm =~ s/(^\s+:)|((?<=\n)\s+:)|(\s+$)//g; my $c_dec = sub { my $N = ord($_[0]); return 126 == $N? 0: 124 == $N? 75: $N < 92? $N-17: $N-92; }; # Decode XPM data $data =~ s/(^[^:]+:)|((?<=\n)\s+(?=:))|(:[^:]+$)//gs; $data =~ s/:\n://g; my $nhuff = $c_dec->(substr($data, 0, 1, "")); my $size = $c_dec->(substr($data, 0, 1, "")); for (my $i = 0; $i < $nhuff; $i++) { my $sym = substr($data, 0, $size, ""); my $rep = substr($data, 0, 1, ""); $data =~ s/\Q$rep\E/$sym/g; } substr($data, 0, $c_dec->(substr($data, 0, 1, "")), ""); my $decode = ""; while ($data) { my $symbol = substr($data, 0, 1, ""); my ($b1, $b2) = substr($data, 0, 2, "") =~ /^(.)(.)$/; $decode .= $symbol x (76 * $c_dec->($b1) + $c_dec->($b2)); } # Merge XPM header and data for (my $i = 1; $i <= $h; $i++) { my $line = substr($decode, 0, $w, ""); $xpm .= qq{\n"$line"} . (($i < $h)? ",": "$rb;"); } return $xpm; } sub sound_on_button { my ($w) = @_; my $data = on_off_data(); my $xpm = create_xpm($a_on_off_geo, $h_on_xpm, $data); my $btn = image_button($xpm, $w); $btn->configure(-command => \&toggle_mute); return packit($btn); } sub sound_off_button { my ($w) = @_; my $data = on_off_data(); my $xpm = create_xpm($a_on_off_geo, $h_off_xpm, $data); my $btn = image_button($xpm, $w); $btn->configure(-command => \&toggle_mute); return $btn; } sub image_button { my ($xpm, $w) = @_; my $mw = $w->toplevel; my $img = $mw->Photo(-format => 'xpm', -data => $xpm); my $btn = $w->Button(); $btn->configure(-image => $img, -takefocus => 0); return $btn; } sub give_help { my ($mw) = @_; my $title = "Help Menu"; my $db = $mw->DialogBox(-title => $title, -buttons => [ "Dismiss" + ]); my $frm = $db->add('Frame'); packit($frm, '0xr4'); my $text = qq{ : : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ : SoundOff is a simple Windows application that mutes the comp +uter : speaker for a given timer interval, after which the volume i +s : automatically restored (unless the timer is inactive). : : The modules 'Tk' and 'Win32::Sound' are both required. : : The following features exist: : : 1. Help button (or F1) : : Displays this help menu. (Same as the <F1> key). : : 2. Master Volume slider (or <Up Arrow> and <Down Arrow>) : : Selects the speaker volume when unmuted. The keyboard : accelerator keys <Up Arrow> and <Down Arrow> may be us +ed : to respectively raise or lower the volume. : : 3. Quit button (or ^Q) : : Exits the program. (Same as the <Control-Q> key). : : 4. Speaker Off/On Button (or <Enter>) : : Mutes or unmutes the speaker for the duration of the : current Mute Time. The <Enter> key does the same thin +g. : : 5. Timer Active button (or <Escape>) : : Disables the timer so the speaker is not automatically : unmuted, even after the mute time interval has elapsed +. : This lets the user mute/unmute the speaker manually. : The <Escape> key can be used as a shortcut for this. : : 6. Mute Time (or <Left Arrow> and <Right Arrow>) : : Selects the exact number of seconds after which the sp +eaker : volume is restored. The <Left Arrow> and <Right Arrow +> keys : respectively subtract or add 5-second intervals to th +e time. : : 7. Progress meter : : A meter which displays a visual indication of the numb +er : of seconds left until the speaker is unmuted. : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ : $prog_title }; $text =~ s/(^\s+:)|((?<=\n)\s+:)|(\s+$)//g; my @text = split /\n/, $text; my @dim = ( -width => 64, -height => 1 + @text ); my $txt = $db->add('ROText', -bg => $bg_help, @dim); packit($txt, '1b'); $txt->configure(-font => create_font($mw, $fo_help)); map { $txt->insert('end', " $_\n") } @text; $txt->see('end'); $db->Show; } sub on_off_data { return q{ :l^0~ ~t!1~"1^#~r$~s%0]&1_'`2(1])0_*~q+x2,b2-~u.~2/_1020eg2~f* +92~: :j*62~l*42~n*22~p*02$*z2$*y2!*,!*,!*,!*,!*,!*,!*,!*,!*,!*,!*,! +*,!: :*,!*,!*,!*,!*,!*,!*,!*,!*,!*,!*,!*,!*,!*,!*,!*,!*,!*v"^2!"^*k +"g2: :!"g*]"l2!"l0^T"q2!"q0^K"u2!"u0^D",!"x0^>"02!"00^8"32!"30^22~c +"z2: :!"z2~c0^,~g",!",~g0^s2~k"w2!"w2~k0^n2~n"v2!"v2~n0^j2+"u2!"u2+ +0^f: :2!1!2!1!2!0^-~v1!2!1!2~v0^^2~y"s2!"s2~y&[2~0"s2!"s2~0&W2/"s2! +"s2: :/&S2~4"s2!"s2~4&O2~6"s2!"s2~6&L2~7"s2!"s2~7&I2~9"s2!"s2~9&F2~ +91!: :2!1!2~9&C2~;1!2!1!2~;&@2~;"u2!"u2~;&=2~<"v2!"v2~<&:2~<"w2!"w2 +~<&: :72~=",!",~=&42~<"z2!"z2~<&22~;"12!"12~;&z2~;"32!"32~;&w2~;"42 +!"4: :2~;&u2~:"62!"62~:&s2~9"82!"82~9&q2~8":2!":2~8&o2~7"<2!"<2~7&m +2~6: :">2!">2~6&k2~6"?2!"?2~6&h2~6"A2!"A2~6&e2~6"B2!"B2~6&c2~5"D2!" +D2~: :5&a2~5"E2!"E2~5&(~3"G2!"G2~3&_2~3"H2!"H2~3&]2/"J2!"J2/ |2/"K2 +!"K: :2/ Z2/"L2!"L2/ X2~1"N2!"N2~1 V2~1"O2!"O2~1 T2~1"P2!"P2~1 R2~1 +"Q2: :!"Q2~1 Q2~0"R2!"R2~0 P2~0"S2!"S2~0 N2~0"T2!"T2~0 L2~0"U2!"U2~ +0 K: :2~y"W2!"W2~y J2~y"X2!"X2~y H2~z"X2!"X2~z G2~y"Y2!"Y2~y F2~y"Z +2!": :Z2~y D2~y"[2!"[2~y C2~x"|2!"|2~x B2~x)/!)/~x @2~x)]2!)]2~x ?2 +~w): :^2!)^2~w >2~w)_2!)_2~w <2~x)_2!)_2~x ;2~w)a2$)a2~w :2~w)-$)-~ +w 9: :2~v)d2~p)d2~v 82~w)e2~n)e2~w 72~v)g2~l)g2~v 62~v)i2~j)i2~v 52 +~v): :k2~f)k2~v 42~v#;2~v 32.#=2. 22~v#=2~v 12.#?2. 02.#A2. z2.#A2. + y2: :.#C2. ,!#E2! w2.#E2. v2!#G2! u2.#G2. t2!#I2! t2!#I2! s2!#K2! +r2!: :#K2! q2!#M2! p2!#M2! p2%#O2% o2!#O2! n2!#O2! n2%#Q2% m2!#Q2! +l2%: :#S2% l2%#S2% k2!#S2! j2%#U2% j2%#U2% i2!#U2! h2%#W2% h2%#W2% +h2%: :#W2% g2%#Y2% f2%#Y2% f2%#Y2% f2$#[2$ f2$#[2$ e2%#[2% d2%#[2% +d2$: :'/$ d2$'/$ d2$'/$ c2%'/% -%'/% -$'^2$ -$'^2$ -$'^2$ -$'^2$ -$ +'^2: :$ -+'(+ -+'(+ a2$'($ ($'($ ($'($ ($'($ ($'($ ($'($ ($'($ (+'- ++ (: :+'-+ (+'-+ (+'-+ (+'-+ (+'-+ (+'-+ (+'-+ (+'-+ (+'-+ (+'-+ (+ +'-+: : (+'-+ (+'-+ ($'($ ($'($ ($'($ ($'($ ($'($ ($'($ ($'($ a2+'(+ + -+: :'(+ -$'^2$ -$'^2$ -$'^2$ -$'^2$ -$'^2$ -%'/% -%'/% c2$'/$ d2$ +'/$: : d2$'/$ d2%#[2% d2%#[2% e2$#[2$ f2$#[2$ f2%#Y2% f2%#Y2% f2%#Y +2% : :g2%#W2% h2%#W2% h2%#W2% h2!#U2! i2%#U2% j2%#U2% j2!#S2! k2%#S +2% : :l2%#S2% l2!#Q2! m2%#Q2% n2!#O2! n2!#O2! o2%#O2% p2!#M2! p2!#M +2! : :q2!#K2! r2!#K2! s2!#I2! t2!#I2! t2.#G2. u2!#G2! v2.#E2. w2!#E +2! : :,.#C2. y2.#A2. z2.#A2. 02.#?2. 12~v#=2~v 22.#=2. 32~v#;2~v 42 +~v#: :92~v 52~v#92~v 62~v#72~v 72~w#52~w 82~v#52~v 92~w#32~w :2~w#1 +2~w: : ;2~x#z2~x <2~w#z2~w >2~w#,~w ?2~x#v2~x @2~x#t2~x B2~x#r2~x C +2~y: :#p2~y D2~y#n2~y F2~y#l2~y G2~z#j2~z H2~y#j2~y J2~y#h2~y K2~0# +d2~: :0 L2~0#-~0 N2~0#(~0 P2~0#^2~0 Q2~1#/~1 R2~1)[2~1 T2~1)Y2~1 V2 +~1): :W2~1 X2/)S2/ Z2/)Q2/ |2/)O2/&]2~3)K2~3&_2~3)I2~3&(~5)E2~5&a2~ +5)C: :2~5&c2~6)?2~6&e2~6)=2~6&h2~6)92~6&k2~6)72~6&m2~7)32~7&o2~8)z2 +~8&: :q2~9)v2~9&s2~:)r2~:&u2~;)n2~;&w2~=)h2~=&z2~=)d2~=&22~?)^2~?&4 +2~A: :"Y2~A&72~B"S2~B&:2~D"M2~D&=2~F"E2~F&@2~J";2~J&C2~M"12~M&F2~U" +j2~: :U&I2]W&L2]U&O2]Q&S2]M&W2]I&[2]E0^^2]A0^-]=0^f2]90^j2]50^n2]10 +^s2: :]v0^,]r0^22]l0^82]f0^>2]`0^D2~[0^K2~S0^T2~I*]2~?*k2~x0e^: }; }


s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

Replies are listed 'Best First'.
Re: SoundOff Program (eg. for Pandora Radio)
by jwkrahn (Abbot) on Dec 05, 2011 at 04:19 UTC
    my $xpm = qq{ :/* XPM */ :static char *xpm[] = $lb :"$w $h $nsyms 1", }; # Fill in XPM color symbols foreach my $key (keys %$h_xpm) { my $line = sprintf "%s c %s", $key, $h_xpm->{$key}; $xpm .= qq{\n\t\t:"$line",}; } $xpm =~ s/(^\s+:)|((?<=\n)\s+:)|(\s+$)//g;

    Why add the leading whitespace and colon when you are just going to remove them anyway?

    And the substitution would be more efficient as:

    $xpm =~ s/^\s+://mg; $xpm =~ s/\s+$//;

    Or at least don't use unneeded capturing parentheses:

    $xpm =~ s/(?:^\s+:)|(?:(?<=\n)\s+:)|(?:\s+$)//g;
          Why add the leading whitespace and colon when you are just going to remove them anyway?

      Because it's far more easy to visually parse when it's indented, and I use that formatting trick in other programs, where I sometimes have to hand-edit the text, and it's much easier when the line begins with ':' than without.

          And the substitution would be more efficient as..."

      So what? It's in the startup code so it's not a performance hit, and I think the "unneeded" capturing parentheses makes it easier to read. But, yeah, thanks for "enlightening" me on regular expressions.

      Honestly, I posted this because I thought it might be useful to a few others besides me, not because I needed the code nit-picked for insignificant optimization. Did you even run it? Or was this just a chance to show off your ikegami-like superiority? It's your type of comments that make me tired and sad that I even post here any more.


      s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: SoundOff Program (eg. for Pandora Radio)
by Tux (Canon) on Dec 05, 2011 at 11:28 UTC

    I did something similar, and talked about that in Belfast on YAPC::EU-2004. Maybe you can pick up some ideas to extend your script. Listening to music you like during work certainly improves both work and motivation :)

    My "radio" followed the playlist on the website of the station that was playing, and noted all song-switches. It then used a database with my song-ratings and modified the volume. If I had rated a song a 10, the volume went up, if I rated it 2 the volume was turned down. If a song started that I rated 1 or less, it switched stations.

    The interface also allowed ratings for new songs (it displayed the rating if available) and then stored the rating in the database. I still have that database:

    $ ratings.pl Low ratings: | 1 64 groups, 492 songs | 2 90 groups, 319 songs | 3 76 groups, 95 songs | 4 55 groups, 62 songs | 202 groups, 968 songs Medium ratings: | 5 42 groups, 42 songs | 6 52 groups, 56 songs | 92 groups, 98 songs High ratings: | 7 152 groups, 196 songs | 8 240 groups, 403 songs | 9 137 groups, 431 songs | 10 40 groups, 150 songs | 415 groups, 1180 songs Total: | 710 groups, 2246 songs Avarage rate: 5.4

    I meanwhile skipped to two stations that fit my taste better and seldom need switching. (I still have to switch when either one is off-line). Both these stations now send title and performer in the stream, so I don't have to follow websites anymore. GStreamer gives me that info while playing. As xmms is dead, I also no longer use that, but a handcrafted radio.pl written in perl/Tk.


    Enjoy, Have FUN! H.Merijn
      You could do this too

      http://6xq.net/projects/pianobar/

Re: SoundOff Program (eg. for Pandora Radio)
by hbm (Hermit) on Dec 05, 2011 at 15:54 UTC

    Nice. I had the same idea when ads came out (what Pandora listener didn't, I suppose), but I just kinda stopped listening.

    I look forward to trying this.

    (It's odd, thinking of you as John C. Norton now, and not simply liverpole...)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://941745]
Approved by GrandFather
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (4)
As of 2024-04-20 04:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found