想做一个支持多平台的QT音频采集。不知道在windows、linux和symbian下有什么解决方案?
不知道有
没有什么库可以用?
搜了下portAudio是c写的一个跨平台音频库
directshow貌似也可以,c++的
貌似可以调用mmsystem.dll来使用waveInOpen等函数
09-1-29
windows下
音频采集 windows下的音频采集我最后还是没用portAudio来做。觉得在windows下还是用windows的办法吧,最后选择了wavein、waveout函数簇。下面简单介绍下我的实现方法(和mfc差
不多):
(一)用到的函数及类库
一、wavein函数簇
1.waveinopen
2.waveinprepareheader
3.waveinaddbuffer
4.waveinstart
二、waveout函数簇
1.waveoutopen
2.waveoutprepareheader
3.waveOutWrite
(二)实现代码
一、录音
void audioDevice::record()
{
if(bRecording == true){waveInReset(hWaveIn);}//如果正在录制,重置输入设备
if (!pBuffer1 || !pBuffer2)
{
if (pBuffer1) free(pBuffer1);
if (pBuffer2) free(pBuffer2);
return;
}
waveform.wFormatTag=WAVE_FORMAT_PCM;
waveform.nChannels=1;
waveform.nSamplesPerSec=44100;
waveform.nAvgBytesPerSec=44100;
waveform.nBlockAlign=1;
waveform.wBitsPerSample=8;
waveform.cbSize=0;
if (waveInOpen(&hWaveIn,WAVE_MAPPER,&waveform,(DWORD)WaveInCallback,0,CALLBACK_FUNCTION)) {
free(pBuffer1);
free(pBuffer2);
qWarning( "can not open audio capture device.Return");
}
for(int i=0;i<=3;i++){
pWaveHdr1->lpData=(LPSTR)pBuffer1;
pWaveHdr1->dwBufferLength=INP_BUFFER_SIZE;
pWaveHdr1->dwBytesRecorded=0;
pWaveHdr1->dwUser=0;
pWaveHdr1->dwFlags=0;
pWaveHdr1->dwLoops=0;
pWaveHdr1->lpNext=NULL;
pWaveHdr1->reserved=0;
waveInPrepareHeader(hWaveIn,pWaveHdr1,sizeof(WAVEHDR));
//////////////////////////////////////////////////////////////////////////
// Add the buffers
waveInAddBuffer (hWaveIn, pWaveHdr1, sizeof (WAVEHDR)) ;
}
// Begin sampling
waveInStart (hWaveIn) ;
qWarning( "dwBytesRecorded.Return %d",pWaveHdr1->dwBytesRecorded);
}
二、播放
void audioDevice::play()
{
if(bPlaying == true){waveOutReset(hWaveOut);}//如果正在播放,重置输出设备
/*
pNewBuffer = (PBYTE)realloc (pSaveBuffer, dwDataLength + pWaveHdr1->dwBytesRecorded) ;
qWarning( "pNewBuffer.Return %d",pNewBuffer);
if (pNewBuffer == NULL)
{
waveInClose (hWaveIn) ;
return ;
}
pSaveBuffer = pNewBuffer ;
qWarning( "pSaveBuffer.Return %d",pSaveBuffer);
//////////////////////////////////////////////////////////////////////////
CopyMemory (pSaveBuffer + dwDataLength, ((PWAVEHDR) pWaveHdr1)->lpData,
((PWAVEHDR) pWaveHdr1)->dwBytesRecorded) ;
dwDataLength += pWaveHdr1->dwBytesRecorded ;
qWarning( "dwDataLength.Return %d",dwDataLength);
*/
//open waveform audio for output
waveform.wFormatTag = WAVE_FORMAT_PCM;
waveform.nChannels = 1;
waveform.nSamplesPerSec =44100;
waveform.nAvgBytesPerSec=44100;
waveform.nBlockAlign =1;
waveform.wBitsPerSample =8;
waveform.cbSize =0;
int ret = waveOutOpen(&hWaveOut,WAVE_MAPPER,&waveform,0,0,CALLBACK_NULL);
if (ret) {
qWarning( "can not open audio play device.Return %d",ret);
}
qWarning( "pSaveBuffer.Return %d",pSaveBuffer);
pWaveHdr1->lpData = (LPSTR)pSaveBuffer ;
qWarning( "dwDataLength.Return %d",dwDataLength);
pWaveHdr1->dwBufferLength = dwDataLength ;
pWaveHdr1->dwBytesRecorded = 0 ;
pWaveHdr1->dwUser = 0 ;
pWaveHdr1->dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP ;
pWaveHdr1->dwLoops = 0 ;
pWaveHdr1->lpNext = NULL ;
pWaveHdr1->reserved = 0 ;
// Prepare and write
waveOutPrepareHeader (hWaveOut, pWaveHdr1, sizeof (WAVEHDR)) ;
waveOutWrite (hWaveOut, pWaveHdr1, sizeof (WAVEHDR)) ;
bPlaying = true;
}
三、回调函数
使用waveinopen和waveoutopen自带的回调函数机制,对录音和播放时发出的消息进行处理。本来打算用mfc的消息映射,不过Qt和MFC的头文件及库交叉使用的方法我不会,最
后为了避重就轻,选择了用回调函数来处理。
1.回调函数的作用
当MM_WOM_DONE、WIM_OPEN、WIM_CLOSE或WIM_DATA消息发出时执行相应操作
2.当WIM_DATA(录音buffer满)发送,调用addNewBuffer存储buffer,然后添加新的buffer到waveheader中继续录音
3.其他信号操作可按你的要求添加
waveinopen函数的回调函数如下
static void CALLBACK
WaveInCallback (HWAVEIN waveindev, UINT uMsg, DWORD dwInstance, DWORD dwParam1,
DWORD dwParam2)
{
switch (uMsg)
{
case MM_WOM_DONE:
qWarning( "MM_WOM_DONE.");
break;
case WIM_OPEN:
qWarning( "Record start.");
bRecording = true;
break;
case WIM_CLOSE:
qWarning( "Record end.");
break;
case WIM_DATA:
qWarning( "Buffer full.");
addNewBuffer();
break;
}
}
[ 此贴被gaoyuke在2009-01-30 22:06重新编辑 ]