我正在尝试制作一种自定义的midi播放器,为此,我使用的阵列已经正确存储了midi消息数据,如下所示:

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

当我希望我的程序发送midi消息(以便可以播放)时,我调用
此阵列,并在音调/关闭,弯音等之间进行所需的区分。弯音值(范围从0到16383,但通常为8192左右,这意味着没有音调偏移)都存储在data1(数组[i] [2])中。为了将int转换为两个7位值并传递给midiOutShortMsg(),我使用了发现的一些代码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++;
        }
    }
}}

无论如何,printf(“bending%d,%d”)函数始终将第一个%d打印为0。这是我第一次在midi中编程,而且以前从未处理过7位值,因此我感到非常困惑,我们将不胜感激。

最佳答案

对于弯音,消息数据1(您的message.data [1])是LSB,数据2(message.data [2])是MSB。我不是C开发人员,但是这是一些伪代码的处理方法:

(byte) data2 = pitchbend >> 7
(byte) data1 = pitchbend & 0x7F

用英语:
  • MSB是:弯音右移7
  • LSB是:弯头按位与且掩码为127

  • 作为引用,进行反向操作(例如,如果已在消息中接收到两个值,则将两个值组合起来以计算弯音)很简单:
    pitchbend = (data2 * 128) + data1
    

    编辑:我更仔细地阅读了您的代码,看来您已经在按照我的描述进行操作了。 IE:
    uint16_t mask = 0x007F;
    bend = (uint16_t) array[i][2];
    
    message.data[1] = bend & mask;
    message.data[2] = (bend & (mask << 7)) >> 7;
    

    您要发送的array[i][2]值是什么?任何为128的偶数倍的结果将导致LSB(message.data[1])为零。设备通常会忽略或不使用低字节提供的增加的分辨率,因此您的示例MIDI数据可能会属于这种情况。

    关于c - 如何将十进制MIDI弯音值正确地分为2个分开的7位值?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30332416/

    10-15 03:13