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

📄 mawavcnv.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
 *
 *		Copyright (C) 2002-2003	YAMAHA CORPORATION. All rights reserved.
 *
 *		Module		: mawavcnv.c
 *
 *		Description	: WAV Stream Converter Module.
 *
 *		Version		: 1.1.0.1		2003.04.09
 *
 *		History		:
 *			2002/09/09 1st try.
 *			2003/03/10 MA-5 Compatible version.
 ****************************************************************************/
#include "mawavcnv.h"

/*--------------------------------------------------------------------------*/
/*   Defines                                                                */
/*--------------------------------------------------------------------------*/
#define	WAVE_TIMEBASE			(20)			/* [ms]                    */
#define	MAWAVCNV_FORMAT_PCM		(1)
#define	MAWAVCNV_MAX_LOAD		(2)
#define	MAWAVCNV_MIN_LENGTH		(20)			/* [ms]                    */
#define	MAWAVCNV_MAX_LENGTH		(0x7FFFFFFF)	/* [ms]                    */
#define	MAWAVCNV_MAX_SIZE		(0x003FFFFF)	/* [byte]                  */
#define	MAWAVCNV_MIN_RATE		(4000)			/* [Hz]                    */
#define	MAWAVCNV_MAX_RATE		(24000)			/* [Hz]                    */
#define	MakeWord(a, b)			(UINT16)(((UINT16)a << 8) | (UINT16)b)
#define	MakeDword(a, b, c, d)	(UINT32)(((UINT32)a << 24) | ((UINT32)b << 16) | ((UINT32)c << 8) | (UINT32)d)

/*--------------------------------------------------------------------------*/
/*   Types                                                                  */
/*--------------------------------------------------------------------------*/
typedef struct _MAWAVCNV_INFO
{
	UINT8		bLoaded;						/*	Load Flag			*/
	UINT32		dFormatType;					/*						*/
	UINT32		dChannel;						/*	Number of Channels	*/
	UINT32		dFs;							/*	Fs[Hz]				*/
	UINT32		dSamplesPerSec;					/*	Samples per second	*/
	UINT32		dBlock;							/*	BytesPerSample		*/
	UINT32		dBit;							/*	Bit width			*/
	UINT8*		pbData;							/*	Top of PCM data		*/
	UINT32		dSize;							/*	Size of PCM [byte]	*/
	UINT32		dLength;						/*	Size of PCM [ms]	*/
} MAWAVCNV_INFO, *PMAWAVCNV_INFO;


typedef	struct _tagWavGlobals
{
	SINT32			sdSeqID;					/*	Sequence ID			*/
	UINT32			dMasterVol;					/*	master volume		*/
	UINT8			bPanpot;					/*	panpot				*/
	UINT32			dLoops;						/*	Loop number			*/
	UINT32			dRepeat;					/*	Number of repeat	*/
	SINT32			sdSeekTime;					/*	[ms]				*/
	SINT32			sdCurrentTime;				/*	[ms]				*/
	MAWAVCNV_INFO	DataInfo[MAWAVCNV_MAX_LOAD];
} WAVGLOBAL, *PWAVGLOBAL;


/*---------------------------------------------------------------------------*/
/*   Globals                                                                 */
/*---------------------------------------------------------------------------*/
static WAVGLOBAL	gWavInfo;
static PWAVGLOBAL	gpWavInfo;

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

/*********************************************************************************
 *	Function Name	:	UINT32	GetBytePos(SINT32 sdFileID, UINT32 dTime)
 *
 *	Description		:	Get byte offset from time.
 *
 *	Argument		:	sdFileID	...	File ID.
 *						dTime		...	[ms]
 *
 *	Return			: Number of Bytes.
 *********************************************************************************/
static UINT32	GetBytePos(SINT32 sdFileID, UINT32 dTime)
{
	UINT32	dBytePosH;
	UINT32	dBytePosL;
	UINT32	dPos;
	UINT32	dPosH;
	UINT32	dPosL;
	
	/* dPos = dTime * 
	          gpWavInfo->DataInfo[sdFileID].dFs / 1000 * 
	          gpWavInfo->DataInfo[sdFileID].dBlock *
	          (gpWavInfo->DataInfo[sdFileID].dBit >> 3)
	*/
	dBytePosH = (dTime >> 16) * gpWavInfo->DataInfo[sdFileID].dFs;
	dBytePosL = (dTime & 0xFFFFL) * gpWavInfo->DataInfo[sdFileID].dFs;
	
	dPosL = dBytePosL & 0xFFFFL;
	dPosH = dBytePosH + (dBytePosL >> 16);
	
	dPos = dPosH / 1000;
	dPosH -= dPos * 1000;
	dPosL += dPosH << 16;
	dPos <<= 16;
	dPos += dPosL / 1000;
	dPos *= gpWavInfo->DataInfo[sdFileID].dBlock;

	if (dPos >= gpWavInfo->DataInfo[sdFileID].dSize) dPos = gpWavInfo->DataInfo[sdFileID].dSize - 1;

	return (dPos);
}

/*******************************************************************************
 *	Function Name	:	SINT32	WAVEChecker(SINT32 sdFileID, UINT8* pbWave, UINT32 dSize, UINT8 bMode)
 *
 *	Description		:	Check Wave format
 *							8bit Mono PCM
 *							8bit Stereo PCM
 *							16bit Mono PCM
 *
 *	Argument		:	sdFileID	...	File ID.
 *						pbWave	...	pointer to WAVE file.
 *						dSize	...	size fo WAVE file.
 *						bMode	...	check mode.
 *
 *	Return			: 0 : NoError, < 0 : Error
 *********************************************************************************/
