音频驱动分析: 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; |