www.pudn.com > AudioTest.rar > AudioTestView.cpp


// AudioTestView.cpp : implementation of the CAudioTestView class 
// 
 
#include "stdafx.h" 
#include "AudioTest.h" 
 
#include "MainFrm.h" 
#include "AudioTestDoc.h" 
#include "AudioTestView.h" 
#include "WaveAnalysis.h" 
#include "math.h" 
//#include "mmsystem.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CAudioTestView 
 
IMPLEMENT_DYNCREATE(CAudioTestView, CFormView) 
 
BEGIN_MESSAGE_MAP(CAudioTestView, CFormView) 
	//{{AFX_MSG_MAP(CAudioTestView) 
	ON_BN_CLICKED(IDC_REC_START, OnStartRecord) 
	ON_BN_CLICKED(IDC_REC_STOP, OnStopRecord) 
	ON_BN_CLICKED(IDC_PLAY_START, OnPlayStart) 
	ON_BN_CLICKED(IDC_PLAY_PAUSE, OnPlayPause) 
	ON_BN_CLICKED(IDC_PLAY_STOP, OnPlayStop) 
	ON_WM_DESTROY() 
	ON_CBN_SELCHANGE(IDC_IN_SPS, OnSelchangeInSps) 
	ON_CBN_SELCHANGE(IDC_OUT_SPS, OnSelchangeOutSps) 
	ON_WM_TIMER() 
	ON_BN_CLICKED(IDC_SAVE, OnSave) 
	ON_WM_KEYDOWN() 
	ON_WM_KEYUP() 
	ON_BN_CLICKED(IDC_MINIMIZE_WINDOW, OnMinimizeWindow) 
	ON_BN_CLICKED(IDC_STOP_START_DRAW, OnStopStartDraw) 
	ON_WM_PAINT() 
	ON_COMMAND(IDM_LOAD_WAVE, OnLoadWave) 
	ON_CBN_SELCHANGE(IDC_ZOOM_TIMERS, OnSelchangeZoomTimers) 
	ON_BN_CLICKED(IDC_CHANGE_DATA_COLOR, OnChangeDataColor) 
	ON_WM_RBUTTONDOWN() 
	ON_WM_RBUTTONUP() 
	ON_WM_MOUSEMOVE() 
	ON_BN_CLICKED(IDC_GEN_SINE_WAVE_ANALYSIS, OnGenSineWaveAnalysis) 
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1) 
	ON_BN_CLICKED(IDC_READ_WAV_FORMAT, OnReadWavFormat) 
	//}}AFX_MSG_MAP 
	// Standard printing commands 
	ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint) 
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CFormView::OnFilePrint) 
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CFormView::OnFilePrintPreview) 
 
	ON_MESSAGE(MM_WIM_OPEN,OnMM_WIM_OPEN) 
	ON_MESSAGE(MM_WIM_DATA,OnMM_WIM_DATA) 
	ON_MESSAGE(MM_WIM_CLOSE,OnMM_WIM_CLOSE) 
 
	ON_MESSAGE(MM_WOM_OPEN,OnMM_WOM_OPEN) 
	ON_MESSAGE(MM_WOM_DONE,OnMM_WOM_DONE) 
	ON_MESSAGE(MM_WOM_CLOSE,OnMM_WOM_CLOSE) 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CAudioTestView construction/destruction 
#define RAND_MAX 0x7fff 
static double RandomValueInRange(double low, double high) 
{ 
    return (((static_cast(::rand()) / RAND_MAX) * (high - low)) + low); 
} 
 
int xori=50; 
int yori=250; 
int yinc=32; 
int xinc=128; 
int xgrids=6; 
int ygrids=10; 
int xtotal= xinc*xgrids; 
int ytotal = yinc*ygrids; 
CRect rc_draw(xori,yori,xori+xtotal,yori+ytotal); 
int buffer_counter=-1;  
int yscale = 256/(32*8); 
int iinc=8; 
int y_0=yori+5*yinc; 
int zoom_times=1; 
 
CPen* pOldPen; 
COLORREF color_data=RGB(50, 234, 122); 
CBrush bk_brush(RGB(255,255,255)); 
BOOL bGen=FALSE; 
BOOL move_isfirst = TRUE; 
BOOL move_ori = TRUE; 
BOOL bEraseOld = FALSE; 
 
CAudioTestView::CAudioTestView() 
	: CFormView(CAudioTestView::IDD) 
{ 
	//{{AFX_DATA_INIT(CAudioTestView) 
	//}}AFX_DATA_INIT 
	// TODO: add construction code here 
 
	bRecording=FALSE; 
	bPlaying=FALSE; 
	bReverse=FALSE; 
	bPaused=FALSE; 
	bEnding=FALSE; 
	bTerminating=FALSE; 
	dwDataLength=0; 
	dwRepetitions=1; 
	bDataRecorded = FALSE; 
 
	pSaveBuffer = NULL; 
 
	aSPS[0] = 8000; 
	aSPS[1] = 11025; 
	aSPS[2] = 22050; 
	aSPS[3] = 44100; 
 
	aChans[0] = 1; 
	aChans[1] = 2; 
 
	aBytes[0] = 8; 
	aBytes[1] = 16; 
 
	timer3_elapse = 20; 
 
} 
 
CAudioTestView::~CAudioTestView() 
{ 
} 
 
