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

📄 maphrcnv.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 5 页
字号:
{
	MAPHRCNV_DBGMSG(("CnvExpression[%d %02X] \n", bCh, bExp));

	if(gChInfo[bCh].bExp != bExp)
	{
		MaSndDrv_SetCommand(gdwPhrId, -1L, MASNDDRV_CMD_EXPRESSION, (UINT32)bCh, (UINT32)bExp, 0L);
		gChInfo[bCh].bExp = bExp;
		return (1L);
	}
	return (0L);
}

/*==============================================================================
//	Function Name	:	UINT32	CnvPanpot(UINT8 bCh, UINT8 bPan)
//
//	Description		:	Convert to Panpot(Native format)
//
//	Argument		:	bCh			...	#Channel(0..15)
//						bPan		...	Panpote(0..127)
//
//	Return			:	>0:Number of converted data  <0:Error Code
//
==============================================================================*/
static UINT32	CnvPanpot(UINT8 bCh, UINT8 bPan)
{
	MAPHRCNV_DBGMSG(("CnvPanpot[%d %02X] \n", bCh, bPan));

	if(gChInfo[bCh].bPan != bPan)
	{
		MaSndDrv_SetCommand(gdwPhrId, -1L, MASNDDRV_CMD_PANPOT, (UINT32)bCh, (UINT32)bPan, 0L);
		gChInfo[bCh].bPan = bPan;
		return (1L);
	}
	return (0L);
}

/*==============================================================================
//	Function Name	:	UINT32	CnvPitchBend(UINT8 bCh, UINT8 bPitch)
//
//	Description		:	Convert to PitchBend(Native format)
//
//	Argument		:	bCh			...	#Channel(0..15)
//						bPitch		...	Pitch(0..127)
//
//	Return			:	>0:Number of converted data  <0:Error Code
//
==============================================================================*/
static UINT32	CnvPitchBend(UINT8 bCh, UINT8 bPitch)
{
	UINT16	wPitch;

	MAPHRCNV_DBGMSG(("CnvPitchBend[%d %02X] \n", bCh, bPitch));

	gChInfo[bCh].bPitch = bPitch;
	wPitch = (UINT16)((UINT16)bPitch << 7);
	MaSndDrv_SetCommand(gdwPhrId, -1L, MASNDDRV_CMD_PITCH_BEND, (UINT32)bCh, (UINT32)wPitch, 0L);
	return (1L);
}

/*==============================================================================
//	Function Name	:	UINT32	CnvNoteOn(UINT8 bCh, UINT8 bOct, UINT8 bKey, UINT32 dwNoteOffTime)
//
//	Description		:	Convert to NoteOn(Native format)
//
//	Argument		:	bCh				...	#Channel(0..15)
//						bOct			...	Octave Shift(0..3)
//						bKey			...	#Key(1..12)
//						dwNoteOffTime	...	NoteOff Time
//
//	Return			:	0:NoError  <0:Error Code
//
==============================================================================*/
static UINT32	CnvNoteOn(UINT8 bCh, UINT8 bOct, UINT8 bKey, UINT32 dwNoteOffTime)
{
	UINT8	bNote;
	SINT16	nOct;
	SINT16	nNote;

	nOct	= (SINT16)(bOct + gChInfo[bCh].nOctShift + 3);
	nNote	= (SINT16)((nOct * 12) + bKey);

	/*	Process for when nNote is out of the range (Note[0..127])	*/
	if(nNote < 0)			bNote = 0;
	else if(nNote >= 127)	bNote = 127;
	else					bNote = (UINT8)nNote;

	gChInfo[bCh].bKey			= bNote;
	gChInfo[bCh].dwKeyOffTime	= dwNoteOffTime;

	/*	Velocity 127 fixed */
	/*
	MAPHRCNV_DBGMSG(("CnvNoteOn[%d %d %02X %08lX] -> [%02X]\n", bCh, bOct, bKey, dwNoteOffTime, bNote));
	*/

	MaSndDrv_SetCommand(gdwPhrId, -1L, MASNDDRV_CMD_NOTE_ON_MA2, (UINT32)bCh, (UINT32)bNote, 0x7FL);
	return (1L);
}

/*==============================================================================
//	Function Name	:	UINT32	CnvNoteOff(UINT8 bCh)
//
//	Description		:	Convert to NoteOff(Native format)
//
//	Argument		:	bCh			...	#Channel(0..15)
//
//	Return			:	0:NoError  <0:Error Code
//
==============================================================================*/
static UINT32	CnvNoteOff(UINT8 bCh)
{
	/*
	MAPHRCNV_DBGMSG(("CnvNoteOff[%d] \n", bCh));
	*/

	if(gChInfo[bCh].dwKeyOffTime != 0xFFFFFFFF) {
		MaSndDrv_SetCommand(gdwPhrId, -1L, MASNDDRV_CMD_NOTE_OFF_MA2, (UINT32)bCh, (UINT32)gChInfo[bCh].bKey, 0L);
		gChInfo[bCh].dwKeyOffTime = 0xFFFFFFFF;
		return (1L);
	}

	return (0L);
}

/*==============================================================================
//	Function Name	:	UINT32	CnvExclusiveMessage(UINT8 bPhrNum, UINT8* pbExMsg, UINT32 dwSize)
//
//	Description		:	Convert to ExclusiveMessage(Native format)
//
//	Argument		:	bPhrNum	...	#Phrase(0..3)
//						pbExMsg	...	pointer to exclusive message.
//						dwSize	...	size of exclusive message.
//
//	Return			:	0:NoError  <0:Error Code
//
==============================================================================*/
static UINT32	CnvExclusiveMessage(UINT8 bPhrNum, UINT8* pbExMsg, UINT32 dwSize)
{
	UINT8	bCh;
	UINT8	bRange;
	UINT32	dwBlkFnum;
	UINT32	dwRet;
	PCHINFO	pCi;
	PVOCINFO pVi;

	MAPHRCNV_DBGMSG(("CnvExclusiveMessage[%d %08lX %08lX] \n", bPhrNum, pbExMsg, dwSize));

	dwRet = 0L;
	if(dwSize == 6L)
	{
		if(	(pbExMsg[0] == 0x43)	&&
			(pbExMsg[1] == 0x03)	&&
			(pbExMsg[2] == 0x90)	&&
			(pbExMsg[5] == 0xF7))			/*	Extend NoteOn/Off	*/
		{
			bCh		= (UINT8)((pbExMsg[3] & 0x03) + (bPhrNum << 2));
			pCi		= &(gChInfo[bCh]);

			if((pbExMsg[3] & 0xF0) == 0xC0) {
				pCi->bExNoteFlag |= 0x02;
				pCi->bRegH = pbExMsg[4];
			}
			else if((pbExMsg[3] & 0xF0) == 0xB0) {
				pCi->bExNoteFlag |= 0x01;
				pCi->bRegL = pbExMsg[4];
			}
			else {
				return (0L);
			}

			if((pCi->bExNoteFlag & 0x03) == 0x03)
			{
				dwBlkFnum	= (UINT32)(((UINT32)(pCi->bRegH & ~0x20) << 8) | (UINT32)pCi->bRegL);
				dwBlkFnum	|= 0x80000000;
				if((pCi->bRegH & 0x20) == 0x20) {
					if (pCi->bNew) {
						pVi = &(gApiInfo[bPhrNum].gPhraseInfo.VocInfo[pCi->bVoiceNo]);
						MAPHRCNV_DBGMSG(("ProgramChange[%d %d %d %d] \n", bCh, pCi->bVoiceNo, pVi->bBankNo, pVi->bProgNo));
						MaSndDrv_SetCommand(gdwPhrId, -1L, MASNDDRV_CMD_PROGRAM_CHANGE,	\
											 (UINT32)bCh, (UINT32)pVi->bBankNo, (UINT32)pVi->bProgNo);
						pCi->bNew = 0x00;
						dwRet++;
					}
					MaSndDrv_SetCommand(gdwPhrId, -1L, MASNDDRV_CMD_NOTE_ON_MA2EX,	 (UINT32)bCh, dwBlkFnum, 0x7FL);
				} else {
					MaSndDrv_SetCommand(gdwPhrId, -1L, MASNDDRV_CMD_NOTE_OFF_MA2EX, (UINT32)bCh, dwBlkFnum, 0L);
				}
				dwRet++;
			}
		}
		else if((pbExMsg[0] == 0x43)	&&
				(pbExMsg[1] == 0x04)	&&
				(pbExMsg[2] == 0x02)	&&
				(pbExMsg[5] == 0xF7))		/*	Pitch Bend Range	*/
		{
			bCh		= (UINT8)((pbExMsg[3] & 0x03) + (bPhrNum << 2));
			pCi		= &(gChInfo[bCh]);
			bRange	= pbExMsg[4];

			if((pCi->bRange != bRange) && (bRange <= 24)) {
				MaSndDrv_SetCommand(gdwPhrId, -1L, MASNDDRV_CMD_BEND_RANGE, (UINT32)bCh, (UINT32)bRange, 0L);
				pCi->bRange = bRange;
				dwRet++;
			}
		}
	}

	return (dwRet);
}

