| 想用vc做時(shí)時(shí)的處理得看你的算法的效率了,但vc中聲音的采集是用api函數來(lái)實(shí)現的,以下是以前在網(wǎng)上昭的,你可以看看,就是幾個(gè)函數: 一、數字音頻基礎知識 Fourier級數: 任何周期的波形可以分解成多個(gè)正弦波,這些正弦波的頻率都是整數倍。級數中其他正線(xiàn)波的頻率是基礎頻率的整數倍?;A頻率稱(chēng)為一級諧波。 PCM: pulse code modulation,脈沖編碼調制,即對波形按照固定周期頻率采樣。為了保證采樣后數據質(zhì)量,采樣頻率必須是樣本聲音最高頻率的兩倍,這就是Nyquist頻率。 樣本大?。翰蓸雍笥糜诖鎯φ穹壍奈粩?,實(shí)際就是脈沖編碼的階梯數,位數越大表明精度越高,這一點(diǎn)學(xué)過(guò)數字邏輯電路的應該清楚。 聲音強度: 波形振幅的平方。兩個(gè)聲音強度上的差常以分貝(db)為單位來(lái)度量, 計算公式如下: 20*log(A1/A2)分貝。A1,A2為兩個(gè)聲音的振幅。如果采樣大小為8位,則采樣的動(dòng)態(tài)范圍為20*log(256)分貝=48db。如果樣本大小為16位,則采樣動(dòng)態(tài)范圍為20*log(65536)大約是96分貝,接近了人聽(tīng)覺(jué)極限和痛苦極限,是再線(xiàn)音樂(lè )的理想范圍。windows同時(shí)支持8位和16位的采樣大小。 二、相關(guān)API函數,結構,消息 對于錄音設備來(lái)說(shuō),windows 提供了一組wave***的函數,比較重要的有以下幾個(gè): 打開(kāi)錄音設備函數 MMRESULT waveInOpen( LPHWAVEIN phwi, //輸入設備句柄 UINT uDeviceID, //輸入設備ID LPWAVEFORMATEX pwfx, //錄音格式指針 DWORD dwCallback, //處理MM_WIM_***消息的回調函數或窗口句柄,線(xiàn)程ID DWORD dwCallbackInstance, DWORD fdwOpen //處理消息方式的符號位 ); 為錄音設備準備緩存函數 MMRESULT waveInPrepareHeader( HWAVEIN hwi, LPWAVEHDR pwh, UINT bwh ); 給輸入設備增加一個(gè)緩存 MMRESULT waveInAddBuffer( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh ); 開(kāi)始錄音 MMRESULT waveInStart( HWAVEIN hwi ); 清除緩存 MMRESULT waveInUnprepareHeader( HWAVEIN hwi,LPWAVEHDR pwh, UINT cbwh); 停止錄音 MMRESULT waveInReset( HWAVEIN hwi ); 關(guān)閉錄音設備 MMRESULT waveInClose( HWAVEIN hwi ); Wave_audio數據格式 typedef struct { WORD wFormatTag; //數據格式,一般為WAVE_FORMAT_PCM即脈沖編碼 WORD nChannels; //聲道 DWORD nSamplesPerSec; //采樣頻率 DWORD nAvgBytesPerSec; //每秒數據量 WORD nBlockAlign; WORD wBitsPerSample;//樣本大小 WORD cbSize; } WAVEFORMATEX; waveform-audio 緩存格式 typedef struct { LPSTR lpData; //內存指針 DWORD dwBufferLength;//長(cháng)度 DWORD dwBytesRecorded; //已錄音的字節長(cháng)度 DWORD dwUser; DWORD dwFlags; DWORD dwLoops; //循環(huán)次數 struct wavehdr_tag * lpNext; DWORD reserved; } WAVEHDR; 相關(guān)消息 MM_WIM_OPEN:打開(kāi)設備時(shí)消息,在此期間我們可以進(jìn)行一些初始化工作 MM_WIM_DATA:當緩存已滿(mǎn)或者停止錄音時(shí)的消息,處理這個(gè)消息可以對緩存進(jìn)行重新分配,實(shí)現不限長(cháng)度錄音 MM_WIM_CLOSE:關(guān)閉錄音設備時(shí)的消息。 相對于錄音來(lái)說(shuō),回放就簡(jiǎn)單的多了,用到的函數主要有以下幾個(gè): 打開(kāi)回放設備 MMRESULT waveOutOpen( LPHWAVEOUT phwo, UINT uDeviceID, LPWAVEFORMATEX pwfx, DWORD dwCallback, DWORD dwCallbackInstance, DWORD fdwOpen ); 為回放設備準備內存塊 MMRESULT waveOutPrepareHeader( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh ); 寫(xiě)數據(放音) MMRESULT waveOutWrite( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh ); 相應的也有三個(gè)消息,用法跟錄音的類(lèi)似: 三、程序設計 一個(gè)錄音程序的簡(jiǎn)單流程: 打開(kāi)錄音設備waveInOpen===>準備wave數據頭waveInPrepareHeader===> 準備數據塊waveInAddBuffer===>開(kāi)始錄音waveInStart===>停止錄音(waveInReset) ===> 關(guān)閉錄音設備(waveInClose) 當開(kāi)始錄音后當buffer已滿(mǎn)時(shí),將收到MM_WIM_DATA消息,處理該消息可以保存已錄好數據。 回放程序比這個(gè)要簡(jiǎn)單的多: 打開(kāi)回放設備waveOutOpen===>準備wave數據頭waveOutPrepareHeader===>寫(xiě)wave數據waveOutWrite===> 停止放音(waveOutRest) ===>關(guān)閉回放設備(waveOutClose) 如何處理MM消息: MSDN告訴我們主要有 CALLBACK_FUNCTION、CALL_BACKTHREAD、CALLBACK_WINDOW 三種方式,常用的是 Thread,window方式。 線(xiàn)程模式 waveInOpen(&hWaveIn,WAVE_MAPPER,&waveform,m_ThreadID,NULL,CALLBACK_THREAD),我們可以繼承MFC的CwinThread類(lèi),只要相應的處理線(xiàn)程消息即可。 MFC線(xiàn)程消息的宏為: ON_THREAD_MESSAGE, 可以這樣添加消息映射: ON_THREAD_MESSAGE(MM_WIM_CLOSE, OnMM_WIM_CLOSE) 窗口模式 類(lèi)似于線(xiàn)程模式,參見(jiàn)源程序即可。 |
聯(lián)系客服