⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mamidcnv.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	dSetup = 0;
	sdTotalTicks = 0;
	sdCurrentTime = 0;
	sdDelta = (SINT32)(500 << 10) / pI->dTimeResolution;	/* default=0.5sec */

	pI->pbTitle = NULL;
	pI->dSizeTitle = 0;
	pI->pbCopyright = NULL;
	pI->dSizeCopyright = 0;
	pI->dStart = 0;
	pI->dSetupBar = 0;
	pI->dVibNoteVoice = 0;
	
	for (dCh = 0; dCh < NUM_OF_MAPS; dCh++)
	{
		for (dTemp = 0; dTemp < 128; dTemp++)
		{
			pI->bVoiceMap[dCh][dTemp] = 0;
		}
	}
	pI->bVoiceMap[MELODY_MAP][0] = 1;						/* GM Default Piano */

	for (dCh = 0; dCh < 16; dCh++)
	{
		dBank[dCh] = 0;
		dCurrBank[dCh] = 0;
		pCh = &pI->ChInfo[dCh];
		pCh->dKeyCon = 0;
		pCh->dVibSync = 0;
		pCh->dLedSync = 0;
	}

	ResetTimeInfo(pI);

	if (pI->dSmfFormat != 0) dSetup |= 0x20;

	while (pI->dEndFlag != 0)
	{
		if (pI->dNumOfTracks == 1)
		{
			sdTr = 0;
		}
		else
		{
			sdTr = GetLeastTimeTrack(pI);
			if (sdTr < 0) break;
		}
		pMt = &(pI->TrackInfo[sdTr]);
		
		dTime = pMt->sdTicks - sdTotalTicks;
		sdCurrentTime += dTime * sdDelta;
		sdTotalTicks = pMt->sdTicks;
		if ((sdCurrentTime < 0) || (sdTotalTicks > 0x07FFFFFFL))
		{
			MASMFCNV_DBGMSG(("MaMidCnv : GetSMFInfo Error/ CurrentTime=%ld, Time=%ld, Delta=%ld, Tr=%ld, EFlag=%08lX\n", sdCurrentTime, dTime, sdDelta, sdTr, pI->dEndFlag));
			return (MASMW_ERROR_LONG_LENGTH);
		}

		dCmd = (UINT32)pMt->pbBase[pMt->dOffset++];

		if (dCmd < 0xf0)
		{
			/*--- MidiMsg ---*/
			if (dCmd < 0x80)
			{
				dCmd = pMt->dSmfCmd;
				if (dCmd < 0x80) return (MASMW_ERROR_SMF_CMD);
				pMt->dOffset--;
			} else {
				pMt->dSmfCmd = dCmd;
			}
			
			dCh = dCmd & 0x0f;
			
			switch (dCmd & 0xf0)
			{
			case 0x90:	/* NoteOn */
				switch (dCurrBank[dCh])
				{
				case 0x7800:	/* Drum */
					pI->bVoiceMap[DRUM_MAP][pMt->pbBase[pMt->dOffset] & 0x7F] = 1;
					break;

				default:		/* Unknown: default GM */
					if ((dBank[dCh] >> 8) != 0x79)
					{
						if (dCh == 9)
						{
							/* Unknown: default GM Drum */
							pI->bVoiceMap[DRUM_MAP][pMt->pbBase[pMt->dOffset] & 0x7F] = 1;
						}
					}
				}
				pMt->dOffset += 2;
				break;
				
			case 0xC0:	/* Program change */
				switch (dBank[dCh])
				{
				case 0x7900:	/* Melody */
					pI->bVoiceMap[MELODY_MAP][pMt->pbBase[pMt->dOffset] & 0x7F] = 1;
					break;

				case 0x7906:	/* Vibration */
				 	if (pMt->pbBase[pMt->dOffset] == 0x7C)
					{
						pI->dVibNoteVoice = 1;
					}
					break;

				default:		/* Unknown: default GM Melody */
					if ((dBank[dCh] >> 8) == 0x79)
					{
						/* Melody */
						pI->bVoiceMap[MELODY_MAP][pMt->pbBase[pMt->dOffset] & 0x7F] = 1;
					}
					else
					{
						/* default GM Melody */
						if (dCh != 9)
						{
							pI->bVoiceMap[MELODY_MAP][pMt->pbBase[pMt->dOffset] & 0x7F] = 1;
						}
					}
				}

				dCurrBank[dCh] = dBank[dCh];
				pMt->dOffset++;
				break;
			
			case 0xD0:	/* Channel pressure */
				pMt->dOffset++;
				break;
			
			case 0xB0:	/* Control Change */
				switch (pMt->pbBase[pMt->dOffset])
				{
				case 0x00:	/* Bank select(MSB) */
					dBank[dCh] = (dBank[dCh] & 0x00FF) | (pMt->pbBase[pMt->dOffset + 1] << 8);
					break;
    
    			case 0x20:	/* Bank select (LSB) */
					dBank[dCh] = (dBank[dCh] & 0xFF00) | pMt->pbBase[pMt->dOffset + 1];
					break;
				}
				pMt->dOffset += 2;
				break;
			
			default:
				pMt->dOffset += 2;
			}
		}
		else
		{
			switch (dCmd)
			{
			case 0xF0:			/* SysEx */
			case 0xF7:			/* SysEx */
				pMt->dSmfCmd = 0;
				dSize = 0;
				do
				{
					dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
					dSize = (dSize << 7) + (dTemp & 0x7f);
				} while (dTemp >= 0x80);
				
				if ((dSize == 5) &&
				    (pMt->pbBase[pMt->dOffset] == 0x7e) &&
				    (pMt->pbBase[pMt->dOffset + 1] == 0x7f) &&
				    (pMt->pbBase[pMt->dOffset + 2] == 0x09) &&
				    (pMt->pbBase[pMt->dOffset + 3] == 0x01))
				{
					/* System On */
					if (sdTotalTicks == 0)
					{
						dSetup |= 0x04;
					}
				}
				else 
				{
					if (pI->dSetupBar == 0)
					{
						if ((dSize == 22) &&
						    (pMt->pbBase[pMt->dOffset] == 0x43) &&
						    (pMt->pbBase[pMt->dOffset + 1] == 0x79) &&
						    (pMt->pbBase[pMt->dOffset + 2] == 0x06) &&
						    (pMt->pbBase[pMt->dOffset + 3] == 0x7C)&&
						    (pMt->pbBase[pMt->dOffset + 4] == 0x02))
						{
							/* Channel status */
							for (dCh = 0; dCh < 16; dCh++)
							{
								pCh = &pI->ChInfo[dCh];
								dTemp = pMt->pbBase[pMt->dOffset + 5 + dCh];
								pCh->dKeyCon = (dTemp >> 2) & 0x03;
								pCh->dVibSync = (dTemp >> 1) & 0x01;
								pCh->dLedSync = dTemp & 0x01;
							}
						}
					}
				}

				pMt->dOffset += dSize;
				break;

			case 0xF1:			/* System Msg */
			case 0xF3:			/* System Msg */
				pMt->dOffset++;
				break;
			
			case 0xF2:			/* System Msg */
				pMt->dOffset += 2;
				break;

			case 0xFF:											/* Meta          */
				dCmd2 = (UINT32)pMt->pbBase[pMt->dOffset++];	/* Meta Command  */
				dSize = 0;										/* Size          */
				do
				{
					dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
					dSize = (dSize << 7) + (dTemp & 0x7f);
				} while (dTemp >= 0x80);

				switch (dCmd2)
				{
				case 0x02:	/* Copyright */
					if (pI->pbCopyright == NULL)
					{
						pI->pbCopyright = &pMt->pbBase[pMt->dOffset];
						pI->dSizeCopyright = dSize;
					}
					break;

				case 0x03:	/* Title */
					if (pI->pbTitle == NULL)
					{
						pI->pbTitle = &pMt->pbBase[pMt->dOffset];
						pI->dSizeTitle = dSize;
					}
					break;

				case 0x2f:		/* End */
					pI->dEndFlag &= ~(1L << sdTr);
					break;
					
				case 0x51:		/* Set Tempo */
					switch (dSize)
					{
					case 3:
					case 4:
						dTime = ((UINT32)pMt->pbBase[pMt->dOffset] << 16) + 
						        ((UINT32)pMt->pbBase[pMt->dOffset + 1] << 8) +
						         (UINT32)pMt->pbBase[pMt->dOffset + 2];
						if ((sdTotalTicks == 0) && (dTime == 250000)) dSetup |= 0x02;
						if (sdTotalTicks == (SINT32)pI->dTimeResolution) dSetup |= 0x08;
						dTime = (dTime << 7) / 125;
						sdDelta = (SINT32)(dTime / pI->dTimeResolution);
					}
					break;
					
				case 0x58:		/* Set TimeSignature */
					if ((sdTotalTicks == 0) && 
					    (pMt->pbBase[pMt->dOffset] == 1) &&
					    (pMt->pbBase[pMt->dOffset + 1] == 2)) dSetup |= 0x01;
					break;
				}
				pMt->dOffset += dSize;
				break;
			}
		}
		
		UpdateTrackTime(pI, (UINT32)sdTr);
		
		if (dSetup == 0x0F)
		{
			dSetup |= 0x10;
			sdCurrentTime = 0;
			pI->dSetupBar = 1;
			pI->dStart = pI->TrackInfo[0].dOffset;
		}
	}

	pI->sdTotalTicks = sdTotalTicks;
	pI->sdDataEndTime = sdCurrentTime;
	
	if (pI->dSetupBar == 0)
	{
		for (dCh = 0; dCh < 16; dCh++)
		{
			pCh = &pI->ChInfo[dCh];
			pCh->dKeyCon = 0;
			pCh->dVibSync = 0;
			pCh->dLedSync = 0;
		}
	}

	MASMFCNV_DBGMSG(("MaMidCnv : GetSMFInfo/ dTotalTicks  = %ld\n", sdTotalTicks));
	MASMFCNV_DBGMSG(("MaMidCnv : GetSMFInfo/ dCurrentTime = %ld\n", sdCurrentTime));

	if ((pI->sdDataEndTime >> 10) <= MINIMUM_LENGTH) return (MASMW_ERROR_SHORT_LENGTH);

	MASMFCNV_DBGMSG(("MaMidCnv : GetSMFInfo/Done\n"));

	return (MASMW_SUCCESS);
}


/****************************************************************************
 *	CheckSMF(UINT8* fp, UINT32 dFsize, UINT8 dMode)
 *
 *	Description:
 *		Check SMF structure
 *	Param:
 *		fp			... pointer to the data
 *		dFsize		... size fo the data
 *		dMode		... error check (0:No, 1:Yes, 2:ErrorCheck, 3:CNTI)
 *	Return:
 *		0 : NoError, < 0 : Error
 ****************************************************************************/
static SINT32	CheckSMF(UINT8* fp, UINT32 dFsize, UINT32 dMode)
{
	UINT32	dTemp;
	UINT32	dSize;
	PMIDINFO pI;
	UINT32	dFormat;
	UINT32	dNumOfTracks;
	UINT32	i;

	MASMFCNV_DBGMSG(("MaMidCnv : CheckSMF\n"));

	while (dFsize >= 22)
	{
		dTemp = ((UINT32)fp[0] << 24) + ((UINT32)fp[1] << 16) +
		        ((UINT32)fp[2] << 8) + (UINT32)fp[3];
		if (dTemp == 0x4D546864)	break;		/* 'MThd' */
		fp ++;
		dFsize --;
	}

	if (dFsize < 22) 
	{
		MASMFCNV_DBGMSG(("MaMidCnv : CheckSMF Error/ Too small size\n"));
		return (MASMW_ERROR_FILE);
	}
	fp += 4;
	dFsize -= 4;

	/*--- Check size ----------------------------------------------------*/
	dTemp = ((UINT32)fp[0] << 24) + ((UINT32)fp[1] << 16) +
	        ((UINT32)fp[2] << 8) + (UINT32)fp[3];
	if (dTemp != 6)
	{
		MASMFCNV_DBGMSG(("MaMidCnv : CheckSMF Error/ Size != 6\n"));
		return (MASMW_ERROR_CHUNK_SIZE);
	}
	fp += 4;
	dFsize -= 4;

	if (dMode < 2)
	{
		if (gpMidInfo->DataInfo[1].dValid == 1) return (MASMW_ERROR);
		pI = &gpMidInfo->DataInfo[1];
	} else {
		pI = &gpMidInfo->DataInfo[0];
	}
	
	/*--- Check format -------------------------------------------------*/
	dFormat = ((UINT32)fp[0] << 8) + (UINT32)fp[1];
	if (dFormat > 1)
	{
		MASMFCNV_DBGMSG(("MaMidCnv : CheckSMF Error/ Not Format 0 or 1\n"));
		return (MASMW_ERROR_SMF_FORMAT);
	}
	
	/*--- Check number of tracks ---------------------------------------*/
	dNumOfTracks = ((UINT32)fp[2] << 8) + (UINT32)fp[3];
	if (dNumOfTracks == 0)
	{
		MASMFCNV_DBGMSG(("MaMidCnv : CheckSMF Error/ Number of Tracks = 0\n"));
		return (MASMW_ERROR_SMF_TRACKNUM);
	}
	if ((dFormat == 0) && (dNumOfTracks != 1))
	{
		MASMFCNV_DBGMSG(("MaMidCnv : CheckSMF Error/ Number of Tracks > 1\n"));
		return (MASMW_ERROR_SMF_TRACKNUM);
	}
	
	if (dNumOfTracks > MAX_SMF_TRACKS) dNumOfTracks = MAX_SMF_TRACKS;
	pI->dNumOfTracks = (UINT8)dNumOfTracks;

	/*--- Check Time unit --------------------------------------------*/
	dTemp = ((UINT32)fp[4] << 8) + (UINT32)fp[5];
	pI->dTimeResolution = dTemp & 0x7fff;
	if (((dTemp & 0x8000) != 0) || (pI->dTimeResolution == 0))
	{
		MASMFCNV_DBGMSG(("MaMidCnv : CheckSMF Error/ Unknown TimeUnit\n"));
		return (MASMW_ERROR_SMF_TIMEUNIT);
	}
	fp += 6;
	dFsize -= 6;
	
	for (i = 0; i < dNumOfTracks; i++)
	{
		/*--- Check chunk name --------------------------------------------*/
		while (dFsize >= 8)
		{
			dTemp = ((UINT32)fp[0] << 24) + ((UINT32)fp[1] << 16) +
			        ((UINT32)fp[2] << 8) + (UINT32)fp[3];
			if (dTemp == 0x4D54726B)	break;	/* 'MTrk' */
			fp ++;
			dFsize --;
		}

		if (dFsize < 8)
		{
			MASMFCNV_DBGMSG(("MaMidCnv : CheckSMF Error/ Bad size\n"));
			return (MASMW_ERROR_CHUNK_SIZE);
		}

		/*--- Check size ----------------------------------------------------*/
		dSize = ((UINT32)fp[4] << 24) + ((UINT32)fp[5] << 16) +
		        ((UINT32)fp[6] << 8) + (UINT32)fp[7];

		if (dFsize < (dSize + 8))
		{
			MASMFCNV_DBGMSG(("MaMidCnv : CheckSMF Error/ Bad size [%ld] vs [%ld]\n", dFsize, dSize + 22));
			return (MASMW_ERROR_CHUNK_SIZE);
		}
		pI->TrackInfo[i].pbBase = &fp[8];
		pI->TrackInfo[i].dSize = dSize;
		fp += (dSize + 8);
		dFsize -= (dSize + 8);
	}
	pI->dSmfFormat = dFormat;

	return (GetSMFInfo(pI));
}


