哪位大神有时间,帮我看下这个windows下的录音程序。
检查了半天也没找出bug在哪,始终是录音没录下来,求高手解答。
//WaveIn.h
#pragma once
#include <Windows.h>
#include <MMSystem.h>
#include <cstdio>
#defineSAMPLE_DEFAULT 16000
#defineCHANNEL_DEFAULT 1
#define BIT_DEFAULT 16
#define NUM_BUF 10
#define AUDIO_BUFFER 960
#pragma comment(lib, "Winmm.lib")
class WaveIn
{
public:
WaveIn(void);
public:
virtual ~WaveIn(void);
static DWORD WINAPI WaveInProc(LPVOID lpParam);
void SetRecPara(WORD channel, DWORD sample, WORD bit);
void GetData(char *pBuffer, int len);
BOOL OpenFile(char *fileName);
BOOL StartRecord();
BOOL StopRecord();
protected:
BOOL OpenDev();
BOOL CloseDev();
BOOL StartThread();
BOOL StopThread();
BOOL PrepareBuffer();
BOOL FreeBuffer();
BOOL OpenRecord();
BOOL CloseRecord();
protected:
WORD m_Channel;/*声道*/
DWORD m_Sample;/*采样频率*/
WORD m_Bit;/*量化位数*/
BOOL m_IsDevOpen;
BOOL m_IsThreadStart;
BOOL m_IsRecordStart;
BOOL m_IsBufferAlloc;
BOOL m_IsRecordOpen;
protected:
HWAVEIN m_hwn;
WAVEHDR *m_pHdr;
DWORD m_AudioInId;
//HWND m_hAudioIn;
HANDLE m_hAudioIn;
private:
FILE *m_WaveFile;
};
//WaveIn.cpp
//#include "StdAfx.h"
#include "WaveIn.h"
WaveIn::WaveIn():m_Channel(CHANNEL_DEFAULT),m_Sample(SAMPLE_DEFAULT),m_Bit(BIT_DEFAULT)
{
m_IsDevOpen = FALSE;
m_IsThreadStart = FALSE;
m_IsRecordStart = FALSE;
m_IsBufferAlloc = FALSE;
m_IsRecordOpen = FALSE;
}
WaveIn::~WaveIn(void)
{
}
void WaveIn::SetRecPara(WORD channel, DWORD sample, WORD bit)
{
m_Channel = channel;
m_Sample = sample;
m_Bit = bit;
}
BOOL WaveIn::OpenDev()
{
if(m_IsDevOpen)
{
return FALSE;
}
/*设置录音输出格式*/
WAVEFORMATEX wfx;
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = m_Channel;
wfx.nSamplesPerSec = m_Sample;
wfx.nAvgBytesPerSec = m_Sample * m_Channel * m_Bit / 8;
wfx.nBlockAlign = m_Channel * m_Bit / 8;
wfx.wBitsPerSample = m_Bit;
wfx.cbSize = 0;
int ret = waveInOpen(0, WAVE_MAPPER, &wfx, 0, 0, WAVE_FORMAT_QUERY);
if( ret)
{
printf("waveInOpen error %d\n", ret);
return FALSE;
}
if( waveInOpen(&m_hwn, WAVE_MAPPER, &wfx, m_AudioInId, 0, CALLBACK_THREAD))
{
return FALSE;
}
m_IsDevOpen = TRUE;
return TRUE;
}
BOOL WaveIn::CloseDev()
{
if(!m_IsDevOpen)
{
return FALSE;
}
if(!m_hwn)
{
return FALSE;
}
if(waveInClose(m_hwn))
{
m_hwn = 0;
m_IsDevOpen = FALSE;
return FALSE;
}
m_hwn = 0;
m_IsDevOpen = FALSE;
return TRUE;
}
BOOL WaveIn::PrepareBuffer()
{
if(m_IsBufferAlloc)
{
return FALSE;
}
if( waveInReset(m_hwn))
{
return FALSE;
}
m_pHdr = new WAVEHDR[ NUM_BUF ];
for(UINT i=0; i<NUM_BUF; i++)
{
ZeroMemory(&m_pHdr[i], sizeof(WAVEHDR));
m_pHdr[i].lpData = new char[AUDIO_BUFFER];
m_pHdr[i].dwBufferLength = AUDIO_BUFFER;
//准备缓存
if(waveInPrepareHeader(m_hwn, &m_pHdr[i], sizeof(WAVEHDR)))
{
return FALSE;
}
//添加缓存
if(waveInAddBuffer(m_hwn, &m_pHdr[i], sizeof(WAVEHDR)))
{
return FALSE;
}
}
m_IsBufferAlloc = TRUE;
return TRUE;
}
BOOL WaveIn::FreeBuffer()
{
if (!m_IsBufferAlloc)
{
return FALSE;
}
if(!m_hwn)
{
return FALSE;
}
for(int i=0; i<NUM_BUF; i++)
{
if(waveInUnprepareHeader(m_hwn, &m_pHdr[i], sizeof(WAVEHDR)))
{
Sleep(100);
continue;
}
if(m_pHdr[i].lpData)
{
delete []m_pHdr[i].lpData;
}
}
delete []m_pHdr;
m_pHdr = NULL;
m_IsBufferAlloc = FALSE;
return TRUE;
}
BOOL WaveIn::OpenRecord()
{
if (m_IsRecordOpen)
{
return FALSE;
}
if(waveInStart(m_hwn))
{
return FALSE;
}
m_IsRecordOpen = TRUE;
return TRUE;
}
BOOL WaveIn::CloseRecord()
{
if (!m_IsRecordOpen)
{
return FALSE;
}
if (!m_hwn)
{
return FALSE;
}
if(waveInReset(m_hwn))
{
return FALSE;
}
m_IsRecordOpen = FALSE;
return TRUE;
}
BOOL WaveIn::StartThread()
{
if (m_IsThreadStart)
{
return FALSE;
}
if (!(m_hAudioIn = CreateThread(0, 0, WaveInProc, this, 0, &m_AudioInId)))
{
return FALSE;
}
m_IsThreadStart = TRUE;
return TRUE;
}
BOOL WaveIn::StopThread()
{
if(!m_IsThreadStart)
{
return FALSE;
}
if (m_AudioInId)
{
//循环变量
int t=50;
//线程结束状态信息
DWORD ExitCode;
//线程结束标记
BOOL bEnd=FALSE;
//发送WM_QUIT消息
PostThreadMessage(m_AudioInId,WM_QUIT,0,0);
//主循环
while(t)
{
//获取线程结束状态信息
GetExitCodeThread(m_hAudioIn,&ExitCode);
//尚未结束
if(ExitCode!= STILL_ACTIVE)
{
//设置线程结束
bEnd=TRUE;
break;
}
//休眠10毫秒
else
{
Sleep(10);
}
//修改循环变量
t--;
}
if(!bEnd)
{
TerminateThread(m_hAudioIn, 0);
}
m_AudioInId = 0;
}
m_IsThreadStart = FALSE;
return TRUE;
}
BOOL WaveIn::StartRecord()
{
if(m_IsRecordStart)
{
return FALSE;
}
if(!StartThread())
{
return FALSE;
}
if( !OpenDev() )
{
return FALSE;
}
if ( !PrepareBuffer() )
{
return FALSE;
}
if ( !OpenRecord() )
{
return FALSE;
}
m_IsRecordStart = TRUE;
return TRUE;
}
BOOL WaveIn::StopRecord()
{
CloseRecord();
Sleep(1500);
FreeBuffer();
if (CloseDev())
{
StopThread();
}
m_IsRecordStart = FALSE;
return TRUE;
}
DWORD WINAPI WaveIn::WaveInProc(LPVOID lpParam)
{
WaveIn *pWaveIn;
pWaveIn = (WaveIn *)lpParam;
char buffer[1024];
MSG msg;
while(GetMessage(&msg, 0, 0, 0))
{
switch(msg.message)
{
case MM_WIM_OPEN:
break;
case MM_WIM_CLOSE:
break;
case MM_WIM_DATA:
WAVEHDR *pwh = (WAVEHDR *)msg.lParam;
waveInUnprepareHeader((HWAVEIN)msg.wParam, pwh, sizeof(WAVEHDR));
if(pwh->dwBytesRecorded != AUDIO_BUFFER)
{
break;
}
/*复制录音数据*/
memcpy(buffer, pwh->lpData, pwh->dwBytesRecorded);
pWaveIn->GetData( buffer, pwh->dwBytesRecorded);
break;
}
}
return msg.wParam;
}
void WaveIn::GetData(char *pBuffer, int len)
{
if(m_WaveFile)
{
fwrite(pBuffer, 1, len, m_WaveFile);
}
}
BOOL WaveIn::OpenFile(char *fileName)
{
if((m_WaveFile = fopen(fileName, "wb")) == NULL)
{
return FALSE;
}
return TRUE;
}
//main.cpp
#include "WaveIn.h"
int main()
{
WaveIn myWaveIn;
if(NULL == myWaveIn.OpenFile("record.pcm"))
{
printf("open File Error\n");
return EXIT_FAILURE;
}
if(myWaveIn.StartRecord())
printf("recording ...");
Sleep(5*1000);
myWaveIn.StopRecord();
return 0;
}