static SINT32	WAVEChecker(SINT32 sdFileID, UINT8* pbWave, UINT32 dSize, UINT32 dMode)
{
	UINT8*	pbFmt;			/*	pointer to "fmt " chunk		*/
	UINT32	dTemp;

	UINT32	dId;
	UINT32	dRemain;
	UINT32	dRiffChunkSize;

	UINT8	bFlag = 0x00;	/*	bit0 : Found "fmt " chunk	*/
							/*	bit1 : Found "data" chunk	*/

	(void)dMode;
	
	/*	Check argument	*/
	if(pbWave == NULL)					return (MASMW_ERROR_ARGUMENT);
	if(dSize < 12L)						return (MASMW_ERROR_FILE);
	if(sdFileID > MAWAVCNV_MAX_LOAD)	return (MASMW_ERROR_ID);

	/*	Check "RIFF" and "WAVE" header ID	*/
	if(	(pbWave[0] != 'R')	||
		(pbWave[1] != 'I')	||
		(pbWave[2] != 'F')	||
		(pbWave[3] != 'F')	||
		(pbWave[8] != 'W')	||
		(pbWave[9] != 'A')	||
		(pbWave[10] != 'V')	||
		(pbWave[11] != 'E'))
	{
		MAWAVCNV_DBGMSG(("MaWavCnv : Error - Invalid header! \n"));
		return (MASMW_ERROR_FILE);
	}

	/*	Get "RIFF" chunk size	*/
	dRiffChunkSize = MakeDword(pbWave[7], pbWave[6], pbWave[5], pbWave[4]);

	/*	Check chunk size	*/
	if((dRiffChunkSize < 12L) || (dSize < (dRiffChunkSize + 8L))) {
		MAWAVCNV_DBGMSG(("MaWavCnv : Error - Invalid chunk size! \n"));
		return (MASMW_ERROR_CHUNK_SIZE);
	}

	/*	Search "fmt " and "data" header ID	*/
	pbWave = (pbWave + 12L);						/*	skip "RIFF" and "WAVE" header	*/
	dRemain = (SINT32)(dRiffChunkSize - 4L);
	while(dRemain > 8L) {
		dId		= MakeDword(pbWave[0], pbWave[1], pbWave[2], pbWave[3]);
		dSize	= MakeDword(pbWave[7], pbWave[6], pbWave[5], pbWave[4]);

		pbWave += 8L;
		dRemain -= 8L;

		/*	Invalid chunk size	*/
		if(dRemain < dSize) {
			MAWAVCNV_DBGMSG(("MaWavCnv : Error - Invalid chunk size! \n"));
			return (MASMW_ERROR_CHUNK_SIZE);
		}

		/*	Found format chunk	*/
		if((dId == MakeDword('f', 'm', 't', ' ')) && !(bFlag & 0x01)) {
			pbFmt = pbWave;

			/*	Check chunk size	*/
			if(dSize < 16L) {
				MAWAVCNV_DBGMSG(("MaWavCnv : Error - Invalid fmt chunk size(%d). \n", dSize));
				return (MASMW_ERROR_CHUNK_SIZE);
			}
			gpWavInfo->DataInfo[sdFileID].dFormatType		= (UINT32)MakeWord(pbFmt[1], pbFmt[0]);
			gpWavInfo->DataInfo[sdFileID].dChannel			= (UINT32)MakeWord(pbFmt[3], pbFmt[2]);
			gpWavInfo->DataInfo[sdFileID].dFs				= MakeDword(pbFmt[7], pbFmt[6], pbFmt[5], pbFmt[4]);
			gpWavInfo->DataInfo[sdFileID].dSamplesPerSec	= MakeDword(pbFmt[11], pbFmt[10], pbFmt[9], pbFmt[8]);
			gpWavInfo->DataInfo[sdFileID].dBlock			= (UINT32)MakeWord(pbFmt[13], pbFmt[12]);
			gpWavInfo->DataInfo[sdFileID].dBit				= (UINT32)MakeWord(pbFmt[15], pbFmt[14]);


			/*	Check format type	*/
			if(gpWavInfo->DataInfo[sdFileID].dFormatType != MAWAVCNV_FORMAT_PCM)
			{
				MAWAVCNV_DBGMSG(("MaWavCnv : Error - Invalid format(%ld). \n", gpWavInfo->DataInfo[sdFileID].dFormatType));
				return (MASMW_ERROR);
			}

			/*	Check number of channel & bit width	*/
			if (!((gpWavInfo->DataInfo[sdFileID].dChannel == 1) && (gpWavInfo->DataInfo[sdFileID].dBit == 8)))
			{
				MAWAVCNV_DBGMSG(("MaWavCnv : Error - Invalid Channel/BitWidth(%ld, %ld). \n", gpWavInfo->DataInfo[sdFileID].dChannel, gpWavInfo->DataInfo[sdFileID].dBit));
				return (MASMW_ERROR);
			}

			/*	Check sampling rate	*/
			dTemp = gpWavInfo->DataInfo[sdFileID].dFs * gpWavInfo->DataInfo[sdFileID].dBlock;
			if ((dTemp < MAWAVCNV_MIN_RATE) || (MAWAVCNV_MAX_RATE < dTemp))
			{
				MAWAVCNV_DBGMSG(("MaWavCnv : Error - Invalid Frequency(%d). \n", gpWavInfo->DataInfo[sdFileID].dFs));
				return (MASMW_ERROR);
			}
			
			/* Check Matching of block */
			if (gpWavInfo->DataInfo[sdFileID].dBlock != (gpWavInfo->DataInfo[sdFileID].dChannel * (gpWavInfo->DataInfo[sdFileID].dBit >> 3)))
			{
				MAWAVCNV_DBGMSG(("MaWavCnv : Error - Invalid block! \n"));
				/* Correct Invalid block */
				gpWavInfo->DataInfo[sdFileID].dBlock = (gpWavInfo->DataInfo[sdFileID].dChannel) * (gpWavInfo->DataInfo[sdFileID].dBit >> 3);
				/* 
				return (MASMW_ERROR_FILE);
				*/
			}
			
			bFlag |= 0x01;
		}
		else if ((dId == MakeDword('d', 'a', 't', 'a')) && !(bFlag & 0x02)) {
			/*	Found data chunk	*/
			gpWavInfo->DataInfo[sdFileID].pbData	= pbWave;
			gpWavInfo->DataInfo[sdFileID].dSize	= dSize;
			bFlag |= 0x02;
		}

		/*	skip chunk	*/
		pbWave += dSize;
		dRemain -= dSize;
		
		/*	Riff chunk size must be an even number	*/
		if ((dSize & 0x00000001) == 1)
		{
			if (dRemain > 0)
			{
				if (*pbWave == 0)
				{
					/*	skip padding	*/
					pbWave += 1;
					dRemain -= 1;
				}
			}
		}
	}

	if ((bFlag & 0x03) != 0x03) {
		/*	Not found "fmt " or "data" chunk.	*/
		gpWavInfo->DataInfo[sdFileID].pbData	= NULL;
		gpWavInfo->DataInfo[sdFileID].dSize	= 0L;
		return (MASMW_ERROR_FILE);
	}

	if (gpWavInfo->DataInfo[sdFileID].dSize > MAWAVCNV_MAX_SIZE) return (MASMW_ERROR_LONG_LENGTH);
	dTemp = gpWavInfo->DataInfo[sdFileID].dFs * gpWavInfo->DataInfo[sdFileID].dBlock;
	gpWavInfo->DataInfo[sdFileID].dLength = ((gpWavInfo->DataInfo[sdFileID].dSize * 1000L + (dTemp - 1)) / dTemp);
	if (gpWavInfo->DataInfo[sdFileID].dLength <= MAWAVCNV_MIN_LENGTH) return (MASMW_ERROR_SHORT_LENGTH);
	if (gpWavInfo->DataInfo[sdFileID].dLength > MAWAVCNV_MAX_LENGTH) return (MASMW_ERROR_LONG_LENGTH);

	MAWAVCNV_DBGMSG(("MaWavCnv : No Error!! \n"));
	MAWAVCNV_DBGMSG(("MaWavCnv : Bit:%d Ch:%d Fs:%d \n", gpWavInfo->DataInfo[sdFileID].dBit,
						gpWavInfo->DataInfo[sdFileID].dChannel,	gpWavInfo->DataInfo[sdFileID].dFs));

	return (0);
}


