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

📄 mammfcnv.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 5 页
字号:


/*********************************************************************************
 *	Check_Initial
 *
 *	Description:
 *			SMAF data load (error check and regist)
 *	Argument:
 *			psLoad			pointer to load information structure
 *	Return:
 *			nothing
 ********************************************************************************/
static void				Check_Initial(
	PLOADINFO			psLoad
)
{
	UINT8				i;

/* Initialize Load information structure	*/
	psLoad->pbMmmd		= NULL;
	psLoad->dMmmdSize	= 0;
	psLoad->dCrc		= MMF_CRC_NULL;
	psLoad->dSmafType	= MMF_SMAF_TYPE_NULL;
	psLoad->dPlayTime	= 0;
	psLoad->dStartTime	= 0;
	psLoad->dTimeBase	= 0;
	psLoad->pfnGetByte	= NULL;

	psLoad->sOption_Info.pbCnti		= NULL;
	psLoad->sOption_Info.dCntiSize	= 0;
	psLoad->sOption_Info.pbOpda		= NULL;
	psLoad->sOption_Info.dOpdaSize	= 0;

	for( i = 0; i < MMF_MAX_TRACK_NUM; i++) {
		psLoad->sTrack_Info[i].pbMtr		= NULL;
		psLoad->sTrack_Info[i].dMtrSize		= 0;
		psLoad->sTrack_Info[i].pbMspi		= NULL;
		psLoad->sTrack_Info[i].dMspiSize	= 0;
		psLoad->sTrack_Info[i].pbMtsu		= NULL;
		psLoad->sTrack_Info[i].dMtsuSize	= 0;
		psLoad->sTrack_Info[i].pbMtsq		= NULL;
		psLoad->sTrack_Info[i].dMtsqSize	= 0;
		psLoad->sTrack_Info[i].pbMtsp		= NULL;
		psLoad->sTrack_Info[i].dMtspSize	= 0;
		psLoad->sTrack_Info[i].pbMthv		= NULL;
		psLoad->sTrack_Info[i].dMthvSize	= 0;
		psLoad->sTrack_Info[i].dPlayTime	= 0;
		psLoad->sTrack_Info[i].dTimeBase	= 0;
		psLoad->sTrack_Info[i].dStartPoint	= MMF_STSP_OFFSET_NULL;
		psLoad->sTrack_Info[i].dStopPoint	= MMF_STSP_OFFSET_NULL;
		psLoad->sTrack_Info[i].dStartTick	= MMF_STSP_TIME_NULL;
		psLoad->sTrack_Info[i].dStopTick	= MMF_STSP_TIME_NULL;
	}

	for( i = 0; i < MMF_MAX_PHRASE_INFO; i++) {
		psLoad->sPhrase_Info[i].dStartPoint	= MMF_STSP_OFFSET_NULL;
		psLoad->sPhrase_Info[i].dStopPoint	= MMF_STSP_OFFSET_NULL;
		psLoad->sPhrase_Info[i].dStartTick	= MMF_STSP_TIME_NULL;
		psLoad->sPhrase_Info[i].dStopTick	= MMF_STSP_TIME_NULL;
	}

	psLoad->sHV_Info.pbVoice		= NULL;
	psLoad->sHV_Info.dVoiceSize		= 0;
	psLoad->sHV_Info.pbScript		= NULL;
	psLoad->sHV_Info.dScriptSize	= 0;
	psLoad->sHV_Info.bHvChannel		= MMF_HV_CHANNEL_NULL;
}


/*********************************************************************************
 *	get_timebase
 *
 *	Description:
 *			get time base (data value -> msec/tick)
 *	Argument:
 *			bData			time base (data value)
 *	Return:
 *			>=0				success(time base (msec/tick))
 *			< 0				error code
 ********************************************************************************/
static SINT32			get_timebase(
	UINT8				bData
)
{
	switch( bData ) {
		case 0x02:	return  4;						/*  4[msec/tick]			*/
		case 0x03:	return  5;						/*  5[msec/tick]			*/
		case 0x10:	return 10;						/* 10[msec/tick]			*/
		case 0x11:	return 20;						/* 20[msec/tick]			*/
		case 0x12:	return 40;						/* 40[msec/tick]			*/
		case 0x13:	return 50;						/* 50[msec/tick]			*/
		default:	return MMF_FUNC_ERROR;			/* Time Base Error			*/
	}
}


/*********************************************************************************
 *	MTR_Check
 *
 *	Description:
 *			score track chunk check (header information and chunk construction)
 *	Argument:
 *			psTrack			pointer to track information structure
 *			bSmafType		SMAF type
 *	Return:
 *			0				success
 *			< 0				error code
 ********************************************************************************/
