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

📄 mamidcnv.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************
 *
 *		Copyright (C) 2002-2003	YAMAHA CORPORATION. All rights reserved.
 *
 *		Module		: mamidcnv.c
 *
 *		Description	: SMF/GML Stream Converter Module.
 *
 *		Version		: 1.1.2 	2003.07.09
 *
 ****************************************************************************/

#include "mamidcnv.h"

/*--------------------------------------------------------------------------*/
/*   Defines                                                                */
/*--------------------------------------------------------------------------*/
#define	SMF_TIMEBASE_SHIFT			2							/*                         */
#define	SMF_TIMEBASE				(1L<<SMF_TIMEBASE_SHIFT)	/* [ms]                    */

#define	MAX_SMF_MESSAGES			256							/*                          */
#define	MAX_SMF_TRACKS				32							/* Should be <= 32          */
#define SMF_MAX_GAIN				76							/* - 6[dB] : 90             */
																/* -18[dB] : 45             */
#define	MINIMUM_LENGTH				(20)

#define MELODY_MAP					(0)
#define DRUM_MAP					(1)
#define NUM_OF_MAPS					(2)

/*--------------------------------------------------------------------------*/
/*   Types                                                                  */
/*--------------------------------------------------------------------------*/
typedef struct _tagMidChInfo
{
	UINT32					dBank;						/* BankH&L (0x00:00..0x7F7F)       */
	UINT32					dCurrBank;					/* BankH&L (0x00:00..0x7F7F)       */
	UINT32					dProg;						/* ProgramChange (0..127)          */
	UINT32					dVolume;					/* ChannelVolume (0..127)          */
	UINT32					dExpression;				/* Expression (0..127)             */
	UINT32					dModulation;				/* Modulation (0..127)             */
	UINT32					dPitchBend;					/* PitchBendH (0..127)             */
	UINT32					dBendRange;					/* CurrentBendRange (0..24)        */
	UINT32					dPreBendRange;				/* LatestBendRange (0..24)         */
	UINT32					dPanpot;					/* Panpot (0..127)                 */
	UINT32					dHold1;						/* Hold1 (0..127)                  */
	UINT32					dMode;						/* 0:MONO, 1:POLY                  */
	UINT32					dRPN;						/* RPN (0x00:00..0xFF7F)           */
	UINT32					dMipMute;					/* Mute switch (1:mute)            */
	UINT32					dKeyCon;					/* 0:Melady, 1:OFF, 2:ON           */
	UINT32					dLedSync;					/* 0:OFF, 1:ON                     */
	UINT32					dVibSync;					/* 0:OFF, 1:ON                     */
	UINT32					dFineTune;					/* 0..0x3FFF                       */
	UINT32					dCoaseTune;					/* 0..0x7F                         */
} MIDCHINFO, *PMIDCHINFO;

typedef struct _tagMIDPACKET
{
	SINT32					sdDeltaTime;
	UINT32					dMsgID;						
	UINT32					dP1;						
	UINT32					dP2;						
	UINT32					dP3;						
} MIDPACKET, *PMIDPACKET;

typedef struct _tagTrack
{
	UINT32					dSmfCmd;					/* CMD @ now                      */
	UINT32					dSize;						/* [byte] 0 measns nothing in it. */
	UINT8*					pbBase;						/* NULL measns nothing in it.     */
	UINT32					dOffset;					/* offset byte                    */
	SINT32					sdTicks;					/*                                */
} TRACKINFO, *PTRACKINFO;

typedef struct _tagOrderList
{
	struct _tagOrderList*	pPrev;
	struct _tagOrderList*	pNext;
	UINT32					dTrack;
	UINT32					dTicks;
} ORDERLIST, *PORDERLIST;