void CAudioTestView::DoDataExchange(CDataExchange* pDX) 
{ 
	CFormView::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CAudioTestView) 
	DDX_Control(pDX, IDC_ZOOM_TIMERS, m_cZoomTimes); 
	DDX_Control(pDX, IDC_PLAY_TIME, m_cPlayTime); 
	DDX_Control(pDX, IDC_REC_TIME, m_cRecTime); 
	DDX_Control(pDX, IDC_OUT_CHANNELS, m_cOutChans); 
	DDX_Control(pDX, IDC_IN_CHANNELS, m_cInChans); 
	DDX_Control(pDX, IDC_OUT_BYTES, m_cOutBytes); 
	DDX_Control(pDX, IDC_IN_BYTES, m_cInBytes); 
	DDX_Control(pDX, IDC_OUT_SPS, m_ctrlOutSPS); 
	DDX_Control(pDX, IDC_IN_SPS, m_ctrlInSPS); 
	//}}AFX_DATA_MAP 
} 
 
BOOL CAudioTestView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
 
	return CFormView::PreCreateWindow(cs); 
} 
 
extern CAudioTestApp theApp; 
void CAudioTestView::OnInitialUpdate() 
{ 
	 
	CFormView::OnInitialUpdate(); 
//	GetParentFrame()->RecalcLayout(); 
//	ResizeParentToFit(); 
 
//	theApp.m_pMainWnd->ShowWindow(SW_MAXIMIZE); 
	((CWnd *)(GetDlgItem(IDC_REC_STOP)))->EnableWindow(FALSE); 
		//allocate memory for wave header 
	pWaveHdr1=reinterpret_cast(malloc(sizeof(WAVEHDR))); 
	pWaveHdr2=reinterpret_cast(malloc(sizeof(WAVEHDR))); 
	 
	//allocate memory for save buffer 
	pSaveBuffer = reinterpret_cast(malloc(1)); 
 
	m_ctrlInSPS.InsertString(0, "8k"); m_ctrlOutSPS.InsertString(0, "8k"); 
	m_ctrlInSPS.InsertString(1, "11k");m_ctrlOutSPS.InsertString(1, "11k"); 
	m_ctrlInSPS.InsertString(2, "22k");m_ctrlOutSPS.InsertString(2, "22k"); 
	m_ctrlInSPS.InsertString(3, "44k");m_ctrlOutSPS.InsertString(3, "44k"); 
	m_ctrlInSPS.SetCurSel(0);m_ctrlOutSPS.SetCurSel(0); 
 
	m_cInChans.InsertString(0, "1");m_cOutChans.InsertString(0, "1"); 
	m_cInChans.InsertString(1, "2");m_cOutChans.InsertString(1, "2"); 
	m_cInChans.SetCurSel(0);m_cOutChans.SetCurSel(0); 
	m_cInBytes.InsertString(0, "8");m_cOutBytes.InsertString(0, "8"); 
	m_cInBytes.InsertString(1, "16");m_cOutBytes.InsertString(1, "16"); 
	m_cInBytes.SetCurSel(0); m_cOutBytes.SetCurSel(0); 
 
	m_cZoomTimes.InsertString( 0, " 1倍"); 
	m_cZoomTimes.InsertString( 1, " 2倍"); 
	m_cZoomTimes.InsertString( 2, " 3倍"); 
	m_cZoomTimes.InsertString( 3, " 4倍"); 
	m_cZoomTimes.InsertString( 4, " 5倍"); 
	m_cZoomTimes.InsertString( 5, " 6倍"); 
	m_cZoomTimes.InsertString( 6, " 7倍"); 
	m_cZoomTimes.InsertString( 7, " 8倍"); 
	m_cZoomTimes.InsertString( 8, " 9倍"); 
	m_cZoomTimes.InsertString( 9, "10倍"); 
	m_cZoomTimes.InsertString(10, "11倍"); 
	m_cZoomTimes.InsertString(11, "12倍"); 
	m_cZoomTimes.InsertString(12, "13倍"); 
	m_cZoomTimes.InsertString(13, "14倍"); 
	m_cZoomTimes.InsertString(14, "15倍"); 
	m_cZoomTimes.InsertString(15, "16倍"); 
	m_cZoomTimes.SetCurSel(0); 
 
//	//m_cAudioGraph. 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CAudioTestView printing 
 
BOOL CAudioTestView::OnPreparePrinting(CPrintInfo* pInfo) 
{ 
	// default preparation 
	return DoPreparePrinting(pInfo); 
} 
 
void CAudioTestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add extra initialization before printing 
} 
 
void CAudioTestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add cleanup after printing 
} 
 
