#!/usr/bin/perl use warnings; use strict; use Tk; use Tk::Pane; use SDL; use SDL::Mixer; use SDL::Music; # a demo for using multi channel sound in Tk # by zentara $|++; my $mw = tkinit; $mw->geometry('600x300+100+100'); ####setup mixer # See # http://aspn.activestate.com/ASPN/CodeDoc/SDL-sdlpl/SDL/Mixer.html my $mixer = SDL::Mixer->new( -frequency => MIX_DEFAULT_FREQUENCY, # 22050 -format => MIX_DEFAULT_FORMAT, # AUDIO_S16 -channels => MIX_DEFAULT_CHANNELS, # 8 -size => 1024 #higher numbers give sloppy reponse #as buffers continue to empty ); # provides 8 channels of # 16 bit audio at 22050 Hz. and a single channel of music. #background can be mp3,ogg or wav (mp3 needs smpeg libs) my $music = new SDL::Music('1bb.mp3'); #sound effects must be wav my $sound0 = new SDL::Sound('cannon.wav'); $sound0->volume(128); #max my $sound1 = new SDL::Sound('explosion.wav'); $sound1->volume(128); #max $mixer->music_volume(MIX_MAX_VOLUME); #128 ############################################################### ######setup volume indicators####################### my $music_vol = 128; my $chan0_vol = 128; #cannon my $chan1_vol = 128; #explosion my $tframe = $mw->Frame(-background =>'black')->pack(-fill=>'x'); $tframe->Label(-background =>'black', -foreground => 'lightyellow', -text => 'Music Vol: ', )->pack(-side=>'left'); $tframe->Entry(-background =>'black', -foreground => 'lightyellow', -textvariable => \$music_vol , -width => 3, )->pack(-side=>'left'); $tframe->Label(-background =>'black', -text => ' ',-width=>1, )->pack(-side=>'left'); $tframe->Label(-background =>'black', -foreground => 'lightgreen', -text => 'Cannon Vol: ', )->pack(-side=>'left'); $tframe->Entry(-background =>'black', -foreground => 'lightgreen', -textvariable => \$chan0_vol , -width => 3, )->pack(-side=>'left'); $tframe->Label(-background =>'black', -text => ' ', -width=>1, )->pack(-side=>'left'); $tframe->Label(-background =>'black', -foreground => 'lightsteelblue', -text => 'Explosion Vol: ', )->pack(-side=>'left'); $tframe->Entry(-background =>'black', -foreground => 'lightsteelblue', -textvariable => \$chan1_vol , -width => 3, )->pack(-side=>'left'); $tframe->Label(-background =>'black', -text => ' ', -width=>1, )->pack(-side=>'left'); my $sound = 1; $tframe->Checkbutton( -text => 'Sound', -background => 'lightskyblue', -variable => \$sound, -command => \&set_sound, )->pack(-side =>'left'); $tframe->Button(-text => 'Exit', -background =>'red', -command => sub{ exit })->pack(-side=>'right'); ################################################################# my $pane = $mw->Scrolled('Pane', -background =>'black', -scrollbars=>'oe', sticky=>'w')->pack(-side => "left", -anchor => "n", -fill=>'both',-expand=>1); my %keyprs = ( 'm' => { text => 'music on/off', command => \&music_toggle }, 'e' => { text => 'explosion', command => sub{ $mixer->play_channel( 1, $sound1, 0 ) } }, 'c' => { text => 'cannon', command => sub{ $mixer->play_channel( 0, $sound0, 0 ) } }, 'q' => { text => 'Exit Program', command => sub{ exit } }, 'space' => { text => 'Pause Music', command => \&pause_toggle }, 'plus' => { text => 'Increase Background Music Volume', command => sub{ &music_vol(1) } }, 'minus' => { text => 'Decrease Background Music Volume', command => sub{ &music_vol(-1) } }, 'F1' => { text => 'Increase Cannon Volume', command => sub{ $chan0_vol += 1; if($chan0_vol > 128){$chan0_vol = 128} $mixer->channel_volume(0,$chan0_vol); } }, 'Control-F1' => { text => 'Decrease Cannon Volume', command => sub{ $chan0_vol -= 1; if($chan0_vol < 0){$chan0_vol = 0} $mixer->channel_volume(0,$chan0_vol); } }, 'F2' => { text => 'Increase Explosion Volume', command => sub{ $chan1_vol += 1; if($chan1_vol > 128){$chan1_vol = 128} $mixer->channel_volume(1,$chan1_vol); } }, 'Control-F2' => { text => 'Decrease Explosion Volume', command => sub{ $chan1_vol -= 1; if($chan1_vol < 0){$chan1_vol = 0} $mixer->channel_volume(1,$chan1_vol); } }, ); #hack to expand pane $pane->Label(-text=>'',-background=>'red',-width =>100) ->pack(-fill=>'x',-expand=>1 ); my @order = qw(m e c space plus minus F1 Control-F1 F2 Control-F2 q); foreach(@order){ $pane->Label(-text => "$_ -> $keyprs{$_}{'text'}", # -font => 'big', -background => 'cyan', -anchor => 'w', -borderwidth =>2, )->pack( -fill =>'x',-expand=>1); $mw->bind("<$_>", $keyprs{$_}{'command'}); } MainLoop; ############################################ sub music_toggle{ if( $mixer->playing_music() ){ $mixer->halt_music(); }else{ $mixer->play_music( $music, 100 ); } } ############################################# sub music_vol{ $music_vol += $_[0]; if($music_vol < 0){$music_vol = 0} if($music_vol > 128){$music_vol = 128} #return if ! $mixer->playing_music(); $mixer->music_volume($music_vol); } ########################################## sub pause_toggle{ return if ! $mixer->playing_music(); if( $mixer->music_paused() ){ $mixer->resume_music(); }else{ $mixer->pause_music() } } ############################################# sub set_sound{ if($sound == 0){ $mixer->music_volume(0); $mixer->channel_volume(0,0); $mixer->channel_volume(1,0); return; } if($sound == 1){ $mixer->music_volume($music_vol); $mixer->channel_volume(0,$chan0_vol); $mixer->channel_volume(1,$chan1_vol); return; } } __END__