typedef struct _tagMidInfo
{
	UINT32					dTimeResolution;			/* 0..0x7fff                       */
	UINT8*					pbTitle;					/*                                 */
	UINT32					dSizeTitle;					/*                                 */
	UINT8*					pbCopyright;				/*                                 */
	UINT32					dSizeCopyright;				/*                                 */
	UINT32					dNumOfTracks;				/* 1..32                           */
	UINT32					dSmfFormat;					/* 0..1                            */
	UINT32					dSetupBar;					/* 0:No, 1:Yes                     */
	UINT32					dStart;						/* Index after SetupBar            */
	UINT32					dVibNoteVoice;				/* 0:No, 1:Yes                     */

	SINT32					sdTotalTicks;				/* Total ticks                     */
	SINT32					sdDataEndTime;				/* (22.10)[ms]                     */
	SINT32					sdDelta;					/* (22.10)[ms]                     */

	UINT32					dEndFlag;					/*                                 */
	TRACKINFO				TrackInfo[MAX_SMF_TRACKS];	
	
	struct _tagOrderList*	pTopOrderList;				
	struct _tagOrderList*	pDoneOrderList;				
	struct _tagOrderList*	pBottomOrderList;			
	ORDERLIST				OrderList[MAX_SMF_TRACKS + 3];

	MIDCHINFO				ChInfo[16];					/*                                 */
	UINT32					dValid;						/* 0:none, 1:Valid                 */

	UINT8					bVoiceMap[NUM_OF_MAPS][128];/* 0:Empty, 1:Valid                */
} MIDINFO, *PMIDINFO;

typedef	struct _tagMidGlobals
{
	SINT32		sdSeqID;						/* Sequence ID             */
	SINT32		sdFileID;						/* File ID                 */
	UINT32		dEnable;						/* 0:disable               */
	UINT32		dSetup;							/* 1: Just after seek      */

	UINT32		dRamBase;						/*                         */
	UINT32		dRamOffset;						/*                         */
	UINT32		dRamSize;						/*                         */

	MIDINFO		DataInfo[2];					/*                         */

	SINT32		sdSeekTime;						/* [ms]                    */
	SINT32		sdLastMsgTime;					/* (22.10)[ms]             */
	SINT32		sdSmfCurrentTicks;				/* Ticks @ now             */
	SINT32		sdSmfCurrentTime;				/* (22.10)[ms]             */
	SINT32		sdSmfDataEndTime;				/* (22.10)[ms]             */
	SINT32		sdSmfEndTime;					/* (22.10)[ms]             */
	SINT32		sdSmfDelta;						/* (22.10)[ms]             */

	UINT32		dMaxGain;						/* MaxGain (0..127)        */
	UINT32		dMasterVolume;					/* MsaterVolume (0..127)   */

	UINT32		dHoldMsgs;						/* Number of messages in Q */
	UINT32		dHoldPtrR;						/* Pointer for Read        */
	MIDPACKET	MsgBuffer[MAX_SMF_MESSAGES];	/* Message Q               */

	UINT32		dMuteFlag;						/* 0:Normal, 1:MUTE        */

	UINT32		dSyncNoteCh;					/* 0..15                   */
	UINT32		dSyncNoteKey;					/* 0..127, 255:OFF         */
	UINT32					dVibNote;			/* 0:No VibiNote, 1:Yes,VibNote    */

} MIDGLOBAL, *PMIDGLOBAL;


/*--------------------------------------------------------------------------*/
/*   Consts                                                                 */
/*--------------------------------------------------------------------------*/
#include "mamid4opvoice.h"


/*---------------------------------------------------------------------------*/
/*   Globals                                                                 */
/*---------------------------------------------------------------------------*/
static MIDGLOBAL	gMidInfo;
static PMIDGLOBAL	gpMidInfo;


/*---------------------------------------------------------------------------*/
/*   Functions (internal use only)                                           */
/*---------------------------------------------------------------------------*/

/****************************************************************************
 *	InitializeOrderList(PMIDINFO pI)
 *
 *	Description:
 *			Initialize OrderList.
 *	Param:
 *		pI			... pointer to the data info
 *	Return:
 *			none
 ****************************************************************************/
static void InitializeOrderList(PMIDINFO pI)
{
	UINT32 i;

	for (i = 1; i <= MAX_SMF_TRACKS + 1; i++)
	{
		pI->OrderList[i].pPrev = &pI->OrderList[i - 1];
		pI->OrderList[i].pNext = &pI->OrderList[i + 1];
		pI->OrderList[i].dTrack = 0xFF;
		pI->OrderList[i].dTicks = 0xFFFFFFFFL;
	}
	pI->OrderList[0].pPrev = NULL;
	pI->OrderList[0].pNext = &pI->OrderList[1];
	pI->OrderList[MAX_SMF_TRACKS + 2].pPrev = &pI->OrderList[MAX_SMF_TRACKS + 1];
	pI->OrderList[MAX_SMF_TRACKS + 2].pNext = NULL;
	pI->pTopOrderList = &pI->OrderList[0];
	pI->pDoneOrderList = &pI->OrderList[1];
	pI->pBottomOrderList = &pI->OrderList[MAX_SMF_TRACKS + 2];
}


