2011年7月14日 星期四

Skype使用程式實作音訊錄製心得

簡單錄、放音並保存為wav文件程序====基礎文件
http://www.vckbase.com/document/viewdoc/?id=1800

WaveOut、WavaIn錄音參考程式
http://read.pudn.com/downloads43/sourcecode/multimedia/audio/146520/XAudioTest/WaveOut.cpp__.htm
http://www.pudn.com/downloads43/sourcecode/multimedia/audio/detail146520.html

上列參考程式中WaveIn與WaveOut錄音基本上大同小異
錄音的實作步驟下面會提到

要注意的是WaveIn與WaveOut的音訊資料是從指標中取出
是為了不破壞音訊資料的格式,一但人為去assign音訊資料
卻又與原來的音訊資料不相同時,會破壞錄製出來的音訊資料
使錄製的檔案出現雜音,甚至壞檔的情況

要知道整體音訊資料的輸出情況
必須把指標指到 資料緩衝區WAVEHDR 印出來看程式實際運作時的 WaveIn與WaveOut的API配置情形
通過觀察上述的配置情形,可以在音訊資料輸出時將音訊錄製下來

錄音的實作步驟
1.需要知道指標指到的資料格式WAVEFORMATEX

在這裡是直接從API的指標取出

WAVEFORMATEX waveformatIN;

waveformatIN.wFormatTag=pwfx->wFormatTag;
waveformatIN.nChannels=pwfx->nChannels;
waveformatIN.wBitsPerSample=pwfx->wBitsPerSample; //指定錄音格式
waveformatIN.nSamplesPerSec=pwfx->nSamplesPerSec;
waveformatIN.nBlockAlign=pwfx->nBlockAlign;
waveformatIN.nAvgBytesPerSec=pwfx->nAvgBytesPerSec;
waveformatIN.cbSize=0;

2.創建可以寫入的空白檔案
HANDLE FileHandleIN=CreateFile( "C:\\myInTest.wav", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

3.在音訊資料輸出的情況中找出真正寫資料的開始位置才能開始錄製音訊檔案

目前使用.wav的檔案格式存取,一開始需要寫入.wav的檔頭

dwNumberIn = FCC("RIFF");
WriteFile(FileHandleIN, &dwNumberIn, 4, &NumToWriteIn, NULL);
dwNumberIn = pwh->dwBytesRecorded + 18 + 20;
//dwNumber = m_pWaveHdrOUT.dwBytesRecorded + 18 + 20;
WriteFile(FileHandleIN, &dwNumberIn, 4, &NumToWriteIn, NULL);
dwNumberIn = FCC("WAVE");
WriteFile(FileHandleIN, &dwNumberIn, 4, &NumToWriteIn, NULL);
dwNumberIn = FCC("fmt ");
WriteFile(FileHandleIN, &dwNumberIn, 4, &NumToWriteIn, NULL);
dwNumberIn = 18L;
WriteFile(FileHandleIN, &dwNumberIn, 4, &NumToWriteIn, NULL);
WriteFile(FileHandleIN, &waveformatIN, sizeof(WAVEFORMATEX), &NumToWriteIn, NULL);
dwNumberIn = FCC("data");
WriteFile(FileHandleIN, &dwNumberIn, 4, &NumToWriteIn, NULL);
dwNumberIn = pwh->dwBytesRecorded;
//dwNumber = m_pWaveHdrOUT.dwBytesRecorded;
WriteFile(FileHandleIN, &dwNumberIn, 4, &NumToWriteIn, NULL);

在來寫入.wav的檔案資料內容

WriteFile(FileHandleIN,pwh->lpData,pwh->dwBufferLength,&NumToWriteIn,NULL);

4.錄製結束時,關閉檔案與清掉資料

    SetEndOfFile(FileHandleIN);            
    CloseHandle(FileHandleIN);              
    FileHandleIN=INVALID_HANDLE_VALUE;  

5. 以上用WaveIn來做解釋,WaveOut的錄製情形同 WaveIn

沒有留言:

張貼留言