static SINT32			MTR_Check(
	PTRACKINFO			psTrack,
	UINT8				bSmafType
)
{
	SINT32				sdResult, sdChunkSize;
	UINT32				dSize, dIndex;
	UINT8*				pbBuf;
	UINT32				dChunkID, dChunkNo;

/* Check Format Type				*/
	switch (bSmafType) {
	case MMF_SMAF_TYPE_MA1 :
	case MMF_SMAF_TYPE_MA2 :
		if (psTrack->pbMtr[0] != 0x00) {
			return MMF_ERR_CHUNK;
		}
		break;
	case MMF_SMAF_TYPE_MA3 :
		if ((psTrack->pbMtr[0] != 0x01) && (psTrack->pbMtr[0] != 0x02)) {
			return MMF_ERR_CHUNK;
		}
		break;
	case MMF_SMAF_TYPE_MA5 :
		if (psTrack->pbMtr[0] != 0x02) {
			return MMF_ERR_CHUNK;
		}
		break;
	}

/* Check Sequence Type		*/
	if (psTrack->pbMtr[1] != 0x00) {
		return MMF_ERR_CHUNK;
	}

/* Check Time Base		*/
	if (psTrack->pbMtr[2] != psTrack->pbMtr[3]) {
		return MMF_ERR_CHUNK;
	}
	sdResult = get_timebase(psTrack->pbMtr[2]);
	if (sdResult == MMF_FUNC_ERROR) {
		return MMF_ERR_CHUNK;
	}
	psTrack->dTimeBase = (UINT32)sdResult;

/* Check sub chunk disposition	*/
	if ((bSmafType == MMF_SMAF_TYPE_MA1) || (bSmafType == MMF_SMAF_TYPE_MA2))
		dIndex = MMF_MINIMUM_TRACKSIZE2;
	else
		dIndex = MMF_MINIMUM_TRACKSIZE3;
	pbBuf = psTrack->pbMtr;
	dSize = psTrack->dMtrSize;
	while (dSize > (dIndex + MMF_CHUNK_HEADER_SIZE)) {
		sdChunkSize = malib_NextChunk(&pbBuf[dIndex], (dSize-dIndex),
			MALIB_CHUNK_PHASE_MTRSUB, &dChunkID, &dChunkNo);
		if (sdChunkSize < 0) {
			return MMF_ERR_CHUNK;
		}
		dIndex += MMF_CHUNK_HEADER_SIZE;
		switch (dChunkID) {
		case MALIB_CHUNKCODE_MSPI :
			psTrack->pbMspi		= &(pbBuf[dIndex]);
			psTrack->dMspiSize	= sdChunkSize;
			break;
		case MALIB_CHUNKCODE_MTSU :
			psTrack->pbMtsu		= &(pbBuf[dIndex]);
			psTrack->dMtsuSize	= sdChunkSize;
			break;
		case MALIB_CHUNKCODE_MTSQ :
			psTrack->pbMtsq		= &(pbBuf[dIndex]);
			psTrack->dMtsqSize	= sdChunkSize;
			break;
		case MALIB_CHUNKCODE_MTSP :
			psTrack->pbMtsp		= &(pbBuf[dIndex]);
			psTrack->dMtspSize	= sdChunkSize;
			break;
		case MALIB_CHUNKCODE_MTHV :
			psTrack->pbMthv		= &(pbBuf[dIndex]);
			psTrack->dMthvSize	= sdChunkSize;
			break;
		default :
			break;
		}
		dIndex += sdChunkSize;
	}

	if ((psTrack->pbMtsq == NULL) ||
		(psTrack->dMtsqSize == 0)) {
		return MMF_ERR_SLENGTH;
	}
	return MMF_FUNC_SUCCESS;
}


/*********************************************************************************
 *	ATR_Check
 *
 *	Description:
 *			audio track chunk check (header information and chunk construction)
 *	Argument:
 *			psTrack			pointer to track information structure
 *	Return:
 *			0				success
 *			< 0				error code
 ********************************************************************************/
