📄 midifile.c
字号:
} metaevent(type); break; case 0xf0: /* start of system exclusive */ /* watch out - Don't combine the next 2 statements */ lng = readvarinum(); if (midifile_error) return; lookfor = Mf_toberead - lng; msginit(); msgadd(0xf0); while ( Mf_toberead > lookfor ) { c = egetc(); if (midifile_error) return; msgadd(c); } if ( c==0xf7 || Mf_nomerge==0 ) sysex(); else sysexcontinue = 1; /* merge into next msg */ break; case 0xf7: /* sysex continuation or arbitrary stuff */ /* watch out - Don't combine the next 2 statements */ lng = readvarinum(); if (midifile_error) return; lookfor = Mf_toberead - lng; if ( ! sysexcontinue ) msginit(); while ( Mf_toberead > lookfor ) { c = egetc(); if (midifile_error) return; msgadd(c); } if ( ! sysexcontinue ) { if ( Mf_arbitrary ) (*Mf_arbitrary)(msgleng(),msg()); } else if ( c == 0xf7 ) { sysex(); sysexcontinue = 0; } break; default: badbyte(c); break; } } if ( Mf_endtrack ) (*Mf_endtrack)(); return;}static voidbadbyte(c)int c;{ char buff[32]; (void) sprintf(buff,"unexpected byte: 0x%02x",c); mferror(buff);}static voidmetaevent(type){ int leng = msgleng(); char *m = msg(); switch ( type ) { case 0x00: if ( Mf_seqnum ) (*Mf_seqnum)(to16bit(m[0],m[1])); break; case 0x01: /* Text event */ case 0x02: /* Copyright notice */ case 0x03: /* Sequence/Track name */ case 0x04: /* Instrument name */ case 0x05: /* Lyric */ case 0x06: /* Marker */ case 0x07: /* Cue point */ case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: /* These are all text events */ if ( Mf_text ) (*Mf_text)(type,leng,m); break; case 0x2f: /* End of Track */ if ( Mf_eot ) (*Mf_eot)(); break; case 0x51: /* Set tempo */ if ( Mf_tempo ) (*Mf_tempo)(to32bit(0,m[0],m[1],m[2])); break; case 0x54: if ( Mf_smpte ) (*Mf_smpte)(m[0],m[1],m[2],m[3],m[4]); break; case 0x58: if ( Mf_timesig ) (*Mf_timesig)(m[0],m[1],m[2],m[3]); break; case 0x59: if ( Mf_keysig ) (*Mf_keysig)(m[0],m[1]); break; case 0x7f: if ( Mf_sqspecific ) (*Mf_sqspecific)(leng,m); break; default: if ( Mf_metamisc ) (*Mf_metamisc)(type,leng,m); }}static voidsysex(){ if ( Mf_sysex ) (*Mf_sysex)(msgleng(),msg());}static voidchanmessage(status,c1,c2)int status;int c1, c2;{ int chan = status & 0xf; switch ( status & 0xf0 ) { case NOTEOFF: if ( Mf_off ) (*Mf_off)(chan,c1,c2); break; case NOTEON: if ( Mf_on ) (*Mf_on)(chan,c1,c2); break; case PRESSURE: if ( Mf_pressure ) (*Mf_pressure)(chan,c1,c2); break; case CONTROLLER: if ( Mf_controller ) (*Mf_controller)(chan,c1,c2); break; case PITCHBEND: if ( Mf_pitchbend ) (*Mf_pitchbend)(chan,c1,c2); break; case PROGRAM: if ( Mf_program ) (*Mf_program)(chan,c1); break; case CHANPRESSURE: if ( Mf_chanpressure ) (*Mf_chanpressure)(chan,c1); break; }}/* readvarinum - read a varying-length number, and return the *//* number of characters it took. */static longreadvarinum(){ long value; int c; c = egetc(); if (midifile_error) return 0; value = (long) c; if ( c & 0x80 ) { value &= 0x7f; do { c = egetc(); if (midifile_error) return 0; value = (value << 7) + (c & 0x7f); } while (c & 0x80); } return (value);}static longto32bit(c1,c2,c3,c4){ long value = 0L; value = (c1 & 0xff); value = (value<<8) + (c2 & 0xff); value = (value<<8) + (c3 & 0xff); value = (value<<8) + (c4 & 0xff); return (value);}static intto16bit(c1,c2)int c1, c2;{ return ((c1 & 0xff ) << 8) + (c2 & 0xff);}static longread32bit(){ int c1, c2, c3, c4; c1 = egetc(); if (midifile_error) return 0; c2 = egetc(); if (midifile_error) return 0; c3 = egetc(); if (midifile_error) return 0; c4 = egetc(); if (midifile_error) return 0; return to32bit(c1,c2,c3,c4);}static intread16bit(){ int c1, c2; c1 = egetc(); if (midifile_error) return 0; c2 = egetc(); if (midifile_error) return 0; return to16bit(c1,c2);}static voidmferror(s)char *s;{ if ( Mf_error ) (*Mf_error)(s); midifile_error = 1;}/* The code below allows collection of a system exclusive message of *//* arbitrary length. The Msgbuff is expanded as necessary. The only *//* visible data/routines are msginit(), msgadd(), msg(), msgleng(). */#define MSGINCREMENT 128static char *Msgbuff = 0; /* message buffer */static int Msgsize = 0; /* Size of currently allocated Msg */static int Msgindex = 0; /* index of next available location in Msg */static voidmsginit(){ Msgindex = 0;}static char *msg(){ return(Msgbuff);}static intmsgleng(){ return(Msgindex);}static voidmsgadd(c)int c;{ /* If necessary, allocate larger message buffer. */ if ( Msgindex >= Msgsize ) msgenlarge(); Msgbuff[Msgindex++] = c;}static voidmsgenlarge(){ char *newmess; char *oldmess = Msgbuff; int oldleng = Msgsize; Msgsize += MSGINCREMENT; newmess = MALLOC((sizeof(char)*Msgsize) ); /* copy old message into larger new one */ if ( oldmess != 0 ) { register char *p = newmess; register char *q = oldmess; register char *endq = &oldmess[oldleng]; for ( ; q!=endq ; p++,q++ ) *p = *q; free(oldmess); } Msgbuff = newmess;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -