SoundPlayer2
Visual C++ 2005 Express Edition
Windows Server 2003 SP1 Platform SDK
Windowsアプリケーション / 空のプロジェクト
SoundPlayer2.c
// マルチバイト文字セット // winmm.lib #define _USE_MATH_DEFINES #include
#include
#include
#include
#include
#define APPNAME "SoundPlayer" #define SAMPLING_RATE 44100 #define DATANUM (SAMPLING_RATE * 2) #define IDC_BTN_START 1 #define IDC_BTN_STOP 2 #define IDC_EDT_LOOPS 3 #define IDC_TRB_VOLUME_L 4 #define IDC_LBL_VOLUME_L 5 #define IDC_TRB_VOLUME_R 6 #define IDC_LBL_VOLUME_R 7 // グローバル変数 static HINSTANCE g_hInstance; static char g_acIniFile[_MAX_PATH]; static HWND g_hBtnStart; static HWND g_hEdtFreq; static HWND g_hTrbVolumeL; static HWND g_hLblVolumeL; static HWND g_hTrbVolumeR; static HWND g_hLblVolumeR; static double g_dFreq; static int g_iVolumeL; static int g_iVolumeR; static HWAVEOUT g_hwo = NULL; static WAVEHDR g_wh; static short g_asWaveformData[DATANUM]; // プロトタイプ宣言 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void OnWomOpen(); void OnWomDone(); void OnBtnStart(HWND hWnd); void OnHScroll(LPARAM lParam); void OnCreate(HWND hWnd); void OnDestroy(HWND hWnd); void PlayStop(); void Trace(const char *pcFormat, ...); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char acAppName[] = APPNAME; WNDCLASSEX wcex; HWND hWnd; MSG msg; char acDrive[_MAX_DRIVE]; char acDir[_MAX_DIR]; char acFname[_MAX_FNAME]; char acExt[_MAX_EXT]; int iX; int iY; g_hInstance = hInstance; _splitpath_s(__argv[0], acDrive, _MAX_DRIVE, acDir, _MAX_DIR, acFname, _MAX_FNAME, acExt, _MAX_EXT); _makepath_s(g_acIniFile, _MAX_PATH, acDrive, acDir, acFname, ".ini"); iX = GetPrivateProfileInt("General", "iX", 0, g_acIniFile); iY = GetPrivateProfileInt("General", "iY", 0, g_acIniFile); g_dFreq = GetPrivateProfileInt("General", "dFreq", 440, g_acIniFile); g_iVolumeL = GetPrivateProfileInt("General", "iVolumeL", 0, g_acIniFile); g_iVolumeR = GetPrivateProfileInt("General", "iVolumeR", 0, g_acIniFile); wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = 0; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = g_hInstance; wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); wcex.lpszMenuName = NULL; wcex.lpszClassName = acAppName; wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx(&wcex); hWnd = CreateWindow( acAppName, // ClassName acAppName, // WindowName WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX, iX, // x iY, // y 320, // Width 152, // Height NULL, // WndParent NULL, // Menu g_hInstance, NULL); // Param if (hWnd == NULL) { return 0; } ShowWindow(hWnd, nCmdShow); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case MM_WOM_OPEN: OnWomOpen(); break; case MM_WOM_DONE: OnWomDone(); break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_BTN_START: // 再生ボタン OnBtnStart(hWnd); break; case IDC_BTN_STOP: // 停止ボタン PlayStop(); break; } break; case WM_HSCROLL: OnHScroll(lParam); break; case WM_CREATE: OnCreate(hWnd); break; case WM_DESTROY: OnDestroy(hWnd); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } return 0; } void OnWomOpen() { MMRESULT mmr; int i; Trace("OnWomOpen\n"); g_wh.lpData = (LPSTR)g_asWaveformData; // 必須 g_wh.dwBufferLength = DATANUM; // 必須 g_wh.dwBytesRecorded = 0; g_wh.dwUser = 0; g_wh.dwFlags = 0; // 必ず0 g_wh.dwLoops = 0; g_wh.lpNext = NULL; g_wh.reserved = 0; mmr = waveOutPrepareHeader(g_hwo, &g_wh, sizeof(WAVEHDR)); if (mmr != MMSYSERR_NOERROR) { Trace("waveOutPrepareHeader\n"); return; } Trace("g_wh.dwFlags=%.8X\n", g_wh.dwFlags); for (i = 0; i < DATANUM; i += 2) { g_asWaveformData[i] = (short)(g_iVolumeL * sin(i * 2.0 * M_PI * g_dFreq / SAMPLING_RATE)); g_asWaveformData[i + 1] = (short)(128 + g_iVolumeR * sin(i * 2.0 * M_PI * g_dFreq / SAMPLING_RATE)); } g_wh.dwFlags |= WHDR_BEGINLOOP | WHDR_ENDLOOP; g_wh.dwLoops = 1; mmr = waveOutWrite(g_hwo, &g_wh, sizeof(WAVEHDR)); if (mmr != MMSYSERR_NOERROR) { Trace("waveOutWrite\n"); return; } EnableWindow(g_hBtnStart, FALSE); } void OnWomDone() { Trace("OnWomDone\n"); PlayStop(); } void OnBtnStart(HWND hWnd) { WAVEFORMATEX wfx; MMRESULT mmr; char acBuf[16]; double dFreq; int iRet; Trace("OnStart\n"); iRet = GetWindowText(g_hEdtFreq, acBuf, sizeof(acBuf)); iRet = sscanf_s(acBuf, "%lf", &dFreq); if (iRet != 1 || dFreq < 0.0) { MessageBox(hWnd, "Freq", NULL, MB_OK); return; } g_dFreq = dFreq; wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.wBitsPerSample = 16; wfx.nChannels = 2; wfx.nSamplesPerSec = SAMPLING_RATE; wfx.nBlockAlign = (wfx.wBitsPerSample / 8) * wfx.nChannels; wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; wfx.cbSize = 0; mmr = waveOutOpen(&g_hwo, WAVE_MAPPER, &wfx, (DWORD_PTR)hWnd, 0, CALLBACK_WINDOW); if (mmr != MMSYSERR_NOERROR) { Trace("waveOutOpen\n"); return; } } void OnHScroll(LPARAM lParam) { HWND hWnd; int iPos; char acBuf[16]; hWnd = (HWND)lParam; if (hWnd == g_hTrbVolumeL) { iPos = (int)SendMessage(g_hTrbVolumeL, TBM_GETPOS, 0, 0); Trace("OnHScroll(%d)\n", iPos); g_iVolumeL = iPos; sprintf_s(acBuf, sizeof(acBuf), "%d", g_iVolumeL); SetWindowText(g_hLblVolumeL, acBuf); } if (hWnd == g_hTrbVolumeR) { iPos = (int)SendMessage(g_hTrbVolumeR, TBM_GETPOS, 0, 0); Trace("OnHScroll(%d)\n", iPos); g_iVolumeR = iPos; sprintf_s(acBuf, sizeof(acBuf), "%d", g_iVolumeR); SetWindowText(g_hLblVolumeR, acBuf); } } void OnCreate(HWND hWnd) { char acBuf[16]; g_hBtnStart = CreateWindow("BUTTON", "▲", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 16, 16, 48, 24, hWnd, (HMENU)IDC_BTN_START, g_hInstance, NULL); CreateWindow("BUTTON", "■", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 80, 16, 48, 24, hWnd, (HMENU)IDC_BTN_STOP, g_hInstance, NULL); // Hz sprintf_s(acBuf, sizeof(acBuf), "%.1f", g_dFreq); g_hEdtFreq = CreateWindow("EDIT", acBuf, WS_CHILD | WS_VISIBLE, 192, 16, 64, 24, hWnd, (HMENU)IDC_EDT_LOOPS, g_hInstance, NULL); CreateWindow("STATIC", "Hz", WS_CHILD | WS_VISIBLE, 264, 16, 24, 24, hWnd, (HMENU)0, g_hInstance, NULL); // VolumeL CreateWindow("STATIC", "L", WS_CHILD | WS_VISIBLE, 16, 56, 8, 24, hWnd, (HMENU)0, g_hInstance, NULL); g_hTrbVolumeL = CreateWindow(TRACKBAR_CLASS, NULL, WS_CHILD | WS_VISIBLE | TBS_AUTOTICKS, 32, 56, 232, 24, hWnd, (HMENU)IDC_TRB_VOLUME_L, g_hInstance, NULL); SendMessage(g_hTrbVolumeL, TBM_SETRANGE, (WPARAM)FALSE, MAKELPARAM(0, 32767)); SendMessage(g_hTrbVolumeL, TBM_SETTICFREQ, (WPARAM)4096, 0); SendMessage(g_hTrbVolumeL, TBM_SETPOS, (WPARAM)TRUE, g_iVolumeL); sprintf_s(acBuf, sizeof(acBuf), "%d", g_iVolumeL); g_hLblVolumeL = CreateWindow("STATIC", acBuf, WS_CHILD | WS_VISIBLE, 272, 56, 24, 24, hWnd, (HMENU)IDC_LBL_VOLUME_L, g_hInstance, NULL); // VolumeR CreateWindow("STATIC", "R", WS_CHILD | WS_VISIBLE, 16, 88, 8, 24, hWnd, (HMENU)0, g_hInstance, NULL); g_hTrbVolumeR = CreateWindow(TRACKBAR_CLASS, NULL, WS_CHILD | WS_VISIBLE | TBS_AUTOTICKS, 32, 88, 232, 24, hWnd, (HMENU)IDC_TRB_VOLUME_R, g_hInstance, NULL); SendMessage(g_hTrbVolumeR, TBM_SETRANGE, (WPARAM)FALSE, MAKELPARAM(0, 32767)); SendMessage(g_hTrbVolumeR, TBM_SETTICFREQ, (WPARAM)4096, 0); SendMessage(g_hTrbVolumeR, TBM_SETPOS, (WPARAM)TRUE, g_iVolumeR); sprintf_s(acBuf, sizeof(acBuf), "%d", g_iVolumeR); g_hLblVolumeR = CreateWindow("STATIC", acBuf, WS_CHILD | WS_VISIBLE, 272, 88, 24, 24, hWnd, (HMENU)IDC_LBL_VOLUME_R, g_hInstance, NULL); } void OnDestroy(HWND hWnd) { RECT rect; char acBuf[16]; PlayStop(); GetWindowRect(hWnd, &rect); sprintf_s(acBuf, sizeof(acBuf), "%d", rect.left); WritePrivateProfileString("General", "iX", acBuf, g_acIniFile); sprintf_s(acBuf, sizeof(acBuf), "%d", rect.top); WritePrivateProfileString("General", "iY", acBuf, g_acIniFile); sprintf_s(acBuf, sizeof(acBuf), "%f", g_dFreq); WritePrivateProfileString("General", "dFreq", acBuf, g_acIniFile); sprintf_s(acBuf, sizeof(acBuf), "%d", g_iVolumeL); WritePrivateProfileString("General", "iVolumeL", acBuf, g_acIniFile); sprintf_s(acBuf, sizeof(acBuf), "%d", g_iVolumeR); WritePrivateProfileString("General", "iVolumeR", acBuf, g_acIniFile); } void PlayStop() { Trace("PlayStop\n"); if (g_hwo != NULL) { waveOutReset(g_hwo); waveOutUnprepareHeader(g_hwo, &g_wh, sizeof(WAVEHDR)); waveOutClose(g_hwo); g_hwo = NULL; } EnableWindow(g_hBtnStart, TRUE); } void Trace(const char *pcFormat, ...) { va_list args; char acBuf[512]; int iRet; va_start(args, pcFormat); iRet = vsprintf_s(acBuf, sizeof(acBuf), pcFormat, args); if (0 < iRet) { OutputDebugString(acBuf); } va_end(args); }