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

📄 lawavecapture.cpp

📁 Lakey这是一个免费的CW练习/收/发软件
💻 CPP
字号:
#include "StdAfx.h"
#include "lawavecapture.h"

CLaWaveCapture::CLaWaveCapture(IPaintableParent* pParent, const RECT* pRect, int nSamplePerSec, int nAnalyzeSamples, ICwEventListener* pCwEventListener/* = NULL */)
{
	m_pFont = new CFont("Arial", 8, CFont::THIN);
	m_pParent = pParent;
	m_oRect = *pRect;
	SetRect(&m_oPaintRect, 0, 0, m_oRect.right - m_oRect.left, m_oRect.bottom - m_oRect.top - 9);
	SetRect(&m_oRulerRect, 0, m_oRect.bottom - m_oRect.top - 9, m_oRect.right - m_oRect.left, m_oRect.bottom - m_oRect.top);

	m_pPaintBoard = pParent->NewGraphics(pRect->right - pRect->left, pRect->bottom - pRect->top);
	m_pPaintBoard->DrawRect(&m_oRulerRect);

	m_pCwEventListener = pCwEventListener;

	m_pDsCap = NULL;
	m_pDsCapBuff = NULL;

	memset(&m_oFormat, 0, sizeof(m_oFormat)); 
	m_oFormat.wFormatTag = WAVE_FORMAT_PCM;
	m_oFormat.nChannels = 1;
	m_oFormat.nSamplesPerSec = nSamplePerSec;
	m_oFormat.wBitsPerSample = 16;
	m_oFormat.nAvgBytesPerSec = m_oFormat.nSamplesPerSec * (m_oFormat.wBitsPerSample / 8) * m_oFormat.nChannels;
	m_oFormat.nBlockAlign = m_oFormat.wBitsPerSample / 8 * m_oFormat.nChannels;
	m_oFormat.cbSize = 0;

	memset(&m_oCaptureBufferDesc, 0, sizeof(m_oCaptureBufferDesc));
	m_oCaptureBufferDesc.dwSize = sizeof(m_oCaptureBufferDesc);
	m_oCaptureBufferDesc.dwFlags = 0;
	m_oCaptureBufferDesc.dwBufferBytes = m_oFormat.nAvgBytesPerSec;
	m_oCaptureBufferDesc.lpwfxFormat = &m_oFormat;
	m_oCaptureBufferDesc.dwFXCount = 0;
	m_oCaptureBufferDesc.lpDSCFXDesc = NULL;

	m_nAnalyzeSamples = nAnalyzeSamples;
	m_pWavBuff = new short int[m_nAnalyzeSamples * 2];
	m_pDctBuff = new short int[m_nAnalyzeSamples];
	m_pFreqRuler = new short int[m_nAnalyzeSamples];

	DrawRuler();

	m_nRecvThreshold = (short int)(32768 * 0.5l);
	m_nRecvFreqStart = 850;
	m_nRecvFreqEnd = 1250;
	m_bState = FALSE;

	m_pFft = new TCosFFT<short int>(m_nAnalyzeSamples);
}

CLaWaveCapture::~CLaWaveCapture(void)
{
	delete m_pFont;
	delete m_pPaintBoard;

	if (NULL != m_pDsCap)
	{
		if (NULL != m_pDsCapBuff)
		{
			m_pDsCapBuff->Release();
			m_pDsCapBuff = NULL;
		}

		m_pDsCap->Release();
		m_pDsCap = NULL;
	}

	delete[] m_pWavBuff;
	delete[] m_pDctBuff;
	delete[] m_pFreqRuler;
}

void CLaWaveCapture::SetThresholdLevel(double rThresholdLevel)
{
	m_nRecvThreshold = (short int)(32768 * rThresholdLevel);
}

void CLaWaveCapture::SetFreqRange(int nLowFreq, int nHighFreq)
{
	m_nRecvFreqStart = nLowFreq;
	m_nRecvFreqEnd = nHighFreq;
}