/****************************************************************************
 *	SortOrderList(PMIDINFO pI)
 *
 *	Description:
 *			Sort OrderList. (Ascending order)
 *	Param:
 *		pI			... pointer to the data info
 *	Return:
 *			none
 ****************************************************************************/
static void SortOrderList(PMIDINFO pI)
{
	PORDERLIST pSlot;
	PORDERLIST pTerget;

	pSlot = (pI->pTopOrderList)->pNext;
	(pSlot->pPrev)->pNext = pSlot->pNext;
	(pSlot->pNext)->pPrev = pSlot->pPrev;
	pSlot->dTicks = ((UINT32)pI->TrackInfo[pSlot->dTrack].sdTicks << 5) + pSlot->dTrack;

	pTerget = pSlot->pNext;
	while (pTerget != pI->pDoneOrderList)
	{
		if (pSlot->dTicks <= pTerget->dTicks) break;
		pTerget = pTerget->pNext;
	}

	(pTerget->pPrev)->pNext = pSlot;
	pSlot->pPrev = pTerget->pPrev;
	pTerget->pPrev = pSlot;
	pSlot->pNext = pTerget;
}


/****************************************************************************
 *	InsertOrderList(PMIDINFO pI, UINT32 dTrack, SINT32 sdTicks)
 *
 *	Description:
 *			Add item to the top of the list.
 *	Param:
 *		pI			... pointer to the data info
 *	Return:
 *			none
 ****************************************************************************/
static void InsertOrderList(PMIDINFO pI, UINT32 dTrack, SINT32 sdTicks)
{
	PORDERLIST pTerget;

	if (pI->dNumOfTracks == 1) return;
	if (((pI->dEndFlag >> dTrack) & 0x01) == 0) return;

	pTerget = pI->pDoneOrderList->pNext;
	if (pTerget == pI->pBottomOrderList) return;
	
	pI->pDoneOrderList->pNext = pTerget->pNext;
	(pTerget->pNext)->pPrev = pI->pDoneOrderList;

	pTerget->dTrack = dTrack;
	pTerget->dTicks = ((UINT32)sdTicks << 5) + dTrack;
	pTerget->pPrev = pI->pTopOrderList;
	pTerget->pNext = (pI->pTopOrderList)->pNext;
	((pI->pTopOrderList)->pNext)->pPrev = pTerget;
	(pI->pTopOrderList)->pNext = pTerget;
	
	SortOrderList(pI);
}


/****************************************************************************
 *	RemoveFromOrderList(PMIDINFO pI)
 *
 *	Description:
 *			delete Item from the top of the list.
 *	Param:
 *		pI			... pointer to the data info
 *	Return:
 *			none
 ****************************************************************************/
static void RemoveFromOrderList(PMIDINFO pI)
{
	PORDERLIST pSlot;
	PORDERLIST pTerget;

	pSlot = (pI->pTopOrderList)->pNext;
	(pSlot->pPrev)->pNext = pSlot->pNext;
	(pSlot->pNext)->pPrev = pSlot->pPrev;
	
	pTerget = pI->pBottomOrderList;
	(pTerget->pPrev)->pNext = pSlot;
	pSlot->pPrev = pTerget->pPrev;
	pTerget->pPrev = pSlot;
	pSlot->pNext = pTerget;
}


/****************************************************************************
 *	GetTrackTime(PMIDINFO pI, UINT32 dTrack)
 *
 *	Description:
 *		Get the 1st DT from the list.
 *	Param:
 *		pI			... pointer to the data info
 *		bTrack		... #Track
 *	Return:
 *		0 : NoError, < 0 : Error code
 ****************************************************************************/
static SINT32	GetTrackTime(PMIDINFO pI, UINT32 dTrack)
{
	UINT32		dTemp;
	SINT32		dTime;
	PTRACKINFO	pMt;

	if (((pI->dEndFlag >> dTrack) & 0x01) == 0) return (-1);

	pMt = &(pI->TrackInfo[dTrack]);

	dTime = 0;
	do
	{
		if (pMt->dOffset >= pMt->dSize)
		{
			pI->dEndFlag &= ~(1L << dTrack);
			return (-1);
		}
		dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
		dTime = (dTime << 7) + (dTemp & 0x7f);
	} while (dTemp >= 0x80);

	pMt->sdTicks += dTime;

	return (0);
}


/****************************************************************************
 *	UpdateTrackTime(PMIDINFO pI, UINT32 dTrack)
 *
 *	Description:
 *		Update the 1st DT on the Track and OrderList
 *	Param:
 *		pI			... pointer to the data info
 *		bTrack		... #Track
 *	Return:
 *		0 : NoError, < 0 : Error code
 ****************************************************************************/
