CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Win32 Programming Help:
waveInOpen through winmm.dll problem.

 



tals
Novice

Sep 11, 2011, 2:48 AM

Post #1 of 3 (19385 views)
waveInOpen through winmm.dll problem. Can't Post

Hi,

I'm tring to manually open the microphone for recording.

I'm using winmm.dll to do that (windows 7 pro, x86).

I'm receiving an error while closing the audio device.... error number 5.
#define MMSYSERR_BASE 0
#define MMSYSERR_NOERROR 0
#define MMSYSERR_INVALHANDLE (MMSYSERR_BASE + 5)

Even though the outcome function (waveInOpen) is 0 (MMSYSERR_NOERROR), it seems like the waveInOpen doesn't gives me a handler.

I need help, I have no idea how to solve this issue.

I could not find a model that can help me. In the end I need to record (simultaneously) a large number of microphones (around 20 microphones).

Thanks,
TalS.

msdn help site http://msdn.microsoft.com/en-us/library/aa909811.aspx
winmm.pm

Code
package winmm; 

use strict;
use warnings;
use Win32::API::Prototype;

use vars qw ($VERSION);
$VERSION = 0.01;

### MSDN help site ==> http://msdn.microsoft.com/en-us/library/aa909811.aspx

BEGIN
{

ApiLink( 'winmm.dll',
'DWORD waveInGetNumDevs()' )
|| die "Can't register waveInGetNumDevs";
ApiLink( 'winmm.dll',
'DWORD waveInGetErrorText( MMRESULT mmrError, LPTSTR pszText, UINT cchText )' )
|| die "Can't register waveInGetErrorText";
ApiLink( 'winmm.dll',
'DWORD waveInGetDevCaps( UINT uDeviceID, LPWAVEINCAPS pwic, UINT cbwic)' )
|| die "Can't register waveInGetDevCaps";
ApiLink( 'winmm.dll',
'DWORD waveInOpen( LPHWAVEIN phwi, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD dwCallback, DWORD dwInstance, DWORD fdwOpen )' )
|| die "Can't register waveInOpen";
ApiLink( 'winmm.dll',
'DWORD waveInStart( HWAVEIN hwi )' )
|| die "Can't register waveInStart";
ApiLink( 'winmm.dll',
'DWORD waveInStop( HWAVEIN hwi )' )
|| die "Can't register waveInStop";
ApiLink( 'winmm.dll',
'DWORD waveInClose( HWAVEIN hwi )' )
|| die "Can't register waveInClose";
}
sub WAVEFORMATEX {
return "S S L L S S S";
}

sub sizeOfPack {
return length(pack(shift));
}

sub printError {
my $errNumber = shift;

return if($errNumber == 0);

my $uReturnLength = 1024;
my $structReturned = NewString( $uReturnLength );

my $r = main::waveInGetErrorText($errNumber, \$structReturned, $uReturnLength);
printf "Error %d in querying the error string for error code %d: ",$r, $errNumber, $structReturned;
}

sub getNumOfWaveIn {
return main::waveInGetNumDevs();
}

sub getWaveInCap {
my $devNumber = shift;
my $structReturned = shift;
my $uReturnLength = shift;

$$structReturned = NewString( $uReturnLength );

my $eResult = main::waveInGetDevCaps($devNumber, $$structReturned, $uReturnLength);
return $eResult;
}

sub openInputDevice {
my $handler = shift;
my $devNumber = shift;
my $nChannels = shift;
my $nSamplesPerSec = shift;
my $wBitsPerSample = shift;
my $self = shift;
my $proc = shift;

my $nBlockAlign = $nChannels*$wBitsPerSample/8;
# round up the nBlockAlign
$nBlockAlign+=0.5;
$nBlockAlign =~ s/(\d+)\..*/$1/;

my $nAvgBytesPerSec=$nSamplesPerSec*$nBlockAlign;
my $eResult = main::waveInOpen($handler,
$devNumber,
pack (WAVEFORMATEX,
1, # WAVE_FORMAT_PCM equal to 1
$nChannels,
$nSamplesPerSec,
$nAvgBytesPerSec,
$nBlockAlign,
$wBitsPerSample,
sizeOfPack(WAVEFORMATEX)
),
$proc,
$self,
3145729 # CALLBACK_FUNCTION
);
return $eResult;
}

