www.pudn.com > waveinFFT_demo.zip > SpectrumGraph.cpp
// SpectrumGraph.cpp : implementation file // #include "stdafx.h" #include "waveInFFT.h" #include "SpectrumGraph.h" #include#include "memoryDc.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CFrequencyGraph CFrequencyGraph::CFrequencyGraph() { m_nLength = 0; m_dArray = NULL; m_nMinValue = 0; m_nMaxValue = 10; m_nHighLevel = 80; m_nMediumLevel = 60; m_wSteps = 16; m_nStepFactor = 1; m_clrLow = RGB(0,0,255); m_clrMedium = RGB(0,255,0); m_clrHigh = RGB(255,0,0); m_bGrid = TRUE; m_bLogScale = FALSE; m_graphType = FG_EQ_CHANNEL; } CFrequencyGraph::~CFrequencyGraph() { if (m_dArray) delete []m_dArray; } BEGIN_MESSAGE_MAP(CFrequencyGraph, CWnd) //{{AFX_MSG_MAP(CFrequencyGraph) ON_WM_PAINT() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CFrequencyGraph message handlers void CFrequencyGraph::Point(HDC hDC, int x, int y, COLORREF color) { ::SetPixel (hDC, x, y, color); } BOOL CFrequencyGraph::Line(HDC hDC, int x1, int y1, int x2, int y2) { ::MoveToEx(hDC, x1, y1, 0); return ::LineTo(hDC, x2, y2); } void CFrequencyGraph::OnPaint() { CRect rct; GetClientRect(&rct); //Needs to use CMemoryDC or else CMemDC... //using either class will get ride of the //flicker problem that otherwise presents itself... CPaintDC paintdc(this); CMemDC dc(&paintdc,&rct); // graph if (m_nLength == 0) return; CBrush* pOldBrush = NULL; CBrush* pbbr = NULL; CBrush* pabr = NULL; CBrush br(RGB(0,0,0)); CBrush bg(RGB(0,65,0)); CBrush bg1(RGB(0,192,0)); CBrush bbr(RGB(0,0,255)); CBrush abr(RGB(0,255,0)); CPen blk1(PS_SOLID,3,RGB(0,0,0)); CPen wht(PS_SOLID,1,RGB(192,192,192)); CPen grn(PS_SOLID,2,RGB(0,128,0)); CPen grn1(PS_SOLID,2,RGB(0,212,0)); CPen pen(PS_SOLID,1,RGB(255,255,255)); CPen bpen(PS_SOLID,1,RGB(0,0,255)); CPen* pOldPen = NULL; CPen* pbOldPen = NULL; float div[16]={9,16,33,66,132,282,485, 540,632,987,1283,2732,5820,11640,17123,19123}; CRect stepRect; CRect rc, lr, rr; int i, n, x,ctr,py,half,y=0; int nBars = m_wSteps; int pos=0; int xRight = (int)ceil((float)rct.Width() / (float)nBars); int nDiv=m_nLength/(nBars); int leftzerolevel = (rct.Height()/2-10)/2; int rightzerolevel = rct.Height()/2+10+leftzerolevel; int StereoY = rct.Height()/2; int StereoX = rct.Width()/2; double dRangePerStep = (m_nMaxValue-m_nMinValue); double timescale = leftzerolevel/dRangePerStep; double ts = static_cast (rct.Width())/static_cast (m_nLength); double ksum = 0.0; double rqsum = 0.0; double lqsum = 0.0; double left, right, coef, l, r, correlation; double peakleft = 0; double peakright = 0; double StereoScale = static_cast (StereoX)/dRangePerStep; double StereoScaleY = static_cast (StereoY)/dRangePerStep; double stereoleft = 0; double stereoright = 0; double* data = m_dArray; float alfa = 45.0f*3.1415926535897932384626433832795f/180.0f; float hcos = cos(alfa); float hsin = sin(alfa); switch (m_graphType) { case FG_MICRO_EQ: dc.SelectObject(bg); dc.SelectObject(blk1); dc.Rectangle(rct); dc.SelectObject(wht); dc.MoveTo(rct.left+1,rct.Height()/2-2); dc.LineTo(rct.left+1,rct.top+1); dc.LineTo(rct.right-1,rct.top+1); dc.SelectObject(grn); dc.MoveTo(rct.left+2,rct.Height()/2); dc.LineTo(rct.right-2,rct.Height()/2); dc.SelectObject(grn1); dc.SelectObject(bg1); if (m_dArray != NULL) { x=16; for(ctr=1; ctr nLargest) nLargest = (int)m_dArray[i]; } //17 130 61 130 = 37 //60 130 61 130 = 127 //108 130 61 130 = 100 //17 130 61 230 = 36 / 231 * 130 = 20 //60 130 61 230 = 127 / 231 * 130 = 71 //108 130 61 230 = 231 / 231 * 130 = 130 tot /= (nDiv); /*if (m_bLogScale) { tot = log10((float)tot)/log10(abs((float)m_nMaxValue-m_nMinValue))*rct.Height(); } */ if (m_nMaxValue-m_nMinValue < tot) { tot = rct.Height()/max(abs(m_nMinValue),abs(m_nMaxValue))*tot; } else tot = (int)(scalefactor*tot); //tot = (int)(((((float)tot*rct.Height())/((float)(m_nMaxValue-m_nMinValue)))/(float)scalefactor)*rct.Height()); //tot *= 2; //tot = (int)log(tot); TRACE("Total=%d Div=%d, Bars=%d dRange=%f Max=%d Min=%d Largest=%d\n",tot,nDiv,nBars,dRangePerStep,m_nMaxValue,m_nMinValue,nLargest); { stepRect.left = (rct.left+((xRight*(w+1))-xRight)); stepRect.right = (xRight*(w+1)); stepRect.bottom = stepRect.top; stepRect.top = rct.bottom - int(tot); CBrush br1; if (tot > m_nHighLevel) br1.CreateSolidBrush(GetHighColor()); else if (tot > m_nMediumLevel) br1.CreateSolidBrush(GetMediumColor()); else br1.CreateSolidBrush(GetLowColor()); dc.FillRect(&stepRect,&br1); if (m_bGrid) dc.FrameRect(&stepRect,&br); stepRect.bottom = stepRect.top; stepRect.top = 0; } pos+=nDiv; } } } break; case FG_OSCILLOSCOPE: pOldBrush = dc.SelectObject(&br); pOldPen = dc.SelectObject(&pen); dc.Rectangle( 0, 0, rct.Width(), rct.Height() ); pbOldPen = dc.SelectObject(&bpen); dc.MoveTo(0, leftzerolevel); for(i=0; i (m_dArray[i])*timescale); dc.LineTo( x ,y ); } dc.MoveTo(0, rightzerolevel); for(i=1; i (m_dArray[i])*timescale); dc.LineTo( x ,y ); } dc.SelectObject(pbOldPen); dc.SelectObject(pOldPen); dc.SelectObject(pOldBrush); break; case FG_PEAK: for(i=0; i (*data++); l = static_cast (*data++); ksum += r * l; rqsum += r * r; lqsum += l * l; } correlation = ksum / sqrt(lqsum * rqsum); dc.FillRect( rct,&br ); half = rct.Width()/2; n = (int)(half+correlation*half); if( n+8 >= rct.Width() ) { n = rct.Width()-5; } rct.left=n-4; rct.right=rct.left+8; rct.top=5; rct.bottom=rct.Height()-5; dc.FillRect(rct,&bbr); break; case FG_PEAK2: for(i = 0; i (*data++)); right = fabs(static_cast (*data++)); peakleft = left>peakleft?left:peakleft; peakright = right>peakright?right:peakright; } coef = rct.Width()/dRangePerStep; lr.left=1; lr.right=(LONG)(coef*peakleft); lr.top=2; lr.bottom=rct.Height()/2-2; rr.left=1; rr.right=(LONG)(coef*peakright); rr.top=rct.Height()/2+2; rr.bottom=rct.bottom-2; pOldBrush = dc.SelectObject(&br); pOldPen = dc.SelectObject(&pen); dc.Rectangle( 0, 0, rct.Width(), rct.Height() ); pbbr = dc.SelectObject(&bbr); pabr = dc.SelectObject(&abr); dc.FillRect( lr,&bbr ); dc.FillRect( rr,&abr ); dc.SelectObject(pabr); dc.SelectObject(pbbr); dc.SelectObject(pOldPen); dc.SelectObject(pOldBrush); break; case FG_PIXELGRAM: pOldBrush = dc.SelectObject(&br); pOldPen = dc.SelectObject(&pen); dc.Rectangle(0, 0, rct.Width(), rct.Height()); for(i=0; i (*data++); right=static_cast (*data++); stereoleft = (hcos*left - hsin*right)*2; stereoright = (hsin*right + hcos*left)*2; dc.SetPixel((int)(StereoX+stereoright*StereoScale),(int)(StereoY+stereoleft*StereoScaleY),RGB(255,255,255)); } break; } if (pOldPen) dc.SelectObject(pOldPen); if (pOldBrush) dc.SelectObject(pOldBrush); } void CFrequencyGraph::Update(int nNumber, double* dArray) { if (m_nLength != nNumber) { m_nLength = nNumber; if (m_dArray) delete []m_dArray; m_dArray = new double[m_nLength]; } m_nStepFactor = (int)((m_nLength/m_wSteps)+0.5); memcpy(m_dArray,dArray,nNumber*sizeof(double)); Invalidate(FALSE); }