无法继续进行 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_smfread_track

【讨论】:

谢谢,我会试着从你给出的例子中学习。但是,实际上我只转发那些消息。我应该继续处理增量时间和运行状态吗? 如果没有这些功能,该程序将根本无法运行。

以上是关于无法继续进行 switch case C 编程的主要内容,如果未能解决你的问题,请参考以下文章

C switch

c语言case

case语言怎么用

c语言中应用switch语句编程:输入1-7之间的任意数字,程序按照用户的输入输出相应的星期值!!

c语言中case的意思和用法

C语言中的Switch-case语句