sub startInputDevice {
return main::waveInStart(shift);
}

sub stopInputDevice {
return main::waveInStop(shift);
}

sub closeInputDevice {
return main::waveInClose(shift);
}

1;

sound.pl

Code
#!/usr/bin/perl -w 
use strict;
use warnings;
use Data::Dumper;

# sound interface
use winmm;

my $str;
my $r;
my $i = 0;
my $c = 0;
my %devs = ();

my $numOfDevs = winmm::getNumOfWaveIn;
printf "the computer found %d audio inputs\n", $numOfDevs;

while ($i < $numOfDevs) {
my $struct = "";
$r = winmm::getWaveInCap ($i,
\$struct,
100);
($devs{$i}->{wMid},
$devs{$i}->{wPid},
$devs{$i}->{vDriverVersion},
$devs{$i}->{szPname},
$devs{$i}->{dwFormats},
$devs{$i}->{wChannels},
$devs{$i}->{wReserved1}
) = unpack("S S I Z32 L S S", $struct);
print "Device number $i ==> ";
print Dumper \$devs{$i};
print "\n";
$i+=1;
}
$i = 0;
#my $dev = pack "i", 0;
my $dev = 0;
printf "open result %d\n",
winmm::openInputDevice (\$dev,
0, # device number
1, # number of channels
44100, # sps
16, # bits per samples
\&main,
\&doProc
);
print Dumper $dev;
#printf "%d\n", unpack "i", $dev;
printf "%d\n", $dev;
#winmm::printError
printf "close result %d\n",
winmm::closeInputDevice(\$dev);

sub doProc{
print Dumper \@_;
}

print "end\n";


------- start result screen ------
the computer found 2 audio inputs
Device number 0 ==> $VAR1 = \{
'wReserved1' => 30645,
'wChannels' => 2,
'dwFormats' => 1048575,
'vDriverVersion' => 1537,
'wMid' => 1,
'szPname' => 'Microphone (Realtek High Defini',
'wPid' => 101
};

Device number 1 ==> $VAR1 = \{
'wReserved1' => 30645,
'wChannels' => 2,
'dwFormats' => 1048575,
'vDriverVersion' => 256,
'wMid' => 65535,
'szPname' => 'Microphone (2- Generic USB Audi',
'wPid' => 65535
};

open result 0
$VAR1 = 0;
0
close result 5
end
------- end result screen ------

Attachments: winmm.pm (7.11 KB)
  sound.pl (1.38 KB)


tals
Novice

Sep 15, 2011, 12:28 AM

Post #2 of 3 (19191 views)
Re: [tals] waveInOpen through winmm.dll problem. [In reply to] Can't Post

an update:

I'm now able to to retrieve the waveInOpen handler, but I encountered a new problem :\...

For some reason I'm not able to create a callback function inside perl script. So I used the "use inline c" to define the callback function and retrieve the callback function pointer (a bit dirty, but working), otherwise the script is stalled.

The problem here is how do I jump back to the script from the callback function ? Or how can I pass extra parameters to the the callback function ?

__HELP__

Thanks,
TalS.

winmm.pm was deleted.
sound.pl

Code
#!/perl 

use strict;
use warnings;
use Data::Dumper;

use Win32::API;
use threads;
use Thread::Queue;
use Inline 'C';
use Devel::Pointer;

my $result;

# Private Type WAVEFORMATEX
Win32::API::Struct->typedef( 'WAVEFORMATEX', qw{ USHORT FormatTag;
USHORT Channels;
ULONG SamplesPerSec;
ULONG AvgBytesPerSec;
USHORT BlockAlign;
USHORT BitsPerSample;
USHORT ExtraDataSize;
}
) or die "Typedef error $!\n";

