Windows 声音处理编程(基于winmm.dll)(3)

来源:互联网 发布:android 流程图软件 编辑:程序博客网 时间:2024/05/13 18:14

这一篇介绍向声卡发送数据的方法。首先在C#中重写midiOutOpen和midiOutShortMsg方法:

//打开指定的MIDI输出设备进行回放

[DllImport("winmm.dll")]
        public static extern uint midiOutOpen(out IntPtr lphMidiOut, uint uDeviceID, IntPtr dwCallback, IntPtr dwInstance, uint dwFlags);

//向指定的MIDI输出设备发送一条短MIDI消息

[DllImport("winmm.dll")]
        public static extern uint midiOutShortMsg(IntPtr hMidiOut, uint dwMsg);

GM音色表:http://www2.gxai.edu.cn/dnyy/dnzp/ShowArticle.asp?ArticleID=488 ,声卡也可以模拟此声色表中的声音进行演奏,操作流程如下:

midiOutOpen(out handle, 0, IntPtr.Zero, IntPtr.Zero, 0); //打开设备,获取handle

midiOutShortMsg(handle, Convert.ToUInt32(0x000000C0 +音色值 * 256)); //设置音色,音色值通过GM音色表可以查到,例如:73是短笛

midiOutShortMsg(handle, Convert.ToUInt32(0x00403B90 + data * 256));//给声卡发送数据,播放声音,midiOutShortMsg参数如下:

来自百度百科:http://baike.baidu.com/view/2089748.htm

3、使用格式:
  ret=midiOutShortMsg(midiout, &H90 + ((flip) * &H100) + (volume * &H10000) + channel)
  说明:
  midiout是midioutopen开启设备成功后就会提供这个Long型变量,flip是Integer型参数,代表音的高低,相邻为半音,如60和61,隔1为全音,如63和65;volume为设备的音量值,普遍使用的是0-100之间的值。channel为通道,默认使用0即可。所谓通道就是MIDI音乐中的音层,就像电子琴的16个音层,有节奏通道,和弦通道,低音通道等等。最大可以支持16层,可以取其任意一个值即可。

将以上步骤封装在一个函数中,如下:

private void playNote(IntPtr handle, uint data, int time)
        {
            Audio.midiOutShortMsg(handle, Convert.ToUInt32(0x000000C0 + comboBox1.SelectedIndex * 256));
            if (data == 0)
            {
                System.Threading.Thread.Sleep(time);
                return;
            }
            Audio.midiOutShortMsg(handle, Convert.ToUInt32(0x00403B90 + data * 256));
            System.Threading.Thread.Sleep(time);
            Audio.midiOutReset(handle);
        }
//combobox1是音色的下拉列表,data是基于3B的音阶

通过以上函数,执行下列代码,即可播放98笑傲江湖(吕颂贤)中的音调。

private void btnSample_Click(object sender, EventArgs e)
        {
            playNote(handle, 12, 250);
            playNote(handle, 12, 250);
            playNote(handle, 15, 250);
            playNote(handle, 17, 250);
            playNote(handle, 19, 1000);
            playNote(handle, 24, 700);
            playNote(handle, 19, 250);
            playNote(handle, 22, 200);
            playNote(handle, 00, 250);
            playNote(handle, 22, 900);
            playNote(handle, 19, 400);
            playNote(handle, 17, 400);
            playNote(handle, 19, 400);
            playNote(handle, 22, 400);
            playNote(handle, 24, 250);
            playNote(handle, 22, 250);
            playNote(handle, 19, 1500);
            playNote(handle, 00, 300);
            playNote(handle, 19, 1000);
            playNote(handle, 24, 700);
            playNote(handle, 19, 250);
            playNote(handle, 22, 200);
            playNote(handle, 00, 250);
            playNote(handle, 22, 900);
            playNote(handle, 19, 400);
            playNote(handle, 17, 400);
            playNote(handle, 19, 400);
            playNote(handle, 22, 400);
            playNote(handle, 24, 250);
            playNote(handle, 22, 250);
            playNote(handle, 19, 1000);
            playNote(handle, 00, 300);
            playNote(handle, 19, 400);
            playNote(handle, 17, 250);
            playNote(handle, 15, 600);
            playNote(handle, 00, 100);
            playNote(handle, 15, 250);
            playNote(handle, 17, 400);
            playNote(handle, 19, 400);
            playNote(handle, 17, 100);
            playNote(handle, 00, 250);
            playNote(handle, 17, 500);
            playNote(handle, 00, 100);
            playNote(handle, 17, 400);
            playNote(handle, 15, 250);
            playNote(handle, 12, 250);
            playNote(handle, 00, 100);
            playNote(handle, 12, 250);
            playNote(handle, 15, 250);
            playNote(handle, 17, 400);
            playNote(handle, 19, 400);
            playNote(handle, 22, 600);
            playNote(handle, 24, 250);
            playNote(handle, 22, 400);
            playNote(handle, 19, 250);
            playNote(handle, 17, 250);
            playNote(handle, 15, 600);
            playNote(handle, 17, 600);
            playNote(handle, 19, 400);
            playNote(handle, 17, 150);
            playNote(handle, 00, 250);
            playNote(handle, 17, 600);
            playNote(handle, 15, 600);
            playNote(handle, 12, 300);
            playNote(handle, 00, 100);
            playNote(handle, 12, 250);
            playNote(handle, 15, 250);
            playNote(handle, 17, 250);
            playNote(handle, 19, 400);
            playNote(handle, 22, 250);
            playNote(handle, 24, 700);
            playNote(handle, 00, 100);
            playNote(handle, 24, 500);
        }

原创粉丝点击