在MIDI上播放类似连续音乐的声音

时间:2011-06-24 06:09:06

标签: c# .net midi winmm

我正在尝试创建一个类似theremin的程序,它根据鼠标光标位置播放连续音符。我正在使用Carl Franklin的MIDI Tools库来执行此操作。

这是我用来播放笔记的代码段。

byte pitch = 0;
while (exit == false)
{
    byte newpitch = (byte)(32 + ((float)Cursor.Position.X / (float)SystemParameters.PrimaryScreenWidth) * 64);

    if (newpitch != pitch)
    {
        instrument.StopNote(pitch,0);
        instrument.PlayNote(newpitch, 53);
        pitch = newpitch;
    }
};

问题在于以这种方式播放的音符听起来不同;从一个音符到另一个音符有明显的过渡。

如何连续播放像声音那样连续改变音高?

3 个答案:

答案 0 :(得分:2)

这个问题与MIDI无关,更多的是与产生声音的合成器有关。

如果你想用当前的实现顺利地从一个音符到另一个音符,你需要一个有很多滑音的合成音色补丁。初始化时,通过将CC37设置为127,您可以将其用于许多补丁。

理想情况下,为了完全平滑,您需要一个合成补丁来解释弯音,而不仅仅是向上和向下一步。同样,这与你发送的值有 nothing 。无论怎样,这些都是14位的。由合成器来决定这些值的上升/下降程度。

根据合成器的不同,您可以使用RPN调节弯音范围以适应弯音灵敏度。您可以在此处阅读:http://www.hoofjaw.com/forums/Topic946-32-1.aspx#bm1254

或者在这里:http://www.philrees.co.uk/nrpnq.htm

答案 1 :(得分:2)

您应该可以通过MIDI音高轮更换事件来完成此操作。

  • 第一个字节是0xE0 + MIDI通道号(0表示通道1)
  • 第二和第三个字节是变桨距变化值。 0x2000表示在中间,0x4000是最大值(通常被解释为+2半音,但音序器可以使用此消息执行它喜欢的操作)。

在幕后,Carl很可能只使用midiOutShortMsg发送消息,该消息将三个字节转换为DWORD。可能是他公开了一种让你直接发送DWORD的方法,如果他没有变距轮更改发送功能。

您需要记住,在每个音高移位值字节中都没有使用最高位,所以如果您将音高值作为整数,它会变成这样的短消息:

 int pitch = 0x2000; // no pitch change
 byte byte2 = (byte)(pitch & 0x7f));
 byte byte3 = (byte)((pitch >> 7)& 0x7f));
 int shortMessage = 0xE0 + (channelNumber - 1) + (byte2 << 8) + (byte3 << 16);

答案 2 :(得分:1)

已经很长时间了,但我确实记得MIDI能够代表音高变换,例如在MIDI控制器(合成器或键盘)上滚动弯音轮是通过MIDI传输的。您可以考虑使用此类消息来改变连续播放音符的音高。