【问题标题】:Cannot proceed on the switch case C programming无法继续进行 switch case C 编程
【发布时间】: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


【解决方案1】:

您没有正确处理元事件的长度。

元事件的格式为 FF type length data...,因此您必须跳过的字节数(除了 FF byte 本身)在大多数情况下是 2 加上长度,而不是 4+长度。

另外,元事件长度是一个可变长度的数字,而不是一个字节。

另外,我没有看到用于处理每个事件前面的增量时间的代码。

另外,你没有处理运行状态。


我建议您阅读并尝试理解一些现有的已知可以工作的 SMF 解析器。 例如,请参见 aplaymidi.c 中的函数 read_smfread_track

【讨论】:

  • 谢谢,我会试着从你给出的例子中学习。但是,实际上我只转发那些消息。我应该继续处理增量时间和运行状态吗?
  • 如果没有这些功能,该程序将根本无法运行。
猜你喜欢
  • 1970-01-01
  • 2011-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多