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

📄 mamidcnv.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 5 页
字号:
 ****************************************************************************/
static void	SendGmOn(SINT32 sdTime)
{
	UINT32		dCh;
	PMIDPACKET	pMsg;
	PMIDCHINFO	pCh;

	MASMFCNV_DBGMSG(("MaMidCnv : %8ld:SendGmOn\n", sdTime));

	gpMidInfo->dMaxGain = SMF_MAX_GAIN;
	gpMidInfo->dMasterVolume = 127;
	gpMidInfo->dVibNote = 0;
	
	for (dCh = 0; dCh < 16; dCh++)
	{
		pCh = &gpMidInfo->DataInfo[1].ChInfo[dCh];
		pCh->dRPN = 0x7f7f;
		pCh->dBank = (dCh == 9) ? 0x7800 : 0x7900;
		pCh->dMipMute = 0;
	}
	
	if (sdTime >= 0)
	{
		SendAllSoundOff(sdTime, 0);
		for (dCh = 1; dCh < 16; dCh++) SendAllSoundOff(0, dCh);

		pMsg = &gpMidInfo->MsgBuffer[gpMidInfo->dHoldMsgs++];
		pMsg->sdDeltaTime = 0;
		pMsg->dMsgID = MASNDDRV_CMD_SYSTEM_ON;
		
		for (dCh = 0; dCh < 16; dCh++)
		{
			pCh = &gpMidInfo->DataInfo[1].ChInfo[dCh];
			SendLedSync(0, dCh, pCh->dLedSync);
			SendVibSync(0, dCh, pCh->dVibSync);
		}
		SendMasterVolume(0, gpMidInfo->dMaxGain);
	} else {
		for (dCh = 0; dCh < 16; dCh++)
		{
			pCh = &gpMidInfo->DataInfo[1].ChInfo[dCh];
			pCh->dCurrBank = pCh->dBank;
			pCh->dProg = 255;
			pCh->dVolume = 255;
			pCh->dExpression = 255;
			pCh->dModulation = 255;
			pCh->dPitchBend = 255;
			pCh->dPreBendRange = 255;
			pCh->dBendRange = 255;
			pCh->dPanpot = 255;
			pCh->dHold1 = 255;
			pCh->dMode = 255;
			pCh->dFineTune = 0x2000;
			pCh->dCoaseTune = 0x40;
		}
	}
}


/****************************************************************************
 *	SendShortMsg(SINT32 sdTime, UINT32 dCmd, UINT32 dCh, UINT32 dP1, UINT32 dP2)
 *
 *	Desc.
 *		Send ShortMsg message
 *	Param
 *		sdTime		Delta time
 *		dCmd		MIDI command
 *		dCh			#Channel(0..15)
 *		dP1			Parameter 1
 *		dP2			Parameter 2
 *	Return
 *		Length of the command[byte]
 ****************************************************************************/
static SINT32	SendShortMsg(SINT32 sdTime, UINT32 dCmd, UINT32 dCh, UINT32 dP1, UINT32 dP2)
{
	static void (*MidiMsg[16])(SINT32 sdTm, UINT32 dChannel, UINT32 dPara1, UINT32 dPara2) =
	{
		ErrorFunction,	ErrorFunction,	ErrorFunction,	ErrorFunction, 
		ErrorFunction, 	ErrorFunction,	ErrorFunction,	ErrorFunction, 
		SendNoteOff,	SendNoteOn,		NotSupported,	SendControl,
		SendProgram,	NotSupported,	SendPitchBend,	NotSupported
	};

	static const SINT32	sdMidiMsgLength[16] = 
	{
		0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 2, 0
	};

	MidiMsg[dCmd](sdTime, dCh, dP1 & 0x7F, dP2 & 0x7F);

	return (sdMidiMsgLength[dCmd]);
}


/****************************************************************************
 *	SendSysEx(SINT32 sdTime, UINT8* pbMsg, UINT32 dSize)
 *
 *	Desc.
 *		Send SysEx message
 *	Param
 *		sdTime		Delta time
 *		pbMsg		Pointer to the message
 *		dSize		Size of the message [byte]
 *	Return
 *		0 : NoError, < 0 : Error code
 ****************************************************************************/
