開発環境 |
Microsoft Visual C++ 2010 Express (SP1) |
実行環境 |
Microsoft Windows XP Home Edition (SP3) |
プロジェクトの種類 |
Win32 プロジェクト |
プロジェクト名 |
WaveTest2 |
アプリケーションの種類 |
Windows アプリケーション |
追加のオプション |
空のプロジェクト |
WaveTest2.cpp
// WaveTest2 周波数
#pragma comment(lib, "winmm")
#define _USE_MATH_DEFINES
#include <Windows.h>
#include <math.h>
#include "resource.h"
#define SAMPLING_RATE 44100
#define DATA_NUM SAMPLING_RATE
// 関数プロトタイプ宣言
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnInitDialog(HWND hDlg);
void OnDrawItem(WPARAM wParam, LPARAM lParam);
void OnOK(HWND hDlg);
void OnWomOpen(void);
void OnWomDone(HWND hDlg);
// 外部変数
HWAVEOUT hwo;
WAVEHDR wh;
BYTE waveformData[DATA_NUM];
//==============================================================================
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG), NULL, DlgProc);
return 0;
}
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
INT_PTR result = TRUE; // メッセージを処理した
switch (uMsg) {
case MM_WOM_OPEN:
OnWomOpen();
break;
case MM_WOM_DONE:
OnWomDone(hDlg);
break;
case WM_DRAWITEM:
OnDrawItem(wParam, lParam);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
OnOK(hDlg);
break;
case IDCANCEL:
EndDialog(hDlg, IDCANCEL);
break;
}
break;
case WM_INITDIALOG:
OnInitDialog(hDlg);
break;
case WM_CLOSE:
EndDialog(hDlg, 0);
break;
default:
result = FALSE; // メッセージを処理しなかった
}
return result;
}
void OnInitDialog(HWND hDlg)
{
for (int i = 0; i < DATA_NUM; i++) {
waveformData[i] = 128;
}
}
void OnDrawItem(WPARAM wParam, LPARAM lParam)
{
LPDRAWITEMSTRUCT pdi = (LPDRAWITEMSTRUCT)lParam;
HDC hdc = pdi->hDC;
RECT rc;
GetClientRect(pdi->hwndItem, &rc);
FillRect(hdc, &rc, GetSysColorBrush(COLOR_WINDOW));
HPEN pen = CreatePen(PS_SOLID, 0, RGB(0,0,255));
HGDIOBJ penOld = SelectObject(hdc, pen);
for (int i = 0; i < rc.right; i++) {
MoveToEx(hdc, i, rc.bottom / 2, NULL);
LineTo(hdc, i, rc.bottom * (255 - waveformData[i]) / 256);
}
SelectObject(hdc, penOld);
DeleteObject(pen);
}
void OnOK(HWND hDlg)
{
double freq = GetDlgItemInt(hDlg, IDC_FREQ, NULL, FALSE);
for (int i = 0; i < DATA_NUM; i++) {
double t = fmod(freq * i / SAMPLING_RATE, 1);
double y = sin(2 * M_PI * t);
waveformData[i] = BYTE(128 + 64 * y);
}
InvalidateRect(GetDlgItem(hDlg, IDC_PREVIEW), NULL, FALSE);
WAVEFORMATEX wfx;
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.wBitsPerSample = 8;
wfx.nChannels = 1;
wfx.nSamplesPerSec = SAMPLING_RATE;
wfx.nBlockAlign = (wfx.wBitsPerSample / 8) * wfx.nChannels;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
wfx.cbSize = 0;
MMRESULT mmr = waveOutOpen(&hwo, WAVE_MAPPER, &wfx, (DWORD_PTR)hDlg, 0, CALLBACK_WINDOW);
if (mmr != MMSYSERR_NOERROR) {
return;
}
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
}
void OnWomOpen(void)
{
wh.lpData = (LPSTR)waveformData;
wh.dwBufferLength = DATA_NUM;
wh.dwBytesRecorded = 0;
wh.dwUser = 0;
wh.dwFlags = 0;
wh.dwLoops = 0;
wh.lpNext = NULL;
wh.reserved = 0;
MMRESULT mmr = waveOutPrepareHeader(hwo, &wh, sizeof wh);
if (mmr != MMSYSERR_NOERROR) {
return;
}
wh.dwFlags |= WHDR_BEGINLOOP | WHDR_ENDLOOP;
wh.dwLoops = 1;
mmr = waveOutWrite(hwo, &wh, sizeof wh);
}
void OnWomDone(HWND hDlg)
{
waveOutReset(hwo);
waveOutUnprepareHeader(hwo, &wh, sizeof wh);
waveOutClose(hwo);
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
}
resource.h
#define IDD_DIALOG 100
#define IDC_STATIC -1
#define IDC_PREVIEW 1000
#define IDC_FREQ 1001
WaveTest2.rc
// resource script
#include <windows.h>
#include "resource.h"
IDD_DIALOG DIALOGEX 100, 100, 320, 200
STYLE WS_POPUPWINDOW | WS_MINIMIZEBOX
EXSTYLE WS_EX_APPWINDOW
CAPTION "WaveText2"
FONT 9, "MS Pゴシック"
BEGIN
LTEXT "",IDC_PREVIEW,10,10,300,150,WS_BORDER | SS_OWNERDRAW
LTEXT "周波数(&F)",IDC_STATIC,10,170,50,12
EDITTEXT IDC_FREQ,60,170,50,12
LTEXT "Hz",IDC_STATIC,120,170,20,12
DEFPUSHBUTTON "Play(&P)",IDOK,260,170,50,15
END
最終更新:2013年03月04日 09:33