调用API获取话筒声音

来源:互联网 发布:java电商框架 编辑:程序博客网 时间:2024/05/17 06:47
主要代码如下

设置wav文件格式的结构体
C/C++ code
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;

打开话筒句柄
C/C++ code
HWAVEIN m_hWaveIn;waveInOpen(&m_hWaveIn,WAVE_MAPPER,&m_stWaveFrom,(DWORD)this->m_hWnd,NULL,CALLBACK_WINDOW));

关联缓存
C/C++ code
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));

开始录音
C/C++ code
waveInSatrt(m_hWaveIn);


下面是响应MM_WIM_DATA消息
当开始录音时 m_bRcord = TRUE;
当停止录音时 m_bRcord = FALSE;
C/C++ code
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
C/C++ code
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函数的实现
C/C++ code
UINT WaveHeaderSize = 36;UINT WaveFormatSize = 16;UINT ChunkSize = m_uFileBuLength + WaveHeaderSize;FILE * outFile = fopen("Voice.wav","wb");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;