static SINT32	SendSysEx(SINT32 sdTime, UINT8* pbMsg, UINT32 dSize)
{
	PMIDCHINFO	pCh;
	UINT32		dCh;
	UINT32		dNumCh;
	UINT32		i;
	UINT32		dMip;
	UINT32		dMax;
	
	MASMFCNV_DBGMSG(("MaMidCnv : SendSysEx[%ld, %08lX, %ld]\n", sdTime, pbMsg, dSize));

	if (dSize < 4) return (MASMW_SUCCESS);
	
	if ((pbMsg[0] == 0x7e) &&
	    (pbMsg[1] == 0x7f) &&
	    (pbMsg[2] == 0x09) &&
	    ((pbMsg[3] == 0x01) || (pbMsg[3] == 0x03) || (pbMsg[3] == 0x02)) &&
	    (dSize == 4))
	{
		/* GM System On */
		SendGmOn(sdTime);
		return (MASMW_SUCCESS);
	}
	
	if ((pbMsg[0] == 0x7f) &&
	    (pbMsg[1] == 0x7f) &&
	    (pbMsg[2] == 0x04) &&
	    (pbMsg[3] == 0x01) &&
	    (dSize == 6))
	{
		/* Universal Master Volume */
		gpMidInfo->dMasterVolume = (UINT32)(pbMsg[5] & 0x7f);
		pCh = &gpMidInfo->DataInfo[1].ChInfo[0];
		SendExpression(sdTime, 0, pCh->dExpression);
		if (sdTime >= 0) sdTime = 0;
		for (dCh = 1; dCh < 16; dCh++)
		{
			pCh = &gpMidInfo->DataInfo[1].ChInfo[dCh];
			SendExpression(sdTime, dCh, pCh->dExpression);
		}

		return (MASMW_SUCCESS);
	}

	/*---- MIP(SP-MIDI) message ---------------------------------------------*/
	if ((pbMsg[0] == 0x7f) &&
	    (pbMsg[1] == 0x7f) &&
	    (pbMsg[2] == 0x0B) &&
	    (pbMsg[3] == 0x01))
	{
		dNumCh = (dSize - 4) >> 1;
		dMax = 16;
		if ((dNumCh > 0) && (dNumCh <= 16))
		{
			for (i = 0; i < 16; i++)
			{
				pCh = &gpMidInfo->DataInfo[1].ChInfo[i];
				pCh->dMipMute = 1;
			}
			for (i = 0; i < dNumCh; i++)
			{
				dCh = pbMsg[(i << 1) + 4];
				dMip = pbMsg[(i << 1) + 5];
				pCh = &gpMidInfo->DataInfo[1].ChInfo[dCh];
				if (dMip <= dMax) pCh->dMipMute = 0;
			}
		}
	}
	/*---- SP-MIDI message ---------------------------------------------*/

	if ((pbMsg[0] != 0x43) ||
	    (pbMsg[1] != 0x79) ||
	    (pbMsg[2] != 0x06) ||
	    (pbMsg[3] != 0x7f) ||
	    (dSize != 6)) return (MASMW_SUCCESS);

	switch (pbMsg[4])
	{
	case 0x00:		/* Max Gain */
		gpMidInfo->dMaxGain = (UINT32)(pbMsg[5] & 0x7F);
		SendMasterVolume(sdTime, gpMidInfo->dMaxGain);
		return (MASMW_SUCCESS);
	}

	return (MASMW_SUCCESS);
}


/****************************************************************************
 *	GetTimeCount(void)
 *
 *	Desc.
 *		Get Delta time
 *	Param
 *		none
 *	Return
 *		DeltaTime
 ****************************************************************************/
static SINT32 GetTimeCount(void)
{
	SINT32	sdTime;

	if (gpMidInfo->sdSmfCurrentTime > gpMidInfo->sdLastMsgTime)
	{
		sdTime = gpMidInfo->sdSmfCurrentTime - gpMidInfo->sdLastMsgTime;	/* [22.10][ms] */
		sdTime >>= SMF_TIMEBASE_SHIFT;										/*             */
		sdTime += 0x0200;													/* + 0.5       */
		sdTime >>= 10;
	} else {
		sdTime = 0;
	}
	
	return (sdTime);
}


/****************************************************************************
 *	SeekSmfMessage(SINT32 sdSeekTime)
 *
 *	Desc.
 *		Do seek
 *	Param
 *		sdSeekTime :	Time [22.10 ms]  
 *	Return
 *		none
 ****************************************************************************/
static void SeekSmfMessage(SINT32 sdSeekTime)
{
	UINT32		dCmd;
	UINT32		dCmd2;
	UINT32		dCh;

	UINT32		dParam1, dParam2;
	UINT32		dSize;

	UINT32		dTemp;
	UINT32		dTime;
	SINT32		sdTr;
	SINT32		sdCurrTime;
	SINT32		sdPreTime;

	PMIDINFO	pI;
	PTRACKINFO	pMt;

	/*--- Initialize --------------------------*/
	sdPreTime = 0;
	pI = &gpMidInfo->DataInfo[1];
	gpMidInfo->sdSmfCurrentTime = 0;
	gpMidInfo->sdSmfCurrentTicks = 0;
	gpMidInfo->sdSmfDelta = (SINT32)(500 << 10) / pI->dTimeResolution;	/* default=0.5sec */

	ResetTimeInfo(pI);

	SendGmOn(-1);
	
	/*--- Seek till StartPoint ------------------------*/
	if (pI->dSetupBar == 1)
	{
		while (pI->TrackInfo[0].dOffset < pI->dStart)
		{
			/*--- Get Delta time --------------------------*/
			if (pI->dNumOfTracks == 1)
			{
				sdTr = 0;
			}
			else
			{
				sdTr = GetLeastTimeTrack(pI);
				if (sdTr < 0) break;
			}
			pMt = &(pI->TrackInfo[sdTr]);
			dTime = (UINT32)(pMt->sdTicks - gpMidInfo->sdSmfCurrentTicks);
			gpMidInfo->sdSmfCurrentTicks = pMt->sdTicks;
			
			dCmd = (UINT32)pMt->pbBase[pMt->dOffset++];
			if (dCmd < 0xF0)
			{
				if (dCmd < 0x80)
				{
					dCmd = pMt->dSmfCmd;
					pMt->dOffset--;
				} else {
					pMt->dSmfCmd = dCmd;
				}
				
				dCh = dCmd & 0x0F;
				dCmd = (dCmd & 0xf0) >> 4;
				dParam1 = (UINT32)pMt->pbBase[pMt->dOffset];
				dParam2 = (UINT32)pMt->pbBase[pMt->dOffset + 1];
				pMt->dOffset += SendShortMsg(-1, dCmd, dCh, dParam1, dParam2);
			}
			else
			{
				switch (dCmd)
				{
				case 0xFF:			/* Meta */
					dCmd2 = (UINT32)pMt->pbBase[pMt->dOffset++];
					dSize = 0;
					do
					{
						dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
						dSize = (dSize << 7) + (dTemp & 0x7f);
					} while (dTemp >= 0x80);

					switch (dCmd2)
					{
					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];
							dTime = (dTime << 7) / 125;
							gpMidInfo->sdSmfDelta = (SINT32)(dTime / pI->dTimeResolution);
							break;
						}
						break;
					}
					pMt->dOffset += dSize;
					break;

				case 0xF0:			/* SysEx */
					dSize = 0;
					do
					{
						dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
						dSize = (dSize << 7) + (dTemp & 0x7f);
					} while (dTemp >= 0x80);
					
					SendSysEx(-1, &pMt->pbBase[pMt->dOffset], dSize - 1);
					pMt->dOffset += dSize;
					break;
					
				case 0xF7:			/* SysEx */
					dSize = 0;
					do
					{
						dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
						dSize = (dSize << 7) + (dTemp & 0x7f);
					} while (dTemp >= 0x80);
					
					SendSysEx(-1, &pMt->pbBase[pMt->dOffset], dSize);
					pMt->dOffset += dSize;
					break;

				case 0xF1:			/* System Msg */
				case 0xF3:			/* System Msg */
					pMt->dOffset++;
					break;
				
				case 0xF2:			/* System Msg */
					pMt->dOffset += 2;
					break;
				}
			}
			UpdateTrackTime(pI, (UINT32)sdTr);
		}
	}
	
	/*--- Seek till SeekTime --------------------------*/
	while (gpMidInfo->sdSmfCurrentTime < sdSeekTime)
	{
		/*--- Get Delta time --------------------------*/
		if (pI->dNumOfTracks == 1)
		{
			sdTr = 0;
		}
		else
		{
			sdTr = GetLeastTimeTrack(pI);
			if (sdTr < 0) break;
		}
		pMt = &(pI->TrackInfo[sdTr]);
		dTime = (UINT32)(pMt->sdTicks - gpMidInfo->sdSmfCurrentTicks);
		sdPreTime = gpMidInfo->sdSmfCurrentTime;
		sdCurrTime = sdPreTime + dTime * gpMidInfo->sdSmfDelta;
		if (sdCurrTime >= sdSeekTime)
		{
			gpMidInfo->sdSmfCurrentTime = sdSeekTime;
			break;
		}

		gpMidInfo->sdSmfCurrentTime = sdCurrTime;
		gpMidInfo->sdSmfCurrentTicks = pMt->sdTicks;
		
		dCmd = (UINT32)pMt->pbBase[pMt->dOffset++];
		if (dCmd < 0xF0)
		{
			if (dCmd < 0x80)
			{
				dCmd = pMt->dSmfCmd;
				pMt->dOffset--;
			} else {
				pMt->dSmfCmd = dCmd;
			}
			
			dCh = dCmd & 0x0f;
			dCmd = (dCmd & 0xf0) >> 4;
			dParam1 = (UINT32)pMt->pbBase[pMt->dOffset];
			dParam2 = (UINT32)pMt->pbBase[pMt->dOffset + 1];
			pMt->dOffset += SendShortMsg(-1, dCmd, dCh, dParam1, dParam2);
		}
		else
		{
			switch (dCmd)
			{
			case 0xFF:			/* Meta */
				dCmd2 = pMt->pbBase[pMt->dOffset++];
				dSize = 0;
				do
				{
					dTemp = pMt->pbBase[pMt->dOffset++];
					dSize = (dSize << 7) + (UINT32)(dTemp & 0x7f);
				} while (dTemp >= 0x80);

				switch (dCmd2)
				{
				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];
						dTime = (dTime << 7) / 125;
						gpMidInfo->sdSmfDelta = (SINT32)(dTime / pI->dTimeResolution);
						break;
					}
					break;
				}
				pMt->dOffset += dSize;
				break;

			case 0xF0:			/* SysEx */
				dSize = 0;
				do
				{
					dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
					dSize = (dSize << 7) + (dTemp & 0x7f);
				} while (dTemp >= 0x80);
				
				SendSysEx(-1, &pMt->pbBase[pMt->dOffset], dSize - 1);
				pMt->dOffset += dSize;
				break;
				
			case 0xF7:			/* SysEx */
				dSize = 0;
				do
				{
					dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
					dSize = (dSize << 7) + (dTemp & 0x7f);
				} while (dTemp >= 0x80);
				
				SendSysEx(-1, &pMt->pbBase[pMt->dOffset], dSize);
				pMt->dOffset += dSize;
				break;

			case 0xF1:			/* System Msg */
			case 0xF3:			/* System Msg */
				pMt->dOffset++;
				break;
			
			case 0xF2:			/* System Msg */
				pMt->dOffset += 2;
				break;
			}
		}
		UpdateTrackTime(pI, (UINT32)sdTr);
	}

	gpMidInfo->sdLastMsgTime = gpMidInfo->sdSmfCurrentTime;
	gpMidInfo->sdSmfCurrentTime = sdPreTime;
}


/***************************************************************************

⌨️ 快捷键说明

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