void CLaWaveCapture::DrawRuler()
{
	double rTotalLogNum = log10(15000.0l) - 2;
	int nGradCount = m_oRulerRect.right - m_oRulerRect.left;
	for (int i = 0; i < nGradCount; ++i)
	{
		m_pFreqRuler[i] = (short int)pow(10, 2 + (i * rTotalLogNum / nGradCount));
	}

	m_pPaintBoard->SetColor(RGB(192,192,192));
	m_pPaintBoard->DrawLine(m_oRulerRect.left, m_oRulerRect.top, m_oRulerRect.right, m_oRulerRect.top);
	m_pPaintBoard->SetFont(m_pFont);
	double d = nGradCount / rTotalLogNum;
	RECT r = m_oRulerRect;
	r.top += 1;
	for (int i = 0; i < rTotalLogNum; ++i)
	{
		char grad[8];
		r.left = (int)(d * i);

		if (0 == i)
			sprintf(grad, "%.0lfHz", pow(10.0, i + 2));
		else if (3 > i + 2)
			sprintf(grad, "%.0lf", pow(10.0, i + 2));
		else
			sprintf(grad, "%.0lfK", pow(10.0, i + 2) / 1000);

		m_pPaintBoard->SetColor(RGB(192, 192, 192));
		m_pPaintBoard->DrawText(&r, grad, DT_LEFT);
		m_pPaintBoard->SetColor(RGB(224, 224, 224));
		m_pPaintBoard->DrawLine(r.left, 0 == i ? 0 : m_oRulerRect.top, r.left, m_oRulerRect.bottom - 1);

		if (4 > i)
		{
			for (int j = 2; j < 6; ++j)
			{
				r.left = (int)(d * (i + log10((double)j)));

				sprintf(grad, "%d", j);

				m_pPaintBoard->SetColor(RGB(192, 192, 192));
				m_pPaintBoard->DrawText(&r, grad, DT_LEFT);
				m_pPaintBoard->SetColor(RGB(224, 224, 224));
				m_pPaintBoard->DrawLine(r.left, m_oRulerRect.top, r.left, m_oRulerRect.bottom - 5);
			}
		}
	}
}

BOOL CLaWaveCapture::Initialize()
{
	if (FAILED(DirectSoundCaptureCreate8(NULL, &m_pDsCap, NULL)))
		return FALSE;

	if (FAILED(m_pDsCap->CreateCaptureBuffer(&m_oCaptureBufferDesc, &m_pDsCapBuff, NULL)))
		return FALSE;

	return FAILED(m_pDsCapBuff->Start(DSCBSTART_LOOPING));
}

BOOL CLaWaveCapture::IsRelated(int x, int y)
{
	return IControl::PointInRect(&m_oRect, x, y);
}

void CLaWaveCapture::GetRect(RECT* r)
{
	*r = m_oRect;
}

void CLaWaveCapture::OnPaint(void* owner, CGraphics* g, const RECT* pRect)
{
	int w = m_oRect.right - m_oRect.left;
	int h = m_oRect.bottom - m_oRect.top;

	RECT r;
	r.top = 0; r.bottom = h;
	r.left = 0; r.right = w;
	g->Copy(&r, m_pPaintBoard, 0, 0);
}

