www.pudn.com > Éù²¨ÆµÂÊÏÔʾ .zip > PeakLevelDlg.cpp


/********************************************************************/ 
/*																	*/ 
/*  PeakLevelDlg.cpp												*/ 
/*																	*/ 
/*  Implementation of the CPeakLevelDlg.							*/ 
/*																	*/ 
/*  Programmed by Pablo van der Meer								*/ 
/*  Copyright Pablo Software Solutions 2003							*/ 
/*	http://www.pablovandermeer.nl									*/ 
/*																	*/ 
/*  Last updated: 11 January 2003									*/ 
/*																	*/ 
/********************************************************************/ 
 
 
#include "stdafx.h" 
#include "PeakLevel.h" 
#include "PeakLevelDlg.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
 
CPeakLevelDlg::CPeakLevelDlg(CWnd* pParent /*=NULL*/) 
	: CDialog(CPeakLevelDlg::IDD, pParent) 
{ 
	//{{AFX_DATA_INIT(CPeakLevelDlg) 
	//}}AFX_DATA_INIT 
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 
} 
 
void CPeakLevelDlg::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CPeakLevelDlg) 
	DDX_Control(pDX, IDC_HOMEPAGE, m_Homepage); 
	DDX_Control(pDX, IDC_GRAPH_RIGHT, m_OscilloGraphRight); 
	DDX_Control(pDX, IDC_GRAPH_LEFT, m_OscilloGraphLeft); 
	DDX_Control(pDX, IDC_VUMETER_RIGHT, m_VuMeterRight); 
	DDX_Control(pDX, IDC_VUMETER_LEFT, m_VuMeterLeft); 
	//}}AFX_DATA_MAP 
} 
 
BEGIN_MESSAGE_MAP(CPeakLevelDlg, CDialog) 
	//{{AFX_MSG_MAP(CPeakLevelDlg) 
	ON_BN_CLICKED(IDC_START, OnStart) 
	ON_BN_CLICKED(IDC_STOP, OnStop) 
	//}}AFX_MSG_MAP 
	ON_MESSAGE(MM_WIM_DATA, OnMMWimData) 
