如何将一个小数MIDI弯音值到2正确分离7位值? [英] How to divide a decimal MIDI pitch-bend value into 2 separated 7 bit values correctly?

查看:494
本文介绍了如何将一个小数MIDI弯音值到2正确分离7位值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做一个排序定制MIDI播放器,这样做,我使用已经正确地记住这样的MIDI信息数据的数组:

I'm trying to make a sort of custom midi player, to do so I'm using an array that already has memorized correctly the midi messages data like this:

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

当我希望我的程序发送MIDI消息(以便它可以播放)我叫
这个数组并做noteon开/关,弯音并且这样的需要区别。音调弯曲值(范围从0到16383,但通常是大约8192,这意味着无音高移位)在DATA1所有记忆(阵列[I] [2])。对于从int到两个7位的值传递给midiOutShortMsg()转换我用了一些code,我发现<一的href=\"http://stackoverflow.com/questions/13589979/calculating-coremidi-pitch-bend-values-for-ios\">here.下面是我在实际使用code:

when I want my program to send the midi message (so that it can be played) I call this array and do the needed distinctions between noteon/off, pitch-bend and such. The pitch-bend value (ranging from 0 to 16383, but usually is around 8192 which means no pitch shifting) is all memorized in data1 (array[i][2]). For the conversion from int to the two 7 bits values to pass to midiOutShortMsg() I've used some of the code I found here. Here is the code I'm actually using:

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(%弯曲D,%D)函数始终打印第一个%d个为0,不管是什么。这是我第一次在节目MIDI和我从来没有处理前7位的值,所以我得到相当混乱,任何帮助将AP preciated。

The printf("bending %d,%d") function always prints the first %d as a 0, no matter what. It's the first time I program in midi and I never had to deal with 7 bits values before, so I'm getting quite confused, any help will be appreciated.

推荐答案

有关弯音信息数据1(你message.data [1])是LSB和数据2(message.data [2])是MSB。我不是一个C语言开发,但这里是我如何做到这一点在一些伪code:

For a pitch bend message data1 (your message.data[1]) is the LSB, and data2 (message.data[2]) is MSB. I'm not a C developer, but here's how I do it in some pseudo-code:

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

在英语:


  • MSB是:弯音位右移7

  • LSB是:弯音位与127
  • 的面具

有关参考,在做相反的(两个值,结合计算弯音,如果你已经在消息中接收他们为实例)是一个简单的问题:

For reference, doing the reverse (combining the two values to calculate pitch bend, if you had received them in a message, for instance) is a simple matter of:

pitchbend = (data2 * 128) + data1

编辑:我更仔细地看了你的code,它看起来像你已经做了什么,我描述。 IE浏览器:

I read your code more closely, and it looks like you're already doing what I described. IE:

uint16_t mask = 0x007F;
bend = (uint16_t) array[i][2];

message.data[1] = bend & mask;
message.data[2] = (bend & (mask << 7)) >> 7;

数组[我] [2] 是你想送什么样的价值观?凡是是的偶数倍128将导致零LSB( message.data [1] )。这是不寻常的设备忽略,或不使用的低字节提供的附加分辨率,因此您的样本MIDI数据可能在此条件下下降。

What values for array[i][2] are you trying to send? Anything that is an even multiple of 128 will result in an LSB (message.data[1]) of zero. It is not uncommon for devices to ignore, or not use the added resolution provided by the low byte, so your sample MIDI data may fall under this condition.

这篇关于如何将一个小数MIDI弯音值到2正确分离7位值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