如何在 c 中正确发送 midi 弯音消息?

Posted

技术标签:

【中文标题】如何在 c 中正确发送 midi 弯音消息?【英文标题】:How to send midi pitch bend messages correctly in c? 【发布时间】:2015-05-20 16:26:06 【问题描述】:

我正在尝试制作一个自定义的 midi 播放器,为此我使用了一个已经正确记住 midi 消息数据的数组,如下所示:

int array[3000][4]=time,status,data1,data2,...,...

当我希望我的程序发送 midi 消息(以便可以播放)时,我调用这个数组并在 note/off、pitch-bend 等之间进行必要的区分。起初我以为我在两个 7 位变量中的除法是错误的,因为我从来没有使用过这个过程,我只是从 *** 上的另一个问题中复制了代码,我发布了我自己关于它的问题 (here) 和它原来复制的代码工作得很好。然而声音输出不是正确的,它几乎没有任何音调变化,当它有变化时,它是如此之小,我什至不确定我是否听到它(它听起来应该像半音弯曲,带有最后的颤音)。代码如下:

 union  unsigned long word; unsigned char data[4];  message;
 int main(int argc, char** argv) 
     int midiport; // select which MIDI output port to open
     uint16_t bend;
     int flag,u;    // monitor the status of returning functions
     uint16_t mask = 0x007F;
     HMIDIOUT device;    // MIDI device interface for sending MIDI output
     message.data[0] = 0x90;  
     message.data[1] = 60;    
     message.data[2] = 100;   
     message.data[3] = 0;     // Unused parameter


 // Assign the MIDI output port number (from input or default to 0)
 if (!midiOutGetNumDevs())
     printf("non ci sono devices");
 
 if (argc < 2) 
     midiport = 0;
 
 else 
     midiport = 0;
 
 printf("MIDI output port set to %d.\n", midiport);

 // Open the MIDI output port
 flag = midiOutOpen(&device, midiport, 0, 0, CALLBACK_NULL);
 if (flag != MMSYSERR_NOERROR) 
     printf("Error opening MIDI Output.\n");
     return 1;
 i = 0;
 message.data[0] = 0xC0;
 message.data[1] = 25;
 message.data[2] = 0;
 flag = midiOutShortMsg(device, message.word); //program change to steel guitar
 if (flag != MMSYSERR_NOERROR) 
     printf("Warning: MIDI Output is not open.\n");
 
 while (1)
     if (array[i][1] == 1)  //note on 
         this_works();i++;
     
     else if (array[i][1] == 0)//note off
         this_also_works();i++;
     
     else if (array[i][1] == 2)//pitch bend
         while (array[i][1] == 2)
             Sleep(10);
             message.data[0] = 0xE0;
             bend = (uint16_t) array[i][2];
             message.data[1] = bend & mask;
             message.data[2] = (bend & (mask << 7)) >> 7;
             printf("bending %d, %d\n", message.data[1],message.data[2]); 
             flag = midiOutShortMsg(device, message.word);
             if (flag != MMSYSERR_NOERROR) 
                 printf("Warning: MIDI Output is not open.\n");
             i++;
         
     
 

这是带有颤音的半音弯音的弯音数组[][] 值:

 6560, 2, 8192 ,
 6576, 2, 8320 ,
 6592, 2, 8448 ,
 6608, 2, 8704 ,
 6624, 2, 8832 ,
 6720, 2, 8832 ,
 6729, 2, 8832 ,
 6739, 2, 8832 ,
 6748, 2, 8832 ,
 6757, 2, 8832 ,
 6766, 2, 8832 ,
 6776, 2, 8704 ,
 6785, 2, 8704 ,
 6794, 2, 8704 ,
 6804, 2, 8704 ,
 6813, 2, 8704 ,
 6822, 2, 8832 ,
 6831, 2, 8832 ,
 6841, 2, 8832 ,
 6850, 2, 8832 ,
 6859, 2, 8832 ,
 6868, 2, 8832 ,
 6878, 2, 8832 ,
 6887, 2, 8832 ,
 6896, 2, 8832 ,
 6906, 2, 8832 ,
 6915, 2, 8832 ,
 6924, 2, 8960 ,
 6933, 2, 8960 ,
 6943, 2, 8960 ,
 6952, 2, 8960 ,
 6961, 2, 8960 ,
 6971, 2, 8832 ,
 6980, 2, 8832 ,
 6989, 2, 8832 ,
 6998, 2, 8832 ,
 7008, 2, 8832 ,
 7017, 2, 8832 ,
 7026, 2, 8832 ,
 7036, 2, 8960 ,
 7045, 2, 8960 ,
 7054, 2, 8960 ,
 7063, 2, 8960 ,
 7073, 2, 8960 ,
 7082, 2, 8960 ,
 7091, 2, 8960 ,
 7101, 2, 8960 ,
 7110, 2, 8960 ,
 7119, 2, 8960 ,
 7128, 2, 8960 ,
 7138, 2, 8960 ,
 7147, 2, 8960 ,
 7156, 2, 8832 ,
 7165, 2, 8832 ,
 7175, 2, 8832 ,
 7184, 2, 8704 ,
 7193, 2, 8704 ,
 7203, 2, 8704 ,
 7212, 2, 8704 ,
 7221, 2, 8704 ,
 7230, 2, 8704 ,
 7240, 2, 8704 ,
 7249, 2, 8704 ,
 7258, 2, 8704 ,
 7268, 2, 8704 ,
 7277, 2, 8704 ,
 7286, 2, 8704 ,
 7295, 2, 8704 ,
 7305, 2, 8832 ,
 7314, 2, 8832 ,
 7323, 2, 8832 ,
 7333, 2, 8960 ,
 7342, 2, 8960 ,
 7351, 2, 9088 ,
 7360, 2, 9088 ,
 7370, 2, 9088 ,
 7379, 2, 9088 ,
 7388, 2, 9088 ,
 7398, 2, 9088 ,
 7407, 2, 9088 ,
 7416, 2, 9088 ,
 7425, 2, 9088 ,
 7435, 2, 8960 ,
 7444, 2, 8960 ,
 7453, 2, 8832 ,
 7462, 2, 8832 ,
 7472, 2, 8832 ,
 7481, 2, 8704 ,
 7490, 2, 8704 ,
 7500, 2, 8576 ,
 7509, 2, 8576 ,
 7518, 2, 8576 ,
 7527, 2, 8576 ,
 7537, 2, 8576 ,
 7546, 2, 8576 ,
 7555, 2, 8576 ,
 7565, 2, 8576 ,
 7574, 2, 8576 ,
 7583, 2, 8704 ,
 7592, 2, 8704 ,
 7602, 2, 8832 ,
 7611, 2, 8832 ,
 7620, 2, 8832 ,
 7630, 2, 8832 ,
 7639, 2, 8832 ,
 7648, 2, 8832 ,
 7657, 2, 8832 ,
 7667, 2, 8832 ,
 7676, 2, 8832 ,

这是 printf 的输出:

我真的不知道我做错了什么,任何帮助将不胜感激。

【问题讨论】:

@WeatherVane arrayint(显示在顶部)。 在同一个 printf 调用中显示 array[i][2]bend @CL。我已经使用带有 array[i][2] 的新输出图像编辑了我的问题,并根据要求在 printf 中弯曲。 【参考方案1】:

message.data[] 值计算正确;代码没有错。

问题在于弯曲值不对应于半色调。 默认弯音范围将 0..16383 控制值映射到 ±2 半色调;要提高半音,值必须达到 12288。

【讨论】:

以上是关于如何在 c 中正确发送 midi 弯音消息?的主要内容,如果未能解决你的问题,请参考以下文章

iOS 中的 MIDI 合成行为不端 WRT 弯音:忽略 LSB

在 C# 中将 MIDI 消息发送到 DAW

如何使用 pyPortMidi 或 pygame 发送 midi 控制更改消息 (CC)?

如何使用 Audiokit 发送 midi poly pressure 消息?

在 Android 中从钢琴中读取 MIDI 消息

C# / nAudio - 向控制器发送 MIDI 消息