/*這是以前寫的一個簡單的錄音程序(是dll文件).在此備份.調用時需要映射這幾個消息:
ON_MESSAGE(MM_WIM_OPEN,MmWimOpen)
ON_MESSAGE(MM_WIM_DATA,MmWimData)
ON_MESSAGE(MM_WIM_CLOSE,MmWimClose)
ON_MESSAGE(MM_WOM_CLOSE,MmWomClose)
ON_MESSAGE(MM_WOM_OPEN,MmWomOpen)
ON_MESSAGE(MM_WOM_DONE,MmWomDone)
*/
/* .h*/
#include "windows.h"
#include "mmsystem.h"
#pragma comment(lib,"winmm.lib")
#ifdef WAVEFILEEX_EXPORTS
#define WAVEFILEEX_API __declspec(dllexport)
#else
#define WAVEFILEEX_API __declspec(dllimport)
#endif
// 森濬岆植 WaveFileEx.dll 絳堤腔
class WAVEFILEEX_API CWaveFileEx {
public:
CWaveFileEx(void);
CWaveFileEx(HWND hwnd);
~CWaveFileEx();
/* wave length*/
DWORD getWaveLen_Size();
DWORD getWaveLen_Time();
/* record */
bool RecordWav(LPSTR filename,int devno);
bool StopRecordWav();
bool PlayWav(LPSTR filename,int sounddevno = -1);
bool StopPlayWav();
/* select devNo */
void SelectDevNo(int devno);
void PauseWav();
/* call back function waveIn*/
void MmWimOpen();
void MmWimData(WPARAM wParam,LPARAM lParam);
void MmWimClose();
/* call back function waveOut */
void MmWomOpen();
void MmWomDone(WPARAM wParam,LPARAM lParam);
void MmWomClose();
/* the handle of play wave */
void SetWnd(HWND hwnd);
protected:
bool CreateWaveFile(void);
void GetLastErrorMsg(LPCTSTR flag);
bool Write(char* data,DWORD dwlen);
void Close();
private:
char m_fileName[256];
WAVEFORMATEX m_waveformat;
DWORD m_waveLength;
DWORD dwDataLength;
HWAVEIN m_hWi;
HWAVEOUT m_hWo;
HANDLE m_hFile;
int m_devNo;
HWND m_hWnd;
MMCKINFO m_mmInfoParent;
MMCKINFO m_mmInfoChild;
PWAVEHDR pWaveHdr1 ;
PWAVEHDR pWaveHdr2;
WAVEHDR waveOutHdr;
HMMIO m_hm;
HMMIO m_hMmio;
char* lpdwData;
BYTE* pbuf1;
BYTE* pbuf2;
DWORD m_dwSize;
char* pSaveBuffer;
char* pNewBuffer;
};
/*
.CPP
*/
#include "stdafx.h"
#include "WaveFileEx.h"
#include "Windows.h"
#include "assert.h"
#include "tchar.h"
#include <malloc.h>
#pragma comment(lib,"User32.lib")
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
/* 蚚懂翹秞 凳婖勤砓*/
CWaveFileEx::CWaveFileEx(HWND hwnd)
{
assert(hwnd);
m_hWnd = hwnd;
m_devNo = -1;
strcpy(this->m_fileName,"");
m_hFile = 0x00;
m_hWi = 0x00;
m_hWo = 0x00;
lpdwData = 0x00;
/* */
m_waveformat.wFormatTag=WAVE_FORMAT_PCM;
m_waveformat.nChannels=1;
m_waveformat.nSamplesPerSec=8000;
m_waveformat.nAvgBytesPerSec=8000;
m_waveformat.nBlockAlign=1;
m_waveformat.wBitsPerSample=8; //硌隅翹秞跡宒
m_waveformat.cbSize=0;
m_dwSize = 10240;
m_hMmio = 0x00;
pSaveBuffer = 0x00;
pNewBuffer = 0x00;
pWaveHdr1 =(WAVEHDR*)malloc(sizeof(WAVEHDR));
pWaveHdr2 =(WAVEHDR*)malloc(sizeof(WAVEHDR));
pbuf1 = 0x00;
pbuf2 = 0x00;
}
/* 蚚懂畦溫 凳婖勤砓*/
CWaveFileEx::CWaveFileEx()
{
m_devNo = -1;
strcpy(this->m_fileName,"");
m_hFile = 0x00;
m_hWi = 0x00;
m_hWo = 0x00;
lpdwData = 0x00;
/* */
m_waveformat.wFormatTag=WAVE_FORMAT_PCM;
m_waveformat.nChannels=1;
m_waveformat.nSamplesPerSec=8000;
m_waveformat.nAvgBytesPerSec=8000;
m_waveformat.nBlockAlign=1;
m_waveformat.wBitsPerSample=8; //硌隅翹秞跡宒
m_waveformat.cbSize=0;
pWaveHdr1 =(WAVEHDR*)malloc(sizeof(WAVEHDR));
pWaveHdr2 =(WAVEHDR*)malloc(sizeof(WAVEHDR));
pbuf1 = 0x00;
pbuf2 = 0x00;
m_hMmio = 0x00;
}
CWaveFileEx::~CWaveFileEx()
{
StopPlayWav();
free(pWaveHdr1);
free(pWaveHdr2);
if(pbuf1 != 0x00)
{
delete[] pbuf1;
}
if(pbuf2 != 0x00)
delete[] pbuf2;
pbuf1 = 0x00;
pbuf2 = 0x00;
}
void CWaveFileEx::GetLastErrorMsg(LPCTSTR flag)
{
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL,
SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL );
MessageBox(NULL,(LPCTSTR)lpMsgBuf,flag,0);
}
void CWaveFileEx::SelectDevNo(int devno)
{
m_devNo = devno;
}
DWORD CWaveFileEx::getWaveLen_Size()
{
return m_waveLength;
}
DWORD CWaveFileEx::getWaveLen_Time()
{
return m_waveLength/8000;
}
bool CWaveFileEx::RecordWav(LPSTR filename,int devno)
{
MMRESULT hr = 0x00;
assert(filename);
strcpy(m_fileName,filename);
this->m_devNo = devno;
int devcount = waveInGetNumDevs();
assert(devcount>0);
assert(devno<devcount);
hr = waveInOpen(&m_hWi,m_devNo,
&m_waveformat,
(DWORD)m_hWnd,
0,
CALLBACK_WINDOW);
if(hr != MMSYSERR_NOERROR )
{
MessageBox(NULL,_T("wave in open failed!"),_T("error"),0);
return false;
}
pbuf1 =new BYTE[m_dwSize];
if(pbuf1 == NULL)
return false;
if(!pWaveHdr1)
return false;
pWaveHdr1->lpData = (char*)pbuf1;
pWaveHdr1->dwBufferLength=m_dwSize;
pWaveHdr1->dwBytesRecorded=0;
pWaveHdr1->dwUser=0;
pWaveHdr1->dwFlags=0;
pWaveHdr1->dwLoops=1;
pWaveHdr1->lpNext=NULL;
pWaveHdr1->reserved=0;
pbuf2 =new BYTE[m_dwSize];
if(pbuf2 == NULL)
return false;
if(!pWaveHdr2)
return false;
pWaveHdr2->lpData = (char*)pbuf2;
pWaveHdr2->dwBufferLength=m_dwSize;
pWaveHdr2->dwBytesRecorded=0;
pWaveHdr2->dwUser=0;
pWaveHdr2->dwFlags=0;
pWaveHdr2->dwLoops=1;
pWaveHdr2->lpNext=NULL;
pWaveHdr2->reserved=0;
if(!m_hWi)
return false;
waveInPrepareHeader(m_hWi,pWaveHdr1,sizeof(WAVEHDR));
waveInPrepareHeader(m_hWi,pWaveHdr2,sizeof(WAVEHDR));
return true;
}
bool CWaveFileEx::CreateWaveFile(void)
{
try
{
if(this->m_hMmio)
{
m_hMmio = 0x00;
}
this->m_hMmio = ::mmioOpen(this->m_fileName,NULL, MMIO_CREATE|MMIO_WRITE|MMIO_EXCLUSIVE | MMIO_ALLOCBUF);
if(this->m_hMmio == NULL)
return false;
ZeroMemory(&m_mmInfoParent,sizeof(m_mmInfoParent));
m_mmInfoParent.fccType = mmioFOURCC('W','A','V','E');
MMRESULT mmResult = mmioCreateChunk(this->m_hMmio,&m_mmInfoParent,MMIO_CREATERIFF);
if(mmResult ==MMIOERR_CANNOTSEEK)
{
GetLastErrorMsg("mmioFourcc(\"wave 1\")");
return false;
}
if(mmResult ==MMIOERR_CANNOTWRITE)
{
GetLastErrorMsg("mmioFourcc(\"wave 2\")");
return false;
}
ZeroMemory(&m_mmInfoChild,sizeof(m_mmInfoChild));
m_mmInfoChild.ckid = mmioFOURCC('f','m','t',' ');
m_mmInfoChild.cksize = sizeof(WAVEFORMATEX)+ m_waveformat.cbSize;
mmResult = mmioCreateChunk(this->m_hMmio,&m_mmInfoChild,0);
if(mmResult ==MMIOERR_CANNOTSEEK)
{
GetLastErrorMsg("mmioFourcc(\"fmt 1\")");
return false;
}
if(mmResult ==MMIOERR_CANNOTWRITE)
{
GetLastErrorMsg("mmioFourcc(\"fmt 2\")");
return false;
}
mmResult = mmioWrite(this->m_hMmio,(char*)&this->m_waveformat, sizeof(WAVEFORMATEX) + this->m_waveformat.cbSize);
if(mmResult == -1)
{
GetLastErrorMsg("mmioWrite");
return false;
}
mmResult = mmioAscend(this->m_hMmio,&m_mmInfoChild,0);
if(mmResult == MMIOERR_CANNOTSEEK)
{
GetLastErrorMsg("mmioAscend _seek");
return false;
}
if(mmResult ==MMIOERR_CANNOTWRITE )
{
GetLastErrorMsg("mmioAscend _write");
return false;
}
m_mmInfoChild.ckid = mmioFOURCC('d','a','t','a');
mmResult = mmioCreateChunk(this->m_hMmio,&m_mmInfoChild,0);
if(mmResult ==MMIOERR_CANNOTSEEK)
{
GetLastErrorMsg("mmioFourcc(\"data 1\")");
return false;
}
if(mmResult ==MMIOERR_CANNOTWRITE)
{
GetLastErrorMsg("mmioFourcc(\"data 2\")");
return false;
}
return true;
}
catch(...)
{
return false;
}
}
bool CWaveFileEx::Write(char* data,DWORD dwlen)
{
DWORD len= 0;
len = mmioWrite(this->m_hMmio,data,dwlen);
if(len <=0 )
return false;
return true;
}
void CWaveFileEx::MmWimOpen()
{
try
{
pSaveBuffer = new char[1];
if(pSaveBuffer == NULL)
return;
dwDataLength = 0;
waveInAddBuffer(m_hWi,pWaveHdr1,sizeof(WAVEHDR));
waveInAddBuffer(m_hWi,pWaveHdr2,sizeof(WAVEHDR));
waveInStart(m_hWi);
}
catch(...)
{
}
}
void CWaveFileEx::MmWimData(WPARAM wParam,LPARAM lParam)
{
DWORD numOfWritten = 0x00;
pNewBuffer =(char *) realloc(pSaveBuffer,
dwDataLength+((PWAVEHDR)lParam)->dwBytesRecorded);
if(pNewBuffer!=NULL)
{
try
{
pSaveBuffer=pNewBuffer;
CopyMemory(pSaveBuffer+dwDataLength,((PWAVEHDR)lParam)->lpData,
((PWAVEHDR)lParam)->dwBytesRecorded);
dwDataLength+=((PWAVEHDR)lParam)->dwBytesRecorded;
CreateWaveFile();
Write(pSaveBuffer,dwDataLength);
Close();
waveInAddBuffer(m_hWi,(PWAVEHDR)lParam,sizeof(WAVEHDR));
}
catch(...)
{
}
}
else
{
waveInClose(m_hWi);
}
}
void CWaveFileEx::MmWimClose()
{
waveInUnprepareHeader(m_hWi,pWaveHdr1,sizeof(WAVEHDR));
waveInUnprepareHeader(m_hWi,pWaveHdr2,sizeof(WAVEHDR));
waveInReset(m_hWi);
waveInClose(m_hWi);
}
bool CWaveFileEx::StopRecordWav()
{
try
{
waveInStop(m_hWi);
if(pbuf1 != 0x00)
delete[] pbuf1;
if(pbuf2 != 0x00)
delete[] pbuf2;
pbuf1 = 0x00;
pbuf2 = 0x00;
return true;
}
catch(...)
{
return false;
}
}
bool CWaveFileEx::PlayWav(LPSTR filename,int sounddevno)
{
MMCKINFO mmckinfoParent;
MMCKINFO mmckinfoSubChunk;
MMRESULT _mr;
DWORD _dwFmtSize = 0x00;
assert(filename);
int devcount = waveOutGetNumDevs();
assert(sounddevno >= -1);
assert(sounddevno <= devcount);
//湖羲疏倛恅璃
try
{
StopPlayWav();
m_hm = mmioOpen(filename,NULL,MMIO_READ);
if(m_hm == 0x00)
{
GetLastErrorMsg("mmioOPen");
return false;
}
//輛?輸ㄛ潰脤湖羲恅璃岆瘁岆wave恅璃
mmckinfoParent.fccType = mmioFOURCC('W','A','V','E');
_mr = mmioDescend(m_hm,(LPMMCKINFO)&mmckinfoParent,NULL,MMIO_FINDRIFF);
if(_mr != MMSYSERR_NOERROR)
{
GetLastErrorMsg("mmioFourcc wave open");
return false;
}
//扆梑 'fmt' 輸
mmckinfoSubChunk.ckid = mmioFOURCC('f','m','t',' ');
_mr = mmioDescend(m_hm,(LPMMCKINFO)&mmckinfoSubChunk,(LPMMCKINFO)&mmckinfoParent,
MMIO_FINDCHUNK);
if(_mr != MMSYSERR_NOERROR)
{
GetLastErrorMsg("mmioFourcc fmt open");
return false;
}
//鳳腕 'fmt '輸腔湮苤ㄛ扠?囀湔
_dwFmtSize = mmckinfoSubChunk.cksize;
PWAVEFORMATEX lpFormat = (WAVEFORMATEX *)&m_waveformat;
if (!lpFormat)
{
GetLastErrorMsg("mmioFourcc lpFormat = NULL open");
return false;
}
if ((unsigned long) mmioRead(m_hm, (HPSTR)lpFormat, _dwFmtSize) !=
_dwFmtSize)
{
GetLastErrorMsg("mmioFourcc _dwFmtSize = NULL open");
return false;
}
//燭羲 fmt 輸
mmioAscend(m_hm, &mmckinfoSubChunk, 0);
//扆梑 'data' 輸
mmckinfoSubChunk.ckid = mmioFOURCC('d', 'a', 't', 'a');
_mr = mmioDescend(m_hm, &mmckinfoSubChunk, &mmckinfoParent,
MMIO_FINDCHUNK);
if (_mr != MMSYSERR_NOERROR)
{
GetLastErrorMsg("mmioFourcc data open");
return false;
}
// 鳳?data輸腔湮苤
DWORD _dwDataSize = mmckinfoSubChunk.cksize ;
DWORD _dwDataOffset = mmckinfoSubChunk.dwDataOffset ;
if( _dwDataOffset== 0L)
{
GetLastErrorMsg("mmioFourcc _dwDataOffset open");
return false;
}
//峈秞?杅擂煦饜囀湔
lpdwData = new char[_dwDataSize];
if(!lpdwData)
return false;
DWORD lSoundOffset = _dwDataOffset;
LONG lSize = mmioSeek(m_hm, lSoundOffset, SEEK_SET);
if (lSize < 0)
{
GetLastErrorMsg("mmioFourcc lSize open");
return false;
}
DWORD _soundLong = _dwDataSize;
DWORD _waveLong = mmioRead(m_hm,lpdwData,_soundLong);
if(_waveLong<= 0)
return false;
m_waveLength = _waveLong;
MMRESULT hr = 0x00;
hr = waveOutOpen(&m_hWo,sounddevno,
&m_waveformat,
(DWORD)this->m_hWnd,
0,
CALLBACK_WINDOW);
if(hr !=MMSYSERR_NOERROR)
{
GetLastErrorMsg("waveOutOpen");
return false;
}
return true;
}
catch(...)
{
return false;
}
//MmWomOpen();
}
bool CWaveFileEx::StopPlayWav()
{
try
{
if(m_hm!=0x00)
{
mmioClose(m_hm,NULL);
m_hm = 0x00;
}
if(m_hWo != 0x00)
{
waveOutReset(m_hWo);
waveOutClose(m_hWo);
m_hWo = NULL;
}
if(lpdwData != 0x00)
{
delete[] lpdwData;
lpdwData = NULL;
}
return true;
}
catch(...)
{
return false;
}
}
void CWaveFileEx::MmWomOpen()
{
try
{
if(lpdwData == NULL)
return;
waveOutHdr.lpData = (char*)lpdwData;
waveOutHdr.dwBufferLength = m_waveLength;
waveOutHdr.dwBytesRecorded =0;
waveOutHdr.dwUser =0;
waveOutHdr.dwFlags =WHDR_BEGINLOOP|WHDR_ENDLOOP;
waveOutHdr.dwLoops =1;
waveOutHdr.lpNext =NULL;
waveOutHdr.reserved =0;
waveOutPrepareHeader(m_hWo,&waveOutHdr,sizeof(WAVEHDR));
if(waveOutWrite(m_hWo,&waveOutHdr,sizeof(WAVEHDR)) != MMSYSERR_NOERROR)
{
GetLastErrorMsg("waveOutWrite");
}
}
catch(...)
{
}
}
void CWaveFileEx::MmWomDone(WPARAM wParam,LPARAM lParam)
{
waveOutUnprepareHeader(m_hWo,&waveOutHdr,sizeof(WAVEHDR));
waveOutReset(m_hWo);
}
void CWaveFileEx::MmWomClose()
{
try
{
waveOutUnprepareHeader(m_hWo,pWaveHdr1,sizeof(pWaveHdr1));
waveOutUnprepareHeader(m_hWo,pWaveHdr2,sizeof(pWaveHdr2));
m_hWo=NULL;
free(pWaveHdr1);
free(pWaveHdr2);
delete[] pbuf1;
delete[] pbuf2;
pWaveHdr1 = NULL;
pWaveHdr2 = NULL;
pbuf1 = NULL;
pbuf2 = NULL;
}
catch(...)
{
}
}
void CWaveFileEx::Close()
{
if(this->m_hMmio)
{
mmioAscend(this->m_hMmio,&this->m_mmInfoChild,0);
mmioAscend(this->m_hMmio,&this->m_mmInfoParent,0);
mmioClose(this->m_hMmio,0);
this->m_hMmio = 0x0;
}
}
void CWaveFileEx::PauseWav()
{
static bool _bpause = true;
if(_bpause )
{
::waveOutPause(m_hWo);
}
else
{
::waveOutRestart(m_hWo);
}
_bpause = !_bpause;
}
void CWaveFileEx::SetWnd(HWND hwnd)
{
this->m_hWnd = hwnd;
}