END_MESSAGE_MAP() 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : OnInitDialog										*/ 
/* Description   : Initialize dialog								*/ 
/*																	*/ 
/********************************************************************/ 
BOOL CPeakLevelDlg::OnInitDialog() 
{ 
	CDialog::OnInitDialog(); 
 
	SetIcon(m_hIcon, TRUE);			// Set big icon 
	SetIcon(m_hIcon, FALSE);		// Set small icon 
	 
	m_VuMeterLeft.SetRange(0, 127); 
	m_VuMeterRight.SetRange(0, 127); 
 
	m_OscilloGraphLeft.SetPixelColor(RGB(255, 255, 0)); 
	return TRUE;  // return TRUE  unless you set the focus to a control 
} 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : OnStart											*/ 
/* Description   : Start monitoring the input						*/ 
/*																	*/ 
/********************************************************************/ 
void CPeakLevelDlg::OnStart()  
{ 
	StartInput(); 
} 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : OnStop											*/ 
/* Description   : Stop monitoring the input						*/ 
/*																	*/ 
/********************************************************************/ 
void CPeakLevelDlg::OnStop()  
{ 
	StopInput();	 
} 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : OnMMWimData										*/ 
/* Description   : Called when the input buffer is full.			*/ 
/*																	*/ 
/********************************************************************/ 
LRESULT CPeakLevelDlg::OnMMWimData(WPARAM wParam, LPARAM lParam) 
{ 
	int nLeft = 0, nRight = 0; 
 
	SetOscilloGraphData((LPWAVEHDR)lParam); 
 
	// analyse input data 
	if (AnalyseDataBlock((LPWAVEHDR)lParam, nLeft, nRight)) 
	{ 
		m_VuMeterLeft.SetValue(nLeft); 
		m_VuMeterRight.SetValue(nRight); 
	} 
	 
	return 0L; 
} 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : StartInput										*/ 
/* Description   : Start monitoring the audio input					*/ 
/*																	*/ 
/********************************************************************/ 
BOOL CPeakLevelDlg::StartInput() 
{ 
    int i; 
 
	m_PcmWaveFormat.wf.nChannels = NUM_CHANNELS; 
	m_PcmWaveFormat.wBitsPerSample = 8; 
	m_PcmWaveFormat.wf.nSamplesPerSec = 11025; 
    m_PcmWaveFormat.wf.wFormatTag = WAVE_FORMAT_PCM; 
    m_PcmWaveFormat.wf.nBlockAlign = m_PcmWaveFormat.wf.nChannels * m_PcmWaveFormat.wBitsPerSample / 8; 
    m_PcmWaveFormat.wf.nAvgBytesPerSec = m_PcmWaveFormat.wf.nSamplesPerSec * m_PcmWaveFormat.wf.nBlockAlign; 
 
    // calculate buffer size for specified update interval 
    m_dwBufferLength = m_PcmWaveFormat.wf.nAvgBytesPerSec/UPDATE_INTERVAL; 
 
    m_hWave = NULL; 
 
    if (waveInOpen(&m_hWave, WAVE_MAPPER, (LPWAVEFORMATEX)&m_PcmWaveFormat, (DWORD)m_hWnd, 0, CALLBACK_WINDOW))  
	{ 
        return FALSE; 
    } 
 
    // initialize to null 
    for (i = 0; i < NUM_CHANNELS; i++)  
	{ 
        m_WaveHeader[i] = NULL; 
    } 
 
    // allocate memory, prepare headers and add the buffers 
    for (i = 0; i < NUM_CHANNELS; i++)  
	{ 
		HGLOBAL hGlobalMem = GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE, sizeof(WAVEHDR) + m_dwBufferLength); 
        m_WaveHeader[i] = (LPWAVEHDR)GlobalLock(hGlobalMem); 
        if (m_WaveHeader[i] == NULL)  
		{ 
            return FALSE; 
        } 
 
        m_WaveHeader[i]->lpData = (LPSTR) (m_WaveHeader[i] + 1); 
        m_WaveHeader[i]->dwBufferLength = m_dwBufferLength; 
        m_WaveHeader[i]->dwBytesRecorded = 0; 
        m_WaveHeader[i]->dwUser = 0; 
        m_WaveHeader[i]->dwFlags = 0; 
        m_WaveHeader[i]->dwLoops = 0; 
 
        if (waveInPrepareHeader(m_hWave, m_WaveHeader[i], sizeof(WAVEHDR)))  
		{ 
            return FALSE; 
        } 
 
        if (waveInAddBuffer(m_hWave, m_WaveHeader[i], sizeof(WAVEHDR)))  
		{ 
            return FALSE; 
        } 
    } 
 
    waveInStart(m_hWave); 
 
    return TRUE; 
} 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : StopInput										*/ 
/* Description   : Stop monitoring the audio input					*/ 
/*																	*/ 
/********************************************************************/ 
void CPeakLevelDlg::StopInput() 
{ 
    if (m_hWave == NULL) 
	{ 
        return; 
    } 
 
    // stop streaming data 
    waveInStop(m_hWave); 
 
    // release buffers 
    waveInReset(m_hWave); 
 
    // clean up 
    for (int i = 0; i < NUM_CHANNELS; i++)  
	{ 
        if (m_WaveHeader[i])  
		{ 
            waveInUnprepareHeader(m_hWave, m_WaveHeader[i], sizeof(WAVEHDR)); 
			 
			HGLOBAL hGlobalMem = GlobalHandle(m_WaveHeader[i]); 
            GlobalFree(hGlobalMem); 
 
            m_WaveHeader[i] = NULL; 
        } 
 
    } 
    waveInClose(m_hWave); 
} 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : AnalyseDataBlock									*/ 
/* Description   : Analyse received data and get maximum levels.	*/ 
/*																	*/ 
/********************************************************************/ 
BOOL CPeakLevelDlg::AnalyseDataBlock(LPWAVEHDR pWaveHdr, int &nLevelLeft, int &nLevelRight) 
{ 
    if (m_hWave == NULL) 
	{ 
        return FALSE; 
    } 
 
    int nSampleLevel; 
 
    // find maximum absolute level 
	for (DWORD i=0; ilpData[i]) - 128; 
 
		// get maximum 
		nLevelLeft = __max(nLevelLeft, abs(nSampleLevel)); 
         
		// skip to right channel 
		i++; 
 
		// adjust to be in range 0..128 
		nSampleLevel = (int)((unsigned char) pWaveHdr->lpData[i]) - 128; 
 
		// get maximum 
		nLevelRight = __max(nLevelRight, abs(nSampleLevel)); 
	} 
 
    // put the buffer back on the queue 
    if (waveInAddBuffer(m_hWave, pWaveHdr, sizeof(WAVEHDR)))  
	{ 
        return FALSE; 
    } 
    return TRUE; 
} 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : SetOscilloGraphData								*/ 
/* Description   : Copy received data to oscillograph.				*/ 
/*																	*/ 
/********************************************************************/ 
void CPeakLevelDlg::SetOscilloGraphData(LPWAVEHDR pWaveHdr) 
{ 
    if (m_hWave == NULL) 
	{ 
        return; 
    } 
 
	BYTE *pBytesLeft = new BYTE[m_dwBufferLength/2]; 
	BYTE *pBytesRight = new BYTE[m_dwBufferLength/2]; 
 
	// copy wave data 
	for (DWORD i=0; ilpData[i]); 
		// copy data for right channel 
		pBytesRight[i/2] = (int)((unsigned char) pWaveHdr->lpData[i+1]); 
	} 
	m_OscilloGraphLeft.SetData(pBytesLeft, m_dwBufferLength/2); 
	m_OscilloGraphRight.SetData(pBytesRight, m_dwBufferLength/2); 
 
	delete pBytesLeft; 
	delete pBytesRight; 
}