0

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

这是我用来播放音符的代码片段。

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;
    }
};

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

如何播放连续的 theremin 声音,如连续改变音高的声音?

4

3 回答 3

2

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

如果你想在当前的实现中顺利地从一个音符切换到下一个音符,你需要一个有很多滑音的合成器补丁。通过在初始化时将 CC37 设置为 127,您可能可以让它在许多补丁上工作。

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

根据合成器的不同,您可以使用 RPN 调整其弯音范围以获得弯音灵敏度。你可以在这里阅读:http: //www.hoofjaw.com/forums/Topic946-32-1.aspx#bm1254

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

于 2011-06-24T13:39:51.560 回答
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);
于 2011-06-24T13:55:48.520 回答
1

已经有很长一段时间了,但我确实记得 MIDI 具有表示音高变化的能力,例如,在 MIDI 控制器(合成器或键盘)上滚动弯音轮是通过 MIDI 传输的。您可以考虑使用这种类型的消息来改变连续演奏音符的音高。

于 2011-06-24T06:20:46.480 回答