调用API获取话筒声音

主要代码如下

设置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 ;

你可能感兴趣的:(c/c++/vc,DirectShow)