Click here to Skip to main content
15,893,668 members
Articles / Desktop Programming / MFC

Play Wave file with DirectSound and display its spectrum in real time

Rate me:
Please Sign up or sign in to vote.
3.44/5 (8 votes)
15 Sep 2008CPOL2 min read 144.8K   8.4K   58  
An article to show how to play a Wave file with DirectSound and display its spectrum in real time.
// DirectSound.cpp : ����Ӧ�ó������ڵ㡣
//

#include "stdafx.h"
#include "DirectSound.h"

#define MAX_LOADSTRING 100

// ȫ�ֱ���:
HINSTANCE hInst;								// ��ǰʵ��
HWND hWndMain;									// ��ǰ���ھ��
TCHAR szTitle[MAX_LOADSTRING];					// �������ı�
TCHAR szWindowClass[MAX_LOADSTRING];			// ����������
extern TCHAR szDisplaySamples[32];
extern FLOAT floatMag[FFT_SAMPLE_SIZE/2];
extern PLAY_MOD* gp_playmod;

// �˴���ģ���а����ĺ�����ǰ������:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
					   HINSTANCE hPrevInstance,
					   LPTSTR    lpCmdLine,
					   int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	// TODO: �ڴ˷��ô��롣
	MSG msg;
	HACCEL hAccelTable;

	// ��ʼ��ȫ���ַ���
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_DIRECTSOUND, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// ִ��Ӧ�ó����ʼ��:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_DIRECTSOUND));

	//open select file dialog
	TCHAR fileName[MAX_PATH];
	OPENFILENAME ofn;
	memset(&ofn, 0, sizeof(OPENFILENAME));
	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = hWndMain;
	ofn.lpstrFile = fileName;
	ofn.lpstrFile[0] = '\0';
	ofn.nMaxFile = MAX_PATH;
	ofn.lpstrFilter = _T("WAVE File(*.wav)\0*.wav\0");
	ofn.nFilterIndex = 1;
	ofn.lpstrFileTitle = NULL;
	ofn.nMaxFileTitle = 0;
	ofn.lpstrInitialDir = NULL;
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

	if (GetOpenFileName(&ofn) == TRUE)
	{
		// create play thread
		PLAY_MOD playmod;
		memset(&playmod, 0, sizeof(PLAY_MOD));
		gp_playmod = &playmod;

		playmod.hInst = hInst;
		playmod.hWndMain = hWndMain;
		playmod.iStatus = PLAY_STATUS_OPEN;
		playmod.lptstrFileName = ofn.lpstrFile;

		WAVEFORMATEX wfx;
		CWaveFile wavfile;
		wavfile.Open(playmod.lptstrFileName, &wfx, WAVEFILE_READ);
		wfx = *wavfile.GetFormat();

		DWORD dwTotalSamples = wavfile.GetSize()/wfx.nBlockAlign;
		playmod.dwTotalSamples = dwTotalSamples;
		playmod.pWaveFile = &wavfile;
		playmod.pWFX = &wfx;

		CMyDirectSound myDS;
		playmod.pMyDS = &myDS;

		FFT fft(FFT_SAMPLE_SIZE);
		playmod.fft = &fft;
		playmod.pFFTData = floatMag;

		myDS.SetFormat(wfx);
		myDS.SetCallback(GetSamples, (void*)&playmod);
		myDS.Play();

		wsprintf(szTitle, _T("DirectSound - %s [Playing]"), ofn.lpstrFile);
		SendMessage(hWndMain, WM_SETTEXT, (WPARAM)0, (LPARAM)szTitle);

		playmod.mmTimerID = 0;
		playmod.mmTimerID = timeSetEvent(70, 0, TimerProc, (DWORD)&playmod, TIME_PERIODIC);

		//DWORD dwThreadId = 0;
		//HANDLE hThread = 0;
		//hThread = CreateThread(NULL, 0, FFTThreadProc, (void*)&playmod, 0, &dwThreadId);

		//UINT_PTR uTimer = 0;
		//uTimer = SetTimer(hWndMain, IDT_TIMER, 5, (TIMERPROC)WindowTimerProc);

		// ����Ϣѭ��:
		while (GetMessage(&msg, NULL, 0, 0))
		{
			if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}

		if(playmod.mmTimerID != 0)
		{
			timeKillEvent(playmod.mmTimerID);
			playmod.mmTimerID = 0;
		}

		//if(hThread != 0)
		//{
		//	CloseHandle(hThread);
		//	hThread = 0;
		//}

		//if(uTimer != 0)
		//{
		//	KillTimer(hWndMain, uTimer);
		//	uTimer = 0;
		//}

		myDS.Stop();
		wavfile.Close();

		return (int) msg.wParam;
	}
	
	return 0;
}

//
//  ����: MyRegisterClass()
//
//  Ŀ��: ע�ᴰ���ࡣ
//
//  ע��:
//
//    ����ϣ��
//    �˴�������ӵ� Windows 95 �еġ�RegisterClassEx��
//    ����֮ǰ�� Win32 ϵͳ����ʱ������Ҫ�˺��������÷������ô˺���ʮ����Ҫ��
//    ����Ӧ�ó���Ϳ��Ի�ù�����
//    ����ʽ��ȷ�ġ�Сͼ�ꡣ
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DIRECTSOUND));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= NULL; // MAKEINTRESOURCE(IDC_DIRECTSOUND);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
//   ����: InitInstance(HINSTANCE, int)
//
//   Ŀ��: ����ʵ�����������������
//
//   ע��:
//
//        �ڴ˺����У�������ȫ�ֱ����б���ʵ�������
//        ��������ʾ�����򴰿ڡ�
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // ��ʵ������洢��ȫ�ֱ�����

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, 520, 177, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   hWndMain = hWnd;
   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  ����: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  Ŀ��: ���������ڵ���Ϣ��
//
//  WM_COMMAND	- ����Ӧ�ó���˵�
//  WM_PAINT	- ����������
//  WM_DESTROY	- �����˳���Ϣ������
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// �����˵�ѡ��:
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: �ڴ���������ͼ����...
		if(lParam == 13)
			DrawSpectrum(hWnd, floatMag);
		EndPaint(hWnd, &ps);
		break;
	case WM_PAINT+913:
		{
			//HDC xx = GetWindowDC(hWnd);
			//TextOut(xx, 150, 250, szDisplaySamples, lParam);
			//ReleaseDC(hWnd, xx);
			if(lParam == 13)
				DrawSpectrum(hWnd, floatMag);
		}
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

// �����ڡ������Ϣ�������
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer none
China China
To be, or not to be, this is question. That's are all depend on your decision. What do you think?

Comments and Discussions