• 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

  • 相关阅读:
    vue父组件props参数太大时子组件created取不到数据-解决方法
    uniapp-高德地图Android+IOS appkey申请与使用
    用iframe解决jquery.js和prototype.js的冲突
    iview-project 改写页面 title
    iview-project-3.0安装记录
    用live2d给你的博客放个二次元看店娘
    vue全局公共函数
    微信h5页面下拉露出网页来源的解决办法
    Java ConcurrentModificationException 异常分析与解决方案
    Java注释@interface的用法【转】
  • 原文地址:https://www.cnblogs.com/sosoft/p/csmidi.html
Copyright © 2020-2023  润新知