static SINT32			ATR_Check(
	PTRACKINFO			psTrack
)
{
	SINT32				sdResult, sdChunkSize;
	UINT32				dSize, dIndex;
	UINT8*				pbBuf;
	UINT32				dChunkID, dChunkNo;
	UINT8				fbWave;

/* Check Format Type				*/
	if (psTrack->pbMtr[0] != 0x00) {
		return MMF_ERR_CHUNK;
	}

/* Check Sequence Type		*/
	if (psTrack->pbMtr[1] != 0x00) {
		return MMF_ERR_CHUNK;
	}

/* Check Wave Type			*/
	if (((psTrack->pbMtr[2] != 0x10) && (psTrack->pbMtr[2] != 0x11)) ||
		((psTrack->pbMtr[3] & 0xF0) != 0x00)) {
		return MMF_ERR_CHUNK;
	}

/* Check Time Base		*/
	if (psTrack->pbMtr[4] != psTrack->pbMtr[5]) {
		return MMF_ERR_CHUNK;
	}
	sdResult = get_timebase(psTrack->pbMtr[4]);
	if (sdResult == MMF_FUNC_ERROR) {
		return MMF_ERR_CHUNK;
	}
	psTrack->dTimeBase = (UINT32)sdResult;

	pbBuf	= psTrack->pbMtr;
	dSize	= psTrack->dMtrSize;
	dIndex	= 6;
	fbWave	= MMF_MA2_VOICE_NULL;

/* Check sub chunk disposition	*/
	while (dSize > (dIndex + MMF_CHUNK_HEADER_SIZE)) {
		sdChunkSize = malib_NextChunk(&pbBuf[dIndex], (dSize-dIndex),
			MALIB_CHUNK_PHASE_ATRSUB, &dChunkID, &dChunkNo);
		if (sdChunkSize < 0) {
			return MMF_ERR_CHUNK;
		}
		dIndex += MMF_CHUNK_HEADER_SIZE;
		switch (dChunkID) {
		case MALIB_CHUNKCODE_ASPI :
			psTrack->pbMspi		= &(pbBuf[dIndex]);
			psTrack->dMspiSize	= sdChunkSize;
			break;
		case MALIB_CHUNKCODE_ATSQ :
			psTrack->pbMtsq		= &(pbBuf[dIndex]);
			psTrack->dMtsqSize	= sdChunkSize;
			break;
		case MALIB_CHUNKCODE_AWA :
			if ((0x01 <= dChunkNo) && (dChunkNo <= 0x3E))
				fbWave = MMF_MA2_VOICE_FOUND;
			break;
		default :
			break;
		}
		dIndex += sdChunkSize;
	}

	if ((psTrack->pbMtsq == NULL) ||
		(psTrack->dMtsqSize == 0) ||
		(fbWave == MMF_MA2_VOICE_NULL)) {
		return MMF_ERR_SLENGTH;
	}
	return MMF_FUNC_SUCCESS;
}


/*********************************************************************************
 *	MspI_Check
 *
 *	Description:
 *			seek & phrase info chunk check (get phrase information)
 *	Argument:
 *			psTrack			pointer to track information structure
 *			psPhrase		pointer to phrase information structure
 *	Return:
 *			0				success
 *			< 0				error code
 ********************************************************************************/
