【付録4】MIDIで音楽演奏 #include "myWin.h" #pragma comment(lib,"winmm.lib") #define SMSG(st, ch,d1,d2)((DWORD)(st<<4)|ch|(d1<<8)|(d2<<16)) #define MAXLEN 80 #define NUMCHAN 2 typedef struct{ int Len; //音の長さ。0で終わり。 BYTE note; //音の高さ。休符のとき無視。 BYTE vel; //音の強さ。休符のときは0を入れる。 }MY_SCALE_DATA; //音の高さのコード // ド ド# レ レ# ミ ファ ファ# ソ ソ# ラ ラ# シ ド // 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 // 30 31 32 33 34 35 36 37 38 39 39 3B 3C static MY_SCALE_DATA scale[NUMCHAN][MAXLEN]={ {{4,0x45,0x45},{4,0x45,0x40},{8,0x47,0x45}, //さくら {4,0x45,0x45}, {4,0x45,0x40},{8,0x47,0x45}, //さくら {4,0x45,0x45},{4,0x47,0x40},{4,0x48,0x45},{4,0x47,0x40}, //やよいの {4,0x45,0x45},{2,0x47,0x40},{2,0x45,0x45},{8,0x41,0x40}, //そらは {4,0x40,0x45},{4,0x3C,0x40},{4,0x40,0x45},{4,0x41,0x40}, //みわたす {4,0x40,0x45},{2,0x40,0x40},{2,0x3C,0x45},{8,0x3B,0x40}, //かぎり {4,0x45,0x45},{4,0x47,0x40},{4,0x48,0x45},{4,0x47,0x40}, //かすみか {4,0x45,0x45},{2,0x47,0x40},{2,0x45,0x45},{8,0x41,0x40}, //くもか {4,0x40,0x45},{4,0x3C,0x40},{4,0x40,0x45},{4,0x41,0x40}, //においぞ {4,0x40,0x45},{2,0x40,0x40},{2,0x3C,0x45},{8,0x3B,0x40}, //いずる {4,0x45,0x45},{4,0x45,0x40},{8,0x47,0x45}, //いざや {4,0x45,0x45},{4,0x45,0x40},{8,0x47,0x45}, //いざや {4,0x40,0x45}, {4,0x41,0x40},{2,0x47,0x40},{3,0x45,0x35},{6,0x41,0x32}, {8,0x40,0x30} //みにゆかん }, {{6,0x39,0x45},{2,0x39,0},{6,0x34,0x40},{2,0x39,0},//以下,低音伴奏 {6,0x39,0x45},{2,0x39,0},{6,0x34,0x40},{2,0x39,0}, {6,0x39,0x45},{2,0x39,0},{6,0x39,0x40},{2,0x39,0}, {6,0x39,0x45},{2,0x39,0},{6,0x32,0x40},{2,0x32,0}, {6,0x39,0x40},{2,0x39,0},{6,0x34,0x40},{2,0x34,0}, {6,0x39,0x40},{2,0x39,0},{6,0x34,0x40},{2,0x34,0}, {6,0x39,0x45},{2,0x39,0},{6,0x39,0x40},{2,0x39,0}, {6,0x39,0x45},{2,0x39,0},{6,0x32,0x40},{2,0x32,0}, {6,0x39,0x40},{2,0x39,0},{6,0x34,0x40},{2,0x34,0}, {6,0x39,0x40},{2,0x39,0},{6,0x34,0x40},{2,0x34,0}, {6,0x39,0x45},{2,0x39,0},{6,0x34,0x40},{2,0x39,0}, {6,0x39,0x45},{2,0x39,0},{6,0x34,0x40},{2,0x39,0}, {6,0x39,0x45},{2,0x39,0},{3,0x34,0x45},{2,0x34,0},{5,0x32,0x32},{1,0x39,0}, {6,0x39,0x30} }}; static MY_SCALE_DATA Temp[NUMCHAN][MAXLEN]; static int ID[NUMCHAN];static int prog[NUMCHAN]={0,1}; static HMIDIOUT hM; static HINSTANCE hInstance; void procRButtonUp(HWND hw, WPARAM wp,LPARAM lp){ KillTimer(hw,1); midiOutReset(hM); } void procLButtonUp(HWND hw, WPARAM wp,LPARAM lp){ for(int j=0;j0){ Temp[j][ID[j]].Len--; if(Temp[j][ID[j]].Len==0){ midiOutShortMsg(hM,SMSG(0x9,j,Temp[j][ID[j]].note,0)); midiOutShortMsg(hM,SMSG(0xC,j,prog[j],0)); ID[j]++; if(Temp[j][ID[j]].note>0) midiOutShortMsg(hM,SMSG(0x9,j, Temp[j][ID[j]].note,Temp[j][ID[j]].vel)); } } } BOOL endCH=TRUE; for(int j=0;j0)endCH=FALSE; if(endCH){ KillTimer(hw,1); midiOutReset(hM); } } void procCreate(HWND hw, WPARAM wp,LPARAM lp){ midiOutOpen(&hM,MIDIMAPPER,NULL,0,CALLBACK_NULL); } LRESULT CALLBACK WndProc(HWND hw, UINT msg, WPARAM wp,LPARAM lp){ switch(msg){ case WM_DESTROY : midiOutReset(hM); midiOutClose(hM); PostQuitMessage(0) ;return 0; case WM_CREATE : procCreate (hw,wp,lp);return 0; case WM_LBUTTONUP : procLButtonUp(hw,wp,lp);return 0; case WM_RBUTTONUP : procRButtonUp (hw,wp,lp);return 0; case WM_TIMER : procTimer (hw,wp,lp);return 0; } return DefWindowProc(hw,msg,wp,lp); } 【付録5】AVIファイルの表示 #include "myWin.h" #pragma comment(lib,"winmm.lib") static HWND hM; static MCI_ANIM_OPEN_PARMS openP; static MCI_PLAY_PARMS playP; static MCI_GENERIC_PARMS geneP; static HINSTANCE hInstance; static OPENFILENAME CC;BYTE dtBuff[16]; static TCHAR strFile[1024],strFileTitle[128];TCHAR msg[4200]; static TCHAR sFilter[]=TEXT("AVI Files\0*.avi\0All Files\0*.*\0"); void procLButtonUp(HWND hw, WPARAM wp,LPARAM lp){ TCHAR str[1024]; if(GetOpenFileName(&CC)){ openP.dwCallback=(DWORD)hw; openP.lpstrDeviceType=TEXT("avivideo"); openP.lpstrElementName=strFile; TEXT("D:\\test.avi"); int iErr=mciSendCommand(0,MCI_OPEN,MCI_OPEN_TYPE|MCI_OPEN_ELEMENT, (DWORD_PTR)&openP); //openP.dwStyle=WS_CHILD|WS_VISIBLE;//ウィンドウ内に表示するときは //openP.hWndParent=hw; //上記2行をこの5行に変える //int iErr=mciSendCommand(0,MCI_OPEN,MCI_OPEN_TYPE|MCI_OPEN_ELEMENT| // MCI_ANIM_OPEN_PARENT|MCI_ANIM_OPEN_WS, // (DWORD_PTR)&openP); if(iErr){ mciGetErrorString(iErr,str,1024); MessageBox(hw,str,NULL,MB_OK); } else{ playP.dwCallback=(DWORD)hw; mciSendCommand(openP.wDeviceID,MCI_PLAY,0,(DWORD)&playP); } } } void procRButtonUp(HWND hw, WPARAM wp,LPARAM lp){ mciSendCommand(openP.wDeviceID,MCI_STOP,0,(DWORD_PTR)&geneP); mciSendCommand(openP.wDeviceID,MCI_CLOSE,0,(DWORD_PTR)&geneP); } void procCreate(HWND hw, WPARAM wp,LPARAM lp){ CC.lStructSize =sizeof(OPENFILENAME); CC.hwndOwner =hw ; CC.hInstance =hInstance; CC.lpstrFilter =sFilter ; CC.nFilterIndex =1; CC.lpstrCustomFilter=NULL ; CC.nMaxCustFilter=0; CC.lpstrFile =strFile ; CC.nMaxFile =1024; CC.lpstrFileTitle =strFileTitle; CC.nMaxFileTitle =128; CC.lpstrInitialDir =TEXT("D:\\"); CC.lpstrTitle =TEXT("AVI再生"); CC.lpstrDefExt =TEXT("AVI") ; CC.FlagsEx =0; CC.Flags =OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_DONTADDTORECENT |OFN_NOTESTFILECREATE; procLButtonUp(hw, wp, lp); } LRESULT CALLBACK WndProc(HWND hw, UINT msg, WPARAM wp,LPARAM lp){ switch(msg){ case WM_DESTROY : mciSendString(TEXT("stop test"),NULL,0,NULL); mciSendString(TEXT("close test"),NULL,0,NULL); PostQuitMessage(0) ;return 0; case WM_CREATE : procCreate(hw,wp,lp) ;return 0; case WM_LBUTTONUP: procLButtonUp(hw,wp,lp);return 0; case WM_RBUTTONUP: procRButtonUp(hw,wp,lp);return 0; } return DefWindowProc(hw,msg,wp,lp); }