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

📄 melody_env.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/**
 *	Author: 
 *		Robert.Chen
 *
 *	Module:
 *		Low level API wrapping Yamaha YMU765/762 chip sound middleware, interrupt driving
 *
 *  History:
 *		=== 2003/12/01   Robert.Chen ===	
 *		1)	Initiated.
 *
 *		=== 2004/05/08	 Robert.Chen ===
 *		1)	Adjusted volume setting sequence, replacing volume control after starting of
 *			playing a music (MI_PlayMusic_Start(), MI_PlayMusic_Resume()) to avoid pop noise
 *		2)  Removed EQ, HP and SP volume setting in MI_Melody_Initialize() to avoid pop noise
 *
 *		=== 2004/07/05	 Robert.Chen ===
 *		1) Add function to support play music data from FFS file, using static memory buffer
 *
 *		=== 2004/07/10	 Robert.Chen ===
 *		1) Add function to support play music data from FFS file, using dynamic memory buffer
 *		   (configuralbe in melody_cfg.h)	
 **/
 
#include "nucleus.h"
#include "typedefs.h"

#include <stdio.h>
#include <string.h>
#include <stdarg.h>

#include "rvf_api.h"
#include "chipset.cfg"
#include "armio.h"
#include "mamachdep.h"
#include "madefs.h"

#include "rvm_use_id_list.h"
#include "melody_cfg.h"
#include "melody_struct_i.h"
#include "melody_api.h"
#include "melody_env.h"

#include "masound.h"					/* MA Sound Player API */
#include "madebug.h"

#include "ffs.h"
#include "mmiutilapi.h"


T_MELODY_CTRL_BLK	melodyCtrlBlk;

#if (MELODY_FFS_SUPPORT == 1)
  #if (MELODY_DATA_STATIC == 1)
	static UINT8 music_data_buffer[MELODY_DATA_BUF_SZ];
  #else
	static UINT8 *music_data_buffer = NULL;		
  #endif

  	static UINT8 music_info_buffer[MELODY_INFO_BUF_SZ];
	static T_FFS_FD melodyFd = -1;
#endif

extern SINT32 MaDevDrv_PowerManagement(UINT8 mode);
extern UINT8 spkLev2val[MI_MELODY_VOLUME_MAX+1];
extern UINT8 gbMelLP;

extern char *musicList[];

#if (MELODY_FFS_SUPPORT == 1)
/******************************************************************************
 *
 * Function:
 *		MI_LoadMusicByName
 *
 * Description:
 *		Loading a music file in FFS to the internal music data buffer.
 *
 * Input:
 *		musicName	string
 *		type		music type, if type equal to 0xFF means type not specified		
 *
 * Output:
 *		MI_MELODY_OK
 *		MI_MELODY_PARA_ERR
 *		MI_MELODY_FILE_NOT_EXIST
 *		MI_MELODY_FILE_SIZE_ZERO
 *		MI_MELODY_FILE_SIZE_LARGE
 *		MI_MELODY_FILE_READ_ERR
 *		   
 *****************************************************************************/

T_MELODY_RET MI_LoadMusicByName(const char *musicName, UINT8 type)
{
	T_FFS_RET ret;
	struct stat_s stat;
	UINT32 *pType, sz;
	
	MELODYTRACE_MSG(("MI_LoadMusicByName():name=\"%s\"",musicName));
	
	/* acquire file info */
	ret = ffs_stat(musicName, &stat);
	if(ret == EFFS_NOTFOUND || stat.type != OT_FILE)
	{
		MELODYTRACE_MSG(("MI_LoadMusicByName():acquire file info err!"));
		return MI_MELODY_FILE_NOT_EXIST;
	}

	if(stat.size == 0)
	{
		MELODYTRACE_MSG(("MI_LoadMusicByName():file size zero!"));
		return MI_MELODY_FILE_SIZE_ZERO;
	}

#if (MELODY_DATA_STATIC == 1)
	if(stat.size > (MELODY_DATA_BUF_SZ - 8))
	{
		MELODYTRACE_MSG(("MI_LoadMusicByName():file size large!"));
		return MI_MELODY_FILE_SIZE_LARGE;
	}
	else
#endif	
	{
		MELODYTRACE_MSG(("MI_LoadMusicByName():flen=%d", stat.size));
	}

	/* loading first 12 bytes file data to internal buffer */
	melodyFd = ffs_open(musicName, FFS_O_RDONLY);
	if(melodyFd < 0)
	{
		MELODYTRACE_MSG(("MI_LoadMusicByName():open file err,fd=%d", melodyFd));		
		return MI_MELODY_FILE_READ_ERR;
	}
	else
	{
		MELODYTRACE_MSG(("MI_LoadMusicByName():open file ok,fd=%d", melodyFd));		
	}	
	
	sz = ffs_read(melodyFd, (void*)&music_info_buffer[8], (MELODY_INFO_BUF_SZ - 8));
	if(sz != (MELODY_INFO_BUF_SZ - 8))
	{
		MELODYTRACE_MSG(("MI_LoadMusicByName():read file err,ret=%d", sz));		
		return MI_MELODY_FILE_READ_ERR;
	}
	
	if(type == 0xFF)	/* type not specified, we must detect music type */
	{
		ret = MI_DetectMusicType((const char*)&music_info_buffer[8], &type);
		if(ret != MI_MELODY_OK)
		{
			MELODYTRACE_MSG(("MI_LoadMusicByName():music type unknow,ret=%d", ret));	
			return MI_MELODY_FILE_TYPE_UNKNOW;		
		}	
	}
	
	pType 		= (UINT32*)music_info_buffer;
	*pType++	= type;
	*pType		= stat.size;
	return MI_MELODY_OK;
}