void CAudioTestView::OnPrint(CDC* pDC, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add customized printing code here 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CAudioTestView diagnostics 
 
#ifdef _DEBUG 
void CAudioTestView::AssertValid() const 
{ 
	CFormView::AssertValid(); 
} 
 
 
void CAudioTestView::Dump(CDumpContext& dc) const 
{ 
	CFormView::Dump(dc); 
} 
 
CAudioTestDoc* CAudioTestView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CAudioTestDoc))); 
	return (CAudioTestDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CAudioTestView message handlers 
int play_time=0; 
int rec_time = 0; 
 
void CALLBACK WIMProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance,  DWORD dwParam1, DWORD dwParam2) 
{ 
	CAudioTestView* pView=(CAudioTestView*)dwInstance; 
 
	switch (uMsg) 
	{ 
	case WIM_OPEN: 
		((CWnd *)(pView->GetDlgItem(IDC_REC_START)))->EnableWindow(FALSE); 
		((CWnd *)(pView->GetDlgItem(IDC_REC_STOP)))->EnableWindow(TRUE); 
		((CWnd *)(pView->GetDlgItem(IDC_PLAY_START)))->EnableWindow(FALSE); 
		((CWnd *)(pView->GetDlgItem(IDC_PLAY_PAUSE)))->EnableWindow(FALSE); 
		((CWnd *)(pView->GetDlgItem(IDC_PLAY_STOP)))->EnableWindow(FALSE); 
		pView->bRecording=TRUE; 
		//	TRACE("MM_WIM_OPEN\n"); 
		break; 
	case WIM_DATA: 
		pView->pNewBuffer = (PBYTE)realloc (pView->pSaveBuffer, pView->dwDataLength + 
		((PWAVEHDR) dwParam1)->dwBytesRecorded) ; 
	 
		if (pView->pNewBuffer == NULL) 
		{ 
			waveInReset(pView->hWaveIn);	 
			waveInClose (pView->hWaveIn) ; 
			MessageBeep (MB_ICONEXCLAMATION) ; 
			AfxMessageBox("erro memory"); 
			return ; 
		} 
		 
		pView->pSaveBuffer = pView->pNewBuffer ; 
		////////////////////////////////////////////////////////////////////////// 
		 
		CopyMemory( pView->pSaveBuffer + pView->dwDataLength, ((PWAVEHDR) dwParam1)->lpData, 
			((PWAVEHDR) dwParam1)->dwBytesRecorded) ; 
		 
		pView->dwDataLength += ((PWAVEHDR) dwParam1)->dwBytesRecorded ; 
		pView->SetDlgItemInt(IDC_RECORDED_DATA_LEN, pView->dwDataLength, FALSE); 
		if (pView->bEnding) 
		{ 
			TRACE("stop rec clicked\n"); 
			waveInReset(pView->hWaveIn); 
			Sleep(100); 
			waveInClose (pView->hWaveIn) ; 
			return ; 
		} 
  
		 
		// Send out a new buffer 
		 
		waveInAddBuffer (pView->hWaveIn, (PWAVEHDR) dwParam1, sizeof (WAVEHDR)) ; 
		TRACE("done input data\n"); 
		return ; 
		break; 
	case WIM_CLOSE: 
		TRACE("MM_WIM_CLOSE\n"); 
		if (0==pView->dwDataLength) { 
			return; 
		} 
	 
 
		waveInUnprepareHeader (pView->hWaveIn, pView->pWaveHdr1, sizeof (WAVEHDR)) ; 
		waveInUnprepareHeader (pView->hWaveIn, pView->pWaveHdr2, sizeof (WAVEHDR)) ; 
		 
		free (pView->pBuffer1) ; 
		free (pView->pBuffer2) ; 
		 
		if (pView->dwDataLength > 0) 
		{ 
			//enable play 
			((CButton*)(pView->GetDlgItem(IDC_REC_START)))->EnableWindow(TRUE); 
			((CButton*)(pView->GetDlgItem(IDC_REC_STOP)))->EnableWindow(FALSE); 
			((CButton*)(pView->GetDlgItem(IDC_PLAY_START)))->EnableWindow(TRUE); 
			((CButton*)(pView->GetDlgItem(IDC_PLAY_PAUSE)))->EnableWindow(FALSE); 
			((CButton*)(pView->GetDlgItem(IDC_PLAY_STOP)))->EnableWindow(FALSE); 
		} 
		pView->bRecording = FALSE ; 
		((CWnd*)(pView->GetDlgItem(IDC_REC_START)))->EnableWindow(TRUE); 
		((CWnd*)(pView->GetDlgItem(IDC_REC_STOP)))->EnableWindow(FALSE); 
		 
		return ; 
		break; 
	} 
 
}; 
 
UINT DrawProc(LPVOID pParam) 
{ 
	CAudioTestView* pView =  (CAudioTestView*)pParam; 
 
	while(pView->bDataRecorded) 
	{ 
		/*for (int i=0; i//m_cAudioGraph.Plots.Item(1).ChartY(pView->pSaveBuffer[pView->dwDataLength-INP_BUFFER_SIZE+i]); 
		pView->bDataRecorded = FALSE; 
		*/ 
		return 1; 
	} 
 
	return 0; 
} 
 
void CAudioTestView::OnStartRecord()  
{ 
	rec_time = 0; 
	SetTimer(1,100,NULL); 
	SetDlgItemInt(IDC_RECORDED_DATA_LEN, 0, FALSE); 
	//allocate buffer memory 
	pBuffer1=(PBYTE)malloc(INP_BUFFER_SIZE); 
	pBuffer2=(PBYTE)malloc(INP_BUFFER_SIZE); 
	if (!pBuffer1 || !pBuffer2) { 
		if (pBuffer1) free(pBuffer1); 
		if (pBuffer2) free(pBuffer2); 
		MessageBeep(MB_ICONEXCLAMATION); 
		AfxMessageBox("Memory erro!"); 
		return ; 
	} 
	 
	//open waveform audo for input 
	 
	waveform.wFormatTag=WAVE_FORMAT_PCM; 
	waveform.nChannels=aChans[m_cInChans.GetCurSel()]; 
	waveform.wBitsPerSample=aBytes[m_cInBytes.GetCurSel()]; 
	waveform.nBlockAlign=waveform.nChannels*waveform.wBitsPerSample/8; 
	waveform.nSamplesPerSec= aSPS[m_ctrlInSPS.GetCurSel()]; 
	waveform.nAvgBytesPerSec= waveform.nSamplesPerSec*waveform.nBlockAlign; 
	waveform.cbSize=0; 
 
	//open wavefrom-audio input device for recording 
	//if (waveInOpen(&hWaveIn,WAVE_MAPPER,&waveform,(DWORD)WIMProc,(DWORD)this,CALLBACK_FUNCTION)) { 
	if (MMSYSERR_NOERROR!=waveInOpen(&hWaveIn,WAVE_MAPPER,&waveform,(DWORD)this->m_hWnd,NULL,CALLBACK_WINDOW)) { 
		free(pBuffer1); 
		free(pBuffer2); 
		MessageBeep(MB_ICONEXCLAMATION); 
		AfxMessageBox("Audio can not be open!"); 
		return; 
	} 
 
//The WAVEHDR structure defines the header used to identify a waveform-audio buffer 
//	typedef struct wavehdr_tag { 
 //   LPSTR       lpData;                 /* pointer to locked data buffer */ 
//    DWORD       dwBufferLength;         /* length of data buffer */ 
//    DWORD       dwBytesRecorded;        /* used for input only */ 
//    DWORD       dwUser;                 /* for client's use */ 
//    DWORD       dwFlags;                /* assorted flags (see defines) */ 
//    DWORD       dwLoops;                /* loop control counter */ 
//    struct wavehdr_tag FAR *lpNext;     /* reserved for driver */ 
//    DWORD       reserved;               /* reserved for driver */ 
//} WAVEHDR, *PWAVEHDR, NEAR *NPWAVEHDR, FAR *LPWAVEHDR; 
 
	pWaveHdr1->lpData=(LPTSTR)pBuffer1; 
	pWaveHdr1->dwBufferLength=INP_BUFFER_SIZE; 
	pWaveHdr1->dwBytesRecorded=0; 
	pWaveHdr1->dwUser=0; 
	pWaveHdr1->dwFlags=0; 
//The lpData, dwBufferLength, and dwFlags members must be set before calling the waveInPrepareHeader  
//	or waveOutPrepareHeader function. (For either function, the dwFlags member must be set to zero.) 
	pWaveHdr1->dwLoops=1; 
	pWaveHdr1->lpNext=NULL; 
	pWaveHdr1->reserved=0; 
	 
	//prepares a buffer for audio input 
	waveInPrepareHeader(hWaveIn,pWaveHdr1,sizeof(WAVEHDR)); 
	 
	pWaveHdr2->lpData=(LPTSTR)pBuffer2; 
	pWaveHdr2->dwBufferLength=INP_BUFFER_SIZE; 
	pWaveHdr2->dwBytesRecorded=0; 
	pWaveHdr2->dwUser=0; 
	pWaveHdr2->dwFlags=0; 
	pWaveHdr2->dwLoops=1; 
	pWaveHdr2->lpNext=NULL; 
	pWaveHdr2->reserved=0; 
	 
	waveInPrepareHeader(hWaveIn,pWaveHdr2,sizeof(WAVEHDR)); 
	 
	////////////////////////////////////////////////////////////////////////// 
	pSaveBuffer = (PBYTE)realloc (pSaveBuffer, 1) ; 
	// Add the buffers 
	//The waveInAddBuffer function sends an input buffer to the given waveform-audio input device. When the buffer is filled, the application is notified 
	waveInAddBuffer (hWaveIn, pWaveHdr1, sizeof (WAVEHDR)) ; 
	waveInAddBuffer (hWaveIn, pWaveHdr2, sizeof (WAVEHDR)) ; 
	 
	// Begin sampling 
	 
	bRecording = TRUE ; 
	bEnding = FALSE ; 
	dwDataLength = 0 ; 
 
/*	pThread = AfxBeginThread(DrawProc, this, 0, 0, CREATE_SUSPENDED, NULL); 
	bDataRecorded = FALSE; 
	pThread->m_bAutoDelete = FALSE; 
	pThread->ResumeThread(); 
	*/ 
	//starts input on the given waveform-audio input device. 
	//Buffers are returned to the application when full or when the waveInReset function is called (the dwBytesRecorded member in the header will contain the length of data). If there are no buffers in the queue, the data is thrown away without notifying the application, and input continues. 
	//Calling this function when input is already started has no effect, and the function returns zero 
	//create a thread to show the data 
 
	waveInStart (hWaveIn) ; 
	 
} 
 
void CAudioTestView::OnStopRecord()  
{ 
	KillTimer(1); 
	KillTimer(3); 
	bEnding=TRUE; 
//	Sleep(1500); 
 
/*	bDataRecorded = FALSE; 
	DWORD dwExitCode; 
	::GetExitCodeThread(pThread->m_hThread, &dwExitCode); 
	if(dwExitCode == STILL_ACTIVE) 
	{ 
		pThread->SuspendThread(); 
		::CloseHandle(pThread->m_hThread); 
	} 
	 
	delete pThread; 
	*/ 
 
 
} 
 
