📄 plotdata.cpp
字号:
// PlotData.cpp: implementation of the CPlotData class.
//
//
#include "stdafx.h"
#include "winpsk.h"
#include "Settings.h"
#include "WinPSKView.h"
#include "PlotData.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CPlotData::CPlotData()
{
m_pDoc = NULL;
m_DispHead = 0;
m_DispTail = 0;
m_BufToggle = FALSE;
m_NeedToClrBufs = FALSE;
m_LastOvrLoad = FALSE;
//allocate memory space
m_pDispBuf = new INT[DISPBUF_SIZE+10];
ASSERT( m_pDispBuf );
ClearBuffers();
m_TranslateTbl = new INT[DISPBUF_SIZE+10];
ASSERT( m_TranslateTbl );
//allocate FFT object
m_CursPos = 0;
m_pPenR = new CPen; // create some colored pens for drawing
m_pPenG = new CPen;
m_pPenY = new CPen;
m_pPenW = new CPen;
m_pPenC = new CPen;
m_pPenB = new CPen;
m_pPenR->CreatePen( PS_SOLID,0, RGB(255,0,0) );
m_pPenG->CreatePen( PS_SOLID,0, RGB(0,255,0) );
m_pPenY->CreatePen( PS_DOT,0, RGB(255,255,0) );
m_pPenW->CreatePen( PS_SOLID,0, RGB(128,128,128) );
m_pPenC->CreatePen( PS_SOLID,0, RGB(0,255,255) );
m_pPenB->CreatePen( PS_SOLID,0, RGB(0,0,255) );
}
CPlotData::~CPlotData()
{
m_pPenR->DeleteObject(); delete m_pPenR;
m_pPenG->DeleteObject(); delete m_pPenG;
m_pPenY->DeleteObject(); delete m_pPenY;
m_pPenW->DeleteObject(); delete m_pPenW;
m_pPenC->DeleteObject(); delete m_pPenC;
m_pPenB->DeleteObject(); delete m_pPenB;
if(m_pDispBuf)
{
delete m_pDispBuf;
m_pDispBuf = NULL;
}
if(m_TranslateTbl)
{
delete m_TranslateTbl;
m_TranslateTbl = NULL;
}
// Delete two ping pong bitmap buffers for waterfall display
if( m_bmWaterA.m_hObject != NULL ) // delete old bitmap object
m_bmWaterA.DeleteObject();
if( m_bmWaterB.m_hObject != NULL ) // delete old bitmap object
m_bmWaterB.DeleteObject();
}
//////////////////////////////////////////////////////////////////////
// Called from the Windows view class when the window has changed
// and needs to update the screen coordinates.
//////////////////////////////////////////////////////////////////////
void CPlotData::OnDrawPlot(HWND hWnd, CFormView* pView, CWinPSKDoc* pDoc)
{
CRect rScrn;
m_pDoc = pDoc;
m_hViewWnd = hWnd;
//calculate new plot area coordinates
// Get pixel size of plot area bitmap
ASSERT_VALID( pView );
CWnd* pWnd = pView->GetDlgItem( IDC_PLOTAREA );
ASSERT_VALID( pWnd);
pWnd->GetWindowRect( m_rPlot );
pView->GetWindowRect(rScrn);
m_rPlot.top -= (rScrn.top+1);
m_rPlot.left -= (rScrn.left+1);
m_rPlot.bottom = m_rPlot.top+m_rPlotsize.bottom;
m_rPlot.right = m_rPlot.left+m_rPlotsize.right;
// Create two ping pong bitmap buffers for waterfall display
if( m_bmWaterA.m_hObject != NULL ) // delete old bitmap object
m_bmWaterA.DeleteObject();
if( m_bmWaterB.m_hObject != NULL ) // delete old bitmap object
m_bmWaterB.DeleteObject();
//create a waterfall ping pong bitmap with current screen DC settings
CClientDC ClientDC(CWnd::FromHandle(m_hViewWnd) );
m_bmWaterA.CreateCompatibleBitmap( &ClientDC, m_rPlot.Width(), m_rPlotsize.bottom );
m_bmWaterB.CreateCompatibleBitmap( &ClientDC, m_rPlot.Width(), m_rPlotsize.bottom );
m_NeedToClrBufs = TRUE; // so waterfal buffers can get cleared
//
m_pDoc->m_FFTModeChange = TRUE;
}
//////////////////////////////////////////////////////////////////////
// Called to clear plot surface, draw cursor, and call specific plot
// routine.
//////////////////////////////////////////////////////////////////////
void CPlotData::DrawPlot()
{
// erases plot surface
// plots data points
INT i;
CDC MemDC;
CPen* pOldPen;
CClientDC ClientDC(CWnd::FromHandle(m_hViewWnd) );
m_InputOverload = FALSE;
if( m_bmPlot.m_hObject != NULL ) // delete old bitmap object
m_bmPlot.DeleteObject();
//create a new bitmap with current screen DC settings
m_bmPlot.CreateCompatibleBitmap( &ClientDC, m_rPlot.Width(),
m_rPlot.Height() );
//create memory DC pointer to the plot bitmap
MemDC.CreateCompatibleDC( &ClientDC );
CBitmap* pbmOld = MemDC.SelectObject( &m_bmPlot );
// set bitmap background to black using slightly faster ExtTextOut function
MemDC.SetBkColor( RGB(0, 0, 0) );
MemDC.ExtTextOut( 0, 0,ETO_OPAQUE, &m_rPlotsize,NULL,0,NULL);
pOldPen = MemDC.SelectObject(m_pPenY); //save original pen.
if( m_pDoc->m_FFTModeChange)
{
m_pDoc->m_FFTModeChange = FALSE;
if( m_pDoc->m_pSettings->m_fSlowAve)
m_FFTAveVal = 6;
else
m_FFTAveVal = 2;
if( m_pDoc->m_pSettings->m_TabSel == FFT_DISPVIEW)
fnSetFFTMode( m_FFTAveVal, m_rPlotsize.bottom, 1 );
else
fnSetFFTMode( m_FFTAveVal, 255, 20 );
}
// draw selected data plot
switch( m_pDoc->m_pSettings->m_TabSel )
{
case FFT_DISPVIEW:
// Draw vertical yellow dotted plot cursor line
MemDC.MoveTo( m_CursPos, 0);
MemDC.LineTo( m_CursPos, m_rPlotsize.bottom );
MemDC.SelectObject(m_pPenW);
for( i=10; i<100; i+=10 ) //draw 10dB tic marks
{
MemDC.MoveTo( 0, (m_rPlotsize.bottom*i)/100 );
MemDC.LineTo( m_rPlotsize.right, (m_rPlotsize.bottom*i)/100 );
}
if( ((CWinPSKView*)m_pDoc->m_pWinPSKView)->m_ProgramState == STATE_RX)
MemDC.SelectObject(m_pPenG);
else
MemDC.SelectObject(m_pPenC);
PlotFFTData( &MemDC );
MemDC.SelectObject(m_pPenW);
PlotOverlayVectData( &MemDC );
break;
case WATERFALL_DISPVIEW:
// Draw vertical yellow dotted plot cursor line
MemDC.MoveTo( m_CursPos, 0);
MemDC.LineTo( m_CursPos, m_rPlotsize.bottom );
if( ((CWinPSKView*)m_pDoc->m_pWinPSKView)->m_ProgramState == STATE_RX)
MemDC.SelectObject(m_pPenG);
else
MemDC.SelectObject(m_pPenC);
PlotFFTWater( &MemDC);
MemDC.SelectObject(m_pPenW);
PlotOverlayVectDataWaterfall( &MemDC );
break;
case INPUT_DISPVIEW:
MemDC.SelectObject(m_pPenW);
for( i=10; i<100; i+=10 ) //draw 10dB tic marks
{
MemDC.MoveTo( 0, (m_rPlotsize.bottom*i)/100 );
MemDC.LineTo( m_rPlotsize.right, (m_rPlotsize.bottom*i)/100 );
}
MemDC.SelectObject(m_pPenG);
PlotInputData( &MemDC );
break;
case SYNC_DISPVIEW:
PlotSyncData( &MemDC);
break;
default:
break;
}
if(m_InputOverload && m_LastOvrLoad) //need two in a row
{
MemDC.SetTextColor( RGB(255,0,0) );
MemDC.TextOut( m_rPlotsize.right/4, m_rPlotsize.bottom/8,
_T("Reduce Audio Level"), 18 );
}
m_LastOvrLoad = m_InputOverload;
if( m_pDoc->m_SoundCardReset)
{
MemDC.SetTextColor( RGB(255,0,0) );
MemDC.TextOut( m_rPlotsize.right/4, m_rPlotsize.bottom/8,
_T("CPU Too Slow"), 12 );
m_pDoc->m_SoundCardReset = FALSE;
}
// Copy memory bitmap into screen device context for flicker free update
ClientDC.BitBlt( m_rPlot.left, m_rPlot.top,
m_rPlotsize.right,
m_rPlotsize.bottom, &MemDC,
0,0,SRCCOPY);
MemDC.SelectObject(pOldPen); //deselect pens and bitmap
MemDC.SelectObject( pbmOld ); // from memory DC
}
//////////////////////////////////////////////////////////////////////
// Perform FFT and plot two dimensional results
//////////////////////////////////////////////////////////////////////
void CPlotData::PlotFFTData( CDC* pDC)
{
INT x,y,k1;
k1 = m_rPlotsize.bottom; //y range
m_InputOverload = fnGetFFTData( (long*)m_pDispBuf,
m_XMinPos,
m_XMaxPos );
pDC->MoveTo( 0, k1-m_pDispBuf[m_XMinPos]);//move to first position
for( x=m_XMinPos; x<m_XMaxPos; x++ ) //~11mSecs on 266PII
{
y = k1-m_pDispBuf[x];
pDC->LineTo( m_TranslateTbl[x], y ); //draw to the next pt.
}
}
//////////////////////////////////////////////////////////////////////
// Perform FFT and plot waterfall
//////////////////////////////////////////////////////////////////////
void CPlotData::PlotFFTWater( CDC* pDC)
{
INT i,x,y,k1,k2,k3,k4;
COLORREF cr;
CDC MemDCA; // memory DCs for the above bitmaps
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -