读书人

调用API获取发话器声音 播放有杂音

发布时间: 2013-01-08 14:02:14 作者: rapoo

调用API获取话筒声音 播放有杂音
主要代码如下

设置wav文件格式的结构体


WAVEFORMATEX m_stWaveFrom;
m_stWaveFrom.wFormatTag = WAVE_FORMAT_PCM;
m_stWaveFrom.nChannels = 1;
m_stWaveFrom.nSamplesPerSec = 8000;
m_stWaveFrom.nAvgBytesPerSec= 16000;
m_stWaveFrom.nBlockAlign = 2;
m_stWaveFrom.wBitsPerSample = 16;
m_stWaveFrom.cbSize = 0;

打开话筒句柄

HWAVEIN m_hWaveIn;
waveInOpen(&m_hWaveIn,WAVE_MAPPER,&m_stWaveFrom,(DWORD)this->m_hWnd,NULL,CALLBACK_WINDOW));

关联缓存

WAVEHDR m_stWaveHeadr1;
WAVEHDR m_stWaveHeadr2;
BYTE* m_pHandlBuffer1 = (PBYTE)malloc(16384);
BYTE* m_pHandlBuffer2 = (PBYTE)malloc(16384);

m_stWaveHeadr1.lpData = (LPSTR)m_pHandlBuffer1;
m_stWaveHeadr1.dwBufferLength = 16384;

m_stWaveHeadr2.lpData = (LPSTR)m_pHandlBuffer2;
m_stWaveHeadr2.dwBufferLength = 16384;

waveInPrepareHeader(m_hWaveIn, &m_stWaveHeadr1, sizeof(m_stWaveHeadr1));
waveInPrepareHeader(m_hWaveIn, &m_stWaveHeadr2, sizeof(m_stWaveHeadr2));

waveInAddBuffer(m_hWaveIn, &m_stWaveHeadr1, sizeof(m_stWaveHeadr1));
waveInAddBuffer(m_hWaveIn, &m_stWaveHeadr2, sizeof(m_stWaveHeadr2));

开始录音

waveInSatrt(m_hWaveIn);


下面是响应MM_WIM_DATA消息
当开始录音时 m_bRcord = TRUE;
当停止录音时 m_bRcord = FALSE;

PWAVEHDR fp = (PWAVEHDR) lParam;

SaveVoice(fp);

if(!m_bRcord)
{
waveInUnprepareHeader(m_hWaveIn, &m_stWaveHeadr1, sizeof(m_stWaveHeadr1));
memset(&m_stWaveHeadr1, 0, sizeof(m_stWaveHeadr1));
waveInUnprepareHeader(m_hWaveIn, &m_stWaveHeadr2, sizeof(m_stWaveHeadr2));
memset(&m_stWaveHeadr2, 0, sizeof(m_stWaveHeadr2));
waveInClose(m_hWaveIn);
m_hWaveIn = NULL;
}
else
{
waveInAddBuffer(m_hWaveIn, fp, sizeof(*fp));
}


下面是SaveVoice函数体
m_uFileBuLength是UINT类型的变量 用于存储 已经存放的字节数
m_pSaveFileBuffer 是PBYTE类型的变量,用于指向准备放入文件的内容
pVoice 是PWAVEHDR类型的变量,即上一段中的 fp

if(NULL == m_pSaveFileBuffer)
{
m_uFileBuLength = pVoice->dwBytesRecorded;
m_pSaveFileBuffer = (PBYTE)malloc(m_uFileBuLength+1);

if(NULL == m_pSaveFileBuffer)
{
m_uFileBuLength = 0;
fputs("内存空间不足 in SaveVoice\n",m_pErrorFile);
}
else memcpy(m_pSaveFileBuffer, pVoice->lpData, pVoice->dwBytesRecorded);
}
else //如果内存中有内容
{
PBYTE pNewBuffer = (PBYTE)realloc(m_pSaveFileBuffer, m_uFileBuLength+pVoice->dwBytesRecorded);

//如果重新开辟空间失败 则输出到文件
if(NULL == pNewBuffer) WriteToFile(m_pSaveFileBuffer);
else
{
m_pSaveFileBuffer = pNewBuffer;

memcpy(m_pSaveFileBuffer+m_uFileBuLength, pVoice->lpData, pVoice->dwBytesRecorded);


m_uFileBuLength += pVoice->dwBytesRecorded;

//如果内存中数据大于 1M 则输出到文件 重置环境
if(m_uFileBuLength >= VOICE_MAX) WriteToFile(m_pSaveFileBuffer);
else if(!m_bRcord) WriteToFile(m_pSaveFileBuffer);
}
}


以下是WriteToFile函数的实现

UINT WaveHeaderSize = 36;
UINT WaveFormatSize = 16;
UINT ChunkSize = m_uFileBuLength + WaveHeaderSize;

FILE * outFile = fopen("Voice.wav","w");
if(NULL == outFile)
{
fprintf(m_pErrorFile, "打开%s 失败\n","Voice.wav");
return;
}
fwrite("RIFF", 4, 1, outFile);
fwrite(&ChunkSize, sizeof(ChunkSize), 1, outFile);
fwrite("WAVE", 4, 1, outFile);
fwrite("fmt ", 4, 1, outFile);
fwrite(&WaveFormatSize, sizeof(WaveFormatSize), 1, outFile);

fwrite(&m_stWaveFrom.wFormatTag, sizeof(m_stWaveFrom.wFormatTag), 1, outFile);
fwrite(&m_stWaveFrom.nChannels, sizeof(m_stWaveFrom.nChannels), 1, outFile);
fwrite(&m_stWaveFrom.nSamplesPerSec, sizeof(m_stWaveFrom.nSamplesPerSec), 1, outFile);
fwrite(&m_stWaveFrom.nAvgBytesPerSec, sizeof(m_stWaveFrom.nAvgBytesPerSec), 1, outFile);
fwrite(&m_stWaveFrom.nBlockAlign, sizeof(m_stWaveFrom.nBlockAlign), 1, outFile);
fwrite(&m_stWaveFrom.wBitsPerSample, sizeof(m_stWaveFrom.wBitsPerSample), 1, outFile);
//fwrite(&m_stWaveFrom.cbSize,sizeof(m_stWaveFrom.cbSize),1,outFile);
fwrite("data", 4, 1, outFile);
fwrite(&m_uFileBuLength, sizeof(m_uFileBuLength), 1, outFile);

fwrite(m_pSaveFileBuffer,m_uFileBuLength, 1, outFile);
fseek(outFile,m_uFileBuLength,SEEK_SET);

fclose(outFile);

free(m_pSaveFileBuffer);
m_pSaveFileBuffer = NULL;
m_uFileBuLength = 0;

存放的文件可以正常播放,就是有杂音,求解!!!!!!
[解决办法]
是不是话筒连接线受到干扰?
[解决办法]
以二进制文件打开,否则有些数据据不能处理。

读书人网 >VC/MFC

热点推荐