Skip Menu |

This queue is for tickets about the Win32-Sound CPAN distribution.

Report information
The Basics
Id: 43776
Status: resolved
Priority: 0/
Queue: Win32-Sound

People
Owner: dada [...] perl.it
Requestors: perl [...] vertz.info
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.49
Fixed in: 0.51



Subject: Old bug in Win32::Sound::Volume
I believe there is still a problem with Win32::Sound::Volume. The behavior I see is similar to these writeups: http://aspn.activestate.com/ASPN/Mail/Message/perl-win32-users/2149174 http://aspn.activestate.com/ASPN/Mail/Message/perl-win32-users/2149175
Here are some more specifics. Setting the volume is impacted by two bugs. #1 Setting volume works for left channel but silences right channel. When called as: Win32::Sound::Volume(128); -or- Win32::Sound::Volume(128,128); The actual result is that the left channel volume is set to 50% and the right channel is set to 0%. #2 Parsing of percentage volumes appears to be incorrect. When called as: Win32::Sound::Volume("50%"); The actual result is that the left channel is set very low, almost silent. Right channel is set to 0% due to bug #1.
On Mon Mar 02 14:28:32 2009, cvertz wrote: Show quoted text
> #1 Setting volume works for left channel but silences right channel. > #2 Parsing of percentage volumes appears to be incorrect.
Attached an (untested) patch that: (1) Fixes the range of allowed volumes to be 0-65535 to match the documentation (along with correct bit-shifts of 16-bits rather than 8-bits). (2) Fixes the percentage volume calculations. (3) Bumps the version to 0.50 Also (untested), I beleive that the following can be used to work around the problems: #!perl -w use strict; use warnings; use Win32::Sound(); sub win32_volume { my(@in) = @_; if(not scalar @in) { my $volume = Win32::Sound::_Volume(); if (wantarray) { my $left = ($volume >> 16) & 0x0000FFFF; my $right = ($volume ) & 0x0000FFFF; return ($left, $right); } return $volume; } # Allows '0%'..'100%' $in[0] =~ s{ ([\d\.]+)%$ }{ int($1*65535/100) }ex if defined $in[0]; $in[1] =~ s{ ([\d\.]+)%$ }{ int($1*65535/100) }ex if defined $in[1]; $in[1] = $in[0] unless defined $in[1]; my $volume = (($in[0] & 0x0000FFFF) << 16) | ($in[1] & 0x0000FFFF); return Win32::Sound::_Volume($volume, 0); }
diff U3w META.yml META.yml --- META.yml Wed Apr 23 18:23:34 2008 +++ META.yml Tue Mar 10 09:32:53 2009 @@ -1,7 +1,7 @@ --- #YAML:1.0 name: Win32-Sound abstract: An extension to play with Windows sounds -version: 0.49 +version: 0.50 author: - Aldo Calpini <dada@perl.it> - Jan Dubois <jand@activestate.com> diff U3w README README --- README Thu Feb 14 02:00:14 2008 +++ README Tue Mar 10 09:33:09 2009 @@ -3,7 +3,7 @@ # Win32::Sound - An extension to play with Windows sounds # # Author: Aldo Calpini <dada@divinf.it> -# Version: 0.45 +# Version: 0.50 # Info: # http://www.divinf.it/dada/perl # http://www.perl.com/CPAN/authors/Aldo_Calpini diff U3w Sound.pm Sound.pm --- Sound.pm Sat Jun 14 01:11:34 2008 +++ Sound.pm Tue Mar 17 09:48:38 2009 @@ -3,7 +3,7 @@ # Win32::Sound - An extension to play with Windows sounds # # Author: Aldo Calpini <dada@perl.it> -# Version: 0.49 +# Version: 0.50 # Info: # http://www.divinf.it/dada/perl # http://www.perl.com/CPAN/authors/Aldo_Calpini @@ -29,6 +29,8 @@ # fix package name in META.yml # move sample.pl into eg/ subdirectory to prevent it # from being installed +# 0.50 (10 Mar 2009) Fix to correctly set volumes. RT43776. +# (Robert May robertmay@cpan.org) package Win32::Sound; @@ -83,7 +85,7 @@ ####################################################################### # STATIC OBJECT PROPERTIES # -$VERSION="0.49"; +$VERSION="0.50"; undef unless $VERSION; # [dada] to avoid "possible typo" warning ####################################################################### @@ -95,8 +97,8 @@ sub Volume { my(@in) = @_; # Allows '0%'..'100%' - $in[0] =~ s{ ([\d\.]+)%$ }{ int($1*100/255) }ex if defined $in[0]; - $in[1] =~ s{ ([\d\.]+)%$ }{ int($1*100/255) }ex if defined $in[1]; + $in[0] =~ s{ ([\d\.]+)%$ }{ int($1*65535/100) }ex if defined $in[0]; + $in[1] =~ s{ ([\d\.]+)%$ }{ int($1*65535/100) }ex if defined $in[1]; _Volume(@in); } @@ -135,8 +137,8 @@ sub Volume { my(@in) = @_; # Allows '0%'..'100%' - $in[0] =~ s{ ([\d\.]+)%$ }{ int($1*255/100) }ex if defined $in[0]; - $in[1] =~ s{ ([\d\.]+)%$ }{ int($1*255/100) }ex if defined $in[1]; + $in[0] =~ s{ ([\d\.]+)%$ }{ int($1*65535/100) }ex if defined $in[0]; + $in[1] =~ s{ ([\d\.]+)%$ }{ int($1*65535/100) }ex if defined $in[1]; _Volume(@in); } @@ -578,7 +580,7 @@ =head1 VERSION -Win32::Sound version 0.46, 25 Sep 1999. +Win32::Sound version 0.50, 10 Mar 2009. =head1 AUTHOR diff U3w Sound.xs Sound.xs --- Sound.xs Thu Feb 28 02:21:06 2008 +++ Sound.xs Tue Mar 10 09:57:16 2009 @@ -4,7 +4,7 @@ # Win32::Sound - An extension to play with Windows sounds # # Author: Aldo Calpini <dada@perl.it> -# Version: 0.45 +# Version: 0.50 # Info: # http://www.divinf.it/dada/perl # http://www.perl.com/CPAN/authors/Aldo_Calpini @@ -348,8 +348,8 @@ if(mmr == MMSYSERR_NOERROR) { if(GIMME == G_ARRAY) { EXTEND(SP, 2); - XST_mIV(0, (long) volume & 0x00FF); - XST_mIV(1, (long) (volume & 0xFF00) >> 8); + XST_mIV(0, (long) (volume & 0x0000FFFF) ); + XST_mIV(1, (long) ((volume & 0xFFFF0000) >> 16)); XSRETURN(2); } else { XSRETURN_IV(volume); @@ -360,7 +360,7 @@ } break; case 1: - volume = SvIV(ST(0)) | SvIV(ST(0)) << 8; + volume = ( SvIV(ST(0)) & 0x0000FFFF ) | (( SvIV(ST(0)) & 0x0000FFFF ) << 16 ); mmr = waveOutSetVolume((HWAVEOUT) WAVE_MAPPER, volume); if(mmr == MMSYSERR_NOERROR) { XSRETURN_YES; @@ -370,7 +370,7 @@ } break; default: - volume = SvIV(ST(0)) | SvIV(ST(1)) << 8; + volume = ( SvIV(ST(0)) & 0x0000FFFF ) | (( SvIV(ST(1)) & 0x0000FFFF ) << 16); mmr = waveOutSetVolume((HWAVEOUT) WAVE_MAPPER, volume); if(mmr == MMSYSERR_NOERROR) { XSRETURN_YES; @@ -1268,8 +1268,8 @@ if(mmr == MMSYSERR_NOERROR) { if(GIMME == G_ARRAY) { EXTEND(SP, 2); - XST_mIV(0, (long) volume & 0x00FF); - XST_mIV(1, (long) (volume & 0xFF00) >> 8); + XST_mIV(0, (long) (volume & 0x0000FFFF )); + XST_mIV(1, (long) ((volume & 0xFFFF0000) >> 16)); XSRETURN(2); } else { XSRETURN_IV(volume); @@ -1280,7 +1280,7 @@ } break; case 1: - volume = SvIV(ST(0)) | SvIV(ST(0)) << 8; + volume = ( SvIV(ST(0)) & 0x0000FFFF ) | (( SvIV(ST(0)) & 0x0000FFFF ) << 16 ); mmr = waveOutSetVolume(wo, volume); if(mmr == MMSYSERR_NOERROR) { XSRETURN_YES; @@ -1290,7 +1290,7 @@ } break; default: - volume = SvIV(ST(0)) | SvIV(ST(1)) << 8; + volume = ( SvIV(ST(0)) & 0x0000FFFF ) | (( SvIV(ST(1)) & 0x0000FFFF ) << 16 ); mmr = waveOutSetVolume(wo, volume); if(mmr == MMSYSERR_NOERROR) { XSRETURN_YES;
Thank you Robert. I have tested your patch and I believe it works perfectly. After calling Volume("50%"), volume is now 50% and the left-right balance is no longer affected. Now Volume() returns (32767,32767). I did not test the workaround. Thanks again! On Tue Mar 17 05:56:50 2009, ROBERTMAY wrote: Show quoted text
> On Mon Mar 02 14:28:32 2009, cvertz wrote:
> > #1 Setting volume works for left channel but silences right channel. > > #2 Parsing of percentage volumes appears to be incorrect.
> > Attached an (untested) patch that: > > (1) Fixes the range of allowed volumes to be 0-65535 to match the > documentation (along with correct bit-shifts of 16-bits rather than
8-bits). Show quoted text
> (2) Fixes the percentage volume calculations. > (3) Bumps the version to 0.50 > > Also (untested), I beleive that the following can be used to work around > the problems: > > #!perl -w > use strict; > use warnings; > > use Win32::Sound(); > > sub win32_volume { > my(@in) = @_; > > if(not scalar @in) { > my $volume = Win32::Sound::_Volume(); > > if (wantarray) { > my $left = ($volume >> 16) & 0x0000FFFF; > my $right = ($volume ) & 0x0000FFFF; > > return ($left, $right); > } > > return $volume; > } > > # Allows '0%'..'100%' > $in[0] =~ s{ ([\d\.]+)%$ }{ int($1*65535/100) }ex if defined $in[0]; > $in[1] =~ s{ ([\d\.]+)%$ }{ int($1*65535/100) }ex if defined $in[1]; > > $in[1] = $in[0] unless defined $in[1]; > > my $volume = (($in[0] & 0x0000FFFF) << 16) | ($in[1] & 0x0000FFFF); > > return Win32::Sound::_Volume($volume, 0); > } > >