開発環境 |
Microsoft Visual C++ 2010 Express (SP1) |
実行環境 |
Microsoft Windows XP Home Edition (SP3) |
プロジェクトの種類 |
Win32 プロジェクト |
プロジェクト名 |
WaveTestLR |
アプリケーションの種類 |
Windows アプリケーション |
追加のオプション |
空のプロジェクト |
WaveTestLR.cpp
#pragma comment(lib, "winmm")
#define _USE_MATH_DEFINES
#include <Windows.h>
#include <WindowsX.h>
#include <wchar.h>
#include <math.h>
#include "resource.h"
#define SAMPLING_RATE 44100
// 外部変数
HWAVEOUT hwo;
WAVEHDR wh;
BYTE waveformData[SAMPLING_RATE * 2];
// 関数プロトタイプ宣言
void Trace(LPCTSTR format, ...);
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnOK(HWND hDlg);
void OnWomOpen();
void OnWomDone(HWND hDlg);
void GenerateWaveform(HWND hDlg);
//==============================================================================
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG), NULL, DlgProc);
return 0;
}
void Trace(LPCTSTR format, ...)
{
va_list arg_ptr;
va_start(arg_ptr, format);
TCHAR buffer[256];
int size = _vsnwprintf_s(buffer, _TRUNCATE, format, arg_ptr);
va_end(arg_ptr);
OutputDebugString(buffer);
if (size < 0) {
OutputDebugString(L"...\n");
}
}
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
INT_PTR res = TRUE; // メッセージを処理した
switch (uMsg) {
case MM_WOM_OPEN:
OnWomOpen();
break;
case MM_WOM_DONE:
OnWomDone(hDlg);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_MODE:
GenerateWaveform(hDlg);
break;
case IDOK:
OnOK(hDlg);
break;
case IDCANCEL:
OnWomDone(hDlg);
break;
}
break;
case WM_INITDIALOG:
Button_SetCheck(GetDlgItem(hDlg, IDC_MODE), BST_CHECKED);
GenerateWaveform(hDlg);
break;
case WM_CLOSE:
EndDialog(hDlg, 0);
break;
default:
res = FALSE; // メッセージを処理しなかった
}
return res;
}
void OnOK(HWND hDlg)
{
WAVEFORMATEX wfx;
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.wBitsPerSample = 8;
wfx.nChannels = 2;
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) {
Trace(L"waveOutOpen\n");
return;
}
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
}
void OnWomOpen()
{
wh.lpData = (LPSTR)waveformData;
wh.dwBufferLength = sizeof waveformData;
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) {
Trace(L"waveOutPrepareHeader\n");
return;
}
wh.dwFlags |= WHDR_BEGINLOOP | WHDR_ENDLOOP;
wh.dwLoops = 60;
mmr = waveOutWrite(hwo, &wh, sizeof wh);
if (mmr != MMSYSERR_NOERROR) {
Trace(L"waveOutWrite\n");
return;
}
}
void OnWomDone(HWND hDlg)
{
Trace(L"OnWomDone\n");
waveOutReset(hwo);
waveOutUnprepareHeader(hwo, &wh, sizeof wh);
waveOutClose(hwo);
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
}
void GenerateWaveform(HWND hDlg)
{
int m = Button_GetCheck(GetDlgItem(hDlg, IDC_MODE));
int h = SAMPLING_RATE / 2;
for (int i = 0; i < SAMPLING_RATE; i++) {
double t, y;
// 低音
t = fmod(i * 441.0 / SAMPLING_RATE, 1.0);
y = sin(2 * M_PI * t);
if (h <= i) y = 0;
BYTE low = BYTE(128 + 16 * y);
// 高音
t = fmod(i * 882.0 / SAMPLING_RATE, 1.0);
y = sin(2 * M_PI * t);
if (i < h) y = 0;
BYTE high = BYTE(128 + 4 * y);
// Left
waveformData[i * 2 + 0] = (m == BST_CHECKED) ? low : high;
// Right
waveformData[i * 2 + 1] = (m == BST_CHECKED) ? high : low;
}
}
resource.h
#define IDD_DIALOG 100
#define IDC_MODE 1000
WaveTestLR.rc
// resource script
#include <Windows.h>
#include "resource.h"
IDD_DIALOG DIALOGEX 100, 100, 115, 45
STYLE WS_POPUPWINDOW | WS_MINIMIZEBOX
EXSTYLE WS_EX_APPWINDOW
CAPTION "WaveTestLR"
FONT 9, "MS Pゴシック"
BEGIN
AUTOCHECKBOX "L:低音 R:高音",IDC_MODE,5,5,100,15
PUSHBUTTON "Play(&P)",IDOK,5,25,50,15
PUSHBUTTON "Stop(&S)",IDCANCEL,60,25,50,15
END
最終更新:2013年05月15日 09:27