/*==============================================================================
//	Function Name	:	UINT32	CnvAllSoundOff(UINT8 bCh)
//
//	Description		:	Convert to AllSoundOff(Native format)
//
//	Argument		:	bCh			...	#Channel(0..15)
//
//	Return			:	>=0:Number of converted data  <0:Error Code
//
==============================================================================*/
static UINT32	CnvAllSoundOff(UINT8 bCh)
{
	MAPHRCNV_DBGMSG(("CnvAllSoundOff[%d] \n", bCh));

	MaSndDrv_SetCommand(gdwPhrId, -1L, MASNDDRV_CMD_ALL_SOUND_OFF, (UINT32)bCh, 0L, 0L);
	return (1L);
}

/*=============================================================================
//	Function Name	:	UINT32	PutInitPhraseMessage(UINT8 phr_id)
//
//	Description		:	Initialize Phrase commands message
//
//	Argument		:	phr_id	.... Phrase ID (0..3)
//
//	Return			:	0:NoError <0:Error Code
//
=============================================================================*/
static SINT32	PutInitPhraseMessage(UINT8 phr_id)
{
	UINT8		i;
	UINT8		bCh;
	UINT16		wPitch;
	PCHINFO		pCi;

	MAPHRCNV_DBGMSG(("PutInitPhraseMessage[%ld] \n", phr_id));

	for(i = 0; i < MAX_PHRASE_SLOT; i++)
	{
		bCh = (UINT8)(i + (phr_id << 2));
		pCi = &(gChInfo[bCh]);

		/*	All Sound Off	*/
		MaSndDrv_SetCommand(gdwPhrId, -1L, MASNDDRV_CMD_ALL_SOUND_OFF, (UINT32)bCh, 0L, 0L);

		/*	Program Change	*/
		/*	Send command with next NoteOn message	*/
		pCi->bNew = 1;

		/*	Channel Volume	*/
		MaSndDrv_SetCommand(gdwPhrId, -1L, MASNDDRV_CMD_CHANNEL_VOLUME, (UINT32)bCh, (UINT32)pCi->bVolume, 0L);

		/*	Expression		*/
		MaSndDrv_SetCommand(gdwPhrId, -1L, MASNDDRV_CMD_EXPRESSION, (UINT32)bCh, (UINT32)pCi->bExp, 0L);

		/*	Panpot			*/
		MaSndDrv_SetCommand(gdwPhrId, -1L, MASNDDRV_CMD_PANPOT, (UINT32)bCh, (UINT32)pCi->bPan, 0L);

		/*	Modulation		*/
		MaSndDrv_SetCommand(gdwPhrId, -1L, MASNDDRV_CMD_MODULATION_DEPTH, (UINT32)bCh, (UINT32)pCi->bMod, 0L);

		/*	BendRange		*/
		MaSndDrv_SetCommand(gdwPhrId, -1L, MASNDDRV_CMD_BEND_RANGE, (UINT32)bCh, (UINT32)pCi->bRange, 0L);

		/*	PitchBend		*/
		wPitch = (UINT16)((UINT16)pCi->bPitch << 7);
		MaSndDrv_SetCommand(gdwPhrId, -1L, MASNDDRV_CMD_PITCH_BEND, (UINT32)bCh, (UINT32)wPitch, 0L);
	}

	return (MASMW_SUCCESS);
}

