Greetings perl-win32-users,
I have a script that uses media player (from CPAN) to play MIDI files
using mciSendString of the Win32 API. I have never been able to figure
out how to change the output device so I decided to use TieRegistry to
change the default MIDI output device. This works but changing the
value from the script does not have an immediate effect. In order for
the change of default devices to take effect, the script needs to
terminate. Using regedit I can see that the value is changing
immediately but the win 32 Media control interface does not see the
new default value until the script is run again. Is this normal
behavior with the registry and the MCI or is there some way to effect
an immediate update? Anything else in the script that might be
responsible for this behavior?
use strict;
use Win32::API;
use Win32::MediaPlayer; # this seems to come from D:\Perl\win32\
use Win32::TieRegistry;
my $path = 'C:/miditemp/01028e.mid'; # set to approp file
my @device_array = devnames();
my $index = 0;
foreach my $device (@device_array){
print "$index $device\n";
$index ++;
}
print "\nenter device number\n";
my $input = <STDIN>;
chomp $input;
my $valueDataString = $device_array[$input];
print"\nSelected device is $valueDataString\n";
my $rk = 'CUser/Software/Microsoft/Windows/CurrentVersion/Multimedia/MIDIMap';
my $key = new Win32::TieRegistry $rk, {Access => 'KEY_ALL_ACCESS', Delimiter =>
'/' };
$key->SetValue( "szPname", $valueDataString);
my $ValueData= $key->GetValue('szPname');
$key = undef;
my $winmm = new Win32::MediaPlayer; # new media player object
$winmm->load($path); # Load music file
my $total =$winmm->length(1);
print"\ntotal length $total enter to continue\n";
$input = <STDIN>;
$winmm->play; # Play the music
$winmm->seek(100); # seek location in
microseconds
$winmm->pause; # Pause music playing
print "\npaused enter to continue\n";
$input = <STDIN>;
$winmm->resume; # Resume music playing
my $pos = 0; # media player reports
time in minutes and seconds so convert to seconds
my @t = split ':', $total; # for the while loop
my $ntotal = $t[0] * 60 + $t[1];
while ($pos < $ntotal) { # print the time until file
finishes
sleep .1;
$winmm->pos(1);
my $rpos = $winmm->pos(1);
my @p = split ':', $rpos;
$pos = $p[0] * 60 + $p[1];
printf "\rNow Pos: %02u:%02u ", int ($pos / 60), $pos % 60; # now time.
}
sub devnames { # get device names from MCI
my @devices;
my $mognd = new Win32::API("winmm", "midiOutGetNumDevs", "", "I");
unless ($mognd) {die "error, midiOutGetNumDevs, $!"; }
my $mognd_devices = $mognd->Call();
my $buf = " " x 200; # no idea; size of
returned data!?
my ($rtn, $i);
my $mogdc = new Win32::API("winmm", "midiOutGetDevCaps", "IPI", "I");
unless ($mogdc) {die "error, midiOutGetDevCaps, $!";}
for ($i = 0; $i < $mognd_devices; $i++) {
$rtn = $mogdc->Call($i, $buf , 200);
if ($rtn) {die "midiOutGetDevCaps returned $rtn"; }
push(@devices, get_sz_at($buf, 8));
}
return @devices;
}
sub get_sz_at {
my $s = substr $_[0], $_[1];
substr($s, 0, index($s, "\x0"));
}
$winmm->close;
--
Best regards,
Spencer Chase mailto:[EMAIL PROTECTED]
67550 Bell Springs Rd.
Garberville, CA 95542 Postal service only.
Laytonville, CA 95454 UPS only.
[EMAIL PROTECTED]
http://www.spencerserolls.com
http://www.spencerserolls.com/MidiValve.htm
(707) 984-8356
_______________________________________________
Perl-Win32-Users mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs