音频驱动分析:
1、这里主要介绍一下流式音频驱动,在应用程序进行音频操作之前,首先向内核产生一个调用,内核将这个调用传给驱动程序的WAV_IOCcontrol进行处理,内核传递这个调用的模块被称为Wave_API管理器,然后驱动程序对硬件进行操作,和普通的流接口驱动程一样,音频驱动也使用注册表来存储信息并且向系统注册自身,在Platform.reg中添加如下键:HKEY_LOCAL_MACHINE/Drivers/Builtin/Audio用于存储信息。在系统启动时,设备管理器将加载音频驱动,并且创建HKEY_LOCAL_MACHINE/Drivers/Active键。
流接口驱动程序接口如下,在wavedev.def中导出。
LIBRARY WAVEDEV
EXPORTS
WAV_Init
WAV_Deinit
WAV_Open
WAV_Close
WAV_PowerUp
WAV_PowerDown
WAV_IOControl
(二)驱动中主要用的类:
1. Devctxt.h中定义DviceContext类;分成两个子类InputDeviceContext,OutputDeviceContext。主要实现了对音设备的性能参数设定与返回,以及对音频流操作方法,(对音频数据流的操作最终调用的是StreamContext类里面的方法)。
2. Strmctxt.h中定义StreamContext类,在该类中主要实现了对音频流文件进行操作的方法。(最终是通过系统的回调函数实现的)
3. Hwctxt.h 中定义HardwareContext类,在该类中主要包含了一些对硬进行操作的代码,IIS、DMA、AUDIO芯片操作。
(三)主要数据结构:
1.typedef struct {
UINT uDeviceId;
UINT uMsg;
DWORD dwUser;
DWORD dwParam1;
DWORD dwParam2;
} MMDRV_MESSAGE_PARAMS, *PMMDRV_MESSAGE_PARAMS;
(在../public/common/sdk/inc/wavedev.h定义)
这个是传输给WAV_IOControlr的数据结构。
(1)其中dwUser 参数在使用时为被强制转换成StreamContext,
例如:StreamContext *pStreamContext = (StreamContext *)dwUser;
(2)uMsg参数表示驱动要执行什么样的操作。具体对应如下:
// messages sent to wodMessage() entry-point function
#define WODM_GETNUMDEVS 3 //请求WAVEFORM输出驱动返回其支持的设备实例数量。
#define WODM_GETDEVCAPS 4 //请求WAVEFORM输出驱动返回特定设备的功能。
#define WODM_OPEN 5 //请求WAVEFORM输出驱动打开一个设备对应的流接口。
#define WODM_CLOSE 6 //请求WAVEFORM输出驱动关闭由WODM_OPEN建立的流接口。
#define WODM_PREPARE 7 // 请求WAVEFORM输出驱动为输出准备一个系统中唯一的数据缓冲。
#define WODM_UNPREPARE 8 // WODM_PREPARE的逆操作。
#define WODM_WRITE 9 //
#define WODM_PAUSE 10 //请求WAVEFORM输出驱动暂停WAVEFORM的播放。
#define WODM_RESTART 11 //请求WAVEFORM输出驱动继续播放被暂停的WAVEFORM。
#define WODM_RESET 12 //请求WAVEFORM输出驱动停止发送输出数据并且返回所有的输出缓冲到列表。
#define WODM_GETPOS 13 //请求返回当前数据流中相对于WAVEFORM起始的相对位置。
#define WODM_GETPITCH 14 //
#define WODM_SETPITCH 15
#define WODM_GETVOLUME 16 //请求WAVEFORM输出驱动返回指定设备的音量水平。
#define WODM_SETVOLUME 17 //请求WAVEFORM输出驱动设置指定设备的音量水平。
#define WODM_GETPLAYBACKRATE 18//请求WAVEFORM输出驱动返回特定设备当前的播放率放大值。
#define WODM_SETPLAYBACKRATE 19//请求WAVEFORM输出驱动设置特定设备当前的播放率放大值。
#define WODM_BREAKLOOP 20//请求WAVEFORM输出驱动停止由WODM_WRIT建立的输出循环。
#define WODM_BUSY 21
#define WODM_GETEXTDEVCAPS 22 // new in Windows CE 4.0
#define WODM_GETPROP 23 // new in Windows CE 5.0
#define WODM_SETPROP 24 // new in Windows CE 5.0
#define WODM_MAPPER_STATUS (DRVM_MAPPER_STATUS + 0)
#define WAVEOUT_MAPPER_STATUS_DEVICE 0
#define WAVEOUT_MAPPER_STATUS_MAPPED 1
#define WAVEOUT_MAPPER_STATUS_FORMAT 2
// messages sent to widMessage() entry-point function
#define WIDM_GETNUMDEVS 50
#define WIDM_GETDEVCAPS 51
#define WIDM_OPEN 52
#define WIDM_CLOSE 53//请求WAVEFORM输入驱动关闭一个指定的设备实例,这个设备实例由先前的WIDM_OPEN创建并且打开。
#define WIDM_PREPARE 54
#define WIDM_UNPREPARE 55
#define WIDM_ADDBUFFER 56//请求WAVEFORM输入驱动在输入队列中添加一个BUFFER。
#define WIDM_START 57//请求WAVEFORM输入驱动开始录音
#define WIDM_STOP 58//请求WAVEFORM输入驱动停止录音
#define WIDM_RESET 59//请求WAVEFORM输入驱动停止录音并且将所有的缓冲数据返回给调用者。
#define WIDM_GETPOS 60//请求输入流接口输入,驱动返回当前输入位置,位置是相对于第一个采样的WAVEFORM样本。
#define WIDM_GETPROP 61 // new in Windows CE 5.0
#define WIDM_SETPROP 62 // new in Windows CE 5.0
#define WIDM_MAPPER_STATUS (DRVM_MAPPER_STATUS + 0)
#define WAVEIN_MAPPER_STATUS_DEVICE 0
#define WAVEIN_MAPPER_STATUS_MAPPED 1
#define WAVEIN_MAPPER_STATUS_FORMAT 2
(3)dwParam1参数在执行具体功能是需要强制转换成不同的结构体。
例如: 在 WODM_OPEN:
dwRet = pDeviceContext->OpenStream((LPWAVEOPENDESC)dwParam1, dwParam2, (StreamContext **)dwUser);
(4)dwParam1参数主要作为一些标志位。
../public/common/sdk/inc/mmsystem.h
/* flags for dwFlags parameter in waveOutOpen() and waveInOpen() */
#define WAVE_FORMAT_QUERY 0x00000001
#define WAVE_ALLOWSYNC 0x00000002
#define WAVE_MAPPED 0x00000004
#define WAVE_FORMAT_DIRECT 0x00000008
#define WAVE_FORMAT_DIRECT_QUERY (WAVE_FORMAT_QUERY | WAVE_FORMAT_DIRECT)
#define WAVE_NOMIXER 0x00000080 /* Windows CE only - bypass software mixer */
2.typedef struct waveopendesc_tag {
HWAVE hWave; // handle驱动句柄,WAVEAPI.DLL 分派。
LPWAVEFORMATEX lpFormat; // format of wave data见3
DWORD dwCallback; // callback
DWORD dwInstance; // app's private instance information
UINT uMappedDeviceID; // device to map to if WAVE_MAPPED set
} WAVEOPENDESC;
typedef WAVEOPENDESC FAR *LPWAVEOPENDESC;
在../public/common/oak/inc/mmddk.h中定义。
3.音频格式结构WAVEFORMATEX,作为打开操作的参数要事先准备好
../public/common/sdk/inc/mmsystem.h
* extended waveform format structure used for all non-PCM formats. this
* structure is common to all non-PCM formats.
typedef struct tWAVEFORMATEX
{
WORD wFormatTag; /* format type */格式
WORD nChannels; /* number of channels (i.e. mono, stereo...) */声道数
DWORD nSamplesPerSec; /* sample rate */每秒采样率
DWORD nAvgBytesPerSec; /* for buffer estimation */每秒字节数
WORD nBlockAlign; /* block size of data */块对齐
WORD wBitsPerSample; /* number of bits per sample of mono data */每个样本的bit数
WORD cbSize; /* the count in bytes of the size of */
/* extra information (after cbSize) */
} WAVEFORMATEX, *PWAVEFORMATEX, NEAR *NPWAVEFORMATEX, FAR *LPWAVEFORMATEX;
typedef const WAVEFORMATEX FAR *LPCWAVEFORMATEX;