# Private Type WAVEHDR
Win32::API::Struct->typedef( 'WAVEHDR', qw{ LONG lpData;
LONG dwBufferLength;
LONG dwBytesRecorded;
LONG dwUser;
LONG dwFlags;
LONG dwLoops;
LONG lpNext;
LONG Reserved
}
) or die "Typedef error $!\n";

# Private Type WAVEINCAPS
Win32::API::Struct->typedef( 'WAVEINCAPS', qw{ USHORT ManufacturerID;
USHORT ProductID;
UINT DriverVersion;
TCHAR ProductName[32];
ULONG Formats;
USHORT Channels;
USHORT Reserved;
}
) or die "Typedef error $!\n";
# Private Type WAVEINCAPS
Win32::API::Struct->typedef( 'WAVEINCAPS', qw{ USHORT ManufacturerID;
USHORT ProductID;
UINT DriverVersion;
TCHAR ProductName[32];
ULONG Formats;
USHORT Channels;
USHORT Reserved;
}
) or die "Typedef error $!\n";
# Private Type HWAVEIN
#Win32::API::Struct->typedef( 'HWAVEIN', qw{ INT value;
# }
# ) or die "Typedef error $!\n";

Win32::API::Struct->typedef( 'CALLBACK', qw{DWORD_PTR val} ) or die "Typedef error $!\n";
Win32::API::Struct->typedef( 'LRESULT', qw{UINT val} ) or die "Typedef error $!\n";
Win32::API::Struct->typedef( 'ERR_TXT', qw{TCHAR str[1024]} ) or die "Typedef error $!\n";

# Declare Function ...
Win32::API->Import( 'winmm', 'UINT waveInGetNumDevs()');
Win32::API->Import( 'winmm', 'LRESULT waveInGetErrorText(LRESULT mmrError, LPERR_TXT pszText, UINT cchText ); ' );
Win32::API->Import( 'winmm', 'LRESULT waveInGetDevCaps(UINT DeviceID, LPWAVEINCAPS pwic, UINT cbwic)' );
Win32::API->Import( 'winmm', 'LRESULT waveInGetID( UINT hwi, PUINT puDeviceID )' );
Win32::API->Import( 'winmm', 'LRESULT waveInAddBuffer(UINT hwi,LPWAVEHDR pwh,UINT cbwh)' );
Win32::API->Import( 'winmm', 'LRESULT waveInOpen(PUINT phwi, UINT uDeviceID, LPWAVEFORMATEX pwfx, DWORD dwCallback, DWORD dwInstance, DWORD fdwOpen )' );
Win32::API->Import( 'winmm', 'LRESULT waveInPrepareHeader(UINT hwi,LPWAVEHDR pwh,UINT cbwh)' );
Win32::API->Import( 'winmm', 'LRESULT waveInUnprepareHeader(UINT hwi,LPWAVEHDR pwh,UINT cbwh)' );
Win32::API->Import( 'winmm', 'LRESULT waveInStart(UINT hwi)' );
Win32::API->Import( 'winmm', 'LRESULT waveInStop(UINT hwi)' );
Win32::API->Import( 'winmm', 'LRESULT waveInReset(UINT hwi)' );
Win32::API->Import( 'winmm', 'LRESULT waveInClose(UINT hwi)' );

Win32::API->Import( 'winmm', 'LRESULT mixerOpen(PUINT phmx, UINT uMxId, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)' );
Win32::API->Import( 'winmm', 'LRESULT mixerClose(UINT hwi)' );

my $numOfDevs = waveInGetNumDevs()."\n";
printf "the computer found %d audio inputs\n", $numOfDevs;
my $i = 0;

my $caps = Win32::API::Struct->new('WAVEINCAPS');

