柔城

SOSOFT articles

C# WinForm使用乐器数字接口

继续,前面已经实现了C#调用Windows API实现了弹出对话框功能。使用了User32.dll文件,主要代码如下:

[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);
详情请参考:http://hovertree.com/h/bjaf/psjdasa2.htm

效果如下:


也练习了调用winmm.dll播放wav声音文件,主要代码:
[DllImport("winmm.dll")]
private static extern int sndPlaySoundA(byte[] lpszSoundName, int uFlags);

详情参考:http://hovertree.com/h/bjaf/jeg0ytf5.htm

效果图:


接下来继续练习调用别API,就调用winmm.dll的midi播放功能吧。

MIDI(Musical Instrument Digital Interface)乐器数字接口 ,是20 世纪80 年代初为解决电声乐器之间的通信问题而提出的。MIDI是编曲界最广泛的音乐标准格式,可称为“计算机能理解的乐谱”。它用音符的数字控制信号来记录音乐。一首完整的MIDI音乐只有几十KB大,而能包含数十条音乐轨道。几乎所有的现代音乐都是用MIDI加上音色库来制作合成的。MIDI 传输的不是声音信号, 而是音符、控制参数等指令, 它指示MIDI 设备要做什么,怎么做, 如演奏哪个音符、多大音量等。它们被统一表示成MIDI 消息(MIDI Message) 。传输时采用异步串行通信, 标准通信波特率为31.25×( 1±0.01) KBaud。

所以调用API播放midi也是按照格式指定播放指令。接下来就测试实现midi功能。

首先是打开midi输出设备的API:
MMRESULT midiOutOpen(
LPHMIDIOUT lphmo,
UINT uDeviceID,
DWORD_PTR dwCallback,
DWORD_PTR dwCallbackInstance,
DWORD dwFlags
);
详情请看:http://hovertree.com/h/bjaf/tug59e9l.htm

在C#中调用该API:
[DllImport("winmm.dll")]
private static extern UInt32 midiOutOpen(out UInt32 lphMidiOut, uint uDeviceID, UInt32 dwCallback, UInt32 dwInstance, UInt32 dwFlags);

其中lphMidiOut 为设备的句柄 ,在后面播放声音会用到。

然后是向设备发送播放指令API:
MMRESULT midiOutShortMsg(
HMIDIOUT hmo,
DWORD dwMsg
);
详情请参考:http://hovertree.com/h/bjaf/4ext7m8l.htm

在C#中调用:
[DllImport("winmm.dll")]
private static extern UInt32 midiOutShortMsg(UInt32 hMidiOut, UInt32 dwMsg);

这里hMidiOut就是midiOutOpen方法的lphMidiOut
接下来就封装这些API,Midi输出设备需要打开后才能播放声音,在封装的类HewenqiMidi中加一个状态,表示设备是否打开,代码为:private bool _isOpened; 因为是调用API,所以设备有一个句柄,也就是上面提到的lphMidiOut ,所以类中加一个设备句柄字段,句柄的类型为32位无符号整形UNIT,参考:http://hovertree.com/h/bjaf/exee7473.htm,代码为:private uint _deviceHandle; 用来存储midiOutOpen获得的句柄lphMidiOut,这两个字段可以封装为属性,只读的属性。

接下来,实现设备的打开功能,主要代码:
uint h_Device;
uint h_r = midiOutOpen(out h_Device, 0, 0, 0, 0);
当h_r等与0时,表示打开成功,否则打开不成功,具体返回值可以参考:http://hovertree.com/h/bjaf/tug59e9l.htm

播放声音的方法:
public uint ShortPlay(uint msg)
{
if (_isOpened)
return midiOutShortMsg(_deviceHandle, msg);
else
return 621;
}
先检查设备是否已经打开,打开了就播放声音,返回0表示成功。参考:http://hovertree.com/h/bjaf/37iovb7c.htm

参数msg表示要播放的声音,这个参数可以包含音量和音高等信息,详情请参考:
http://hovertree.com/h/bjaf/4ext7m8l.htm
根据这个参数构造以下方法:

/// <summary>
/// 播放声音
/// </summary>
/// <param name="key">音高(音调)</param>
/// <param name="volume">音量</param>
/// <param name="chenel">通道</param>
/// <returns></returns>
public uint ShortPlay(uint key, uint volume, uint chenel)
{
return ShortPlay(144 + key * 256 + volume * 65536 + chenel);
}


这样就可以方便调节播放的音量和音高了。当然还有可以设置音色,先放到后边介绍。

打开MIDI设备后,要怎么关闭呢?也是调用API:
midiOutClose(
hMidiOut: HMIDIOUT {设备句柄}
)
详情:http://hovertree.com/h/bjaf/gmn82vlo.htm

在C#中调用:
[DllImport("winmm.dll")]
private static extern UInt32 midiOutClose(UInt32 hMidiOut);
返回0表示成功

接着,使用HewenqiMidi 类,建立一个WinForm 窗体,测试播放功能。如下图所示:

演示下载地址:http://hovertree.com/h/bjaf/xy6rbg5m.htm

源码发布到这个网址:http://hovertree.net/

转自:http://hovertree.com/h/bjaf/dg7nbe4t.htm

 

posted on 2016-02-29 20:31  柔城  阅读(2102)  评论(0编辑  收藏  举报

导航