无法继续进行 switch case C 编程
Posted
技术标签:
【中文标题】无法继续进行 switch case C 编程【英文标题】:Cannot proceed on the switch case C programming 【发布时间】: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 调试器。你能建议一些吗? 【参考方案1】:您没有正确处理元事件的长度。
元事件的格式为 FF type length data...,因此您必须跳过的字节数(除了 FF byte 本身)在大多数情况下是 2 加上长度,而不是 4+长度。
另外,元事件长度是一个可变长度的数字,而不是一个字节。
另外,我没有看到用于处理每个事件前面的增量时间的代码。
另外,你没有处理运行状态。
我建议您阅读并尝试理解一些现有的已知可以工作的 SMF 解析器。
例如,请参见 aplaymidi.c 中的函数 read_smf
和 read_track
。
【讨论】:
谢谢,我会试着从你给出的例子中学习。但是,实际上我只转发那些消息。我应该继续处理增量时间和运行状态吗? 如果没有这些功能,该程序将根本无法运行。以上是关于无法继续进行 switch case C 编程的主要内容,如果未能解决你的问题,请参考以下文章