while ($i < $numOfDevs) {
&handleError ( 'open,',
waveInGetDevCaps($i, $caps, $caps->sizeof('WAVEINCAPS'))
);
print "Device ID: $i ,ProductName: ".$caps->{ProductName}."\n";
$i+=1;
}
$i = 0;

my $WaveFormat = Win32::API::Struct->new('WAVEFORMATEX'); # Static WaveFormat As WAVEFORMATEX
$WaveFormat->{FormatTag} = 1; # WAVE_FORMAT_PCM
$WaveFormat->{Channels} = 1;
$WaveFormat->{SamplesPerSec} = 44100;
$WaveFormat->{BitsPerSample} = 16;
$WaveFormat->{BlockAlign} = 2;
$WaveFormat->{AvgBytesPerSec} = $WaveFormat->{SamplesPerSec} * $WaveFormat->{BlockAlign};
$WaveFormat->{ExtraDataSize} = 0;

my $DataQueue = Thread::Queue->new;
my $thr = threads->new(sub {
while (my $DataElement = $DataQueue->dequeue) {
print "Popped $DataElement off the queue\n";
}
});


my $DevHandle = pack "I", 0;# = Win32::API::Struct->new('HWAVEIN');

#$Win32::API::DEBUG = 1;

&handleError ( 'open,',
waveInOpen( $DevHandle,
0,
$WaveFormat,
getPointer(), #getAddress(\&intWaveInProc), #\&intWaveInProc, #\&waveInProc,
0,
#0x00000000 # CALLBACK_NULL
#0x00050000 # CALLBACK_EVENT
#0x00010000 # CALLBACK_WINDOW
#0x00020000 # CALLBACK_TASK
#0x00020000 # CALLBACK_THREAD
0x00030000 # CALLBACK_FUNCTION
)
);
print "handle is ".unpack ("I", $DevHandle)."\n";
$DevHandle = unpack ("I", $DevHandle);

my $gid = pack "I", 999;
&handleError ( 'get ID,',
waveInGetID( $DevHandle,
$gid
)
);
$gid = unpack "I", $gid;
print "gid = ".$gid."\n";

&handleError ( 'start ID,',
waveInStart( $DevHandle
)
);

sleep 5;
&handleError ( 'stop ID,',
waveInStop( $DevHandle
)
);

&handleError ( 'close,',
waveInClose($DevHandle)
);

$DataQueue->enqueue(12);
$DataQueue->enqueue("A", "B", "C");
$DataQueue->enqueue(\$thr);
$DataQueue->enqueue(undef);
$thr->join;


sub intWaveInProc {
my $hwi = shift;
my $uMsg = shift;
my $dwInstance = shift;
my $dwParam1 = shift;
my $dwParam2 = shift;
print "aaa\n";
}

sub handleError {
my $cmd = shift;
my $errNum = shift;
return unless (defined $errNum);
return if ($errNum == 0);
my $eText = Win32::API::Struct->new('ERR_TXT');
print $cmd." error ".$errNum." result => ".waveInGetErrorText($errNum, $eText, 1024);
print " :\n".$eText->{str}."\n";
}

sub getAddress {
return hex scalar((split(/[\(|\)]/, shift))[1]);
}

__END__
__C__
#include <stdio.h>
#include <windows.h>
#include <mmsystem.h>

//void waveInProc(UINT hwi,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2);
void CALLBACK waveInProc(UINT hwi,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2);
unsigned int getPointer();

unsigned int getPointer(){
return &waveInProc;
}

//void waveInProc(UINT hwi,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2) {
void CALLBACK waveInProc(UINT hwi,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2) {
WAVEHDR *pHdr=NULL;
switch(uMsg) {
case WIM_CLOSE:
break;

case WIM_DATA:{
}
break;

case WIM_OPEN:
break;

default:
break;
}
}

Attachments: sound.pl (8.80 KB)


tals
Novice

Sep 17, 2011, 11:34 PM

Post #3 of 3 (19030 views)
Re: [tals] waveInOpen through winmm.dll problem. [In reply to] Can't Post

another update, program is done.