/*********************************************************************************
 *	Function Name	:	SINT32	MaWavCnv_SetVolume(SINT32 sdFileID, UINT8 bVol)
 *
 *	Description		:	Set Master volume
 *
 *	Argument		:	sdFileID			: File ID
 *						bVol			: Volume
 *
 *	Return			: 0 : NoError, < 0 : Error
 *********************************************************************************/
static SINT32	MaWavCnv_SetVolume(SINT32 sdFileID, UINT8 bVol)
{
	(void)sdFileID;

	MAWAVCNV_DBGMSG(("MaWavCnv_SetVolume[%08lX, %d] \n", sdFileID, bVol));

	gpWavInfo->dMasterVol = bVol & 0x7F;
	MaSndDrv_SetVolume(gpWavInfo->sdSeqID, (UINT8)gpWavInfo->dMasterVol);

	return (MASMW_SUCCESS);
}


/*********************************************************************************
 *	Function Name	:	SINT32	MaWavCnv_SetPanpot(SINT32 sdFileID, UINT8 bPan)
 *
 *	Description		:	Set Master panpot
 *
 *	Argument		:	sdFileID			: File ID
 *						bPan			: Panpot
 *
 *	Return			: 0 : NoError, < 0 : Error
 *********************************************************************************/
static SINT32	MaWavCnv_SetPanpot(SINT32 sdFileID, UINT8 bPan)
{
	(void)sdFileID;

	MAWAVCNV_DBGMSG(("MaWavCnv_SetPanpot[%08lX, %d] \n", sdFileID, bPan));

	gpWavInfo->bPanpot = (UINT8)(bPan & 0x7F);

	return (MASMW_SUCCESS);
}


/*********************************************************************************
 *	GetContentsData( SINT32 sdFile_id, PMASMW_CONTENTSINFO pvPtr )
 *
 *	Description:
 *			Get loaded contents information
 *	Argument: 
 *			sdFile_id		file id
 *			PMASMW_CONTENTSINFO pvPtr	pointer to struct MASMW_CONTENTSINFO
 *	Return:
 *			>= 0		contents binary data
 *
 ********************************************************************************/
static SINT32 GetContentsData(SINT32 sdFileID, PMASMW_CONTENTSINFO pvPtr)
{
	MAWAVCNV_DBGMSG(("MaWavCnv/ GetContentsData \n"));

	if ( pvPtr->size < 4 ) return MASMW_ERROR_ARGUMENT;

	if ( pvPtr->tag[0] =='W' )
	{
		*(pvPtr->buf ) = 0;
		*(pvPtr->buf + 1 ) = 0;
		*(pvPtr->buf + 2 ) = 0;
		*(pvPtr->buf + 3 ) = 0;

		switch  ( pvPtr->tag[1] ){
		case '0':		/* Get foramt type */
			*(pvPtr->buf) = (UINT8)((gpWavInfo->DataInfo[sdFileID].dFormatType) & 0xFF);
			*(pvPtr->buf + 1) =(UINT8)((gpWavInfo->DataInfo[sdFileID].dFormatType >> 8) & 0xFF);
			*(pvPtr->buf + 2) = 0;
			*(pvPtr->buf + 3) = 0;
			break;
		case '1':		/* Get channel numbers */
			*(pvPtr->buf) = (UINT8)((gpWavInfo->DataInfo[sdFileID].dChannel) & 0xFF);
			*(pvPtr->buf + 1) = 0;
			*(pvPtr->buf + 2) = 0;
			*(pvPtr->buf + 3) = 0;
			break;
		case '2':		/* Get sample rate */
			*(pvPtr->buf) = (UINT8)((gpWavInfo->DataInfo[sdFileID].dFs) & 0xFF);
			*(pvPtr->buf + 1) = (UINT8)((gpWavInfo->DataInfo[sdFileID].dFs >> 8) & 0xFF);
			*(pvPtr->buf + 2) = (UINT8)((gpWavInfo->DataInfo[sdFileID].dFs >> 16) & 0xFF);
			*(pvPtr->buf + 3) = (UINT8)((gpWavInfo->DataInfo[sdFileID].dFs >> 24) & 0xFF);
			break;
		case '3':		/* Get average transmit rate */
			*(pvPtr->buf) = (UINT8)((gpWavInfo->DataInfo[sdFileID].dSamplesPerSec) & 0xFF);
			*(pvPtr->buf + 1) = (UINT8)((gpWavInfo->DataInfo[sdFileID].dSamplesPerSec >> 8) & 0xFF);
			*(pvPtr->buf + 2) = (UINT8)((gpWavInfo->DataInfo[sdFileID].dSamplesPerSec >> 16) & 0xFF);
			*(pvPtr->buf + 3) = (UINT8)((gpWavInfo->DataInfo[sdFileID].dSamplesPerSec >> 24) & 0xFF);
			break;
		case '4':		/* Get data block size */
			*(pvPtr->buf) = (UINT8)((gpWavInfo->DataInfo[sdFileID].dBlock) & 0xFF);
			*(pvPtr->buf + 1) = (UINT8)((gpWavInfo->DataInfo[sdFileID].dBlock >> 8) & 0xFF);
			*(pvPtr->buf + 2) = 0;
			*(pvPtr->buf + 3) = 0;
			break;
		case '5':		/* Get bits par sample */
			*(pvPtr->buf) = (UINT8)((gpWavInfo->DataInfo[sdFileID].dBit) & 0xFF);
			*(pvPtr->buf + 1) = 0;
			*(pvPtr->buf + 2) = 0;
			*(pvPtr->buf + 3) = 0;
			break;
		case '6':		/* Get wave data size */
			*(pvPtr->buf) = (UINT8)((gpWavInfo->DataInfo[sdFileID].dSize) & 0xFF);
			*(pvPtr->buf + 1) = (UINT8)((gpWavInfo->DataInfo[sdFileID].dSize >> 8) & 0xFF);
			*(pvPtr->buf + 2) = (UINT8)((gpWavInfo->DataInfo[sdFileID].dSize >> 16) & 0xFF);
			*(pvPtr->buf + 3) = (UINT8)((gpWavInfo->DataInfo[sdFileID].dSize >> 24) & 0xFF);
			break;

		default:
			return MASMW_ERROR_ARGUMENT;
		}
		return 4;
	}
	return MASMW_ERROR;
}

/*---------------------------------------------------------------------------*/
/*   Functions                                                               */
/*---------------------------------------------------------------------------*/

/*********************************************************************************
 *	Function Name	:	SINT32	MaWavCnv_Initialize(void)
 *
 *	Description		:	Initialize()
 *
 *	Argument		:	none
 *
 *	Return			: 0 : NoError, < 0 : Error
 *********************************************************************************/
SINT32	MaWavCnv_Initialize(void)
{
	int				nIdx;
	PMAWAVCNV_INFO	pWi;

	MAWAVCNV_DBGMSG(("MaWavCnv_Initialize \n"));

⌨️ 快捷键说明

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