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

📄 soundview.cpp

📁 本光盘包含的是《实用Visual C++ 6.0教程》一书中所有程序的代码
💻 CPP
字号:
// SoundView.cpp : implementation of the CSoundView class
//

#include "stdafx.h"
#include "Sound.h"

#include "SoundDoc.h"
#include "SoundView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CSoundView

IMPLEMENT_DYNCREATE(CSoundView, CView)

BEGIN_MESSAGE_MAP(CSoundView, CView)
	//{{AFX_MSG_MAP(CSoundView)
	ON_WM_KEYDOWN()
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSoundView construction/destruction

CSoundView::CSoundView()
{
	m_pDSObject=NULL;
	m_pDSBuffer=NULL;
	m_pDSMix=NULL;
}

CSoundView::~CSoundView()
{
	if (m_pDSMix) m_pDSMix->Release();
	if (m_pDSBuffer) m_pDSBuffer->Release();
	if (m_pDSObject) m_pDSObject->Release();
}

void CSoundView::PlayFreq(double dFreq)
{
	if (!m_pDSObject)
	{
		//Create the Direct Sound Object
		if (DS_OK==DirectSoundCreate(
							NULL,&m_pDSObject,NULL))
		{
			//Set the Co-Operation level
			m_pDSObject->SetCooperativeLevel(m_hWnd,DSSCL_NORMAL);


			//Set the direct sound buffer
			memset(&m_DSBufferDesc,0,sizeof(DSBUFFERDESC));

			//Setup a secondary buffer
			m_DSBufferDesc.dwSize=sizeof(DSBUFFERDESC);
			m_DSBufferDesc.dwFlags=DSBCAPS_CTRLDEFAULT;
			m_DSBufferDesc.dwBufferBytes=4096;

			//Set a wave format for 22.0Khz,1 byte DtoA
			static WAVEFORMATEX sWave={
				WAVE_FORMAT_PCM,1,22000,22000,1,8,0};

			m_DSBufferDesc.lpwfxFormat=&sWave;

			//Create the First Secondary buffer
			m_pDSObject->CreateSoundBuffer(&m_DSBufferDesc,
										&m_pDSBuffer,NULL);

			//Create the Second Secondary buffer
			m_pDSObject->CreateSoundBuffer(&m_DSBufferDesc,
										&m_pDSMix,NULL);
		}
	}

	//if the DirectSound object is valid...
	if (m_pDSObject)
	{
		//Declare buffer pointers
		LPBYTE pBuffer1,pBuffer2;
		LPBYTE pEnv1,pEnv2;
		DWORD dwSize1,dwSize2;

		//Erase the background
		CClientDC dcClient(this);
		CRect rcClient;
		GetClientRect(&rcClient);
		int yOff=(rcClient.Height()-24)/3;
		dcClient.FillSolidRect(
			rcClient,RGB(255,255,255));

		//Lock the sound buffer
		m_pDSBuffer->Lock(0,m_DSBufferDesc.dwBufferBytes,
			(LPVOID*) &pBuffer1,&dwSize1,
			(LPVOID*) &pBuffer2,&dwSize2,0);
		m_pDSMix->Lock(0,m_DSBufferDesc.dwBufferBytes,
			(LPVOID*) &pEnv1,&dwSize1,
			(LPVOID*) &pEnv2,&dwSize2,0);

		//Set the two buffers
		double dRange=128.0/(double)dwSize1;
		double dXRange=(double)rcClient.Width()
						/(double) dwSize1;
		for (int i=0;i<(int) dwSize1;i++)
		{
			double dAmplitude=1.0+dRange*(double)i;
			BYTE b1=(BYTE)(127+(128.0-dAmplitude)
							*sin((double)i/(0.147*dFreq)));
			BYTE b2=(BYTE)(rand()%(int)dAmplitude)>>1;
			*(pBuffer1+i)=b1;
			*(pEnv1+i)=b2;

			BYTE b3=b1+b2;

			//Draw the waveform
			int x=(int)(dXRange*(double)i);
			dcClient.SetPixelV(x,
				(b1>>1),RGB(255,0,0));
			dcClient.SetPixelV(x,yOff+64+
				(b2>>1),RGB(0,255,0));
			dcClient.SetPixelV(x,yOff*2+
				(b3>>1),RGB(0,0,255));
		}

		//Unlock the buffers and play the sound
		m_pDSBuffer->Unlock(pBuffer1,dwSize1,
						pBuffer2,dwSize2);
		m_pDSMix->Unlock(pEnv1,dwSize1,
						pEnv2,dwSize2);
		m_pDSBuffer->Play(0,0,0);
		m_pDSMix->Play(0,0,0);
	}
}

void CSoundView::OnKeyDown(UINT nChar, UINT nRepCnt,
										UINT nFlags) 
{
	CView::OnKeyDown(nChar, nRepCnt, nFlags);

	//Play the note with a freqency of the key value
	if (nRepCnt==1) PlayFreq((double) nChar);
}

BOOL CSoundView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CSoundView drawing

void CSoundView::OnDraw(CDC* pDC)
{
	CSoundDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
}

/////////////////////////////////////////////////////////////////////////////
// CSoundView printing

BOOL CSoundView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CSoundView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CSoundView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CSoundView diagnostics

#ifdef _DEBUG
void CSoundView::AssertValid() const
{
	CView::AssertValid();
}

void CSoundView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CSoundDoc* CSoundView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSoundDoc)));
	return (CSoundDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CSoundView message handlers


⌨️ 快捷键说明

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