我正在尝试创建一个类似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;
}
};
问题在于以这种方式播放的音符听起来不同;从一个音符到另一个音符有明显的过渡。
如何连续播放像声音那样连续改变音高?
答案 0 :(得分:2)
这个问题与MIDI无关,更多的是与产生声音的合成器有关。
如果你想用当前的实现顺利地从一个音符到另一个音符,你需要一个有很多滑音的合成音色补丁。初始化时,通过将CC37设置为127,您可以将其用于许多补丁。
理想情况下,为了完全平滑,您需要一个合成补丁来解释弯音,而不仅仅是向上和向下一步。同样,这与你发送的值有 nothing 。无论怎样,这些都是14位的。由合成器来决定这些值的上升/下降程度。
根据合成器的不同,您可以使用RPN调节弯音范围以适应弯音灵敏度。您可以在此处阅读:http://www.hoofjaw.com/forums/Topic946-32-1.aspx#bm1254
答案 1 :(得分:2)
您应该可以通过MIDI音高轮更换事件来完成此操作。
在幕后,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传输的。您可以考虑使用此类消息来改变连续播放音符的音高。