silent: ; 
static int read_mfi_track(int trackNo, int length, int mfiVersion, int noteType, int extStDLength, timidity_file *tf){	uint8				data[5];	int					i, pos, note, velocity, dataLength;	uint8				instruments[MAX_CHANNELS];	int					channelMap[4];	LastNoteInfo		lastNotes[MAX_CHANNELS];		readmidi_set_track(trackNo, 1);	pos = 0;	velocity = 0x7F;	for(i = 0; i < 4; i++)		channelMap[i] = (trackNo * 4) + i;	dataLength = (noteType == 1) ? 4 : 3;	data[3] = 0;	/* initialize for debugging purpose */	for(i = 0; i < MAX_CHANNELS; i++)		lastNotes[i].on = NO_LAST_NOTE_INFO;	while (length > 0)	{		CHECK_AND_READ_FROM_FILE(data, dataLength);		pos += data[0];		if (data[1] != 0xFF)	/* note */		{			int					channel;						channel = channelMap[data[1] >> 6];			note = 0x48 - 0x1B + (data[1] & 0x3F);			if (dataLength >= 4)			{				velocity = ((data[3] & 0xFC) >> 1) | (data[3] >> 7);	/* abcdefgh -> 0abcdefa */				if (data[3] & 0x2)		/* sign */					data[3] |= ~0x01;				else					data[3] &= 0x01;				note += ((int8)data[3]) * 12;	/* octave shift */			}			if (LASTNOTEINFO_HAS_DATA(lastNotes[channel]))			{				if (lastNotes[channel].off <= pos						|| note != lastNotes[channel].note)				{					SendLastNoteInfo(lastNotes, channel);					StoreLastNoteInfo(lastNotes, channel, pos, data[2], note, velocity);				}				#if 0				else if (note != lastNotes[channel].note)	/* possible slur */				{					if (lastNotes[channel].on == pos)	/* may be a chord */					{						SendLastNoteInfo(lastNotes, channel);						StoreLastNoteInfo(lastNotes, channel, pos, data[2], note, velocity);					}					else	/* slur */					{						/* not implemented */					}				}				#endif				else	/* tie, what if the velocity isn't the same? :-) */					lastNotes[channel].off = pos + data[2];			}			else				StoreLastNoteInfo(lastNotes, channel, pos, data[2], note, velocity);			silent: ;			NOTE_EVENT_DEBUGSTR(channel, note_name[note % 12], note / 12, velocity, data[2]);		}		else	/* controls */		{			if (dataLength == 3)				CHECK_AND_READ_FROM_FILE(&data[3], 1);			if ((data[2] & 0xF0) == 0xC0)	/* tempo */			{				int				timebase, tempo;								timebase = data[2] & 0xF;				if ((timebase & 0x7) == 0x7)					ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Undefined tempo timebase.");				else				{					if (timebase & 0x8)						timebase = 15 << (timebase & 0x7);					else						timebase = 6 << (timebase & 0x7);					tempo = 48 * (1000000 * 60 / data[3] / timebase);					MIDIEVENT(pos, ME_TEMPO, tempo & 0xFF, (tempo >> 16) & 0xFF, (tempo >> 8) & 0xFF);				}			}			else if ((data[2] & 0xF0) == 0xF0)	/* extended controls */			{				int				extLength, channel;				uint8			extData[512];								CHECK_AND_READ_FROM_FILE(&data[4], 1);				extLength = (data[3] << 8) | data[4];				if (extLength <= sizeof extData)				{					CHECK_AND_READ_FROM_FILE(extData, extLength);					switch(data[2] & 0xF)					{						/* case 0x0:	/-* modify envelope (MFi1) */						case 0x1:	/* vibrato (MFi1) */							if (mfiVersion == 1 && extData[0] == 0x01 && extData[1] & 0x01)							{								channel = channelMap[extData[1] >> 5];								MIDIEVENT(pos, ME_MODULATION_WHEEL, channel, (extData[2] & 0xC0) ? 64 : 0, 0)							}							break;						/*case 0xF:	/-* system exclusive (MFi2 or MFi3) */						default:							EX_UNKNOWN_EXT_DATA_DEBUGSTR(extLength);					}				}				else				{					if (tf_seek(tf, extLength, SEEK_CUR) == -1)						return 1;					EX_UNKNOWN_EXT_DATA_DEBUGSTR(extLength);					length -= extLength;				}			}			else			{				int				part, channel, value;				#define GET_PART_AND_CHANNEL(p, c)		(p) = data[3] >> 6; (c) = channelMap[p]								switch(data[2])				{					case 0xB0:	/* master volume */						value = MAPBITS2(data[3] & 0x7F, 7, 16);						MIDIEVENT(pos, ME_MASTER_VOLUME, 0, value & 0xFF, value >> 8);						EX_NCDATA_DEBUGSTR1("Master Volume", "%d", value);						break;					case 0xBA:	/* set drum channel flag */						channel = (data[3] >> 3) & 0xF;						value = data[3] & 0x1;						MIDIEVENT(pos, ME_DRUMPART, channel, value, 0);						EX_DATA_DEBUGSTR1("Drum Flag", channel, "%d", value);						break;					case 0xD0:	/* music begin/end */						/* ignored */						break;					/* case 0xDD:	/-* loop begin/end */					case 0xDE:	/* nop */						break;					case 0xDF:	/* end-of-track */						if (length != 0)						{							ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "Premature end-of-track (%d)", length);							length = 0;						}						break;					case 0xE0:	/* program change */						GET_PART_AND_CHANNEL(part, channel);						SEND_AND_CLEAR_LASTNOTEINFO(lastNotes, channel);						/*MIDIEVENT(pos, ME_DRUMPART, channel, 0, 0);*/						instruments[channel] = (instruments[channel] & 0x40) | (data[3] & 0x3F);						MIDIEVENT(pos, ME_PROGRAM, channel, instruments[channel], 0);						EX_DATA_DEBUGSTR1("Program Change", channel, "%d", instruments[channel]);						break;					case 0xE1:	/* pre program change */						GET_PART_AND_CHANNEL(part, channel);						instruments[channel] = (data[3] & 0x1) << 6;						EX_DATA_DEBUGSTR1("Pre Program Change", channel, "%d", instruments[channel]);						break;					case 0xE2:	/* volume */						GET_PART_AND_CHANNEL(part, channel);						value = MAPBITS(data[3] & 0x3F, 6, 7);						MIDIEVENT(pos, ME_MAINVOLUME, channel, value, 0);						EX_DATA_DEBUGSTR1("Volume", channel, "%d", value);						break;					case 0xE3:	/* pan */						GET_PART_AND_CHANNEL(part, channel);						value = MAPBITS(data[3] & 0x3F, 6, 7);						MIDIEVENT(pos, ME_PAN, channel, value, 0);						EX_DATA_DEBUGSTR1("Pan", channel, "%d", value);						break;					case 0xE4:	/* pitch bend (MFi3) */						if (mfiVersion >= 3)						{							GET_PART_AND_CHANNEL(part, channel);							value = MAPBITS2(data[3] & 0x3F, 6, 14);							MIDIEVENT(pos, ME_PITCHWHEEL, channel, value & 0x7F, value >> 7);							EX_DATA_DEBUGSTR1("Pitch Bend", channel, "%d", value);						}						break;					case 0xE5:	/* map part to channel */						part = data[3] >> 6;						SEND_AND_CLEAR_LASTNOTEINFO(lastNotes, channelMap[part]);						channelMap[part] = data[3] & 0xF;						SEND_AND_CLEAR_LASTNOTEINFO(lastNotes, channelMap[part]);						EX_DATA_DEBUGSTR1("Map Channel", part, "%d", channelMap[part]);						break;					case 0xE6:	/* expression */						GET_PART_AND_CHANNEL(part, channel);						value = data[3] & 0x3F;						if (value & 0x20)							value = 64 - (((value ^ 0x3F) + 1) << 1);						else if (value & 0x10)							value = 64 + 1 + (value << 1);						else							value = 64 + (value << 1);						MIDIEVENT(pos, ME_EXPRESSION, channel, value, 0);						EX_DATA_DEBUGSTR1("Expression", channel, "%d", value);						break;					case 0xE7:	/* pitch bend range (MFi3) */						if (mfiVersion >= 3)						{							GET_PART_AND_CHANNEL(part, channel);							value = data[3] & 0x3F;							MIDIEVENT(pos, ME_RPN_MSB, channel, 0, 0);							MIDIEVENT(pos, ME_RPN_LSB, channel, 0, 0);							MIDIEVENT(pos, ME_DATA_ENTRY_MSB, channel, value, 0);							EX_DATA_DEBUGSTR1("Pitch Bend Range", channel, "%d", value);						}						break;					case 0xEA:	/* vibrato (MFi3) */						if (mfiVersion >= 3)						{							GET_PART_AND_CHANNEL(part, channel);							value = MAPBITS(data[3] & 0x3F, 6, 7);							MIDIEVENT(pos, ME_MODULATION_WHEEL, channel, value, 0);							EX_DATA_DEBUGSTR1("Vibrato", channel, "%d", value);						}						break;					default:						EX_UNKNOWN_DATA_DEBUGSTR();				}			}		}	}	for(i = 0; i < MAX_CHANNELS; i++)	{		SEND_LASTNOTEINFO(lastNotes, i);	}	return 0;}
4357	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4357/64c3a98e5ef08ab323c2ea983ca497f2df9f9db2/mfi.c/clean/timidity/mfi.c