/****************************************************************************
 *	RegVoice(void)
 *
 *	Desc.
 *		Register default 4op voices.
 *	Param
 *		none
 *	Return
 *      none
 ****************************************************************************/
static void RegVoice(void)
{
	UINT32	i, j;
	UINT8*	pbVoiceParam;
	UINT32	dDrumKey;
	UINT32	dAdr;
	UINT32	dMuteAdr;
	PMIDINFO	pI;

	pI = &gpMidInfo->DataInfo[1];
	dMuteAdr = 0;
	
	/* MutedVoice */
	if ((gpMidInfo->dRamOffset + 30) <= gpMidInfo->dRamSize)
	{
		pbVoiceParam = (UINT8*)&gbMuteVoice[2];
		dMuteAdr = gpMidInfo->dRamBase + gpMidInfo->dRamOffset;
		MaDevDrv_SendDirectRamData(dMuteAdr, 0, pbVoiceParam, 30);
		MaSndDrv_SetVoice(gpMidInfo->sdSeqID, 0x06, 0x7C, 1, 0, dMuteAdr);
		gpMidInfo->dRamOffset += 30;
	}


	/* Melody FM */
	for (i = 0; i < 128; i++)
	{
		if (pI->bVoiceMap[MELODY_MAP][i] == 1)
		{
			if ((gpMidInfo->dRamOffset + 30) <= gpMidInfo->dRamSize)
			{
				pbVoiceParam = (UINT8*)&gbMelodyVoiceTable[i][2];
				dAdr = gpMidInfo->dRamBase + gpMidInfo->dRamOffset;
				MaDevDrv_SendDirectRamData(dAdr, 0, pbVoiceParam, 30);
				MaSndDrv_SetVoice(gpMidInfo->sdSeqID, 0x00, i, 1, 0, dAdr);
				gpMidInfo->dRamOffset += 30;
			}
		}
	}

	/* Drum FM */
	for (i = 35; i < 82; i++)
	{
		if (pI->bVoiceMap[DRUM_MAP][i] == 1)
		{
			j = i - 35;
			if (gbDrumVoiceTable[j][0] == 0)
			{
				if ((gpMidInfo->dRamOffset + 30) <= gpMidInfo->dRamSize)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -