阅读:2217回复:6
弱弱的问:声卡驱动是怎样被调用的?
刚用vc编了个数据采集卡的程序,对硬件的访问是通过调用现成的库函数实现的(库函数应该是再调用相应的运行在内核模式下驱动例程吧)。
突然想到这样一个问题,像winnap这些软件又是怎样知道调用不同的声卡驱动的呢?还望大虾指点 [编辑 - 11/6/04 by gojuventusgo] |
|
沙发#
发布于:2004-11-06 19:07
在Win32 API中提供了约四十多个函数可供对声卡编程:
-----------声音输入 1.waveInGetNumDevs(); Return Values Returns the number of devices. A return value of zero means that no devices are present or that an error occurred. Requirements Windows NT/2000: Requires Windows NT 3.1 or later. Windows 95/98: Requires Windows 95 or later. Header: Declared in Mmsystem.h. Library: Use Winmm.lib. 2.waveInGetDevCaps(UINT uDeviceID, LPWAVEINCAPS pwic, UINT cbwic ); Parameters uDeviceID Identifier of the waveform-audio output device. It can be either a device identifier or a handle of an open waveform-audio input device. pwic Pointer to a WAVEINCAPS structure to be filled with information about the capabilities of the device. cbwic Size, in bytes, of the WAVEINCAPS structure. Return Values Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following. Value Description MMSYSERR_BADDEVICEID Specified device identifier is out of range. MMSYSERR_NODRIVER No device driver is present. MMSYSERR_NOMEM Unable to allocate or lock memory. Remarks Use this function to determine the number of waveform-audio input devices present in the system. If the value specified by the uDeviceID parameter is a device identifier, it can vary from zero to one less than the number of devices present. The WAVE_MAPPER constant can also be used as a device identifier. Only cbwic bytes (or less) of information is copied to the location pointed to by pwic. If cbwic is zero, nothing is copied and the function returns zero. Requirements Windows NT/2000: Requires Windows NT 3.1 or later. Windows 95/98: Requires Windows 95 or later. Header: Declared in Mmsystem.h. Library: Use Winmm.lib. Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000. The WAVEINCAPS structure describes the capabilities of a waveform-audio input device. typedef struct { WORD wMid; WORD wPid; MMVERSION vDriverVersion; CHAR szPname[MAXPNAMELEN]; DWORD dwFormats; WORD wChannels; WORD wReserved1; } WAVEINCAPS; Members wMid Manufacturer identifier for the device driver for the waveform-audio input device. Manufacturer identifiers are defined in Manufacturer and Product Identifiers. wPid Product identifier for the waveform-audio input device. Product identifiers are defined in Manufacturer and Product Identifiers. 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. szPname Product name in a null-terminated string. dwFormats Standard formats that are supported. Can be a combination of the following: Format Description WAVE_FORMAT_1M08 11.025 kHz, mono, 8-bit WAVE_FORMAT_1M16 11.025 kHz, mono, 16-bit WAVE_FORMAT_1S08 11.025 kHz, stereo, 8-bit WAVE_FORMAT_1S16 11.025 kHz, stereo, 16-bit WAVE_FORMAT_2M08 22.05 kHz, mono, 8-bit WAVE_FORMAT_2M16 22.05 kHz, mono, 16-bit WAVE_FORMAT_2S08 22.05 kHz, stereo, 8-bit WAVE_FORMAT_2S16 22.05 kHz, stereo, 16-bit WAVE_FORMAT_4M08 44.1 kHz, mono, 8-bit WAVE_FORMAT_4M16 44.1 kHz, mono, 16-bit WAVE_FORMAT_4S08 44.1 kHz, stereo, 8-bit WAVE_FORMAT_4S16 44.1 kHz, stereo, 16-bit wChannels Number specifying whether the device supports mono (1) or stereo (2) input. wReserved1 Padding. Requirements Windows NT/2000: Requires Windows NT 3.1 or later. Windows 95/98: Requires Windows 95 or later. Header: Declared in Mmsystem.h. Unicode: Declared as Unicode and ANSI structure 3.waveInOpen(LPHWAVEIN phwi, UINT uDeviceID, LPWAVEFORMATEX pwfx, DWORD dwCallback, DWORD dwCallbackInstance, DWORD fdwOpen); Parameters phwi Pointer to a buffer that receives a handle identifying the open waveform-audio input device. Use this handle to identify the device when calling other waveform-audio input functions. This parameter can be NULL if WAVE_FORMAT_QUERY is specified for fdwOpen. uDeviceID Identifier of the waveform-audio input device to open. It can be either a device identifier or a handle of an open waveform-audio input device. You can use the following flag instead of a device identifier. Value Meaning WAVE_MAPPER The function selects a waveform-audio input device capable of recording in the specified format. pwfx Pointer to a WAVEFORMATEX structure that identifies the desired format for recording waveform-audio data. You can free this structure immediately after waveInOpen returns. dwCallback Pointer to a fixed callback function, an event handle, a handle to a window, or the identifier of a thread to be called during waveform-audio recording to process messages related to the progress of recording. If no callback function is required, this value can be zero. For more information on the callback function, see waveInProc. dwCallbackInstance User-instance data passed to the callback mechanism. This parameter is not used with the window callback mechanism. fdwOpen Flags for opening the device. The following values are defined. Value Meaning CALLBACK_EVENT The dwCallback parameter is an event handle. CALLBACK_FUNCTION The dwCallback parameter is a callback procedure address. CALLBACK_NULL No callback mechanism. This is the default setting. CALLBACK_THREAD The dwCallback parameter is a thread identifier. CALLBACK_WINDOW The dwCallback parameter is a window handle. WAVE_FORMAT_DIRECT If this flag is specified, the ACM driver does not perform conversions on the audio data. WAVE_FORMAT_QUERY The function queries the device to determine whether it supports the given format, but it does not open the device. WAVE_MAPPED The uDeviceID parameter specifies a waveform-audio device to be mapped to by the wave mapper. Return Values Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following. Value Description MMSYSERR_ALLOCATED Specified resource is already allocated. MMSYSERR_BADDEVICEID Specified device identifier is out of range. MMSYSERR_NODRIVER No device driver is present. MMSYSERR_NOMEM Unable to allocate or lock memory. WAVERR_BADFORMAT Attempted to open with an unsupported waveform-audio format. Remarks Use the waveInGetNumDevs function to determine the number of waveform-audio input devices present on the system. The device identifier specified by uDeviceID varies from zero to one less than the number of devices present. The WAVE_MAPPER constant can also be used as a device identifier. If you choose to have a window or thread receive callback information, the following messages are sent to the window procedure or thread to indicate the progress of waveform-audio input: MM_WIM_OPEN, MM_WIM_CLOSE, and MM_WIM_DATA. If you choose to have a function receive callback information, the following messages are sent to the function to indicate the progress of waveform-audio input: WIM_OPEN, WIM_CLOSE, and WIM_DATA. Requirements Windows NT/2000: Requires Windows NT 3.1 or later. Windows 95/98: Requires Windows 95 or later. Header: Declared in Mmsystem.h. Library: Use Winmm.lib. typedef struct { WORD wFormatTag; WORD nChannels; DWORD nSamplesPerSec; DWORD nAvgBytesPerSec; WORD nBlockAlign; WORD wBitsPerSample; WORD cbSize; } WAVEFORMATEX; Members 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. nChannels Number of channels in the waveform-audio data. Monaural data uses one channel and stereo data uses two channels. nSamplesPerSec Sample rate, in samples per second (hertz), that each channel should be played or recorded. If wFormatTag is WAVE_FORMAT_PCM, then common values for nSamplesPerSec are 8.0 kHz, 11.025 kHz, 22.05 kHz, and 44.1 kHz. For non-PCM formats, this member must be computed according to the manufacturer's specification of the format tag. nAvgBytesPerSec Required average data-transfer rate, in bytes per second, for the format tag. If wFormatTag is WAVE_FORMAT_PCM, nAvgBytesPerSec should be equal to the product of nSamplesPerSec and nBlockAlign. For non-PCM formats, this member must be computed according to the manufacturer's specification of the format tag. Playback and record software can estimate buffer sizes by using the nAvgBytesPerSec member. nBlockAlign Block alignment, in bytes. The block alignment is the minimum atomic unit of data for the wFormatTag format type. If wFormatTag is WAVE_FORMAT_PCM, nBlockAlign should be equal to the product of nChannels and wBitsPerSample divided by 8 (bits per byte). For non-PCM formats, this member must be computed according to the manufacturer's specification of the format tag. Playback and record software must process a multiple of nBlockAlign bytes of data at a time. Data written and read from a device must always start at the beginning of a block. For example, it is illegal to start playback of PCM data in the middle of a sample (that is, on a non-block-aligned boundary). wBitsPerSample Bits per sample for the wFormatTag format type. If wFormatTag is WAVE_FORMAT_PCM, then wBitsPerSample should be equal to 8 or 16. For non-PCM formats, this member must be set according to the manufacturer's specification of the format tag. Note that some compression schemes cannot define a value for wBitsPerSample, so this member can be zero. cbSize Size, in bytes, of extra format information appended to the end of the WAVEFORMATEX structure. This information can be used by non-PCM formats to store extra attributes for the wFormatTag. If no extra information is required by the wFormatTag, this member must be set to zero. Note that for WAVE_FORMAT_PCM formats (and only WAVE_FORMAT_PCM formats), this member is ignored. Remarks An example of a format that uses extra information is the Microsoft Adaptive Delta Pulse Code Modulation (MS-ADPCM) format. The wFormatTag for MS-ADPCM is WAVE_FORMAT_ADPCM. The cbSize member will typically be set to 32. The extra information stored for WAVE_FORMAT_ADPCM is coefficient pairs required for encoding and decoding the waveform-audio data. Requirements Windows NT/2000: Requires Windows NT 3.1 or later. Windows 95/98: Requires Windows 95 or later. Header: Declared in Mmreg.h. 4.waveInPrepareHeader(HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh ); Parameters hwi Handle to the waveform-audio input device. pwh Pointer to a WAVEHDR structure that identifies the buffer to be prepared. cbwh Size, in bytes, of the WAVEHDR structure. Return Values Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following. Value Description MMSYSERR_INVALHANDLE Specified device handle is invalid. MMSYSERR_NODRIVER No device driver is present. MMSYSERR_NOMEM Unable to allocate or lock memory. Remarks The lpData, dwBufferLength, and dwFlags members of the WAVEHDR structure must be set before calling this function (dwFlags must be zero). Requirements Windows NT/2000: Requires Windows NT 3.1 or later. Windows 95/98: Requires Windows 95 or later. Header: Declared in Mmsystem.h. Library: Use Winmm.lib. typedef struct { LPSTR lpData; DWORD dwBufferLength; DWORD dwBytesRecorded; DWORD dwUser; DWORD dwFlags; DWORD dwLoops; struct wavehdr_tag * lpNext; DWORD reserved; } WAVEHDR; Members lpData Pointer to the waveform buffer. dwBufferLength Length, in bytes, of the buffer. dwBytesRecorded When the header is used in input, this member specifies how much data is in the buffer. dwUser User data. dwFlags Flags supplying information about the buffer. The following values are defined: WHDR_BEGINLOOP This buffer is the first buffer in a loop. This flag is used only with output buffers. WHDR_DONE Set by the device driver to indicate that it is finished with the buffer and is returning it to the application. WHDR_ENDLOOP This buffer is the last buffer in a loop. This flag is used only with output buffers. WHDR_INQUEUE Set by Windows to indicate that the buffer is queued for playback. WHDR_PREPARED Set by Windows to indicate that the buffer has been prepared with the waveInPrepareHeader or waveOutPrepareHeader function. dwLoops Number of times to play the loop. This member is used only with output buffers. wavehdr_tag Reserved. reserved Reserved. Remarks Use the WHDR_BEGINLOOP and WHDR_ENDLOOP flags in the dwFlags member to specify the beginning and ending data blocks for looping. To loop on a single block, specify both flags for the same block. Use the dwLoops member in the WAVEHDR structure for the first block in the loop to specify the number of times to play the loop. The lpData, dwBufferLength, and dwFlags members must be set before calling the waveInPrepareHeader or waveOutPrepareHeader function. (For either function, the dwFlags member must be set to zero.) Requirements Windows NT/2000: Requires Windows NT 3.1 or later. Windows 95/98: Requires Windows 95 or later. Header: Declared in Mmsystem.h. 5.waveInUnprepareHeader(m_inwave,&m_waveinheader1,sizeof(WAVEHDR)); 6.waveInAddBuffer(m_inwave,&m_waveinheader1,sizeof(WAVEHDR) ); 7.waveInStart( m_inwave ); 利用以下几个函数即可对声卡输入进行采样,如采用的是回调用函数或线程,则可在回调函数或线程中周期性的获得数据,可参阅MSDN或SDK来获得函数和相关数据结构详细的使用说明。 --------声卡输出 声卡的输出则相对较简单 8.waveOutGetNumDevs(); 9.waveOutGetDevCaps(0,&outcaps,sizeof(WAVEOUTCAPS)); 10.waveOutOpen(&m_outwave,0,&m_WaveFormat, 0,NULL,CALLBACK_NULL); 11.waveOutPrepareHeader(m_outwave,&m_waveoutheader1,sizeof(WAVEHDR) ); 12.waveOutUnprepareHeader(m_outwave,&m_waveoutheader1,sizeof(WAVEHDR) ); 13.waveOutWrite(m_outwave,&m_waveoutheader1,sizeof(WAVEHDR) ); 如需要输出一定频率的正弦波,可事先通过某些工具获得该正弦波的数据,周期性的通过waveOutWrite函数输出即可。 |
|
板凳#
发布于:2004-11-06 19:39
多谢指点!不过有些地方还是不太明白
你的意思是说像winnap这些多媒体软件是通过调用一些win32 api来实现的?但这些api函数也是无法直接对声卡进行控制的,应该是再由它们调用相应的声卡驱动例程吧?但这两者之间又是怎样建立关联的呢? [编辑 - 11/6/04 by gojuventusgo] |
|
地板#
发布于:2004-11-07 19:01
多谢指点!不过有些地方还是不太明白 ----------------------------------------------------------- 操作系统管理接口的。winnap之类的应该不会知道系统上装了什么驱动,否则世界上那么多声卡驱动都不同,怎么区分呢! 呵呵,我想是这样的 :D |
|
地下室#
发布于:2004-11-07 21:45
nod,其实说了半天我最想搞明白的就是这个问题
会不会是安装声卡驱动时把相关的调用信息写进了注册表特定位置,api函数通过读注册表的信息就可以知道怎样调用声卡驱动了? 有知道的帮忙解释一下阿! |
|
5楼#
发布于:2004-11-10 09:40
可以这样理解
windows对不同驱动有不同的处理模型 声卡也不列外,只要是按照声卡的规范写好驱动,自然就能通过windows的api通信了,你的采集卡驱动也是这样,比如你需要遵循wdm或vfw规范 |
|
|
6楼#
发布于:2004-11-10 15:20
这个问题我也在思考。但是我的是网卡方面!
我觉得好象是操作系统有一个IO管理器,这里管理了一些信息。负责相应的调用! |
|