WaveRecorder
Visual C++ 2005 Express Edition
Windows Server 2003 SP1 Platform SDK
Windowsアプリケーション / 空のプロジェクト
音声の入力
WaveRecorder.c
// マルチバイト文字セット #include
#include
#define APPNAME "WaveRecorder" #define SAMPLING_RATE 8000 #define IDC_BTN_STOP 1 #define IDC_BTN_PLAY 2 #define IDC_BTN_RECORD 3 // グローバル変数 static HINSTANCE g_hInstance; static HWND g_hBtnPlay; static HWND g_hBtnRecord; static HWAVEIN g_hwi = NULL; static HWAVEOUT g_hwo = NULL; static WAVEHDR g_wh; static WAVEFORMATEX g_wfx; static DWORD g_dwSampleLength = 0; static u_char g_aucWaveformData[SAMPLING_RATE * 5]; // プロトタイプ宣言 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void OnBtnStop(); void OnBtnPlay(HWND hWnd); void OnBtnRecord(HWND hWnd); void OnCreate(HWND hWnd); void WaveInError(MMRESULT mmrError); void WaveOutError(MMRESULT mmrError); 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; g_hInstance = hInstance; 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, 100, // x 100, // y 320, // Width 120, // 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_WIM_DATA: Trace("MM_WIM_DATA\n"); OnBtnStop(); break; case MM_WOM_DONE: Trace("MM_WOM_DONE\n"); OnBtnStop(); break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_BTN_STOP: OnBtnStop(); break; case IDC_BTN_PLAY: OnBtnPlay(hWnd); break; case IDC_BTN_RECORD: OnBtnRecord(hWnd); break; } break; case WM_CREATE: OnCreate(hWnd); break; case WM_DESTROY: OnBtnStop(); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } return 0; } void OnBtnStop() { MMRESULT mmr; if (g_hwi != NULL) { mmr = waveInReset(g_hwi); if (mmr != MMSYSERR_NOERROR) { WaveInError(mmr); return; } Trace("g_wh.dwBytesRecorded=%u\n", g_wh.dwBytesRecorded); g_dwSampleLength = g_wh.dwBytesRecorded; mmr = waveInStop(g_hwi); if (mmr != MMSYSERR_NOERROR) { WaveInError(mmr); return; } mmr = waveInUnprepareHeader(g_hwi, &g_wh, sizeof(WAVEHDR)); if (mmr != MMSYSERR_NOERROR) { WaveInError(mmr); return; } mmr = waveInClose(g_hwi); if (mmr != MMSYSERR_NOERROR) { WaveInError(mmr); return; } g_hwi = NULL; } if (g_hwo != NULL) { mmr = waveOutReset(g_hwo); if (mmr != MMSYSERR_NOERROR) { WaveOutError(mmr); return; } mmr = waveOutUnprepareHeader(g_hwo, &g_wh, sizeof(WAVEHDR)); if (mmr != MMSYSERR_NOERROR) { WaveOutError(mmr); return; } mmr = waveOutClose(g_hwo); if (mmr != MMSYSERR_NOERROR) { WaveOutError(mmr); return; } g_hwo = NULL; } EnableWindow(g_hBtnRecord, TRUE); EnableWindow(g_hBtnPlay, (g_dwSampleLength == 0) ? FALSE : TRUE); } void OnBtnPlay(HWND hWnd) { MMRESULT mmr; if (g_hwo != NULL) { return; } mmr = waveOutOpen(&g_hwo, WAVE_MAPPER, &g_wfx, (DWORD_PTR)hWnd, 0, CALLBACK_WINDOW); if (mmr != MMSYSERR_NOERROR) { WaveOutError(mmr); return; } memset(&g_wh, 0, sizeof(WAVEHDR)); g_wh.lpData = g_aucWaveformData; g_wh.dwBufferLength = g_dwSampleLength; mmr = waveOutPrepareHeader(g_hwo, &g_wh, sizeof(WAVEHDR)); if (mmr != MMSYSERR_NOERROR) { WaveOutError(mmr); return; } mmr = waveOutWrite(g_hwo, &g_wh, sizeof(WAVEHDR)); if (mmr != MMSYSERR_NOERROR) { WaveOutError(mmr); return; } EnableWindow(g_hBtnPlay, FALSE); EnableWindow(g_hBtnRecord, FALSE); } void OnBtnRecord(HWND hWnd) { MMRESULT mmr; if (g_hwi != NULL) { return; } g_wfx.wFormatTag = WAVE_FORMAT_PCM; g_wfx.nChannels = 1; g_wfx.nSamplesPerSec = SAMPLING_RATE; g_wfx.nAvgBytesPerSec = SAMPLING_RATE * 1; g_wfx.nBlockAlign = 1; g_wfx.wBitsPerSample = 8; g_wfx.cbSize = 0; mmr = waveInOpen(&g_hwi, WAVE_MAPPER, &g_wfx, (DWORD_PTR)hWnd, 0, CALLBACK_WINDOW); if (mmr != MMSYSERR_NOERROR) { WaveInError(mmr); return; } memset(&g_wh, 0, sizeof(WAVEHDR)); g_wh.lpData = g_aucWaveformData; g_wh.dwBufferLength = sizeof(g_aucWaveformData); mmr = waveInPrepareHeader(g_hwi, &g_wh, sizeof(WAVEHDR)); if (mmr != MMSYSERR_NOERROR) { WaveInError(mmr); return; } mmr = waveInAddBuffer(g_hwi, &g_wh, sizeof(WAVEHDR)); if (mmr != MMSYSERR_NOERROR) { WaveInError(mmr); return; } mmr = waveInStart(g_hwi); if (mmr != MMSYSERR_NOERROR) { WaveInError(mmr); return; } EnableWindow(g_hBtnPlay, FALSE); EnableWindow(g_hBtnRecord, FALSE); } void OnCreate(HWND hWnd) { CreateWindow("BUTTON", "■", WS_CHILD | WS_VISIBLE, 16, 16, 48, 32, hWnd, (HMENU)IDC_BTN_STOP, g_hInstance, NULL); g_hBtnPlay = CreateWindow("BUTTON", "▲", WS_CHILD | WS_VISIBLE, 80, 16, 48, 32, hWnd, (HMENU)IDC_BTN_PLAY, g_hInstance, NULL); g_hBtnRecord = CreateWindow("BUTTON", "●", WS_CHILD | WS_VISIBLE, 144, 16, 48, 32, hWnd, (HMENU)IDC_BTN_RECORD, g_hInstance, NULL); EnableWindow(g_hBtnPlay, FALSE); } void WaveInError(MMRESULT mmrError) { MMRESULT mmr; char acText[MAXERRORLENGTH]; mmr = waveInGetErrorText(mmrError, acText, MAXERRORLENGTH); if (mmr == MMSYSERR_NOERROR) { Trace("%s\n", acText); } } void WaveOutError(MMRESULT mmrError) { MMRESULT mmr; char acText[MAXERRORLENGTH]; mmr = waveOutGetErrorText(mmrError, acText, MAXERRORLENGTH); if (mmr == MMSYSERR_NOERROR) { Trace("%s\n", acText); } } 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); }