//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "recoder.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
//#pragma comment(lib,"Winmm.lib")
#include "mmsystem.h"
#define INP_BUFFER_SIZE 256000
TForm1 *Form1;
bool AddWaveFileDate(HANDLE fh, PBYTE pBufferBits, DWORD dwBufferSize);
MMRESULT WriteWaveFileHeader(LPCTSTR pszFilename, PWAVEFORMATEX pWFX,
DWORD dwBufferSize, bool bCover);
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------
PBYTE pBuffer1,pBuffer2;//pSaveBuffer;
// save the data buffer for recording
// global variables
WAVEFORMATEX waveform; // WAVE波形的采集参数
//MYWAVEFORMATEX waveform;
HWAVEIN hWaveIn ;
HANDLE FileHandle;
PWAVEHDR pWaveHdr1,pWaveHdr2;
UINT cbwh;
bool bRecording = false;
int dwDataLength = 0;
//----------------------------
// ----------------------------
// init()
void init()
{
//allocate memory for save buffer
//pSaveBuffer = reinterpret_cast<PBYTE>(malloc(1));
}
//-------------------------
// ---------------------------------------------------------------------------
void OnWIM_DATA(WPARAM wParam, LPARAM lParam)
{
// bEnding可以作为一个外部定义的BOOL变量,用来判断外部是否
// 按下"停止"按钮;是则不分配内存,直接返回.
// 可以扩充程序中的停止功能
/*
if (bRecording == false)
{
//关闭录音
//waveInClose (hWaveIn) ;
ShowMessage("已经关闭录音!");
return ;
}
*/
if (bRecording == false)
{
ShowMessage("关闭录音前,保存缓冲区数据!");
}
//ShowMessage("开始录音了!");
DWORD dwBytesRecorded = ((PWAVEHDR)wParam)->dwBytesRecorded;
PBYTE pSaveBuffer;
pSaveBuffer = reinterpret_cast<PBYTE>(malloc(dwBytesRecorded));
// ShowMessage(IntToStr(dwBytesRecorded));
// 256000
if(pSaveBuffer == NULL)
{
waveInClose (hWaveIn) ;
ShowMessage("不能再分配额外内存给pSaveBuffer!");
return;
}
//dwDataLength是一个外部定义的DWORD变量,用来记录录音数据的长度.
//dwDataLength += dwBytesRecorded ;
//将内存数据写到文件中
CopyMemory (pSaveBuffer, ((PWAVEHDR) wParam)->lpData, dwBytesRecorded) ;
/*
if( AddWaveFileDate(FileHandle,pSaveBuffer,dwBytesRecorded) == false )
{
//加入不成功
ShowMessage("加入不成功");
waveInClose (hWaveIn) ;
return ;
}
free(pSaveBuffer);
//加入新的内存
DWORD dwBytesWritten;
if(bRecording == true)
{
waveInAddBuffer (hWaveIn, (PWAVEHDR) wParam, sizeof (WAVEHDR)) ;
}
*/
//Write the memory data to the file
DWORD dwBytesWritten;
if(WriteFile(FileHandle, pSaveBuffer, dwBytesRecorded,
&dwBytesWritten, NULL) != true)
{
if(bRecording == true)
{
waveInClose (hWaveIn) ;
}
}
dwDataLength += dwBytesWritten ;
free(pSaveBuffer);
//If m_bRecording is FALSE, it may call the function waveInReset().So don't add buffer.
if(bRecording == true)
{
// Send out a new buffer.The new buffer is the original full buffer, used again.
waveInAddBuffer (hWaveIn, (PWAVEHDR) wParam, sizeof (WAVEHDR)) ;
}
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// **************************************************************************
// 录音完毕的收尾工作
void OnWIM_CLOSE(WPARAM wParam, LPARAM lParam)
{
//关闭文件句柄
ShowMessage("录音完毕");
if(FileHandle != NULL)
{
CloseHandle(FileHandle);
FileHandle = NULL;
}
if (dwDataLength == 0)
{
//长度为0,可能录音失败
return;
}
//重写一次文件头,将文件长度写入文件中
MMRESULT mr;
mr=WriteWaveFileHeader("receive.wav",&waveform,dwDataLength,false);
if(mr != MMSYSERR_NOERROR)
{
ShowMessage("重写文件头失败!");
return;
}
//waveInUnprepareHeader (hWaveIn, pWaveHdr1, sizeof (WAVEHDR)) ;
//waveInUnprepareHeader (hWaveIn, pWaveHdr2, sizeof (WAVEHDR)) ;
//free (pBuffer1) ;
//free (pBuffer2) ;
}
// *********************************************************************
// ---------------------------------------------------------------------
//----------------------------------------------------------------------
//Decription:
// On WIM_OPEN
//------------------------------------------------------------------------
void OnWIM_OPEN(WPARAM wParam, LPARAM lParam)
{
bRecording = true;
dwDataLength = 0;
}
// -----------------------------------------------------------------
//----------------------------------------------------------------------
//Decription:
// WaveIn Process
//
//Parameter:
// hwi: [in] Handle to the waveform-audio device associated with the callback function
// uMsg: [in] Waveform-audio input message. It can be one of the messages shown :WIM_CLOSE,WIM_DATA,WIM_OPEN
// dwInstance: [in] User instance data specified with waveInOpen.
// dwParam1: [in] Message parameter.
// dwParam2: [in] Message parameter.
//
//Retrun Values:
// DWORD type.
//----------------------------------------------------------------------
void CALLBACK WaveInProc(HWAVEIN hWi, UINT uMsg, DWORD dwInstance,
DWORD dwParam1, DWORD dwParam2)
{
switch(uMsg)
{
case WIM_CLOSE:
OnWIM_CLOSE(dwParam1,dwParam2);
break;
case WIM_DATA:
OnWIM_DATA(dwParam1,dwParam2);
break;
case WIM_OPEN:
OnWIM_OPEN(dwParam1,dwParam2);
break;
}
}
// ******************************
// ------------------------------
// 写字符串到文件的函数
DWORD FCC(LPSTR lpStr)
{
DWORD Number = lpStr[0] + lpStr[1] *0x100 + lpStr[2] *0x10000 + lpStr[3] *0x1000000 ;
return Number;
}
// ------------------------------
// ******************************
// --------------------------------------------------------------------------
//写wav文件头
//---------------------------------------------------------------
//pszFilename:保存的路径
//pWFX:保存的格式信息
//dwBufferSize:保存WAV的长度
//bCover:创建文件时如果原文件存在,是否截断(在此函数意义是:是新建文件写文件头,还是改写文件头)
//*******************************************************************************************
//----------------------------------------------------------------
MMRESULT WriteWaveFileHeader(LPCTSTR pszFilename, PWAVEFORMATEX pWFX,
DWORD dwBufferSize, bool bCover)
{
//RIFF_FILEHEADER FileHeader;
DWORD FileHeader;
DWORD FHSize;
//RIFF_CHUNKHEADER WaveHeader;
DWORD WaveHeader;
//DWORD WHSize;
//RIFF_CHUNKHEADER DataHeader;
DWORD DataHeader;
DWORD DHSize;
DWORD dwBytesWritten;
HANDLE fh;
MMRESULT mmRet = MMSYSERR_ERROR;
// Fill in the file, wave and data headers
//WHSize = sizeof(WAVEFORMATEX);
//WaveHeader.dwCKID = RIFF_FORMAT;
//WaveHeader.dwSize = sizeof(WAVEFORMATEX) + pWFX->cbSize;
// the DataHeader chunk contains the audio data
//DataHeader.dwCKID = RIFF_CHANNEL;
//DataHeader.dwSize = dwBufferSize;
DHSize = d