/******************************************************************************
 *
 * Function:
 *		MI_DetectMusicType
 *
 * Description:
 *		Detect the type of a music file pointer to by pData.
 *		At present, three types supported: WAV, MMF, MID
 *
 * Input:
 *		pData	pointer to music data buffer
 *		type	music type, available if return value is MI_MELODY_OK
 *
 * Output:
 *		MI_MELODY_OK
 *		MI_MELODY_PARA_ERR
 *		MI_MELODY_ERROR
 *		   
 *****************************************************************************/
T_MELODY_RET MI_DetectMusicType(const char *pData, UINT8 *type)
{	
	MELODYTRACE_MSG(("MI_DetectMusicType()"));
	
	if(pData == NULL || type == NULL)
	{
		MELODYTRACE_MSG(("MI_DetectMusicType():arg err!"));
		return MI_MELODY_PARA_ERR;
	}

	if(!memcmp(pData, "MMMD", 4))
		*type = MASMW_CNVID_MMF;
	else if(!memcmp(pData, "MThd", 4))
		*type = MASMW_CNVID_MID;
	else if(!memcmp(pData, "RIFF", 4))
		*type = MASMW_CNVID_WAV;
	else
	{
		MELODYTRACE_MSG(("MI_DetectMusicType():failed!,0x%x, 0x%x, 0x%x, 0x%x", *pData++, *pData++, *pData++, *pData++));
		return MI_MELODY_ERROR;
	}	

	return MI_MELODY_OK;	
}

/*** 
 * Close previously opened FFS file
 */
void MI_CloseMusicFile(void)
{
	MELODYTRACE_MSG(("MI_CloseMusicFile():fdi=%d", melodyFd));
	if(melodyFd >= 0)
	{
		ffs_close(melodyFd);
		melodyFd = -1;
	}
}

#endif //MELODY_FFS_SUPPORT
/******************************************************************************
 *
 * Function:
 *		MI_GetMusicInfoByID()
 *
 * Description:
 *		Get information about a music specific by its ID from music database, 
 *		the info returned such as music data start pointer, data lenght, music
 *      format.
 *
 * Input:
 *		musicID  within musicInfo struct
 *			
 * Output:
 *		musicInfo.
 *
 * History:
 *		2004/07/05	Robert.Chen add support to play music saved as FFS file.
 *		   
 *****************************************************************************/
T_MELODY_RET MI_GetMusicInfoByID(T_MUSIC_INFO * const musicInfo)
{
	T_MUSIC_INFO *pInf = musicInfo;		
	UINT32 *pTypeLen;
	
	MELODYTRACE_MSG(("MelFunc:MI_GetMusicInfoByID(),ID=%d.", musicInfo->mID));

#if (MELODY_FFS_SUPPORT == 1)	/* robert.chen, 2004-07-05 */
	if(pInf == NULL || (pInf->mID >= MI_MELODY_MUSICNUM_TOTAL && pInf->mID != MI_MELODY_MUSICID_FILE))
#else
	if(pInf == NULL || pInf->mID >= MI_MELODY_MUSICNUM_TOTAL)
#endif	
	{
		
		MELODYTRACE_MSG(("MelRet:error para: %d", pInf->mID));
		return MI_MELODY_PARA_ERR;
	}

#if (MELODY_FFS_SUPPORT == 1)	/* robert.chen, 2004-07-05 */
	if(pInf->mID == MI_MELODY_MUSICID_FILE)
		pTypeLen	= (UINT32*)music_info_buffer;
	else
		pTypeLen 	= (UINT32*)musicList[pInf->mID];	
#else
	pTypeLen 	= (UINT32*)musicList[pInf->mID];
#endif
	pInf->mType	= (UINT8)*pTypeLen++;
	pInf->mLen	= *pTypeLen++;
	pInf->mPtr	= (UINT8*)pTypeLen;
	return MI_MELODY_OK;	
}

/******************************************************************************
 *
 * Function:
 *		MI_Melody_RstCtrlBlk()
 *
 * Description:
 *		Reset music player control block data
 *
 * Input:
 *		none.
 *			
 * Output:
 *		none.
 *		   
 *****************************************************************************/
