Как правильно отправлять сообщения MIDI Pitch Bend в c?
Я пытаюсь сделать пользовательский MIDI-плеер, для этого я использую массив, который уже запомнил правильно данные MIDI-сообщения, как это:
int array[3000][4]={{time,status,data1,data2},{...},...}
Когда я хочу, чтобы моя программа отправила MIDI-сообщение (чтобы его можно было воспроизвести), я вызываю этот массив и делаю необходимые различия между Noteon / Off, Pitch-Bend и так далее. Сначала я подумал, что делаю неправильные две 7-битные переменные, потому что я никогда не работал с этой процедурой и просто скопировал код из другого вопроса на stackru, я разместил свой собственный вопрос об этом ( здесь) и, как выясняется, Скопированный код работает просто отлично. И, тем не менее, звук не является правильным, он едва меняет высоту тона, а когда он есть, он настолько мал, что я даже не уверен, что слышу его (он должен звучать как полутоновый изгиб с Вибрато в конце). Итак, вот код:
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:
Я действительно не знаю, что я делаю неправильно, любая помощь будет оценена.
1 ответ
message.data[]
значения правильно рассчитаны; код не делает ничего плохого.
Проблема в том, что значения изгиба не соответствуют полутону. Диапазон изменения высоты звука по умолчанию отображает контрольные значения 0..16383 на ±2 полутона; чтобы получить полутон, значения должны быть увеличены до 12288.