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
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to