void CAudioTestView::OnPlayStart()  
{ 
	play_time = 0; 
	 
	SetTimer(2,100,NULL); 
	 
	if (bPlaying) { 
		//stops playback on the given waveform-audio output device and  
		//resets the current position to zero. All pending playback  
		//buffers are marked as done and returned to the application 
		waveOutReset(hWaveOut); 
	} 
 
	//open waveform audio for output 
	waveform.wFormatTag=WAVE_FORMAT_PCM; 
	waveform.nChannels=aChans[m_cOutChans.GetCurSel()]; 
	waveform.wBitsPerSample=aBytes[m_cOutBytes.GetCurSel()]; 
	waveform.nBlockAlign=waveform.nChannels*waveform.wBitsPerSample/8; 
	waveform.nSamplesPerSec= aSPS[m_ctrlOutSPS.GetCurSel()]; 
	waveform.nAvgBytesPerSec= waveform.nSamplesPerSec*waveform.nBlockAlign; 
	waveform.cbSize			= 0; 
		 
	if (waveOutOpen(&hWaveOut,WAVE_MAPPER,&waveform,(DWORD)this->m_hWnd,NULL,CALLBACK_WINDOW)) { 
		MessageBeep(MB_ICONEXCLAMATION); 
		AfxMessageBox("Audio output erro"); 
	} 
	 
 
	return ; 
} 
 
void CAudioTestView::OnPlayPause()  
{ 
 
	if (!bPlaying)  
	{ 
		return; 
	} 
	if (!bPaused) { 
		waveOutPause(hWaveOut); 
		KillTimer(2); 
		bPaused = TRUE; 
	} 
	else 
	{ 
		SetTimer(2, 100, NULL); 
		waveOutRestart(hWaveOut); 
		bPaused=FALSE; 
	}	 
	return ; 
} 
 
void CAudioTestView::OnPlayStop()  
{ 
	KillTimer(2); 
 
	if (!bPlaying) { 
		return ; 
	} 
	bEnding=TRUE; 
	waveOutReset(hWaveOut); 
	return ; 
} 
 
void CAudioTestView::OnDestroy()  
{ 
	CFormView::OnDestroy(); 
	 
	if (bRecording) { 
		bTerminating=TRUE; 
		bEnding=TRUE; 
		waveInReset(hWaveIn); 
		TRACE("waveInReset\n"); 
		Sleep(500); 
		//return CWinThread::ExitInstance(); 
	} 
	if (bPlaying) { 
		bTerminating=TRUE; 
		bEnding=TRUE; 
		waveOutReset(hWaveOut); 
		Sleep(500); 
		//return CWinThread::ExitInstance(); 
	} 
	free (pWaveHdr1) ; 
	free (pWaveHdr2) ; 
	free (pSaveBuffer) ;	 
} 
 
//发送消息到主窗口处理 
void CAudioTestView::OnMM_WIM_OPEN(UINT wParam, LONG lParam)  
{ 
	// TODO: Add your message handler code here and/or call default 
	((CWnd *)(this->GetDlgItem(IDC_REC_START)))->EnableWindow(FALSE); 
	((CWnd *)(this->GetDlgItem(IDC_REC_STOP)))->EnableWindow(TRUE); 
	((CWnd *)(this->GetDlgItem(IDC_PLAY_START)))->EnableWindow(FALSE); 
	((CWnd *)(this->GetDlgItem(IDC_PLAY_PAUSE)))->EnableWindow(FALSE); 
	((CWnd *)(this->GetDlgItem(IDC_PLAY_STOP)))->EnableWindow(FALSE); 
	SetTimer(1,100,NULL); 
	bRecording=TRUE; 
 
//	TRACE("MM_WIM_OPEN\n"); 
	 
	 
} 
 
void CAudioTestView::OnMM_WIM_DATA(UINT wParam, LONG lParam)  
{ 
	// TODO: Add your message handler code here and/or call default 
	// Reallocate save buffer memory 
	 
	////////////////////////////////////////////////////////////////////////// 
/*	for (int i=0;i<((PWAVEHDR) lParam)->dwBytesRecorded;i++) 
	{ 
		//m_cAudioGraph.ChartY(double(((PWAVEHDR) lParam)->lpData[i])); 
	} 
*/ 
	pNewBuffer = (PBYTE)realloc (pSaveBuffer, dwDataLength + 
		((PWAVEHDR) lParam)->dwBytesRecorded) ; 
	 
	if (pNewBuffer == NULL) 
	{ 
		waveInClose (hWaveIn) ; 
		MessageBeep (MB_ICONEXCLAMATION) ; 
		AfxMessageBox("erro memory"); 
		return ; 
	} 
	 
	pSaveBuffer = pNewBuffer ; 
	 
	bDataRecorded = TRUE; 
	InvalidateRect(&rc_draw, TRUE); 
	////////////////////////////////////////////////////////////////////////// 
	 
	CopyMemory (pSaveBuffer + dwDataLength, ((PWAVEHDR) lParam)->lpData, 
		((PWAVEHDR) lParam)->dwBytesRecorded) ; 
	memcpy(draw_buffer, ((PWAVEHDR) lParam)->lpData, 
		((PWAVEHDR) lParam)->dwBytesRecorded); 
	dwDataLength += ((PWAVEHDR) lParam)->dwBytesRecorded ; 
	SetDlgItemInt(IDC_RECORDED_DATA_LEN, dwDataLength, FALSE); 
 
	if (bEnding) 
	{ 
		waveInClose (hWaveIn) ; 
		return ; 
	} 
 
	 
	// Send out a new buffer 
	 
	waveInAddBuffer (hWaveIn, (PWAVEHDR) lParam, sizeof (WAVEHDR)) ; 
	TRACE("done input data\n"); 
	return ; 
 
	 
} 
 