/*=============================================================================
//	Function Name	:	void	InitChInfo(UINT8 bCh)
//
//	Description		:	Initialize Channel Information Struct
//
//	Argument		:	bCh	...	#Channel (0..15)
//
//	Return			:	void
//
=============================================================================*/
static void	InitChInfo(UINT8 bCh)
{
	UINT8	bPhrNum;
	PCHINFO	pCi;

	if(bCh >= MASMW_NUM_CHANNEL)	return;

	pCi = &(gChInfo[bCh]);
	pCi->bNew			= 0x00;
	pCi->bKey			= 0x00;
	pCi->bVoiceNo		= 0x00;			/*	VoiceNo			(0..3)				*/
	pCi->bVolume		= 0x64;			/*	Channel Volume	(0..127)			*/
	pCi->bMod			= 0;			/*	Modulation	(0..4)					*/
	pCi->bPitch			= 0x40;			/*	PitchBend	(0..127)				*/
	pCi->bRange			= 2;			/*	PitchBend Range	(100cent unit)		*/
	pCi->bExNoteFlag	= 0x00;			/*	bit0 : Low	bit1: High				*/
	pCi->bRegL			= 0x00;			/*	Extended Note High-Byte value		*/
	pCi->bRegH			= 0x00;			/*	Extended Note Low-Byte value		*/
	pCi->nOctShift		= 0;			/*	Octave Shift (-4..0..4)				*/
	pCi->dwKeyOffTime	= 0xFFFFFFFF;	/*	KeyOff Time							*/

	bPhrNum		= (UINT8)(bCh >> 2);
	pCi->bExp	= gApiInfo[bPhrNum].vol;
	pCi->bPan	= gApiInfo[bPhrNum].pan;
}


