可有人知道在bcb下如何控制midi?我指得是:写曲谱,选乐器.

brood 2000-03-04 05:15:00
...全文
130 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
BCB 2001-09-17
  • 打赏
  • 举报
回复

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

#include "mmsystem.h" // 多媒体头文件
bool PlayStat=true;
HMIDIOUT hMidi; // 存放MIDI句柄
DWORD Channel=0; // 存放MIDI通道
Word Key_Note[256]; // 存放对应音符

void OpenMidi() // 打开MIDI设备
{
midiOutOpen(&hMidi,-1,0,0,0);
}
void CloseMidi() // 关闭MIDI设备
{
midiOutClose(hMidi);
}
void PlayNote(int x) // 发x音符
{
int t=Form1->Edit1->Text.ToIntDef(88);
DWORD Msg;
Msg=(t<<8)+0xc0+Channel; // 音色
midiOutShortMsg(hMidi,Msg);

Msg=0x7f0090+(x<<8)+Channel;
midiOutShortMsg(hMidi,Msg);
}
void StopNote(int x) // 停x音符
{
DWORD Msg;
Msg=0x000090+(x<<8)+Channel;
midiOutShortMsg(hMidi,Msg);
}

int Note_1=0x3c; // Note_1 存放低音1
int KeyToNote(Word &Key)
{ // 据键求音符
int Idx[]={0,2,4,5,7,9,11};
int Code[4]={'1','Q','A','Z'}; //每排首键
int CodeL[4]={12,12,11,10}; //每排键数
int ScanKey=MapVirtualKey(Key,0); //求Key扫描码
for (int i=0;i<4;i++)
{
int wz=ScanKey-MapVirtualKey(Code[i],0);
if (wz>=0 && wz<CodeL[i])
{
int Note=Note_1+12*i;
if (wz>=7) // 在下一个八度
Note+=Idx[wz-7]+12;
else
Note+=Idx[wz];
return(Note);
}
}
return(0);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
TShiftState Shift)
{
if (PlayStat)
if (Key_Note[Key]==0) // 连续按下时防止重复发音
{
int Note=KeyToNote(Key);
if (Note!=0)
{
if (Shift.Contains(ssShift))
Note++; //Shift 升半音
if (Shift.Contains(ssCtrl))
Note--; //Ctrl 降半音
Key_Note[Key]=Note;
PlayNote(Note); //发声
}
}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormKeyUp(TObject *Sender, WORD &Key,
TShiftState Shift)
{
if (PlayStat)
{
int Note=Key_Note[Key];
if (Note!=0)
StopNote(Note); // 停止发声
Key_Note[Key]=0;
}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
OpenMidi();
for (int i=0;i<=255;i++)
Key_Note[i]=0;
KeyPreview=true;
Button1->TabOrder=1;
Edit1->TabOrder=2;
ComboBox1->ItemIndex=6;
Edit1->Text=88;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
CloseMidi();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
PlayStat=!PlayStat;
Button1->Caption=PlayStat?"演奏On":"演奏Off";
}


void __fastcall TForm1::ComboBox1Change(TObject *Sender)
{
int n[]={21,23,40,89,98,73,88};
Edit1->Text=n[ComboBox1->ItemIndex];
}
//---------------------------------------------------------------------------

这是我写的一个键盘作电子琴的小程序
BCB 2001-09-17
  • 打赏
  • 举报
回复
你要先掌握MIDI控制原理
BCB 2001-09-17
  • 打赏
  • 举报
回复
编电子琴?!
sqlone 2001-09-17
  • 打赏
  • 举报
回复
极其关注
sqlone 2001-09-05
  • 打赏
  • 举报
回复
up

13,824

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