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"; ## ## typedef struct { // info site: http://msdn.microsoft.com/en-us/library/aa910191.aspx ## WORD wMid; // Manufacturer identifier for the device driver for the waveform-audio input device. ## WORD wPid; // Product identifier for the waveform-audio input device. ## MMVERSION vDriverVersion; // Version number of the device driver for the waveform-audio input device. The high-order byte is the major version number, and the low-order byte is the minor version number. ## CHAR szPname[MAXPNAMELEN]; // MAXPNAMELEN = 32 :: Null-terminated string that contains the product name. ## DWORD dwFormats; // Specifies the standard formats that are supported. It is one or a combination of the following flags. ## WORD wChannels; // Number that specifies whether the device supports mono (1) or stereo (2) input. ## WORD wReserved1; // Padding. ## } WAVEINCAPS; ## typedef UINT MMVERSION; ## typedef struct { // info site: http://msdn.microsoft.com/en-us/library/aa908934.aspx ## WORD wFormatTag; // Waveform-audio format type. Format tags are registered with Microsoft Corporation for many compression algorithms. A complete list of format tags can be found in the Mmreg.h header file. ## WORD nChannels; // Number of channels in the waveform-audio data. Monaural data uses one channel and stereo data uses two channels. ## DWORD nSamplesPerSec; // Sample rate, in samples per second (Hertz), that each channel should be played or recorded. ## DWORD nAvgBytesPerSec; // Required average data-transfer rate, in bytes per second, for the format tag. ## WORD nBlockAlign; // Block alignment, in bytes. The block alignment is the minimum atomic unit of data for the wFormatTag format type. ## WORD wBitsPerSample; // Bits per sample for the wFormatTag format type. ## WORD cbSize; // Size, in bytes, of extra format information appended to the end of the WAVEFORMATEX structure. ## } WAVEFORMATEX; ## #define WAVE_FORMAT_PCM 1 ## #define WAVE_INVALIDFORMAT 0x00000000 /* invalid format */ ## #define WAVE_FORMAT_1M08 0x00000001 /* 11.025 kHz, Mono, 8-bit */ ## #define WAVE_FORMAT_1S08 0x00000002 /* 11.025 kHz, Stereo, 8-bit */ ## #define WAVE_FORMAT_1M16 0x00000004 /* 11.025 kHz, Mono, 16-bit */ ## #define WAVE_FORMAT_1S16 0x00000008 /* 11.025 kHz, Stereo, 16-bit */ ## #define WAVE_FORMAT_2M08 0x00000010 /* 22.05 kHz, Mono, 8-bit */ ## #define WAVE_FORMAT_2S08 0x00000020 /* 22.05 kHz, Stereo, 8-bit */ ## #define WAVE_FORMAT_2M16 0x00000040 /* 22.05 kHz, Mono, 16-bit */ ## #define WAVE_FORMAT_2S16 0x00000080 /* 22.05 kHz, Stereo, 16-bit */ ## #define WAVE_FORMAT_4M08 0x00000100 /* 44.1 kHz, Mono, 8-bit */ ## #define WAVE_FORMAT_4S08 0x00000200 /* 44.1 kHz, Stereo, 8-bit */ ## #define WAVE_FORMAT_4M16 0x00000400 /* 44.1 kHz, Mono, 16-bit */ ## #define WAVE_FORMAT_4S16 0x00000800 /* 44.1 kHz, Stereo, 16-bit */ ## #define WAVE_FORMAT_48M08 0x00001000 /* 48 kHz, Mono, 8-bit */ ## #define WAVE_FORMAT_48S08 0x00002000 /* 48 kHz, Stereo, 8-bit */ ## #define WAVE_FORMAT_48M16 0x00004000 /* 48 kHz, Mono, 16-bit */ ## #define WAVE_FORMAT_48S16 0x00008000 /* 48 kHz, Stereo, 16-bit */ ## #define WAVE_FORMAT_96M08 0x00010000 /* 96 kHz, Mono, 8-bit */ ## #define WAVE_FORMAT_96S08 0x00020000 /* 96 kHz, Stereo, 8-bit */ ## #define WAVE_FORMAT_96M16 0x00040000 /* 96 kHz, Mono, 16-bit */ ## #define WAVE_FORMAT_96S16 0x00080000 /* 96 kHz, Stereo, 16-bit */ } 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;