The callback solution is so _U_G_L_Y___!_

I've tried the perlApi method to callback (see forum linkhttp://perlguru.com/gforum.cgi?post=58740;sb=post_latest_reply;so=ASC;forum_view=forum_view_expandable;#58740) but the script stalled!

So .... I've done a polling thread to monitor a valid register :/ Crazy (ugly ugly ugly !!!)

its working. ;)

Thanks,
TalS.

sound.pl

Code
#!/perl 

use strict;
use warnings;
use Data::Dumper;

use Win32::API;
use threads;
use Thread::Queue;
use threads::shared;
#use Inline => Config => LIBS => '-L/usr/local/mylib -lmylib';
#use Inline => Config => INC => '-I/usr/local/mylib';
use Inline 'C';
use Devel::Pointer;

my $kill_thread :shared = 0;
my $nullPoll :shared = 0;
my $result;
my @buffers = ();

my $devNumber = 1;
my $sps = 44100;
my $channels = 1;
my $bps = 16;

# Private Type WAVEFORMATEX
Win32::API::Struct->typedef( 'WAVEFORMATEX', qw{ USHORT FormatTag;
USHORT Channels;
ULONG SamplesPerSec;
ULONG AvgBytesPerSec;
USHORT BlockAlign;
USHORT BitsPerSample;
USHORT ExtraDataSize;
}
) or die "Typedef error $!\n";

# Private Type WAVEHDR
Win32::API::Struct->typedef( 'WAVEHDR', qw{ LPSTR lpData;
DWORD dwBufferLength;
DWORD dwBytesRecorded;
DWORD_PTR dwUser;
DWORD dwFlags;
DWORD dwLoops;
LONG lpNext;
DWORD_PTR Reserved;
}
) or die "Typedef error $!\n";

# Private Type WAVEINCAPS
Win32::API::Struct->typedef( 'WAVEINCAPS', qw{ USHORT ManufacturerID;
USHORT ProductID;
UINT DriverVersion;
TCHAR ProductName[32];
ULONG Formats;
USHORT Channels;
USHORT Reserved;
}
) or die "Typedef error $!\n";

# Private Type MIXERLINECONTROLS
Win32::API::Struct->typedef( 'MIXERLINECONTROLS', qw{ DWORD cbStruct;
DWORD dwLineID;
DWORD dwControlIDorType;
DWORD cControls;
DWORD cbmxctrl;
LPMIXERCONTROL pamxctrl;
}
) or die "Typedef error $!\n";

Win32::API::Struct->typedef( 'CALLBACK', qw{DWORD_PTR val} ) or die "Typedef error $!\n";
Win32::API::Struct->typedef( 'LRESULT', qw{UINT val} ) or die "Typedef error $!\n";
Win32::API::Struct->typedef( 'ERR_TXT', qw{TCHAR str[1024]} ) or die "Typedef error $!\n";
my $WHDR_DONE = 0x0001;
my $WHDR_PREPARED = 0x0002;
my $WHDR_BEGINLOOP = 0x0004;
my $WHDR_ENDLOOP = 0x0008;
my $WHDR_INQUEUE = 0x0010;

