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__