static void				MspI_Check(
	PTRACKINFO			psTrack,
	PPHRASEINFO			psPhrase
)
{
	UINT8*				pbBuf;
	UINT32				dSize, dIndex;
	UINT16				wTag;

	if (psTrack->pbMspi == NULL)
		return;

	pbBuf	= psTrack->pbMspi;
	dSize	= psTrack->dMspiSize;
	dIndex	= 0;

	while (dSize >= dIndex + MMF_PHRAZE_SIZE_A) {
		wTag = (UINT16)((((UINT16)pbBuf[dIndex]) << 8) + (UINT16)pbBuf[dIndex+1]);
		switch (wTag) {
		case MMF_TAG_STARTPOINT :				/* start point					*/
			psTrack->dStartPoint	= get_4byte(&(pbBuf[dIndex + 3]));
			dIndex += MMF_PHRAZE_SIZE_A;
			break;
		case MMF_TAG_STOPPOINT :				/* stop point					*/
			psTrack->dStopPoint		= get_4byte(&(pbBuf[dIndex + 3]));
			dIndex += MMF_PHRAZE_SIZE_A;
			break;
		case MMF_TAG_PHRASE_A :					/* A melody						*/
			if (dSize < dIndex + MMF_PHRAZE_SIZE_B)
				return ;
			psPhrase[0].dStartPoint	= get_4byte(&(pbBuf[dIndex + 3]));
			psPhrase[0].dStopPoint	= get_4byte(&(pbBuf[dIndex + 7]));
			dIndex += MMF_PHRAZE_SIZE_B;
			break;
		case MMF_TAG_PHRASE_B :					/* B melody						*/
			if (dSize < dIndex + MMF_PHRAZE_SIZE_B)
				return ;
			psPhrase[1].dStartPoint	= get_4byte(&(pbBuf[dIndex + 3]));
			psPhrase[1].dStopPoint	= get_4byte(&(pbBuf[dIndex + 7]));
			dIndex += MMF_PHRAZE_SIZE_B;
			break;
		case MMF_TAG_PHRASE_E :					/* Ending						*/
			if (dSize < dIndex + MMF_PHRAZE_SIZE_B)
				return ;
			psPhrase[2].dStartPoint	= get_4byte(&(pbBuf[dIndex + 3]));
			psPhrase[2].dStopPoint	= get_4byte(&(pbBuf[dIndex + 7]));
			dIndex += MMF_PHRAZE_SIZE_B;
			break;
		case MMF_TAG_PHRASE_I :					/* Intro						*/
			if (dSize < dIndex + MMF_PHRAZE_SIZE_B)
				return ;
			psPhrase[3].dStartPoint	= get_4byte(&(pbBuf[dIndex + 3]));
			psPhrase[3].dStopPoint	= get_4byte(&(pbBuf[dIndex + 7]));
			dIndex += MMF_PHRAZE_SIZE_B;
			break;
		case MMF_TAG_PHRASE_K :					/* Interlude					*/
			if (dSize < dIndex + MMF_PHRAZE_SIZE_B)
				return ;
			psPhrase[4].dStartPoint	= get_4byte(&(pbBuf[dIndex + 3]));
			psPhrase[4].dStopPoint	= get_4byte(&(pbBuf[dIndex + 7]));
			dIndex += MMF_PHRAZE_SIZE_B;
			break;
		case MMF_TAG_PHRASE_R :					/* Refrain						*/
			if (dSize < dIndex + MMF_PHRAZE_SIZE_B)
				return ;
			psPhrase[5].dStartPoint	= get_4byte(&(pbBuf[dIndex + 3]));
			psPhrase[5].dStopPoint	= get_4byte(&(pbBuf[dIndex + 7]));
			dIndex += MMF_PHRAZE_SIZE_B;
			break;
		case MMF_TAG_PHRASE_S :					/* Bridge						*/
			if (dSize < dIndex + MMF_PHRAZE_SIZE_B)
				return ;
			psPhrase[6].dStartPoint	= get_4byte(&(pbBuf[dIndex + 3]));
			psPhrase[6].dStopPoint	= get_4byte(&(pbBuf[dIndex + 7]));
			dIndex += MMF_PHRAZE_SIZE_B;
			break;
		default :
			return;
		}
	}
	return;
}


/*********************************************************************************
 *	ST_SP_Check
 *
 *	Description:
 *			track chunk check (offset of start point and stop point)
 *	Argument:
 *			psTrack			pointer to track information structure
 *	Return:
 *			0				success
 *			< 0				error code
 ********************************************************************************/
static SINT32			ST_SP_Check(
	PTRACKINFO			psTrack
)
{
	UINT32				dStart, dStop, dSize;

	dSize	= psTrack->dMtsqSize;

	if (psTrack->dStartPoint == MMF_STSP_OFFSET_NULL)
		dStart	= 0;
	else
		dStart	= psTrack->dStartPoint;

	if (psTrack->dStopPoint == MMF_STSP_OFFSET_NULL)
		dStop	= dSize;
	else
		dStop	= psTrack->dStopPoint;

	if ((dStart >= dStop) || (dStart > dSize) || (dStop > dSize))
		return MMF_ERR_CHUNK;

	return MMF_FUNC_SUCCESS;
}


/*********************************************************************************
 *	Mtsu_Check2
 *
 *	Description:
 *			track chunk check (existence voice parameter)
 *	Argument:
 *			psTrack			pointer to track information structure
 *			bSmafType		SMAF type
 *	Return:
 *			0				success
 *			< 0				error code
 ********************************************************************************/
static SINT32			Mtsu_Check2(
	PTRACKINFO			psTrack,
	UINT8				bSmafType
)
{
	UINT8*				pbBuf;
	UINT32				dSize, dIndex;

	if (psTrack->pbMtsu == NULL) {
		return MMF_MA2_VOICE_NOTFOUND;
	}

	pbBuf	= psTrack->pbMtsu;
	dSize	= psTrack->dMtsuSize;
	dIndex	= 0;

	while (dSize > dIndex + 20) {
		if ((pbBuf[dIndex] != 0xFF) || (pbBuf[dIndex + 1] != 0xF0)) {
			return MMF_MA2_VOICE_NOTFOUND;
		}
		if (pbBuf[dIndex + 3] == 0x43) {

⌨️ 快捷键说明

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