BOOL CLaWaveCapture::Refresh()
{
	DWORD nStatus = 0;
	m_pDsCapBuff->GetStatus(&nStatus);
	if ((DSCBSTATUS_CAPTURING & nStatus) && (DSCBSTATUS_LOOPING & nStatus))
	{
		DWORD nReadPosEnd;
		DWORD nCapturePos;
		if (FAILED(m_pDsCapBuff->GetCurrentPosition(&nCapturePos, &nReadPosEnd)))
			return FALSE;

		int nReadPosStart = nReadPosEnd - m_nAnalyzeSamples * sizeof(short int) * 2;
		if (0 > nReadPosStart)
			nReadPosStart += m_oCaptureBufferDesc.dwBufferBytes;

		short int *pHeadPortion, *pTailPortion;
		DWORD nHpBytes, nTpBytes;
		if (FAILED(m_pDsCapBuff->Lock(nReadPosStart, m_nAnalyzeSamples * sizeof(short int) * 2, (LPVOID *)&pHeadPortion, &nHpBytes, (LPVOID *)&pTailPortion, &nTpBytes, 0)))
			return FALSE;

		DWORD i;
		for (i = 0; i < nHpBytes / sizeof(short int); ++i)
		{
			m_pWavBuff[i] = pHeadPortion[i];
		}

		for (; i < m_nAnalyzeSamples * 2; ++i)
		{
			m_pWavBuff[i] = pTailPortion[i];
		}

		m_pDsCapBuff->Unlock(pHeadPortion, nHpBytes, pTailPortion, nTpBytes);

		//synchronize the wave
		int nStep = 1;
		DWORD nSyncStart;
		for (nSyncStart = 0; nSyncStart < m_nAnalyzeSamples && 0 < nStep; ++nSyncStart)
		{
			switch(nStep)
			{
				case 1:
					if (m_pWavBuff[nSyncStart] < m_pWavBuff[nSyncStart + 1])
						nStep = 2;
					break;
				case 2:
					if (m_pWavBuff[nSyncStart] >= 0 && m_pWavBuff[nSyncStart] > m_pWavBuff[nSyncStart + 1])
						nStep = 0;
				/* for sin wave
				case 1: // look for negative
					if (m_vWavBuff[nSyncStart] < 0)
						nStep = 2;
					break;
				case 2: // through the X axis
					if (m_vWavBuff[nSyncStart] >= 0)
						nStep = 0;
					break;
				*/
			}
		}

		m_pPaintBoard->SetColor(RGB(255, 255, 255));
		m_oPaintRect.left += 1;
		m_pPaintBoard->DrawRect(&m_oPaintRect);
		m_oPaintRect.left -= 1;

		m_pPaintBoard->SetColor(RGB(192, 192, 192));
		short int* pSyncWavBuff = m_pWavBuff + nSyncStart;
		int last = m_oPaintRect.bottom / 2 - pSyncWavBuff[0] * m_oPaintRect.bottom / 65536;
		for (i = 1; i < m_nAnalyzeSamples && i < (DWORD)(m_oPaintRect.right - m_oPaintRect.left); ++i)
		{
			int curr = m_oPaintRect.bottom / 2 - pSyncWavBuff[i] * m_oPaintRect.bottom / 65536;
			m_pPaintBoard->DrawLine(i - 1, last, i, curr);
			last = curr;
		}

		//FFT
		m_pFft->Compute(m_pDctBuff, pSyncWavBuff);

		m_pPaintBoard->SetColor(RGB(0, 0, 0));
		int l = 0;
		BOOL bState = FALSE;
		int nGridCount = m_oRulerRect.right - m_oRulerRect.left;
		for (i = 0; i < m_nAnalyzeSamples; ++i)
		{
			short int nFreq = (short int)((i) * (m_oFormat.nSamplesPerSec / 2 / m_nAnalyzeSamples));
			for (; l < nGridCount; ++l)
			{
				if (m_pFreqRuler[l] >= nFreq)
				{
					m_pPaintBoard->DrawLine(l, m_oPaintRect.bottom - abs(m_pDctBuff[i]) * m_oPaintRect.bottom / 32768, l, m_oPaintRect.bottom);
					break;
				}
			}

			if (!bState && m_nRecvThreshold <= abs(m_pDctBuff[i]))
				if (m_nRecvFreqStart <= nFreq && nFreq <= m_nRecvFreqEnd)
					bState = TRUE;
		}

		RECT r = m_oPaintRect;
		OffsetRect(&r, m_oRect.left, m_oRect.top);
		m_pParent->Invalidate(&r);

		if (NULL != m_pCwEventListener)
			m_pCwEventListener->OnCwEvent(bState);

		return TRUE;
	}

	return FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -