📄 readmidi.c
字号:
/* Print a string from the file, followed by a newline. Any non-ASCII or unprintable characters will be converted to periods. */static char *dumpstring(int type, int32 len, char *label, int allocp, struct timidity_file *tf){ char *si, *so; int s_maxlen = SAFE_CONVERT_LENGTH(len); int llen, solen; if(len <= 0) { ctl->cmsg(CMSG_TEXT, VERB_VERBOSE, "%s", label); return NULL; } si = (char *)new_segment(&tmpbuffer, len + 1); so = (char *)new_segment(&tmpbuffer, s_maxlen); if(len != tf_read(si, 1, len, tf)) { reuse_mblock(&tmpbuffer); return NULL; } si[len]='\0'; if(type == 1 && current_read_track == 1 && current_file_info->format == 1 && strncmp(si, "@KMIDI", 6) == 0) karaoke_format = 1; code_convert(si, so, s_maxlen, NULL, NULL); llen = strlen(label); solen = strlen(so); if(llen + solen >= MIN_MBLOCK_SIZE) so[MIN_MBLOCK_SIZE - llen - 1] = '\0'; ctl->cmsg(CMSG_TEXT, VERB_VERBOSE, "%s%s", label, so); if(allocp) { so = safe_strdup(so); reuse_mblock(&tmpbuffer); return so; } reuse_mblock(&tmpbuffer); return NULL;}static uint16 gs_convert_master_vol(int vol){ double v; if(vol >= 0x7f) return 0xffff; v = (double)vol * (0xffff/127.0); if(v >= 0xffff) return 0xffff; return (uint16)v;}static uint16 gm_convert_master_vol(uint16 v1, uint16 v2){ return (((v1 & 0x7f) | ((v2 & 0x7f) << 7)) << 2) | 3;}static void check_chorus_text_start(void){ struct chorus_text_gs_t *p = &(chorus_status_gs.text); if(p->status != CHORUS_ST_OK && p->voice_reserve[17] && p->macro[2] && p->pre_lpf[2] && p->level[2] && p->feed_back[2] && p->delay[2] && p->rate[2] && p->depth[2] && p->send_level[2]) { ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Chorus text start"); p->status = CHORUS_ST_OK; }}int convert_midi_control_change(int chn, int type, int val, MidiEvent *ev_ret){ switch(type) { case 0: type = ME_TONE_BANK_MSB; break; case 1: type = ME_MODULATION_WHEEL; break; case 2: type = ME_BREATH; break; case 4: type = ME_FOOT; break; case 5: type = ME_PORTAMENTO_TIME_MSB; break; case 6: type = ME_DATA_ENTRY_MSB; break; case 7: type = ME_MAINVOLUME; break; case 8: type = ME_BALANCE; break; case 10: type = ME_PAN; break; case 11: type = ME_EXPRESSION; break; case 32: type = ME_TONE_BANK_LSB; break; case 37: type = ME_PORTAMENTO_TIME_LSB; break; case 38: type = ME_DATA_ENTRY_LSB; break; case 64: type = ME_SUSTAIN; break; case 65: type = ME_PORTAMENTO; break; case 66: type = ME_SOSTENUTO; break; case 67: type = ME_SOFT_PEDAL; break; case 68: type = ME_LEGATO_FOOTSWITCH; break; case 69: type = ME_HOLD2; break; case 71: type = ME_HARMONIC_CONTENT; break; case 72: type = ME_RELEASE_TIME; break; case 73: type = ME_ATTACK_TIME; break; case 74: type = ME_BRIGHTNESS; break; case 84: type = ME_PORTAMENTO_CONTROL; break; case 91: type = ME_REVERB_EFFECT; break; case 92: type = ME_TREMOLO_EFFECT; break; case 93: type = ME_CHORUS_EFFECT; break; case 94: type = ME_CELESTE_EFFECT; break; case 95: type = ME_PHASER_EFFECT; break; case 96: type = ME_RPN_INC; break; case 97: type = ME_RPN_DEC; break; case 98: type = ME_NRPN_LSB; break; case 99: type = ME_NRPN_MSB; break; case 100: type = ME_RPN_LSB; break; case 101: type = ME_RPN_MSB; break; case 120: type = ME_ALL_SOUNDS_OFF; break; case 121: type = ME_RESET_CONTROLLERS; break; case 123: type = ME_ALL_NOTES_OFF; break; case 126: type = ME_MONO; break; case 127: type = ME_POLY; break; default: type = -1; break; } if(type != -1) { if(val > 127) val = 127; ev_ret->type = type; ev_ret->channel = chn; ev_ret->a = val; ev_ret->b = 0; return 1; } return 0;}static int block_to_part(int block, int port){ int p; p = block & 0x0F; if(p == 0) {p = 9;} else if(p <= 9) {p--;} return MERGE_CHANNEL_PORT2(p, port);}/* Map XG types onto GS types. XG should eventually have its own tables */static int set_xg_reverb_type(int msb, int lsb){ int type = 4; if ((msb == 0x00) || (msb >= 0x05 && msb <= 0x0F) || (msb >= 0x14)) /* NO EFFECT */ { ctl->cmsg(CMSG_INFO,VERB_NOISY,"XG Set Reverb Type (NO EFFECT %d %d)", msb, lsb); return -1; } switch(msb) { case 0x01: type = 3; /* Hall 1 */ break; case 0x02: type = 0; /* Room 1 */ break; case 0x03: type = 3; /* Stage 1 -> Hall 1 */ case 0x04: type = 5; /* Plate */ break; default: type = 4; /* unsupported -> Hall 2 */ break; } if (lsb == 0x01) { switch(msb) { case 0x01: type = 4; /* Hall 2 */ break; case 0x02: type = 1; /* Room 2 */ break; case 0x03: type = 4; /* Stage 2 -> Hall 2 */ break; default: break; } } if (lsb == 0x02 && msb == 0x02) type = 2; /* Room 3 */ ctl->cmsg(CMSG_INFO,VERB_NOISY,"XG Set Reverb Type (%d)", type); return type;}/* Map XG types onto GS types. XG should eventually have its own tables */static int set_xg_chorus_type(int msb, int lsb){ int type = 2; if ((msb >= 0x00 && msb <= 0x40) || (msb >= 0x45 && msb <= 0x47) || (msb >= 0x49)) /* NO EFFECT */ { ctl->cmsg(CMSG_INFO,VERB_NOISY,"XG Set Chorus Type (NO EFFECT %d %d)", msb, lsb); return -1; } switch(msb) { case 0x41: type = 0; /* Chorus 1 */ break; case 0x42: type = 0; /* Celeste 1 -> Chorus 1 */ break; case 0x43: type = 5; break; default: type = 2; /* unsupported -> Chorus 3 */ break; } if (lsb == 0x01) { switch(msb) { case 0x41: type = 1; /* Chorus 2 */ break; case 0x42: type = 1; /* Celeste 2 -> Chorus 2 */ break; default: break; } } else if (lsb == 0x02) { switch(msb) { case 0x41: type = 2; /* Chorus 3 */ break; case 0x42: type = 2; /* Celeste 3 -> Chorus 3 */ break; default: break; } } else if (lsb == 0x08) { switch(msb) { case 0x41: type = 3; /* Chorus 4 */ break; case 0x42: type = 3; /* Celeste 4 -> Chorus 4 */ break; default: break; } } ctl->cmsg(CMSG_INFO,VERB_NOISY,"XG Set Chorus Type (%d)", type); return type;}/* XG SysEx parsing function by Eric A. Welsh * Also handles GS patch+bank changes * * This function provides basic support for XG Bulk Dump and Parameter * Change SysEx events */int parse_sysex_event_multi(uint8 *val, int32 len, MidiEvent *evm){ int num_events = 0; /* Number of events added */ uint32 channel_tt; int i, j; static uint8 xg_reverb_type_msb = 0x01, xg_reverb_type_lsb = 0x00; static uint8 xg_chorus_type_msb = 0x41, xg_chorus_type_lsb = 0x00; if(current_file_info->mid == 0 || current_file_info->mid >= 0x7e) current_file_info->mid = val[0]; /* Effect 1 or Multi EQ */ if(len >= 8 && val[0] == 0x43 && /* Yamaha ID */ val[2] == 0x4C && /* XG Model ID */ ((val[1] < 0x10 && val[5] == 0x02) || /* Bulk Dump*/ (val[1] >= 0x10 && val[3] == 0x02))) /* Parameter Change */ { uint8 addhigh, addmid, addlow; /* Addresses */ uint8 *body; /* SysEx body */ int ent, v; /* Entry # of sub-event */ uint8 *body_end; /* End of SysEx body */ if (val[1] < 0x10) /* Bulk Dump */ { addhigh = val[5]; addmid = val[6]; addlow = val[7]; body = val + 8; body_end = val + len - 3; } else /* Parameter Change */ { addhigh = val[3]; addmid = val[4]; addlow = val[5]; body = val + 6; body_end = val + len - 2; } /* set the SYSEX_XG_MSB info */ SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_XG_MSB, 0, addhigh, addmid); num_events++; for (ent = addlow; body <= body_end; body++, ent++) { if(addmid == 0x01) { /* Effect 1 */ switch(ent) { case 0x00: /* Reverb Type MSB */ xg_reverb_type_msb = *body;#if 0 /* XG specific reverb is not supported yet, use GS instead */ SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_XG_LSB, 0, *body, ent); num_events++;#endif break; case 0x01: /* Reverb Type LSB */ xg_reverb_type_lsb = *body;#if 0 /* XG specific reverb is not supported yet, use GS instead */ SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_XG_LSB, 0, *body, ent); num_events++;#else v = set_xg_reverb_type(xg_reverb_type_msb, xg_reverb_type_lsb); if (v >= 0) { SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_GS_LSB, 0, v, 0x05); num_events++; }#endif break; case 0x0C: /* Reverb Return */ SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_XG_LSB, 0, *body, ent); num_events++; break; case 0x20: /* Chorus Type MSB */ xg_chorus_type_msb = *body;#if 0 /* XG specific chorus is not supported yet, use GS instead */ SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_XG_LSB, 0, *body, ent); num_events++;#endif break; case 0x21: /* Chorus Type LSB */ xg_chorus_type_lsb = *body;#if 0 /* XG specific chorus is not supported yet, use GS instead */ SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_XG_LSB, 0, *body, ent); num_events++;#else v = set_xg_chorus_type(xg_chorus_type_msb, xg_chorus_type_lsb); if (v >= 0) { SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_GS_LSB, 0, v, 0x0D); num_events++; }#endif break; case 0x2C: /* Chorus Return */ SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_XG_LSB, 0, *body, ent); num_events++; break; default: SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_XG_LSB, 0, *body, ent); num_events++; break; } } else if(addmid == 0x40) { /* Multi EQ */ switch(ent) { case 0x00: /* EQ type */ SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_XG_LSB, 0, *body, ent); num_events++; break; case 0x01: /* EQ gain1 */ SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_XG_LSB, 0, *body, ent); num_events++; break; case 0x02: /* EQ frequency1 */ SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_XG_LSB, 0, *body, ent); num_events++; break; case 0x03: /* EQ Q1 */ SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_XG_LSB, 0, *body, ent); num_events++; break; case 0x04: /* EQ shape1 */ SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_XG_LSB, 0, *body, ent); num_events++; break; case 0x05: /* EQ gain2 */ SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_XG_LSB, 0, *body, ent); num_events++; break; case 0x06: /* EQ frequency2 */ SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_XG_LSB, 0, *body, ent); num_events++; break; case 0x07: /* EQ Q2 */ SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_XG_LSB, 0, *body, ent); num_events++; break; case 0x09: /* EQ gain3 */ SETMIDIEVENT(evm[num_events], 0, ME_SYSEX_XG_LSB, 0, *body, ent); num_events++; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -