// // エコーと波形表示 // // 2002/12/30 宍戸 輝光 // #include HINSTANCE hInst; LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); HWND hwMain; HDC hdcBMP; HBITMAP hBMP,hOld; HPEN hpenLine; RECT recGraph={0,0,600,256}; short int *lpWave; void drawWave() { int y; /* ビットマップをクリア */ FillRect(hdcBMP,&recGraph,(HBRUSH)GetStockObject(GRAY_BRUSH)); SelectObject(hdcBMP,GetStockObject(BLACK_PEN)); /* ビットマップ中央にy=0の直線描画 */ MoveToEx(hdcBMP,0,128,NULL); LineTo(hdcBMP,600,128); SelectObject(hdcBMP,hpenLine); MoveToEx(hdcBMP,0,128,NULL); /* 各サンプリングデータを線でつないで描画 */ for (int i=0;i<600;i++) { y=(int)(lpWave[i]/256)+128; LineTo(hdcBMP,i,y); } } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, PSTR szCmdLine,int iCmdShow){ MSG msg; WNDCLASSEX wndclass; /* ウインドウクラス設定 */ wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "CWindow"; wndclass.hIconSm = NULL; RegisterClassEx(&wndclass); /* ウインドウクラス登録 */ hwMain=CreateWindow("CWindow","エコー", WS_OVERLAPPEDWINDOW | WS_VISIBLE,CW_USEDEFAULT,CW_USEDEFAULT, 620,320,NULL,NULL,hInstance,NULL); while (GetMessage(&msg,NULL,0,0)) { /* メッセージループ */ TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { static short int *lpWork; static HWAVEOUT hWOut; static HWAVEIN hWIn; static WAVEHDR wh; static WAVEFORMATEX wf; static HWND hwRec,hwPlay,hwEcho; int i,nValue; HDC hdc; PAINTSTRUCT ps; switch (iMsg) { case WM_CREATE: hwRec=CreateWindow("BUTTON","録 音",WS_CHILD|WS_VISIBLE, 4,4,80,32,hwnd,(HMENU)0,hInst,NULL); hwPlay=CreateWindow("BUTTON","再 生",WS_CHILD|WS_VISIBLE, 104,4,80,32,hwnd,(HMENU)1,hInst,NULL); hwEcho=CreateWindow("BUTTON","エ コ ー",WS_CHILD|WS_VISIBLE, 200,4,96,32,hwnd,(HMENU)2,hInst,NULL); EnableWindow(hwPlay,FALSE); EnableWindow(hwEcho,FALSE); lpWave=(short int *)GlobalAlloc(GPTR,48000); lpWork=(short int *)GlobalAlloc(GPTR,48000); wf.wFormatTag=WAVE_FORMAT_PCM; wf.nChannels=1; wf.nSamplesPerSec=8000; wf.nAvgBytesPerSec=16000; wf.nBlockAlign=1; wf.wBitsPerSample=16; wf.cbSize=0; wh.lpData=(char *)lpWave; wh.dwBufferLength=48000; wh.dwBytesRecorded=0; wh.dwUser=0; wh.dwFlags=0; wh.dwLoops=1; wh.lpNext=NULL; wh.reserved=0 ; hdcBMP=CreateCompatibleDC(GetDC(hwnd)); hBMP=CreateCompatibleBitmap(GetDC(hwnd),600,256); hOld=(HBITMAP)SelectObject(hdcBMP,hBMP); hpenLine=CreatePen(PS_SOLID,1,0x000000ff); drawWave(); return 0; case WM_COMMAND: switch (LOWORD(wParam)) { case 0: /* 録音ボタン */ waveInOpen(&hWIn,WAVE_MAPPER,&wf,(DWORD)hwnd,0,CALLBACK_WINDOW); waveInPrepareHeader(hWIn,&wh,sizeof(WAVEHDR)); waveInAddBuffer(hWIn,&wh,sizeof(WAVEHDR)); waveInStart(hWIn); EnableWindow(hwPlay,FALSE); EnableWindow(hwEcho,FALSE); return 0; case 1: /* 再生ボタン */ /* デバイスオープン */ waveOutOpen(&hWOut,WAVE_MAPPER,&wf,(DWORD)hwnd,0,CALLBACK_WINDOW); waveOutPrepareHeader(hWOut,&wh,sizeof(WAVEHDR)); waveOutWrite(hWOut,&wh,sizeof(WAVEHDR)); return 0; case 2: /* エコーボタン */ /* 先頭から400サンプルをワークにコピー */ memcpy(lpWork,lpWave,800); /* 400サンプル前の値を加えエコーの波形を生成 */ for (i=400;i<24000;i++) { nValue=(int)(lpWave[i-400]*0.6)+lpWave[i]; if (nValue>32767) nValue=32767; if (nValue<-32768) nValue=-32768; lpWork[i]=(short int)nValue; } memcpy(lpWave,lpWork,48000); /* 波形描画 */ drawWave(); InvalidateRect(hwnd,NULL,FALSE); UpdateWindow(hwnd); return 0; } case WM_PAINT: hdc=BeginPaint(hwnd,&ps); /* 波形を描いたビットマップを描画 */ BitBlt(hdc,4,48,600,256,hdcBMP,0,0,SRCCOPY); EndPaint(hwnd,&ps); return 0; case MM_WIM_DATA: /* 録音終了 */ waveInUnprepareHeader(hWIn,&wh,sizeof(WAVEHDR)); waveInClose(hWIn); EnableWindow(hwPlay,TRUE); EnableWindow(hwEcho,TRUE); drawWave(); InvalidateRect(hwnd,NULL,FALSE); UpdateWindow(hwnd); return 0; case MM_WOM_DONE: /* 再生終了 */ waveOutUnprepareHeader(hWOut,&wh,sizeof(WAVEHDR)); waveOutClose(hWOut); return 0; case WM_DESTROY : /* 終了処理 */ SelectObject(hdcBMP,hOld); DeleteObject(hBMP); DeleteObject(hdcBMP); GlobalFree(lpWave); GlobalFree(lpWork); PostQuitMessage(0); return 0; } return DefWindowProc(hwnd,iMsg,wParam,lParam); }