# Declare Function ...
Win32::API->Import( 'winmm', 'UINT waveInGetNumDevs()');
Win32::API->Import( 'winmm', 'LRESULT waveInGetErrorText(LRESULT mmrError, LPERR_TXT pszText, UINT cchText ); ' );
Win32::API->Import( 'winmm', 'LRESULT waveInGetDevCaps(UINT DeviceID, LPWAVEINCAPS pwic, UINT cbwic)' );
Win32::API->Import( 'winmm', 'LRESULT waveInGetID( UINT hwi, PUINT puDeviceID )' );
Win32::API->Import( 'winmm', 'LRESULT waveInAddBuffer(UINT hwi,LPWAVEHDR pwh,UINT cbwh)' );
Win32::API->Import( 'winmm', 'LRESULT waveInOpen(PUINT phwi, UINT uDeviceID, LPWAVEFORMATEX pwfx, DWORD dwCallback, DWORD dwInstance, DWORD fdwOpen )' );
Win32::API->Import( 'winmm', 'LRESULT waveInPrepareHeader(UINT hwi,LPWAVEHDR pwh,UINT cbwh)' );
Win32::API->Import( 'winmm', 'LRESULT waveInUnprepareHeader(UINT hwi,LPWAVEHDR pwh,UINT cbwh)' );
Win32::API->Import( 'winmm', 'LRESULT waveInStart(UINT hwi)' );
Win32::API->Import( 'winmm', 'LRESULT waveInStop(UINT hwi)' );
Win32::API->Import( 'winmm', 'LRESULT waveInReset(UINT hwi)' );
Win32::API->Import( 'winmm', 'LRESULT waveInClose(UINT hwi)' );

Win32::API->Import( 'winmm', 'LRESULT waveOutGetVolume(UINT hwi, PUINT pdwVolume)' );
Win32::API->Import( 'winmm', 'LRESULT waveOutSetVolume(UINT hwi, UINT dwVolume)' );

Win32::API->Import( 'winmm', 'LRESULT mixerOpen(PUINT phmx, UINT uMxId, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)' );
Win32::API->Import( 'winmm', 'LRESULT mixerGetID( UINT hmxobj, UINT* puMxId, DWORD fdwId )' );
Win32::API->Import( 'winmm', 'LRESULT mixerClose(UINT hwi)' );

my $numOfDevs = waveInGetNumDevs()."\n";
printf "the computer found %d audio inputs\n", $numOfDevs;
my $i = 0;

my $caps = Win32::API::Struct->new('WAVEINCAPS');

while ($i < $numOfDevs) {
&handleError ( 'open,',
waveInGetDevCaps($i, $caps, $caps->sizeof('WAVEINCAPS'))
);
print "Device ID: $i ,ProductName: ".$caps->{ProductName}."\n";
$i+=1;
}
$i = 0;

my $WaveFormat = Win32::API::Struct->new('WAVEFORMATEX'); # Static WaveFormat As WAVEFORMATEX
$WaveFormat->{FormatTag} = 1; # WAVE_FORMAT_PCM
$WaveFormat->{Channels} = $channels;
$WaveFormat->{SamplesPerSec} = $sps;
$WaveFormat->{BitsPerSample} = $bps;
$WaveFormat->{BlockAlign} = &round( ($WaveFormat->{Channels} * $WaveFormat->{BitsPerSample}) / 8);
$WaveFormat->{AvgBytesPerSec} = $WaveFormat->{SamplesPerSec} * $WaveFormat->{BlockAlign} * $WaveFormat->{Channels};
$WaveFormat->{ExtraDataSize} = $WaveFormat->sizeof('WAVEFORMATEX');

#$Win32::API::DEBUG = 1;

my $scalar;

my $devHandle = pack "I", 0;
## open device
&handleError ( 'open,',
waveInOpen( $devHandle,
$devNumber,
$WaveFormat,
getPointer(),
\$scalar, #\&processHeader,
#0x00000000 # CALLBACK_NULL
#0x00050000 # CALLBACK_EVENT
#0x00010000 # CALLBACK_WINDOW
#0x00020000 # CALLBACK_TASK
#0x00020000 # CALLBACK_THREAD
0x00030000 # CALLBACK_FUNCTION
)
);
$devHandle = unpack ("I", $devHandle);

&prepareBuffers ($devHandle, $WaveFormat->{AvgBytesPerSec}, \@buffers, 8);
my $thr = threads->new(\&polling, \$nullPoll, $WaveFormat->{SamplesPerSec} * $WaveFormat->{BlockAlign} * $WaveFormat->{Channels});

&handleError ( 'start ID,',
waveInStart( $devHandle
)
);


sleep 5;
print "aaa\n";
sleep 5;

&handleError ( 'stop ID,',
waveInStop( $devHandle
)
);

