http://qs1969.pair.com?node_id=975624


in reply to Tk Game Sound demo

Here is a similar script utilizing Tk and SDL-2.541. There are some glitches, but for the most part it works. See ztk-sound-demo-SDL-new for the sample audio files used in the script.
#!/usr/bin/perl use warnings; use strict; use Tk; use Tk::Pane; use SDL; use SDL::Mixer; use SDL::Mixer::Channels; use SDL::Mixer::Samples; # a demo for using multi channel sound in Tk # by zentara, utilizing the latest SDL version SDL-2.541 # make more than the default 2 channels, we make 8, but need 3 printf("We got %d channels!\n", SDL::Mixer::Channels::allocate_channel +s( 8 ) ); SDL::init(SDL_INIT_AUDIO); #mono 1 or stereo 2 SDL::Mixer::open_audio( 44100, SDL::Constants::AUDIO_S16, 1, 4096 ); my $sound1 = SDL::Mixer::Samples::load_WAV('1bb.wav'); my $sound2 = SDL::Mixer::Samples::load_WAV('explosion.wav'); my $sound3 = SDL::Mixer::Samples::load_WAV('cannon.wav'); foreach my $chan(1..3){ SDL::Mixer::Channels::volume( $chan, 128 ); # set max volume } # setup Tk $|++; my $mw = tkinit; $mw->geometry('900x500+100+100'); $mw->protocol('WM_DELETE_WINDOW' => sub { SDL::Mixer::close_audio(); e +xit; }); $mw->fontCreate('big', -size=> 16 ); ######setup volume indicators####################### my $chan1_vol = 128; #music my $chan2_vol = 128; #explosion my $chan3_vol = 128; #cannon my $tframe = $mw->Frame(-background =>'black')->pack(-fill=>'x'); $tframe->Label(-background =>'black', -foreground => 'lightyellow', -font => 'big', -text => 'Music Vol: ', )->pack(-side=>'lef +t'); $tframe->Entry(-readonlybackground =>'black', -foreground => 'lightyel +low', -textvariable => \$chan1_vol , -width => 3, -font => 'big', -takefocus => 0, -state => 'readonly' )->pack(-side=>'left'); $tframe->Label(-background =>'black', -text => ' ',-width=>1, -font => 'big', )->pack(-side=>'left'); $tframe->Label(-background =>'black', -foreground => 'lightsteelblue', -font => 'big', -text => 'Explosion Vol: ', )->pack(-side=> +'left'); $tframe->Entry(-readonlybackground =>'black', -foreground => 'lightste +elblue', -font => 'big', -textvariable => \$chan2_vol , -width => 3, -takefocus => 0, -state => 'readonly' )->pack(-side=>'left' +); $tframe->Label(-background =>'black', -text => ' ', -width=>1, -font => 'big', )->pack(-side=>'left'); $tframe->Label(-background =>'black', -foreground => 'lightgreen', -font => 'big', -text => 'Cannon Vol: ', )->pack(-side=>'le +ft'); $tframe->Entry(-readonlybackground =>'black', -foreground => 'lightgre +en', -textvariable => \$chan3_vol , -width => 3, -font => 'big', -takefocus => 0, -state => 'readonly')->pac +k(-side=>'left'); $tframe->Label(-background =>'black', -text => ' ', -width=>1, -font => 'big', )->pack(-side=>'left'); my $sound = 1; $tframe->Checkbutton( -text => 'Sound', -background => 'lightskyblue', -variable => \$sound, -command => \&set_sound, -font => 'big')->pack(-side =>'left'); $tframe->Button(-text => 'Exit', -background =>'red', -font => 'big', -command => sub{ SDL::Mixer::close_audio(); 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 pause/resume', command => \&music_toggle }, 'e' => { text => 'explosion', command => sub{ SDL::Mixer::Channels::play_channel( 2, $sound2, 0 +); # 1 time } }, 'c' => { text => 'cannon', command => sub{ SDL::Mixer::Channels::play_channel( 3, $sound3, 0 +); # 1 time } }, 'q' => { text => 'Exit Program', command => sub{ SDL::Mixer::close_audio(); exit; } }, '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 Explosion Volume', command => sub{ $chan2_vol += 1; if($chan2_vol > 128){$chan2_vol = 128} SDL::Mixer::Channels::volume( 2, $chan2_v +ol ); } }, 'Control-F1' => { text => 'Decrease Explosion Volume', command => sub{ $chan2_vol -= 1; if($chan2_vol < 0){$chan2_vol = 0} SDL::Mixer::Channels::volume( 2, $chan2_v +ol ); } }, 'F2' => { text => 'Increase Cannon Volume', command => sub{ $chan3_vol += 1; if($chan3_vol > 128){$chan3_vol = 128} SDL::Mixer::Channels::volume( 3, $chan3_v +ol ); } }, 'Control-F2' => { text => 'Decrease Cannon Volume', command => sub{ $chan3_vol -= 1; if($chan3_vol < 0){$chan3_vol = 0} SDL::Mixer::Channels::volume( 3, $chan3_v +ol ); } }, ); #hack to expand pane $pane->Label(-text=>'', -font => 'big', -background=>'red',-width =>10 +0) ->pack(-fill=>'x',-expand=>1 ); my @order = qw(m e c 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'}); } # start music my $music_play = 1; # to toggle music on/pause SDL::Mixer::Channels::play_channel( 1, $sound1, -1 ); #continous loop MainLoop; ############################################ sub music_toggle{ if( $music_play == 0 ){ SDL::Mixer::Channels::resume(1); $music_play = 1; }else{ SDL::Mixer::Channels::pause(1); $music_play = 0; } } ############################################# sub music_vol{ $chan1_vol += $_[0]; if($chan1_vol < 0){$chan1_vol = 0} if($chan1_vol > 128){$chan1_vol = 128} SDL::Mixer::Channels::volume( 1, $chan1_vol ); } ########################################## sub set_sound{ # the -1 setting described in SDL::Mixer::Channels didn't # seem to work for non-looping sounds, so I use a volume hack below if($sound == 0){ print "soundoff\n"; SDL::Mixer::Channels::pause(1); SDL::Mixer::Channels::volume( 2, 0 ); SDL::Mixer::Channels::volume( 3, 0 ); return; } if($sound == 1){ print "soundon\n"; SDL::Mixer::Channels::resume(1); SDL::Mixer::Channels::volume( 2, $chan2_vol ); SDL::Mixer::Channels::volume( 3, $chan3_vol ); return; } } __END__

I'm not really a human, but I play one on earth.
Old Perl Programmer Haiku ................... flash japh