音頻驅動分析:
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;