while ($nullPoll < 5) {
}

&releaseBuffers($devHandle, \@buffers, 8);

#&handleError ( 'close,',
waveInClose($devHandle)
;# );

&stop_polling;

sub round {
my $n = shift;
$n = ($n + 0.5);
return sprintf "%d", $n;
}

sub getAddress {
return hex scalar((split(/[\(|\)]/, shift))[1]);
}

sub handleError {
my $cmd = shift;
my $errNum = shift;
return unless (defined $errNum);
return if ($errNum == 0);
my $eText = Win32::API::Struct->new('ERR_TXT');
print $cmd." error ".$errNum." result => ".waveInGetErrorText($errNum, $eText, 1024);
print " :\n".$eText->{str}."\n";
}

sub polling {
my $np = shift;
my $l = shift;

open (RAW, ">"."wav.raw") or die "cannot open:".$@;
binmode RAW;
while ($kill_thread == 0) {
if (getValid() != 0) {
my $scalar;
packHeader($scalar);
print RAW $scalar;
clearValid();
$$np = 0;
}else{
$$np += 1;
}
select(undef, undef, undef, 0.5)
}
close RAW;
}

sub stop_polling {
$kill_thread = 1;
$thr->detach;
}

sub prepareBuffers{
my $DH = shift;
my $AvgBytesPerSec = shift;
my $array = shift;
my $maxBuffers = shift;
my $i = 0;
while ($i < $maxBuffers) {
my $inData = pack "a".$AvgBytesPerSec, \0;
my $Wave = Win32::API::Struct->new('WAVEHDR'); # Static Wave As WAVEHDR
$Wave->{dwUser} = $i;
$Wave->{lpData} = $inData;
$Wave->{dwBufferLength} = $AvgBytesPerSec;
$Wave->{dwFlags} = 0;
&handleError ( 'prepare header before start,',
waveInPrepareHeader( $DH,
$Wave,
$Wave->sizeof('WAVEHDR')
)
);
&handleError ( 'add buffer,',
waveInAddBuffer( $DH,
$Wave,
$Wave->sizeof('WAVEHDR')
)
);
push @$array, \$Wave;
$i += 1;
}
}

sub releaseBuffers{
my $DH = shift;
my $array = shift;
my $maxBuffers = shift;
my $i = 0;
while ($i < $maxBuffers) {
my $Wave = ${pop @$array};
&handleError ( 'unprepare header before close,',
waveInUnprepareHeader( $DH,
$Wave,
$Wave->sizeof('WAVEHDR')
)
) if ($Wave->{dwBytesRecorded} > 0);
$Wave = undef;
$i += 1;
}
}
__END__
__C__
#include <stdio.h>
#include <windows.h>
#include <mmsystem.h>

unsigned short valid = 0;
unsigned int pHdr = 0;
unsigned int handle = 0;

void CALLBACK waveInProc(UINT hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
unsigned int getPointer();
void clearValid();
unsigned short getValid();
unsigned int getHandle();

unsigned short getValid(){
return valid;
}

unsigned int getHandle(){
return handle;
}

unsigned int getPointerHdr(){
return pHdr;
}

void packHeader(SV* hdr){
WAVEHDR * lH = (WAVEHDR *)pHdr;
sv_setpvn(hdr,
(char *)(lH->lpData),
lH->dwBufferLength //dwBytesRecorded
);
}

void clearValid(){
valid = 0;
}

unsigned int getPointer(){
return &waveInProc;
}


void CALLBACK waveInProc(UINT hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) {
unsigned char nMark = 0;

switch(uMsg) {
case WIM_CLOSE:
break;

case WIM_DATA:{
pHdr = dwParam1;
handle = hwi;
valid = 1;
waveInAddBuffer( hwi,
(WAVEHDR *)dwParam1,
sizeof(WAVEHDR)
);
}
break;

case WIM_OPEN:
break;

default:
break;
}
}

__REMARK__

};


 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives