Как правильно делить десятичное значение тонального изгиба MIDI на 2 разделенных 7-битных значения?

Я пытаюсь создать своего рода пользовательский midi-плеер, для этого я использую массив, который уже правильно запомнил данные midi-сообщений, например:

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

когда я хочу, чтобы моя программа отправила сообщение midi (чтобы его можно было воспроизвести) я вызываю этот массив и делать необходимые различия между примечанием/выключением, наклоном тона и т.д. Значение высоты тона (в диапазоне от 0 до 16383, но обычно около 8192, что означает отсутствие смещения основного тона), запоминается в data1 (array [i] [2]). Для преобразования из int в два значения 7 бит для перехода к midiOutShortMsg() я использовал код, найденный мной здесь. Вот код, который я фактически использую:

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-битными значениями раньше, поэтому я очень запутался, любая помощь будет оценена.

4
задан 19 мая '15 в 20:35
источник поделиться
1 ответ

Для сообщения сообщения с изгибом высоты тона (ваш message.data [1]) является LSB, а data2 (message.data [2]) является MSB. Я не разработчик C, но вот как я это делаю в каком-то псевдокоде:

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

На английском языке:

  • MSB: сдвиг бита бита вправо 7
  • LSB: pitchbend побитовое AND с маской 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 могут подпадать под это условие.

6
ответ дан 20 мая '15 в 12:45
источник

Другие вопросы по меткам или Задайте вопрос