利用VC的MIDI的一个Windows电子琴程序,可以键盘鼠标弹奏,可以选择音色、音量、录音。
#include "stdafx.h"
#include "PIANO.h"
#include <stdio.h>
#include <MMSystem.h>
#include <shlwapi.h>
#pragma comment (lib,"Winmm.lib") // 音乐播放
#include "SkinH.h"
#pragma comment(lib,"SkinH.lib") // 换肤
union {DWORD dwData; BYTE bData[4];}midi; // MIDI消息联合
HMIDIOUT hmo; //MIDI句柄
HWND hwndcombo,hwndmain;
int yinse,yinliang,focus=0;
int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{
DialogBox(hInstance,MAKEINTRESOURCE(IDD_MAINDIALOG),NULL,Main_Proc);
return 0;
}
BOOL WINAPI Main_Proc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
//开始消息测试
HANDLE_MSG(hWnd,WM_INITDIALOG,Main_OnInitDialog);
HANDLE_MSG(hWnd,WM_COMMAND,Main_OnCommand);
HANDLE_MSG(hWnd,WM_CLOSE,Main_OnClose);
//结束消息测试
}
return FALSE;
}
BOOL Main_OnInitDialog(HWND hWnd,HWND hwndFocus,LPARAM lParam)
{
//设置应用程序图标
HICON hIcon = LoadIcon((HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE),MAKEINTRESOURCE(IDI_PIANO));
SendMessage(hWnd,WM_SETICON,TRUE,(LPARAM)hIcon);
SendMessage(hWnd,WM_SETICON,FALSE,(LPARAM)hIcon);
//皮肤初始化
TCHAR skinpath[MAX_PATH];
GetCurrentDirectory(MAX_PATH,skinpath);
sprintf(skinpath,"%s\\Skin\\piano.she",skinpath);
SkinH_Attach();
//添加初始化代码
hwndmain=hWnd;
initmidi();
SetTimer(hWnd,0,1000,playpiano);
return TRUE;
}
void Main_OnCommand(HWND hWnd,int id,HWND hwndCtl,UINT codeNotify)
{
if (focus ==0)
{
SetFocus(GetDlgItem(hWnd,ZH1));
focus=1;
}
switch(id)
{
case DIDI6:
duoruami(45);SetFocus(GetDlgItem(hWnd,DIDI6));
break;
case DIDI7:
duoruami(47);SetFocus(GetDlgItem(hWnd,DIDI7));
break;
case DI1:
duoruami(48);SetFocus(GetDlgItem(hWnd,DI1));
break;
case DI2:
duoruami(50);SetFocus(GetDlgItem(hWnd,DI2));
break;
case DI3:
duoruami(52);SetFocus(GetDlgItem(hWnd,DI3));
break;
case DI4:
duoruami(53);SetFocus(GetDlgItem(hWnd,DI4));
break;
case DI5:case DI52:
duoruami(55);SetFocus(GetDlgItem(hWnd,DI5));
break;
case DI6:case DI62:
duoruami(57);SetFocus(GetDlgItem(hWnd,DI6));
break;
case DI7:case DI72:
duoruami(59);SetFocus(GetDlgItem(hWnd,DI7));
break;
case ZH1:
duoruami(60);SetFocus(GetDlgItem(hWnd,ZH1));
break;
case ZH2:
duoruami(62);SetFocus(GetDlgItem(hWnd,ZH2));
break;
case ZH3:
duoruami(64);SetFocus(GetDlgItem(hWnd,ZH3));
break;
case ZH4:
duoruami(65);SetFocus(GetDlgItem(hWnd,ZH4));
break;
case ZH5:
duoruami(67);SetFocus(GetDlgItem(hWnd,ZH5));
break;
case ZH6:
duoruami(69);SetFocus(GetDlgItem(hWnd,ZH6));
break;
case ZH7:
duoruami(71);SetFocus(GetDlgItem(hWnd,ZH7));
break;
case GAO1:case GAO12:
duoruami(72);SetFocus(GetDlgItem(hWnd,GAO1));
break;
case GAO2:case GAO22:
duoruami(74);SetFocus(GetDlgItem(hWnd,GAO2));
break;
case GAO3:case GAO32:
duoruami(76);SetFocus(GetDlgItem(hWnd,GAO3));
break;
case GAO4:
duoruami(77);SetFocus(GetDlgItem(hWnd,GAO4));
break;
case GAO5:
duoruami(79);SetFocus(GetDlgItem(hWnd,GAO5));
break;
case GAO6:
duoruami(81);SetFocus(GetDlgItem(hWnd,GAO6));
break;
case GAO7:
duoruami(83);SetFocus(GetDlgItem(hWnd,GAO7));
break;
case GAOGAO1:
duoruami(84);SetFocus(GetDlgItem(hWnd,GAOGAO1));
break;
case GAOGAO2:
duoruami(86);SetFocus(GetDlgItem(hWnd,GAOGAO2));
break;
case GAOGAO3:
duoruami(88);SetFocus(GetDlgItem(hWnd,GAOGAO3));
break; //DUORUAMIFASUOLAXI
case IDC_COMBO1:
yinsecombo(yinse);
focus=0;
break;
case IDC_COMBO2:
yinliangcombo(yinliang);
focus=0;
break;//COMMOBO
case IDC_HELP:
MessageBox(hWnd,"超简单的程序 带给你超极致的音乐体验。\n用电脑鼠标键盘演奏美妙音乐不是梦想!\n加上外接MIDI键盘更可用作歌曲录制处理。\n"
"多种音色,弹奏音调优化处理,音调切换过渡处理。\n界面友好,操作简单方便,功能强大,更可录制弹奏音乐。\n"
"\n操作说明:\n对弹奏操作方便度人性化优化设计。\n“F”到“;”是中音区,“C”到“>”是高音区\n“ASD”也可对应低音567。“ ' [ ] ”对应高音123\n"
"“W”到“P”是超低音6到低音7,“ / Z X”是超高音123 \n\n逸雨清风出品 sswyrlyh@foxmail.com","轻松弹钢琴V1.0",MB_OK|MB_ICONINFORMATION);
break;//HELP
case IDC_RECALL:
TCHAR str[MAX_PATH];
GetCurrentDirectory(MAX_PATH,str);
sprintf(str,"%s\\VoiceRecorder\\VoiceRecorder.exe",str);
if (WinExec(str,SW_SHOWNORMAL) == NULL)
{
WinExec("C:\\Users\\逸雨清风\\Desktop\\PIANO\\VoiceRecorder\\VoiceRecorder.exe",SW_SHOWNORMAL);
}
break;
case IDC_EXIT:
if (IDOK==MessageBox(hWnd,"确定关闭钢琴软件?","提示",MB_OKCANCEL|MB_ICONINFORMATION))
{
midiOutClose(hmo);
EndDialog(hWnd,0);
}
break;
default:break;
}
}
void Main_OnClose(HWND hWnd)
{
if (IDOK==MessageBox(hWnd,"确定关闭钢琴软件?","提示",MB_OKCANCEL|MB_ICONINFORMATION))
{
midiOutClose(hmo);
EndDialog(hWnd,0);
}
}
void initmidi()
{
midiOutOpen(&hmo,0,0,0,CALLBACK_NULL); //打开MIDI设备
hwndcombo=GetDlgItem(hwndmain,IDC_COMBO1);
ComboBox_InsertString(hwndcombo,-1,"钢琴"); //0
ComboBox_InsertString(hwndcombo,-1,"吉他"); //24
ComboBox_InsertString(hwndcombo,-1,"竖笛");//74
ComboBox_InsertString(hwndcombo,-1,"短笛");//72
ComboBox_InsertString(hwndcombo,-1,"口琴");//22
ComboBox_InsertString(hwndcombo,-1,"小号");//56
ComboBox_InsertString(hwndcombo,-1,"贝斯");//32
ComboBox_InsertString(hwndcombo,-1,"雨声");//96
ComboBox_InsertString(hwndcombo,-1,"导音");//83
ComboBox_InsertString(hwndcombo,-1,"八音盒");//10
ComboBox_InsertString(hwndcombo,-1,"班卓琴");//105
ComboBox_InsertString(hwndcombo,-1,"萨克斯");//65
ComboBox_InsertString(hwndcombo,-1,"手风琴");//21
ComboBox_InsertString(hwndcombo,-1,"电钢琴");//2
ComboBox_InsertString(hwndcombo,-1,"小提琴");//40
ComboBox_InsertString(hwndcombo,-1,"马林巴琴");//12
ComboBox_SetCurSel(hwndcombo,0);
yinsecombo(yinse);
hwndcombo=GetDlgItem(hwndmain,IDC_COMBO2);
ComboBox_InsertString(hwndcombo,-1,"5");
ComboBox_InsertString(hwndcombo,-1,"4");
ComboBox_InsertString(hwndcombo,-1,"3");
ComboBox_InsertString(hwndcombo,-1,"2");
ComboBox_InsertString(hwndcombo,-1,"1");
ComboBox_SetCurSel(hwndcombo,0);
yinliangcombo(yinliang);
midi.bData[0] = 0x90; // 由通道0发出乐音
midi.bData[2] = 127; // 最大音强
}
void yinsecombo(int combosel)
{
midi.bData[0] = 0xC0; // 设置通道0的音色/乐器种类
midi.bData[2] = 0; // 未使用字节
midi.bData[3] = 0; // 保留为0
hwndcombo=GetDlgItem(hwndmain,IDC_COMBO1);
combosel=ComboBox_GetCurSel(hwndcombo);
switch(combosel)
{
case 0:midi.bData[1] = 0; break;
case 1:midi.bData[1] = 24; break;
case 2:midi.bData[1] = 74; break;
case 3:midi.bData[1] = 72; break;
case 4:midi.bData[1] = 22; break;
case 5:midi.bData[1] = 56; break;
case 6:midi.bData[1] = 32; break;
case 7:midi.bData[1] = 96; break;
case 8:midi.bData[1] = 83; break;
case 9:midi.bData[1] = 10; break;
case 10:midi.bData[1] = 105; break;
case 11:midi.bData[1] = 65; break;
case 12:midi.bData[1] = 21; break;
case 13:midi.bData[1] = 2; break;
case 14:midi.bData[1] = 40; break;
case 15:midi.bData[1] = 12; break;
default: midi.bData[1] = 0;break;
}
midiOutShortMsg(hmo, midi.dwData);
midi.bData[0] = 0x90; // 由通道0发出乐音
midi.bData[2] = 127; // 最大音强
}
void yinliangcombo(int combosel)
{
midi.bData[0] = 0x90; // 由通道0发出乐音
hwndcombo=GetDlgItem(hwndmain,IDC_COMBO2);
combosel=ComboBox_GetCurSel(hwndcombo);
switch(combosel)
{
case 0:midi.bData[2] = 127; break;
case 1:midi.bData[2] = 100 ; break;
case 2:midi.bData[2] = 77; break;
case 3:midi.bData[2] = 45; break;
case 4:midi.bData[2] = 25 ; break;
default: midi.bData[2] = 127;break;
}
}
void duoruami(int yindiao)
{
midiOutReset(hmo);
midi.bData[1]=yindiao;
midiOutShortMsg(hmo,midi.dwData);
SetTimer(hwndmain,2,1000,timereset);
}
VOID CALLBACK playpiano(HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)
{
if (focus == 0)
{
SetFocus(GetDlgItem(hwnd,ZH1));
focus=1;
}
}
VOID CALLBACK timereset(HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)
{
midiOutReset(hmo);
}
/*
******逸雨清风 出品
******http://blog.csdn.net/xyydyyqf
*/