static SINT32	UpdateTrackTime(PMIDINFO pI, UINT32 dTrack)
{
	UINT32		dTemp;
	SINT32		dTime;
	PTRACKINFO	pMt;

	if (pI->dNumOfTracks == 1)
	{
		/* Single track */
		if (((pI->dEndFlag >> dTrack) & 0x01) == 0)
		{
			return (-1);
		}

		pMt = &(pI->TrackInfo[dTrack]);

		dTime = 0;
		do
		{
			if (pMt->dOffset >= pMt->dSize)
			{
				pI->dEndFlag &= ~(1L << dTrack);
				return (-1);
			}
			dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
			dTime = (dTime << 7) + (dTemp & 0x7f);
		} while (dTemp >= 0x80);

		pMt->sdTicks += dTime;
	}
	else
	{
		/* Multi track */
		if (((pI->dEndFlag >> dTrack) & 0x01) == 0)
		{
			RemoveFromOrderList(pI);
			return (-1);
		}

		pMt = &(pI->TrackInfo[dTrack]);

		dTime = 0;
		do
		{
			if (pMt->dOffset >= pMt->dSize)
			{
				pI->dEndFlag &= ~(1L << dTrack);
				RemoveFromOrderList(pI);
				return (-1);
			}
			dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
			dTime = (dTime << 7) + (dTemp & 0x7f);
		} while (dTemp >= 0x80);

		pMt->sdTicks += dTime;
		SortOrderList(pI);
	}

	return (0);
}


/****************************************************************************
 *	ResetTimeInfo(PMIDINFO pI)
 *
 *	Description:
 *		Reset time info
 *	Param:
 *		pI			... pointer to the data info
 *	Return:
 *		none
 ****************************************************************************/
static void	ResetTimeInfo(PMIDINFO pI)
{
	SINT32		sdTrack;
	PTRACKINFO	pMt;

	pI->dEndFlag = 0;

	for (sdTrack = 0; sdTrack < (SINT32)pI->dNumOfTracks; sdTrack++)
	{
		pMt = &(pI->TrackInfo[sdTrack]);

		pMt->dSmfCmd = 0;
		pMt->dOffset = 0;
		pMt->sdTicks = 0;
		if (pMt->dSize > 0) pI->dEndFlag |= (1L << sdTrack);
	}
	
	InitializeOrderList(pI);

	for (sdTrack = 0; sdTrack < (SINT32)pI->dNumOfTracks; sdTrack++)
	{
		GetTrackTime(pI, (UINT32)sdTrack);
		pMt = &(pI->TrackInfo[sdTrack]);
		InsertOrderList(pI,  (UINT32)sdTrack, pMt->sdTicks);
	}
}


/****************************************************************************
 *	GetLeastTimeTrack(PMIDINFO pI)
 *
 *	Description:
 *		Get the track@LeasetTime
 *	Param:
 *		pI			... pointer to the setup storage
 *	Return:
 *		0 : NoError, < 0 : Error
 ****************************************************************************/
static SINT32	GetLeastTimeTrack(PMIDINFO pI)
{
	PORDERLIST	pTerget;

	pTerget = (pI->pTopOrderList)->pNext;
	if (pTerget == pI->pBottomOrderList) return (-1);

	return ((SINT32)pTerget->dTrack);
}


/****************************************************************************
 *	GetSMFInfo(PMIDINFO pI)
 *
 *	Description:
 *		Get SMF info from the file
 *	Param:
 *		pI					... pointer to the setup storage
 *	Return:
 *		0 : NoError, < 0 : Error
 ****************************************************************************/
static SINT32	GetSMFInfo(PMIDINFO pI)
{
	UINT32		dCmd;
	UINT32		dCmd2;
	UINT32		dSize;
	
	UINT32		dTemp;
	UINT32		dTime;
	SINT32		sdTotalTicks;
	SINT32		sdCurrentTime;
	SINT32		sdDelta;
	PMIDCHINFO 	pCh;
	UINT32		dCh;

	UINT32		dSetup;			/* bit0:beat@0, bit1:tempo@0, bit2:GmOn@0, bit3:tempo@1 */
	PTRACKINFO	pMt;
	SINT32		sdTr;

	static UINT32	dBank[16];
	static UINT32	dCurrBank[16];

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

⌨️ 快捷键说明

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