void MI_Melody_RstCtrlBlk(void)
{
#if (MELODY_FFS_SUPPORT == 1 && MELODY_DATA_STATIC == 0)
	int result;
#endif

	MELODYTRACE_MSG(("MelFunc:MI_Melody_RstCtrlBlk()"));
	melodyCtrlBlk.remainCnt = 0;
	melodyCtrlBlk.fileType  = 0;
	melodyCtrlBlk.curPos	= 0;
	melodyCtrlBlk.fileID	= -1;
	melodyCtrlBlk.musicID	= MI_MELODY_MUSICID_INVALID;

#if	(MELODY_FFS_SUPPORT == 1)
  #if (MELODY_DATA_STATIC == 0)
	if(music_data_buffer != NULL)
	{
		MI_FREE(music_data_buffer, result);
		music_data_buffer = NULL;
		
		if(result != EC_MMIMEM_OK)
		{
			MELODYTRACE_MSG(("MI_Melody_RstCtrlBlk():release mem err, ret=%d",result));		
		}
	}	
  #endif //MELODY_DATA_STATIC	
#endif  
	

  #ifdef MELODY_POWERSAVE
	NU_Control_Timer(&melodyCtrlBlk.pwrSaveTmr, NU_ENABLE_TIMER);
  #endif
}

/******************************************************************************
 *
 * Function:
 *		MI_Melody_CB()
 *
 * Description:
 *		Callback function invoked by MA sound middleware when event occurs, user
 *      concered process for these events can be executed here.
 *
 * Input:
 *		id    event ID.
 *			
 * Output:
 *		MASMW_SUCCESS.
 *		   
 *****************************************************************************/

signed long MI_Melody_CB(unsigned char id)
{
	SINT32 func_id;
	SINT32 file_id;	
	
	switch (id)
	{
	case MASMW_REPEAT:
		/* Repeat */
		/* remainCnt equal 0 means a loop play mode */
		if(melodyCtrlBlk.remainCnt != 0)
			melodyCtrlBlk.remainCnt--;
			
		MELODYTRACE_MSG(("MelCB:repeat once, remaincnt=%d", melodyCtrlBlk.remainCnt));
		break;

	case MASMW_END_OF_SEQUENCE:
		/* End of sequence */
		MELODYTRACE_MSG(("MelCB:play end!"));
		
		func_id = melodyCtrlBlk.funcID[melodyCtrlBlk.fileType];
		file_id = melodyCtrlBlk.fileID;
		
		MI_Melody_PostStop(func_id, file_id, MI_PostOnly);
		
		#if 0	/* Robert.Chen removed, 2004-04-08 */
		if(melodyCtrlBlk.vbrSta.ctrlSrc == MI_VBR_SRC_FORCED && melodyCtrlBlk.vbrSta.frcCtrl == MI_VBR_FORCED_OFF)
		{
			MI_Melody_HpAmpCtrl(0);
			gbMelLP = 1;	/* fix vibrator bug when deep sleep, 2004-04-08*/
		}
		#else
		MI_Melody_HpAmpCtrl(0, MI_PWRCTRL_MUSIC);
		#endif

		//gbMelLP = 1;	/* fix vibrator bug when deep sleep, 2004-04-08*/
		/* reset control block */
		MI_Melody_RstCtrlBlk();		
		break;

	default:
		/* User event */
		break;
	}

	return MASMW_SUCCESS;
}

/******************************************************************************
 *
 * Function:
 *		MI_Melody_ErrHdr()
 *
 * Description:
 *		Error recovery function to deal error occurs in each state, such as load
 *      state, open state, playing state.
 *
 * Input:
 *		funcID	function id
 *      fileID	file id 
 *			
 * Output:
 *		none.
 *		   
 *****************************************************************************/

void MI_Melody_ErrHdr(SINT32 funcID, SINT32	fileID)
{
	SINT32 state;
	
	state = MaSound_Control(funcID, fileID, MASMW_GET_STATE, NULL, NULL);

	MELODYTRACE_MSG(("MelErrHdr:err at state %d", state));
	
	switch (state)
	{
	case MASMW_STATE_PLAYING:
	case MASMW_STATE_PAUSE:
		MaSound_Stop(funcID, fileID, NULL);
		/* cotinue to below, don't break switch */

	case MASMW_STATE_READY:
	case MASMW_STATE_OPENED:
		MaSound_Close(funcID, fileID, NULL);
		/* cotinue to below, don't break switch */

	case MASMW_STATE_LOADED:
		MaSound_Unload(funcID, fileID, NULL);
		/* cotinue to below, don't break switch */
		

	case MASMW_STATE_IDLE:
		MaSound_Delete(funcID);
		/* cotinue to below, don't break switch */

⌨️ 快捷键说明

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