【发布时间】:2014-05-19 09:26:24
【问题描述】:
我正在尝试解析 MIDI 文件并发送 MIDI 信号。我首先通过在屏幕上打印来测试它。现在,我一直在解析元事件(不是作为 MIDI 信号发送的东西)。
结果显示第一次使用 case 已经正确,但我无法在第二次切换上进行处理。确切地说,我无法处理第一个 FF 字节之后的 FF 字节。
这是我的代码:
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Programmer : Grahmada Ruci Batara
/// File Name : midiread.c
/// Last modified : 8 Mei 2014
/// Program Description :
///
/// Read MIDI file and return it as a MIDI output /
/// Membaca file MIDI dan mengembalikannya
/// sebagai MIDI keluaran
///
////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
//#include <termios.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//#include <sys/types.h>
//#include <sys/stat.h>
//#include <fcntl.h>
////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// DECLARATION / DEKLARASI
///
///////////////////////////////////////////////////////////////////////////////////////////////////////
#define BAUDRATE B31250
#define MIDIDEVICE "/dev/ttyO4" //Beaglebone Black serial port
#define FALSE 0
#define TRUE 1
FILE* in_file;
char MIDIName[100]=" "; //Storing File Name
int MIDISize;
unsigned char buffer[999999]; // a copy of file for modified
char MThd[4] = "MThd";
unsigned char MTrk[4] = "MTrk";
int MTrksize1;
int i;
//////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// FUNCTIONS / FUNGSI - FUNGSI
///
//////////////////////////////////////////////////////////////////////////////////////////////////////
/// Getting file size / mencari ukuran file (fsize) ///
int fsize(FILE *fp){
int prev=ftell(fp);
fseek(fp, 0L, SEEK_END); // seek to end of file
int sz=ftell(fp); // get current file pointer
fseek(fp,prev,SEEK_SET); //go back to where we were
return sz;
}
//send MIDI message
//void SendMIDImessage(unsigned char command, unsigned char MIDInote, unsigned char MIDIvelocity) {
//Serial.write(command);//send note on or note off command
//Serial.write(MIDInote);//send pitch data
//Serial.write(MIDIvelocity);//send velocity data
//}
//send MIDI message 1 byte
//void SendMIDImessage2(unsigned char command, unsigned char MIDInote) {
//Serial.write(command);//send note on or note off command
//Serial.write(MIDInote);//send pitch data
//}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// -------------------------------- MAIN / UTAMA --------------------------------------------
///
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
printf("Please Enter MIDI file with the extension (ex : file.mid): \n");
scanf("%s",&MIDIName); // Getting MIDI Name
in_file = fopen(MIDIName, "r"); // read only
if (! in_file ) // file checking
{
printf("File not found!\n");
exit(-1);
}
MIDISize = fsize(in_file); // Getting MIDI size
printf("file size : %d \n", MIDISize);
unsigned char temp;
for(i=0; i<MIDISize+1 ; i++) // copying the file to buffer
{
fscanf( in_file, "%c", &temp );
buffer[i]=temp;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// SERIAL COMMUNICATION / KOMUNIKASI SERIAL
///
//////////////////////////////////////////////////////////////////////////////////////////////////////
//fd = open(MIDIDEVICE, O_RDWR | O_NOCTTY | O_NDELAY);
//if(fd == -1) {
//printf( "failed to open port\n" );
//}
//////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// MThd (MIDI HEADER) PART
///
//////////////////////////////////////////////////////////////////////////////////////////////////////
for(i=0; i<4; i++)
{
if (buffer[i] != MThd[i])
{
printf("NOT MIDI FILE!!!");
return -1;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// MTrk (MIDI TRACK) 1 PART
///
//////////////////////////////////////////////////////////////////////////////////////////////////////
for(i=14; i<18; i++)
{
if (buffer[i] != MTrk[(i-14)])
{
printf("%02x", buffer[i]);
printf("MTrk NOT FOUND!!!");
return -1;
}
}
int temptot1;
int shiftk1=3;
int tot1 = 0;
for(i=18; i<22; i++)
{
temptot1 = buffer[i];
temptot1 += (temptot1 * (shiftk1*24));
tot1 += temptot1;
shiftk1--;
}
MTrksize1 = tot1;
printf ("MTrk following byte size : %x \n", MTrksize1);
//////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// MTrk (MIDI TRACK) 1 PART
///
//////////////////////////////////////////////////////////////////////////////////////////////////////
for(i=23; i< 23+MTrksize1; i++)
{
if (buffer[i] > 0x7F)
{
switch (buffer[i])
{
case 0x80:
{
printf("%02x, %02x, %02x",(buffer[i], buffer[i+1], buffer[i+2])); // note off (2 more bytes)
i += 2;
break;
}
case 0x90:
{
printf("%02x, %02x, %02x",(buffer[i], buffer[i+1], buffer[i+2])); // note on (2 more bytes)
i += 2;
break;
}
case 0xA0:
{
printf("%02x, %02x, %02x",(buffer[i], buffer[i+1], buffer[i+2])); // aftertouch (2 more bytes)
i += 2;
break;
}
case 0xB0:
{
printf("%02x, %02x, %02x",(buffer[i], buffer[i+1], buffer[i+2])); // cont. controller (2 more bytes)
i += 2;
break;
}
case 0xE0:
{
printf("%02x, %02x, %02x",(buffer[i], buffer[i+1], buffer[i+2])); // pitch wheel (2 more bytes)
i += 2;
break;
}
case 0xC0:
{
printf("%02x, %02x",(buffer[i], buffer[i+1])); // patch change (1 more byte)
i += 1;
break;
}
case 0xD0:
{
printf("%02x, %02x",(buffer[i], buffer[i+1])); // channel pressure (1 more byte)
i += 1;
break;
}
case 0xFF:
{
switch (buffer[i+1])
{ //meta event
case 0x2F:
{
printf("END OF TRACK");
break;
};
default:
{
printf("i = %d \n", i);
printf("buffer[i] = %02x \n", buffer[i]);
i += 4 + buffer[i+2];
printf("i = %d \n", i);
printf("buffer[i] = %02x \n", buffer[i]);
break;
}
};
break;
}
default:
{
printf("i = %d \n", i);
printf("byte : %02x \n", buffer[i]);
printf("ERROR IN READING FILE 1");
return -1;
break;
}
}
}
else
{
printf("i = %d \n", i);
printf("byte : %02x \n", buffer[i]);
printf("ERROR IN READING FILE 2");
return -1;
}
}
// tester
//for(i=0; i<MIDISize ; i++)
//{
//printf("%02x ",buffer[i]);
//}
fclose(in_file);
return 0; //end of program
}
我将在 beaglebone black 上实现它。如果有什么我需要知道的,请给我一个建议。
【问题讨论】:
-
你为什么不发布一个最小的完整示例呢?
-
你应该创建一个SSCCE
-
调试器告诉你什么?
-
感谢提示。干杯:)
-
我没有任何 C 调试器。你能建议一些吗?
标签: c switch-statement midi