#!/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(), #\&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 #include #include //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; } } __REMARK__ my $InData = " " x $WaveFormat->{AvgBytesPerSec}; my $Wave = Win32::API::Struct->new('WAVEHDR'); # Static Wave As WAVEHDR $Wave->{lpData} = $InData; $Wave->{dwBufferLength} = $WaveFormat->{AvgBytesPerSec}; $Wave->{dwFlags} = 0; #$result = waveInOpen(\$DevHandle, 0, $WaveFormat, 0, 0, 0); #$result = waveInOpen(\$DevHandle, 0, $WaveFormat, \&ddd, 0, 0x00030000); #print "$result, $DevHandle\n"; #$result = waveInPrepareHeader($DevHandle, $Wave, $Wave->sizeof('WaveHdr')); #$result = waveInAddBuffer($DevHandle, $Wave, $Wave->sizeof('WaveHdr')); #$result = waveInStart($DevHandle); # #sleep 1; # #$result = waveInPrepareHeader($DevHandle, $Wave, $Wave->sizeof('WaveHdr')); #$result = waveInClose($DevHandle); sub ddd { print $@; };