開発環境 Microsoft Visual C++ 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 Win32 プロジェクト
プロジェクト名 Fourier2
アプリケーションの種類 Windows アプリケーション
追加のオプション 空のプロジェクト
文字セット Unicode

Fourier2.cpp
#define _USE_MATH_DEFINES
 
#include <Windows.h>
#include <tchar.h>
#include <math.h>
 
#define APP_NAME TEXT("Fourier2")
#define SAMPLENUM 2048	// サンプル数
 
// 関数プロトタイプ宣言
void Trace(LPCTSTR format, ...);
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnCreate();
void OnPaint(HWND hWnd);
void DrawLine(HDC hdc, RECT rc, short* wf, COLORREF color);
 
// 外部変数
short wfs[SAMPLENUM];	// 波形:waveform source
short wfd[SAMPLENUM];	// 波形:waveform destination
 
//==============================================================================
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow)
{
	// ウィンドウクラスの登録
	WNDCLASSEX wcx;
	ZeroMemory(&wcx, sizeof wcx);
	wcx.cbSize		= sizeof wcx;
	wcx.style		= CS_HREDRAW | CS_VREDRAW;
	wcx.lpfnWndProc		= WndProc;
	wcx.hInstance		= hInstance;
	wcx.hCursor		= LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
	wcx.hbrBackground	= HBRUSH(COLOR_WINDOW + 1);
	wcx.lpszClassName	= APP_NAME;
	if (RegisterClassEx(&wcx) == 0) {
		return 0;
	}
 
	// ウィンドウの作成
	HWND hWnd = CreateWindow(
		APP_NAME, APP_NAME,
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0,
		CW_USEDEFAULT, 0,
		NULL, NULL, hInstance, NULL);
	if (hWnd == NULL) {
		return 0;
	}
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);
 
	// メッセージループ
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}
 
void Trace(LPCTSTR format, ...)
{
	va_list argptr;
	TCHAR buffer[256];
 
	va_start(argptr, format);
	int size = _vsntprintf_s(buffer, _TRUNCATE, format, argptr);
	va_end(argptr);
	OutputDebugString(buffer);
	if (size < 0) {
		OutputDebugString(_T("...\n"));
	}
}
 
//------------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg) {
	case WM_CREATE:
		OnCreate();
		return 0;
	case WM_PAINT:
		OnPaint(hWnd);
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
 
void OnCreate()
{
	double y[SAMPLENUM];
	Trace(L"OnCreate\n");
 
	// 波形の生成
	for (int n = 0; n < SAMPLENUM; n++) {
		wfs[n] = (n < (SAMPLENUM / 2)) ? 16384 : -16384;
//		wfs[n] = short(sin(2 * M_PI * n / SAMPLENUM) * 16384);
//		wfs[n] = (sin(n * 2 * M_PI * 172.265625 / 44100) > 0) ? 16384 : -16384;
//		wfs[n] = short(sin(n * 2 * M_PI * 172.265625 / 44100) * 16384);
	}
 
	// a0
	double sum = 0;
	for (int x = 0; x < SAMPLENUM; x++) {
		sum += wfs[x];
	}
	double a0 = sum * (2 * M_PI / SAMPLENUM) / (2 * M_PI);
	Trace(L"a0=%f\n", a0);
 
	for (int x = 0; x < SAMPLENUM; x++) {
		y[x] = a0;
	}
 
	// an, bn
	for (int n = 1; n <= 11; n++) {
		double an = 0;
		double bn = 0;
		for (int x = 0; x < SAMPLENUM; x++) {
			double t = (2.0 * x / SAMPLENUM - 1) * M_PI;
			an += wfs[x] * cos(n * t);
			bn += wfs[x] * sin(n * t);
		}
		an = an * (2 * M_PI / SAMPLENUM) / M_PI;
		bn = bn * (2 * M_PI / SAMPLENUM) / M_PI;
		Trace(L"n=%d an=%f bn=%f\n", n, an, bn);
 
		for (int x = 0; x < SAMPLENUM; x++) {
			double t = (2.0 * x / SAMPLENUM - 1) * M_PI;
			y[x] += an * cos(n * t) + bn * sin(n * t);
		}
	}
 
	// 合成波形
	for (int x = 0; x < SAMPLENUM; x++) {
		wfd[x] = short(y[x]);
//		Trace(L"y[%d]=%f\n", x, y[x]);
	}
}
 
void OnPaint(HWND hWnd)
{
	PAINTSTRUCT ps;
	HDC hdc = BeginPaint(hWnd, &ps);
	Trace(L"OnPaint(%d, %d, %d, %d)\n", ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom);
 
	RECT rc;
	GetClientRect(hWnd, &rc);
	DrawLine(hdc, rc, wfs, RGB(0, 0, 255));
	DrawLine(hdc, rc, wfd, RGB(255, 0, 0));
 
	EndPaint(hWnd, &ps);
}
 
void DrawLine(HDC hdc, RECT rc, short* wf, COLORREF color)
{
	HPEN pen = CreatePen(PS_SOLID, 0, color);
	HGDIOBJ penOld = SelectObject(hdc, pen);
 
	MoveToEx(hdc, 0, rc.bottom * (32768 - wf[0]) / 65536, NULL);
	for (int x = 1; x < SAMPLENUM; x++) {
		LineTo(hdc, rc.right * x / SAMPLENUM, rc.bottom * (32768 - wf[x]) / 65536);
	}
 
	SelectObject(hdc, penOld);
	DeleteObject(pen);
}
 
最終更新:2014年03月06日 11:17