/*=============================================================================
//	Function Name	:	SINT32	Seek(UINT8 phr_id, UINT32 pos)
//
//	Description		:	Seek process of converter data
//
//	Argument		:	phr_id		...	Phrase ID (0..3)
//						pos			...	Starting position of play back (msec)
//
//	Return			:	0:NoError  <0:Error Code
//
=============================================================================*/
static SINT32	Seek(UINT8 phr_id, UINT32 pos)
{
	UINT8		i;
	UINT8		bCh;
	UINT8		bData0;
	UINT8		bData1;
	UINT8*		pbExMsg;
	UINT32		dwSize;
	UINT32		dwSeekTime;
	UINT32		dwCurrent;
	UINT32		dwDuration;
	PCHINFO		pCi;
	PPHRINFO	pPi;

	MAPHRCNV_DBGMSG(("Seek[%08lX %08lX %02X] \n", phr_id, pos, gbPlayStatus));

	dwSeekTime = (UINT32)(pos / PHRASE_TIMEBASE);
	pPi = &(gApiInfo[phr_id].gPhraseInfo);
	if(dwSeekTime >= pPi->dwPlayTime)					return (MASMW_ERROR);

	pPi->dwTimer		= 0L;
	pPi->dwCurrentTime	= 0L;
	pPi->dwDataPosition	= 0L;

	/*	Initialize each channel info	*/
	for(i = 0; i < MAX_PHRASE_SLOT; i++) {
		bCh = (UINT8)(i + (phr_id << 2));
		InitChInfo(bCh);
	}

	/*	Seek the position	*/
	while(pPi->dwSequenceChunkSize > pPi->dwDataPosition)
	{
		/*	Get Current Time	*/
		dwCurrent = pPi->dwDataPosition;
		dwDuration = (UINT32)pPi->pbSequenceChunk[dwCurrent++];
		if(dwDuration & 0x80) {
			dwDuration = (UINT32)(((dwDuration & 0x7F) << 7) + (UINT32)pPi->pbSequenceChunk[dwCurrent++] + 128L);
		}

		if((pPi->dwCurrentTime + dwDuration) >= dwSeekTime) {
			pPi->dwTimer = dwSeekTime;
			break;
		}

		/*	Update position & time	*/
		pPi->dwDataPosition	= dwCurrent;
		pPi->dwCurrentTime	+= dwDuration;

		/**/
		bData0 = pPi->pbSequenceChunk[pPi->dwDataPosition++];
		switch(bData0)
		{
		case 0x00 :
			bData1	= pPi->pbSequenceChunk[pPi->dwDataPosition++];
			bCh		= (UINT8)(((bData1 & 0xC0) >> 6) + (phr_id << 2));
			switch(bData1 & 0x30)
			{
			case 0x00 :	/*	Short type Volume	*/
				gChInfo[bCh].bVolume = gbVolTbl[bData1 & 0x0F];
				break;
			case 0x10 : /*	*/
				break;
			case 0x20 :	/*	Short type Modulation	*/
				gChInfo[bCh].bMod = gbModTbl[bData1 & 0x0F];
				break;
			case 0x30 :
				switch(bData1 & 0x0F)
				{
				case 0x00 :
					gChInfo[bCh].bVoiceNo = (UINT8)(pPi->pbSequenceChunk[pPi->dwDataPosition++] & 0x03);
					break;
				case 0x02 :
					OctaveShift(bCh, pPi->pbSequenceChunk[pPi->dwDataPosition++]);
					break;
				case 0x04 :
					gChInfo[bCh].bPitch = (UINT8)(pPi->pbSequenceChunk[pPi->dwDataPosition++] & 0x7F);
					break;
				case 0x0A :
					gChInfo[bCh].bPan = (UINT8)(pPi->pbSequenceChunk[pPi->dwDataPosition++] & 0x7F);
					break;
				case 0x0B :
					gChInfo[bCh].bVolume = (UINT8)(pPi->pbSequenceChunk[pPi->dwDataPosition++] & 0x7F);
					break;
				default	  :
					pPi->dwDataPosition++;
					break;
				}
				break;
			default	 :
				break;
			}
			break;
		case 0xFF :
			bData1 = pPi->pbSequenceChunk[pPi->dwDataPosition++];
			if(bData1 == 0xF0) {				/*	Exclusive Message	*/
				dwSize	= pPi->pbSequenceChunk[pPi->dwDataPosition++];
				pbExMsg	= &(pPi->pbSequenceChunk[pPi->dwDataPosition]);

				if(dwSize == 6L)
				{
					if(	(pbExMsg[0] == 0x43)	&&
						(pbExMsg[1] == 0x03)	&&
						(pbExMsg[2] == 0x90)	&&
						(pbExMsg[5] == 0xF7))			/*	Extend NoteOn/Off	*/
					{
						bCh		= (UINT8)((pbExMsg[3] & 0x03) + (phr_id << 2));
						pCi		= &(gChInfo[bCh]);
						if((pbExMsg[3] & 0xF0) == 0xC0) {
							pCi->bExNoteFlag |= 0x02;
							pCi->bRegH = pbExMsg[4];
						}

⌨️ 快捷键说明

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