⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plotdata.cpp

📁 PSK31方式通信C++编写的原代码,可以通过声音传递数据.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -