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

📄 masnddrv.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	while ( ( sdDeltaTime > 127 ) && ( dNum < 2 ) )
	{
		*(pbPacket+dNum) = (UINT8)(sdDeltaTime & 0x7F);
		sdDeltaTime >>= 7;
		dNum++;
	}
	*(pbPacket+dNum) = (UINT8)(sdDeltaTime | 0x80 );

	return (UINT32)(dNum+1);
}
/****************************************************************************
 *	GetRealKeyMelody
 *
 *	Description:
 *			Get real key number of melody with key control.
 *	Arguments:
 *			sdSeqId		sequence id (0..1)
 *			dCh			channel number (0..15)
 *			dKey		key number (0..127)
 *	Return:
 *			real key number (0..127)
 *
 ****************************************************************************/
static UINT32 GetRealKeyMelody
(
	SINT32	sdSeqId,					/* sequence id */
	UINT32	dCh,						/* channel number */
	UINT32	dKey						/* key number */
)
{
	SINT32	sdRKey;						/* real key value */
	SINT32	sdKeyOffset;				/* key offset */
	UINT32	dProgNo;
	/*------------------------------------------------------------------------------------*/
	/*  KeyCon Table                                                                      */
	/*------------------------------------------------------------------------------------*/
	static const UINT8 bKeyConRate[128] =
	{
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,		/*   0 */
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,		/*  16 */
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,		/*  32 */
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,		/*  48 */
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,		/*  64 */
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,		/*  80 */
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,		/*  96 */
			1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 5,20,10,10,20, 5,		/* 112 */
	};

	sdRKey = (SINT32)dKey;
	sdKeyOffset = (SINT32)(gpMaSndDrvInfo->sSndDrvInfo[sdSeqId].sbKeyOffset);

	switch ( gpMaSndDrvInfo->sSndDrvInfo[sdSeqId].bMelodyMode )
	{
	case MASNDDRV_RESMODE1_NORMAL:
	case MASNDDRV_RESMODE1_MA3:

		dProgNo = gpMaSndDrvInfo->sChInfo[dCh].bProgNo;
		if (( dProgNo <= 114 ) || ( dProgNo == 120) || ( dProgNo == 121))	/* 0..114 */
		{
			if ( gpMaSndDrvInfo->sChInfo[dCh].bKeyControl != MASNDDRV_KEYCTRL_OFF )
			{
				sdRKey = sdRKey + sdKeyOffset;
				if ( sdRKey < 0   ) sdRKey = 0;
				else if ( sdRKey > 127 ) sdRKey = 127;
			}
		}
		else
		{
			if ( gpMaSndDrvInfo->sChInfo[dCh].bKeyControl == MASNDDRV_KEYCTRL_ON )
			{
				sdRKey = sdRKey + sdKeyOffset * bKeyConRate[dProgNo];
				if ( sdRKey < 0 )	sdRKey = 0;
				else if ( sdRKey > 127 )	sdRKey = 127;
			}
		}
		break;

	case MASNDDRV_RESMODE1_MA2:

		if ( gpMaSndDrvInfo->sChInfo[dCh].bKeyControl != MASNDDRV_KEYCTRL_OFF )
		{
			sdRKey = sdRKey + sdKeyOffset;
			if ( sdRKey < 0   ) sdRKey = 0;
			else if ( sdRKey > 127 ) sdRKey = 127;
		}
		break;

	default:
		break;
	}
	return (UINT32)sdRKey;
}
/****************************************************************************
 *	GetRealKeyDrum
 *
 *	Description:
 *			Get real key number of drum with key control.
 *	Arguments:
 *			sdSeqId		sequence id (0..1)
 *			dCh			channel number (0..15)
 *			dKey		key number (0..127)
 *	Return:
 *			real key number (0..127)
 *
 ****************************************************************************/
static UINT32 GetRealKeyDrum
(
	SINT32	sdSeqId,					/* sequence id */
	UINT32	dCh,						/* channel number */
	UINT32	dKey						/* key number */
)
{
	SINT32	sdRKey;						/* real key value */
	SINT32	sdKeyOffset;				/* key offset */

	sdRKey = (SINT32)dKey;
	sdKeyOffset = (SINT32)(gpMaSndDrvInfo->sSndDrvInfo[sdSeqId].sbKeyOffset);

	if ( gpMaSndDrvInfo->sChInfo[dCh].bKeyControl == MASNDDRV_KEYCTRL_ON )
	{
		sdRKey = (SINT32)( sdRKey + sdKeyOffset );
		if ( sdRKey < 0   ) sdRKey = 0;
		else if ( sdRKey > 127 ) sdRKey = 127;
	}

	return (UINT32)sdRKey;
}
/****************************************************************************
 *	GetFmBlockFnum
 *
 *	Description:
 *			Return Block:Fnum value for FM slot.
 *	Arguments:
 *			sdSeqId		sequence id (0..1)
 *			dCh			channel number (0..15)
 *			dKey		key number (0..127,0x8000xxxx)
 *			dDrumKey	drum key number (0..127)
 *	Return:
 *			Block:Fnum value
 *
 ****************************************************************************/
static UINT32 GetFmBlockFnum
(
	SINT32	sdSeqId,					/* sequence id */
	UINT32	dCh,						/* channel number */
	UINT32	dKey,						/* key number */
	UINT32	dDrumKey					/* key number for drum */
)
{
	UINT32	dRKey;						/* real key number */
	UINT32	dBankNo;					/* bank number */
	UINT32	dProgNo;					/* program number */
	UINT32	dPitch;						/* pitch = block&fnum */

	MASMW_ASSERT( sdSeqId <= MASMW_SEQTYPE_DIRECT );
	MASMW_ASSERT( dKey <= 0x80000000 );

	dBankNo = gpMaSndDrvInfo->sChInfo[dCh].bBankNo;
	dProgNo = gpMaSndDrvInfo->sChInfo[dCh].bProgNo;

	if ( dBankNo < 128 )
	{
		dRKey = GetRealKeyMelody( sdSeqId, dCh, (UINT8)dKey );
		switch ( gpMaSndDrvInfo->sSndDrvInfo[sdSeqId].bMelodyMode )
		{
		  case MASNDDRV_RESMODE1_NORMAL:
		  case MASNDDRV_RESMODE1_MA3:
			dPitch = GetMa5FmPitch( dBankNo, dProgNo, dRKey );
			break;

		case MASNDDRV_RESMODE1_MA2:
		default:
			dPitch = GetMa5FmPitch( 128, dProgNo, dRKey );
			break;
		}
	}
	else
	{
		dRKey = GetRealKeyDrum( sdSeqId, dCh, dDrumKey );
		dPitch = GetMa5FmPitch( 128, dProgNo, dRKey );
	}

	return dPitch;
}
/****************************************************************************
 *	GetFmBlockFnumMa2
 *
 *	Description:
 *			Return MA-2 Block:Fnum value for FM slot.
 *	Arguments:
 *			sdSeqId		sequence id (0..1)
 *			dCh			channel number (0..15)
 *			dKey		key number (0x8000xxxx)
 *			dDrumKey	drum key number (0..127)
 *	Return:
 *			Block:Fnum value
 *
 ****************************************************************************/
static UINT32 GetFmBlockFnumMa2
(
	SINT32	sdSeqId,					/* sequence id */
	UINT8	dCh,						/* channel number */
	UINT32	dKey,						/* key number */
	UINT16	dDrumKey					/* key number for drum */
)
{
	UINT32	dPitch;						/* dPitch = block&fnum */
	UINT32	dBlock;						/* block number */
	UINT32	dFnum;						/* f-number */
	SINT32	sdKeyCon;

	(void)dDrumKey;

	MASMW_ASSERT( sdSeqId <= MASMW_SEQTYPE_DIRECT );
	MASMW_ASSERT( dKey >= 0x80000000 );

	/* compatible mode */

	dBlock = (dKey >> 10) & 0x0007;
	dFnum  =  dKey        & 0x03FF;

	if ( (gpMaSndDrvInfo->sChInfo[dCh].bKeyControl == MASNDDRV_KEYCTRL_ON) ||
		((gpMaSndDrvInfo->sChInfo[dCh].bKeyControl == MASNDDRV_KEYCTRL_NONE) &&
		 (gpMaSndDrvInfo->sChInfo[dCh].bBankNo <= 127))) {
		sdKeyCon = gpMaSndDrvInfo->sSndDrvInfo[sdSeqId].sbKeyOffset + 12;
		dFnum *= ma_ma2ex_fnum[sdKeyCon];
	}
	else
		dFnum *= 0x10911;	/* 49700/48000 */
	
	dFnum >>= 16;
	while ( dFnum > 1023 )
	{
		dFnum >>= 1;
		if ( dBlock < 7 ) dBlock++;
	}

	dPitch = ((dBlock << 10) & 0x1C00)
			| ( dFnum         & 0x03FF);

	return dPitch;
}
/****************************************************************************
 *	GetWtBlockFnum
 *
 *	Description:
 *			Return Block:Fnum value for WT slot.
 *	Arguments:
 *			sdSeqId		sequence id number
 *			dCh			channel number (0..15)
 *			dKey		key number (0..127)
 *			dBaseFs		base fequency
 *	Return:
 *			>=0			Block:Fnum value
 *			< 0			error code
 *
 ****************************************************************************/
static UINT32 GetWtBlockFnum
(
	SINT32	sdSeqId,					/* sequence id number */
	UINT32	dCh,						/* channel number */
	UINT32	dKey,						/* key number */
	UINT32	dBaseFs						/* base frequency */
)
{
	UINT32	dRKey;						/* real key number */
	UINT32	dPitch;						/* dPitch = block&fnum */
	UINT32	dBankNo;					/* bank number */
	UINT32	dProgNo;					/* program number */

	MASMW_ASSERT( sdSeqId <= MASMW_SEQTYPE_DIRECT );

	if ( dKey >= 0x80000000 )
	{
		return 0;
	}

	dBankNo = gpMaSndDrvInfo->sChInfo[dCh].bBankNo;
	dProgNo = gpMaSndDrvInfo->sChInfo[dCh].bProgNo;

	if ( dBankNo < 128 )
	{

		dRKey = GetRealKeyMelody( sdSeqId, dCh, (UINT8)dKey );
		switch ( gpMaSndDrvInfo->sSndDrvInfo[sdSeqId].bMelodyMode )
		{
		  case MASNDDRV_RESMODE1_NORMAL:
			dPitch = GetMa5WtPitch( dBaseFs, dBankNo, dProgNo, dRKey );
			break;

		  case MASNDDRV_RESMODE1_MA3:
			dPitch = GetMa3WtPitch( dBaseFs, dBankNo, dProgNo, dRKey );
			break;

		  case MASNDDRV_RESMODE1_MA2:
		  default:
			dPitch = GetMa5WtPitch( dBaseFs, 128, dProgNo, dRKey );
			break;
		}
	}
	else
	{

		dRKey = GetRealKeyDrum( sdSeqId, dCh, 60 );
		switch ( gpMaSndDrvInfo->sSndDrvInfo[sdSeqId].bDrumMode )
		{
		  case MASNDDRV_RESMODE1_NORMAL:
		  case MASNDDRV_RESMODE1_MA2:
			dPitch = GetMa5WtPitch( dBaseFs, dBankNo, dProgNo, dRKey );
			break;

		  case MASNDDRV_RESMODE1_MA3:
			dPitch = GetMa3WtPitch( dBaseFs, dBankNo, dProgNo, dRKey );
			break;

		  default:
			dPitch = GetMa5WtPitch( dBaseFs, 128, dProgNo, dRKey );
			break;
		}
	}

	return dPitch;
}
/****************************************************************************
 *	MakeStreamAudioParam
 *
 *	Description:
 *			Make parameter of specified stream audio.
 *	Arguments:
 *			sdSeqId			sequence id (0..2)
 *			dCh				channel number (0..15)
 *			dWaveId			wave id number (0..63)
 *			dVelocity		velocity value (0..127)
 *			psStreamParam	stream parameter of stream audio
 *	Return:
 *			0				success
 *			< 0				error
 *
 ****************************************************************************/
static SINT32 MakeStreamAudioParam
(
	SINT32	sdSeqId,					/* sequence id */
	UINT32	dCh,						/* channel number */
	UINT32	dWaveId,					/* wave id */
	UINT32	dVelocity,					/* velocity */
	PMASNDDRVSTMPARAM	psStreamParam	/* stream audio parameter */
)
{
	UINT32	dFormat;
	UINT32	dMnSt;
	UINT32	dPanpot;
	UINT32	dSaId = 0;
	UINT32	dVoVolume = 0;
	SINT32	sdResult;
	PMASNDDRVSTMINFO	psStreamInfo;
	static UINT8 bWaveMode[8] = { 0, 0, 2, 3, 1, 0, 0, 0 };

	(void)dCh;							/* for unused warning message */

	psStreamInfo = & gpMaSndDrvInfo->sStreamInfo[sdSeqId][dWaveId];
	
	if ( psStreamInfo->dFrequency == 0 )
	{
		return MASMW_ERROR;
	}

	dFormat = (UINT32)(psStreamInfo->bFormat);
	if ( ( dFormat & 0x80 ) == 0 )
		dMnSt = 0;
	else
		dMnSt = 1;
	dPanpot = (UINT32)(psStreamInfo->bPan);

	switch ( gpMaSndDrvInfo->sSndDrvInfo[sdSeqId].bDvaMode )
	{
	  case MASNDDRV_RESMODE2_NORMAL:
		sdResult = MaDva_GetStreamSlot( dCh, dWaveId, dMnSt );
		if ( (sdResult != 0) && (sdResult != 1) )
		{
			return MASMW_ERROR;
		}
		dSaId = sdResult;
		break;

	  case MASNDDRV_RESMODE2_MA5MONO:
	  	dSaId = 0;
	  	break;
	}

	if ( gpMaSndDrvInfo->sSndDrvInfo[sdSeqId].bWtVolMode == MASNDDRV_WTVOL_MODE_MA3 )
	{
		dVoVolume = CalcVoiceVolume( sdSeqId, dVelocity, (UINT8)(12 << 1) );	/* +12dB */
	}
	else
	{
		dVoVolume = CalcVoiceVolume( sdSeqId, dVelocity, (UINT8)0 );
	}


	psStreamParam->bPanpot	= (UINT8)( (dPanpot & 0x7C) << 1 );
	psStreamParam->bStm		= (UINT8)( 1 << 1 );
	psStreamParam->bPe		= (UINT8)( ( dPanpot == 255 ) ? 0 : 1 );
	if ( ( dPanpot == 128 ) || ( (dFormat & 0x7F) == 0 ) )
		psStreamParam->bPanOff = (UINT8)(1 << 2);
	else
		psStreamParam->bPanOff = 0;
	psStreamParam->bMode		= bWaveMode[dFormat & 0x07];
	dFormat &= 0x7F;
	if ( dFormat <= 1 )	/* ADPCM */
	{
		if ( dMnSt == 0 )	/* ADPCM Mono */
			psStreamParam->wEndPoint	= MASNDDRV_STMADPCM_ENDPOINT;
		else				/* ADPCM Stereo */
			psStreamParam->wEndPoint	= MASNDDRV_STMADPCM_ST_ENDPOINT;

⌨️ 快捷键说明

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