void CAudioTestView::OnMM_WIM_CLOSE(UINT wParam, LONG lParam)  
{ 
	// TODO: Add your message handler code here and/or call default 
	KillTimer(1); 
	TRACE("MM_WIM_CLOSE\n"); 
	if (0==dwDataLength) { 
		return; 
	} 
	 
//The waveInUnprepareHeader function cleans up the preparation performed by the waveInPrepareHeader function. This function must be called after the device driver fills a buffer and returns it to the application. You must call this function before freeing the buffer. 
 
 
	waveInUnprepareHeader (hWaveIn, pWaveHdr1, sizeof (WAVEHDR)) ; 
	waveInUnprepareHeader (hWaveIn, pWaveHdr2, sizeof (WAVEHDR)) ; 
	 
	free (pBuffer1) ; 
	free (pBuffer2) ; 
	 
	if (dwDataLength > 0) 
	{ 
		//enable play 
		((CWnd *)(this->GetDlgItem(IDC_REC_START)))->EnableWindow(TRUE); 
		((CWnd *)(this->GetDlgItem(IDC_REC_STOP)))->EnableWindow(FALSE); 
		((CWnd *)(this->GetDlgItem(IDC_PLAY_START)))->EnableWindow(TRUE); 
		((CWnd *)(this->GetDlgItem(IDC_PLAY_PAUSE)))->EnableWindow(FALSE); 
		((CWnd *)(this->GetDlgItem(IDC_PLAY_STOP)))->EnableWindow(FALSE); 
	} 
	bRecording = FALSE ; 
	((CWnd *)(this->GetDlgItem(IDC_REC_START)))->EnableWindow(TRUE); 
	((CWnd *)(this->GetDlgItem(IDC_REC_STOP)))->EnableWindow(FALSE); 
	 
	 
	 
	 
	return ; 
	 
} 
 
void CAudioTestView::OnMM_WOM_OPEN(UINT wParam, LONG lParam){ 
	TRACE("open MM_WOM_OPEN\n"); 
	// Set up header 
	 
	pWaveHdr1->lpData          = (LPTSTR)pSaveBuffer ; 
	pWaveHdr1->dwBufferLength  = dwDataLength ; 
	pWaveHdr1->dwBytesRecorded = 0 ; 
	pWaveHdr1->dwUser          = 0 ; 
	pWaveHdr1->dwFlags         = WHDR_BEGINLOOP | WHDR_ENDLOOP ; 
	pWaveHdr1->dwLoops         = dwRepetitions ; 
	pWaveHdr1->lpNext          = NULL ; 
	pWaveHdr1->reserved        = 0 ; 
	 
	// Prepare and write 
	 
	waveOutPrepareHeader (hWaveOut, pWaveHdr1, sizeof (WAVEHDR)) ; 
	waveOutWrite (hWaveOut, pWaveHdr1, sizeof (WAVEHDR)) ; 
	 
	bEnding = FALSE ; 
	bPlaying = TRUE ; 
	 
	((CWnd *)(this->GetDlgItem(IDC_REC_START)))->EnableWindow(TRUE); 
	((CWnd *)(this->GetDlgItem(IDC_REC_STOP)))->EnableWindow(FALSE); 
	((CWnd *)(this->GetDlgItem(IDC_PLAY_START)))->EnableWindow(FALSE); 
	((CWnd *)(this->GetDlgItem(IDC_PLAY_PAUSE)))->EnableWindow(TRUE); 
	((CWnd *)(this->GetDlgItem(IDC_PLAY_STOP)))->EnableWindow(TRUE); 
	 
 
	 
	 
} 
 
void CAudioTestView::OnMM_WOM_DONE(UINT wParam, LONG lParam) 
{ 
 
	KillTimer(2); 
 
	TRACE("open MM_WOM_DONE\n"); 
	waveOutUnprepareHeader (hWaveOut, pWaveHdr1, sizeof (WAVEHDR)) ; 
	waveOutClose (hWaveOut) ; 
	 
	bPaused = FALSE ; 
	dwRepetitions = 1 ; 
	bPlaying = FALSE ;	 
	 
	return  ; 
	 
} 
void CAudioTestView::OnMM_WOM_CLOSE(UINT wParam, LONG lParam) 
{ 
	KillTimer(2); 
 
	TRACE("open MM_WOM_CLOSE\n"); 
	bPaused = FALSE ; 
	dwRepetitions = 1 ; 
	bPlaying = FALSE ;	 
 
	((CWnd *)(this->GetDlgItem(IDC_REC_START)))->EnableWindow(TRUE); 
	((CWnd *)(this->GetDlgItem(IDC_REC_STOP)))->EnableWindow(FALSE); 
	((CWnd *)(this->GetDlgItem(IDC_PLAY_START)))->EnableWindow(TRUE); 
	((CWnd *)(this->GetDlgItem(IDC_PLAY_PAUSE)))->EnableWindow(FALSE); 
	((CWnd *)(this->GetDlgItem(IDC_PLAY_STOP)))->EnableWindow(FALSE); 
	return ; 
	 
} 
 
void CAudioTestView::OnSelchangeInSps()  
{ 
	 
} 
 
void CAudioTestView::OnSelchangeOutSps()  
{ 
	// TODO: Add your control notification handler code here 
	 
} 
 
void CAudioTestView::OnTimer(UINT nIDEvent)  
{ 
 
	if(nIDEvent == 1) 
	{ 
		rec_time+=100; 
		SetDlgItemInt(IDC_REC_TIME, rec_time, FALSE); 
	} 
	else if(nIDEvent == 2) 
	{ 
		play_time+=100; 
		SetDlgItemInt(IDC_PLAY_TIME, play_time, FALSE); 
	} 
	else if(nIDEvent == 3) 
	{ 
		if(bDataRecorded) 
		{ 
			for (int i=0; im_SavePath; 
	m_file.Open(m_csFileName,CFile::modeCreate|CFile::modeReadWrite, &fileException); 
	int StartSect=pDlg->GetStartSector(pDlg->m_List.GetCurSel()+1); 
	int EndSect=pDlg->GetEndSector(pDlg->m_List.GetCurSel()+1); 
	DWORD Bytes2Read=(EndSect - StartSect)*CB_AUDIO; 
	m_AudioDataSize=Bytes2Read; 
	BYTE  Data[CB_AUDIO*NSECTORS]; 
	pDlg->m_Progress.SetRange32(0,Bytes2Read); 
	pDlg->m_Progress.SetPos(0); 
 
	m_file.SeekToBegin(); 
	m_file.Write("RIFF",4); 
	unsigned int Sec=(m_AudioDataSize + m_WaveHeaderSize); 
	m_file.Write(&Sec,sizeof(Sec)); 
	m_file.Write("WAVE",4); 
	m_file.Write("fmt ",4); 
	m_file.Write(&m_WaveFormatSize,sizeof(m_WaveFormatSize)); 
	m_file.Write(&m_WaveFormatEx.wFormatTag,sizeof(m_WaveFormatEx.wFormatTag)); 
	m_file.Write(&m_WaveFormatEx.nChannels,sizeof(m_WaveFormatEx.nChannels)); 
	m_file.Write(&m_WaveFormatEx.nSamplesPerSec,sizeof(m_WaveFormatEx.nSamplesPerSec)); 
	m_file.Write(&m_WaveFormatEx.nAvgBytesPerSec,sizeof(m_WaveFormatEx.nAvgBytesPerSec)); 
	m_file.Write(&m_WaveFormatEx.nBlockAlign,sizeof(m_WaveFormatEx.nBlockAlign)); 
	m_file.Write(&m_WaveFormatEx.wBitsPerSample,sizeof(m_WaveFormatEx.wBitsPerSample)); 
	m_file.Write(&m_WaveFormatEx.cbSize,sizeof(m_WaveFormatEx.cbSize)); 
	m_file.Write("data",4); 
	m_file.Write(&m_AudioDataSize,sizeof(m_AudioDataSize)); 
 
	DWORD m_seek=46; 
	for (int sector = StartSect; (sector < EndSect); sector+=NSECTORS) 
	{ 
		int Sectors2Read = ( (sector + NSECTORS) < EndSect )?NSECTORS:(EndSect-sector); 
		if (pDlg->ReadSector(sector, Data, Sectors2Read))					 
		{						 
			m_file.Write(Data,CB_AUDIO*Sectors2Read); 
			m_file.Seek(m_seek+=CB_AUDIO*Sectors2Read,CFile::begin); 
			pDlg->m_Progress.SetPos(m_seek); 
		}	 
	} 
	m_file.Close(); 
*/ 
 
 
void CAudioTestView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
		if(nChar==VK_ESCAPE) // 如果按的键为Esc键  
		{ 
			((CMainFrame*)AfxGetMainWnd())->EndFullScreen(); 
		} 
	CFormView::OnKeyDown(nChar, nRepCnt, nFlags); 
} 
 
void CAudioTestView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
if(nChar==VK_ESCAPE) // 如果按的键为Esc键  
		{ 
			((CMainFrame*)AfxGetMainWnd())->EndFullScreen(); 
		}	 
	CFormView::OnKeyUp(nChar, nRepCnt, nFlags); 
} 
 
void CAudioTestView::OnMinimizeWindow()  
{ 
	// TODO: Add your control notification handler code here 
	((CMainFrame*)AfxGetMainWnd())->EndFullScreen(); 
} 
 
BOOL bStopDraw = FALSE; 
void CAudioTestView::OnStopStartDraw()  
{ 
	if(	bStopDraw) 
	{ 
		KillTimer(3); 
		((CButton*)GetDlgItem(IDC_STOP_START_DRAW))->SetWindowText("start draw"); 
	} 
	else 
	{ 
		SetTimer(3,timer3_elapse, NULL); 
		((CButton*)GetDlgItem(IDC_STOP_START_DRAW))->SetWindowText("stop draw"); 
	} 
 
	bStopDraw=!bStopDraw; 
} 
 
 
void CAudioTestView::DrawGrid(CPaintDC& dc, int xpos, int ypos, BOOL bErase) 
{ 
	int xpos_ori = xpos; 
	int ypos_ori = ypos; 
 
	CPen pen; 
	pen.CreatePen(PS_SOLID, 1, RGB(255,0,0)); 
	pOldPen = dc.SelectObject(&pen); 
	if(bErase) 
		dc.SetROP2( R2_NOT  ); 
	else 
		dc.SetROP2(R2_COPYPEN); 
		 
//	dc.FillRect(&rc_draw, &bk_brush); 
	 
	//horiz 
	for(int i=0; i<11; i++) 
	{ 
		dc.MoveTo(xpos, ypos);dc.LineTo(xpos+xinc*6,ypos);ypos+=yinc; 
	} 
 
	y_0=yori+5*yinc; 
	dc.TextOut(xpos-10, y_0-8, "0"); 
	//vertical 
	xpos=xpos_ori;ypos=ypos_ori; 
	for( i=0; i<7; i++) 
	{ 
		dc.MoveTo(xpos, ypos);  dc.LineTo(xpos,ypos+10*yinc);xpos+=xinc; 
	} 
 
	dc.SelectObject(pOldPen); 
 
} 
 
void CAudioTestView::DrawAudioData(CPaintDC& dc, int xpos, int ypos) 
{ 
	CPen data_pen(PS_SOLID/*PS_DOT*/, 1, color_data); 
	pOldPen=dc.SelectObject(&data_pen); 
	 
	if(++buffer_counterm_hInstance, MAKEINTRESOURCE(IDC_MYHAND))); 
		SetCapture(); 
		r_o_point= point; 
	} 
	 
	 
	CFormView::OnRButtonDown(nFlags, point); 
} 
 
void CAudioTestView::OnRButtonUp(UINT nFlags, CPoint point)  
{ 
	if(r_captured) 
	{ 
		::ReleaseCapture(); 
		r_captured = FALSE; 
		::SetCursor(::LoadCursor(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDC_ARROW))); 
		r_n_point = point; 
		xori+=r_n_point.x-r_o_point.x; 
		yori+=r_n_point.y-r_o_point.y; 
		rc_draw = CRect(xori,yori,xori+xtotal,yori+ytotal); 
		InvalidateRect(NULL, TRUE); 
		bEraseOld = FALSE; 
	} 
	CFormView::OnRButtonUp(nFlags, point); 
} 
 
void CAudioTestView::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	if(r_captured) 
	{ 
		if(move_ori) 
		{ 
			move_ori = FALSE; 
			r_o_point=point; 
		} 
		 
		if(move_isfirst) 
		{ 
			r_n_point = point; 
		} 
		else 
		{ 
			r_o_point=r_n_point; 
		} 
		 
		move_isfirst = !move_isfirst; 
 
		// erase the old rect 
		rc_draw = CRect(xori-10,yori-10,xori+xtotal+20,yori+ytotal+20); 
	//	bEraseOld = TRUE; 
	//	InvalidateRect(rc_draw, TRUE); 
		//draw the new rect 
		xori+=r_n_point.x-r_o_point.x; 
		yori+=r_n_point.y-r_o_point.y; 
	//	rc_draw = CRect(xori-10,yori,xori+xtotal+20,yori+ytotal+10);//rc_draw = CRect(xori,yori,xori+xtotal,yori+ytotal); 
		bEraseOld = FALSE; 
		InvalidateRect(rc_draw, TRUE); 
	} 
 
	CFormView::OnMouseMove(nFlags, point); 
} 
 
 
void CAudioTestView::OnGenSineWaveAnalysis()  
{ 
		 
	bGen=TRUE; 
	 
	InvalidateRect(rc_draw,TRUE); 
} 
#include  
#include  
#include  
 
 
void __cdecl beginThreadFunc( LPVOID ) 
{ 
   
} 
DWORD __stdcall CreateThreadFunc( LPVOID ) 
{ 
     
    return 0; 
} 
 
 
 
void CAudioTestView::OnButton1()  
{ 
 
//	_beginthread( beginThreadFunc, 0, 0 );//1 
CreateThread( NULL, 0, CreateThreadFunc, 0, 0, 0 );//2 
 
/*	long* lbuf1=new long[100]; 
 
	PBYTE buf1=(PBYTE)malloc(1000); 
	int size = _msize( buf1 ); 
	PBYTE buf2=(PBYTE)realloc(buf1,15); 
	size = _msize( buf2 ); 
	PBYTE buf3=(PBYTE)realloc(buf2,1005); 
	size = _msize( buf3 ); 
	PBYTE buf4=(PBYTE)realloc(buf3,115); 
	size = _msize( buf4 ); 
	PBYTE buf5=(PBYTE)realloc(buf4,1522); 
	size = _msize( buf5 ); 
	free(buf5); 
	*/ 
/*	FILE *pfile; 
	pfile=fopen("c:\\test.gsm.wav", "rb+"); 
	fseek(pfile, 4, 0); 
	int x=1000; 
	fwrite(&x, 4, 1, pfile); 
	fclose(pfile); 
	*/ 
 
} 
 
#include "ReadWavFileFormatDlg.h" 
void CAudioTestView::OnReadWavFormat()  
{ 
CReadWavFileFormatDlg dlg; 
dlg.DoModal();	 
}