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

标签 c winapi midi pitch

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

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

当我希望我的程序发送 midi 消息(以便它可以播放)时,我调用这个数组并在音符/关闭、弯音等之间进行必要的区分。起初我以为我在做两个 7 位变量的除法是错误的,因为我从来没有使用过这个过程,我只是从 stackoverflow 上的另一个问题中复制了代码,我发布了我自己的问题(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 的输出: printf output as requested

我真的不知道我做错了什么,我们将不胜感激。

最佳答案

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

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

关于c - 如何在 c 中正确发送 MIDI 弯音消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30355363/

相关文章:

c - 在 C 中调用 fork() 后引用指针

c - 使用哪种加密方法?

c - 静态变量在栈上的空间分配

c++ - 有没有办法不延迟地播放声音?

c++ - 使用 GetOpenFileName() 限制目录

ios - 混合 midi 文件,每个文件都有自己的声音字体

c - 如何使用 shmget 跨多个进程共享一 block 内存

c++ - 数据类型转换问题

c# - midioutshortmsg 没有声音

python - 识别音乐拍号21