melody_env.c

来自「是一个手机功能的模拟程序」· C语言 代码 · 共 1,294 行 · 第 1/3 页

C
1,294
字号
	default:
		MI_Melody_RstCtrlBlk();
		break;
	}
}

#ifdef MELODY_POWERSAVE
/* power saving timer handler */
void MI_pwrSaveTmrProcess(UINT32 tmrID)
{
	SINT32 result;
	
	MELODYTRACE_MSG(("MelSta:pwr timeout!"));

	result = MaDevDrv_PowerManagement(1); /* power down */

	if(result != MASMW_SUCCESS)
	{
		MELODYTRACE_MSG(("MelRet:enter pwrdown failed,result=%d!", result));
	}
	else
	{
		MELODYTRACE_MSG(("MelSta:pwrdown entered!"));
		melodyCtrlBlk.pwrState = MI_pwrDown;
	}	
}


/******************************************************************************
 *
 * Function:
 *		MI_Melody_PwrRelase()
 *
 * Description:
 *		Release melody device from power down state
 *
 * Input:
 *		none.
 *			
 * Output:
 *		MI_MELODY_OK
 *      MI_MELODY_ERROR
 *		   
 *****************************************************************************/
T_MELODY_RET MI_Melody_PwrRelease(void)
{
	SINT32 result;

	MELODYTRACE_MSG(("MelFunc:MI_Melody_PwrRelease()"));
	
	/* check power state first */
  	if(melodyCtrlBlk.pwrState == MI_pwrRelease)  	
  	{
  		/* device in power release mode, power saving timer is enabled */
  		/* stop the timer */
  		NU_Control_Timer(&melodyCtrlBlk.pwrSaveTmr, NU_DISABLE_TIMER);
  		/* reset the timer expiretion duration for next run */
  		NU_Reset_Timer(&melodyCtrlBlk.pwrSaveTmr, 
  		              MI_pwrSaveTmrProcess,
  		              RVF_SECS_TO_TICKS(MI_POWERSAVE_SECS),
  		              0,
  		              NU_DISABLE_TIMER);  		
  	}
  	else
  	{
  		/* device in power down mode, must release this state before play music */
		MELODYTRACE_MSG(("MelSta:pwr down, release need."));
  		result = MaDevDrv_PowerManagement(2);	/* mode 2 release the device from power down mode */
		if(result != MASMW_SUCCESS)
		{
			MELODYTRACE_MSG(("MelRet:pwr release error,result=%d!", result));
			return MI_MELODY_ERROR;
		}
		else
		{
			MELODYTRACE_MSG(("MelRet:pwr released!"));
		}
  		melodyCtrlBlk.pwrState = MI_pwrRelease;
  	}

	/*
	 * check the power state to ensure that device in power release mode, avoid a timerout
	 * event occurs during the from the first time power state check to NU_Control_Timer()
	 * succuss, the timer handler, a HISR runs in HISR priority 2, can interrupt this function
	 * and set the device to power down, if we ignore that, a wrong power state will be assigned
	 * to the melody device
	 */
  	if(melodyCtrlBlk.pwrState == MI_pwrDown)
  	{
  		MELODYTRACE_MSG(("MelSta:pwr down by interrupt, release need."));
  		result = MaDevDrv_PowerManagement(2);	/* mode 2 release the device from power down mode */
		if(result != MASMW_SUCCESS)
		{
			MELODYTRACE_MSG(("MelRet:pwr release error,result=%d!", result));
			return MI_MELODY_ERROR;
		}
		else
		{
			MELODYTRACE_MSG(("MelRet:pwr released!"));
		}
  		melodyCtrlBlk.pwrState = MI_pwrRelease;
  	}

  	return MI_MELODY_OK;
}
#endif

/******************************************************************************
 *
 * Function:
 *		MI_PlayPrepare()
 *
 * Description:
 *		Get music data from music database, load data to the stream converter 
 *      corresponds to that music type, open data, and enter ready state.
 *
 * Input:
 *		musicID music index in music database
 *		count	playback count
 *
 * Output:
 *		none.
 *		   
 *****************************************************************************/

T_MELODY_RET MI_PlayPrepare(UINT8 musicID, UINT8 count)
{
	SINT32		 result;
	SINT32		 file_id;	/* file id */
	SINT32		 func_id;
	SINT32       volume;
	UINT16		 mode;
	T_MUSIC_INFO mInfo;
#if	(MELODY_FFS_SUPPORT == 1)
	T_FFS_SIZE	sz;
#endif
	

	MELODYTRACE_MSG(("MelFunc:MI_PlayPrepare(ID=%d, count=%d)", musicID, count));

	if(!melodyCtrlBlk.initialized)
	{
		MELODYTRACE_MSG(("MelRet:Not Init."));
		return MI_MELODY_NOT_INIT;
	}

	/* get the music detail information */
	mInfo.mID = musicID;
	result = MI_GetMusicInfoByID(&mInfo);
	if(result != MI_MELODY_OK)
	{
		MELODYTRACE_MSG(("MelRet:get music error,result=%d", result));
		return result;
	}
	else
	{
		MELODYTRACE_MSG(("MelRet:get music success, len = %d, type = %d", mInfo.mLen, mInfo.mType));
	}	

	/* check file and converter availability */
	if(mInfo.mLen == 0 || mInfo.mPtr == NULL)
	{		
		MELODYTRACE_MSG(("MelRet:len zero."));
		return MI_MELODY_FILE_SIZE_ZERO;
	}

		
	if(melodyCtrlBlk.funcID[mInfo.mType] < 0)
	{
		MELODYTRACE_MSG(("MelRet:type not support, funcID=%d!", func_id));
		return MI_MELODY_FILE_TYPE_ERR;
	}
	/* file and converter available */

  #ifdef MELODY_POWERSAVE
	result = MI_Melody_PwrRelease();
	if(result != MI_MELODY_OK)
		return MI_MELODY_ERROR;
  #endif
	
	/*
	 * a music is playing, we must stop it before initiate a new music if 
	 * there is some conflicts on the melody device, only SMAF/Audio can
	 * be played simultaneously with maximum 4 SMAF/Phrase tones, other 
	 * format music is player exclusively
	 */
	AI_MaskIT(0x02); /* 2004-04-01 added */
	
	if(melodyCtrlBlk.musicID != MI_MELODY_MUSICID_INVALID)
	{	
		func_id = melodyCtrlBlk.funcID[melodyCtrlBlk.fileType];
		file_id = melodyCtrlBlk.fileID;

		/* 2004-04-01 added, MUTE before stop playing */
	  #if (MIDI_STEREO == 1)
		MaSound_DeviceControl(MASMW_HP_VOLUME, 0, 0, 0);
	  #endif
		MaSound_DeviceControl(MASMW_EQ_VOLUME, 0, 0, 0);
		/* added end */
				
		result = MI_Melody_PostStop(func_id, file_id, MI_StopAndPost);
		if(result != MI_MELODY_OK)
		{
			MELODYTRACE_MSG(("MelRet:busy, stop err,result=%d!", result));			
		}
		/* reset control block */
		MI_Melody_RstCtrlBlk();		
	}
	else
	{
		MI_Melody_HpAmpCtrl(1, MI_PWRCTRL_MUSIC);
	}	
	AI_UnmaskIT(0x02);	/* 2004-04-01 added */

#if 0
	/* Set Volume for next time playing */
	MaSound_DeviceControl(MASMW_SP_VOLUME, spkLev2val[melodyCtrlBlk.curVolume], 0, 0);
	MaSound_DeviceControl(MASMW_HP_VOLUME, 0, spkLev2val[melodyCtrlBlk.curVolume], spkLev2val[melodyCtrlBlk.curVolume]);
	MaSound_DeviceControl(MASMW_EQ_VOLUME, 31, 0, 0);
#endif 

	/*
	 * prepare to play the new music returned by 'mInfo' struct
	 */
	 
	/* get created function ID corresponds to the requested music type */
	func_id = melodyCtrlBlk.funcID[mInfo.mType];

	/* decide function open mode */
	switch(mInfo.mType)
	{
	case MASMW_CNVID_RMD:
		mode = 0;
		break;

	case MASMW_CNVID_WAV:
		mode = 0;
		break;
		
	case MASMW_CNVID_AUD:
		mode = 1;
		break;
		
	case MASMW_CNVID_MMF:
	case MASMW_CNVID_MID:
	default:
		mode = 0;
		break;	
	}
	
	/* Load the file */
#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	

	/* allocate memory for FFS file */
	if(musicID == MI_MELODY_MUSICID_FILE)
	{
	  #if (MELODY_DATA_STATIC == 0) /* use dynamic memory */	
	  	MI_ALLOC(music_data_buffer, mInfo.mLen, sz);
	  	if(sz != EC_MMIMEM_OK)
	  	{
	  		MELODYTRACE_MSG(("MI_PlayPrepare():alloc dynmem failed, ret=%d", sz));
			music_data_buffer = NULL;
			return MI_MELODY_FILE_READ_ERR;
	  	}
	  #endif
		
		ffs_seek(melodyFd, 0, FFS_SEEK_SET);
		sz = ffs_read(melodyFd, (void*)music_data_buffer, mInfo.mLen);
	  
		if(sz != mInfo.mLen)
		{
			MELODYTRACE_MSG(("MI_PlayPrepare():read FFS file err,len=%d", sz));
			MI_Melody_RstCtrlBlk();
			return MI_MELODY_FILE_READ_ERR;
		}
		else
		{
			mInfo.mPtr = music_data_buffer;
		}		
	}
#endif

	file_id = MaSound_Load(func_id, mInfo.mPtr, mInfo.mLen, 1, MI_Melody_CB, NULL);
	if (file_id < MASMW_SUCCESS)
	{
		MELODYTRACE_MSG(("MelRet:Load file err%d", file_id));
		MI_Melody_ErrHdr(func_id, file_id);
		return MI_MELODY_ERROR;
	}

	/* Open the file */
	result = MaSound_Open(func_id, file_id, mode, NULL);
	if(result != MASMW_SUCCESS)
	{
		MELODYTRACE_MSG(("MelRet:Open file err%d", result));
		MI_Melody_ErrHdr(func_id, file_id);
		return MI_MELODY_ERROR;
	}
	
	/* Set volume */
	volume = 100; /* 0~127, default is 100 */
	result = MaSound_Control(func_id, file_id, MASMW_SET_VOLUME, &volume, NULL);
	if(result != MASMW_SUCCESS)
	{
		MI_Melody_ErrHdr(func_id, file_id);
		return MI_MELODY_ERROR;
	}

	/* Standby for playing */
	result = MaSound_Standby(func_id, file_id, NULL);
	if(result != MASMW_SUCCESS)
	{
		MI_Melody_ErrHdr(func_id, file_id);
		return MI_MELODY_ERROR;
	}	

	melodyCtrlBlk.musicID	= musicID;
	melodyCtrlBlk.remainCnt = count;
	melodyCtrlBlk.curPos	= 0;
	melodyCtrlBlk.fileID	= file_id;
	melodyCtrlBlk.fileType	= mInfo.mType;

	return MI_MELODY_OK;
}

/******************************************************************************
 *
 * Function:
 *		MI_Melody_PostStop()
 *
 * Description:
 *		Process after stop music playing.
 *
 * Input:
 *		func_id function ID
 *      file_id file ID
 *      mode  MI_PostOnly
 *            MI_StopAndPost
 *
 * Output:
 *		MI_MELODY_OK
 *      MI_MELODY_ERROR
 *		   
 *****************************************************************************/
T_MELODY_RET MI_Melody_PostStop(SINT32 funcID, SINT32 fileID, T_POSTSTOP mode)
{
	int result;

	MELODYTRACE_MSG(("MelFunc:MI_Melody_PostStop(), mode = %d", mode));
	
	switch(mode)
	{
	case MI_StopAndPost:
		result = MaSound_Stop(funcID, fileID, NULL);
		if(result != MASMW_SUCCESS)
		{
			MI_Melody_ErrHdr(funcID, fileID);
			return(MI_MELODY_ERROR);
		}
		/* following process need, don't break */
	case MI_PostOnly:
		result = MaSound_Close(funcID, fileID, NULL);
		if(result != MASMW_SUCCESS)
		{
			MI_Melody_ErrHdr(funcID, fileID);
			return(MI_MELODY_ERROR);
		}

		result = MaSound_Unload(funcID, fileID, NULL);
		if(result != MASMW_SUCCESS)
		{
			MI_Melody_ErrHdr(funcID, fileID);
			return(MI_MELODY_ERROR);
		}
	default:
		break;
	}

	return MI_MELODY_OK;
}

void MI_Melody_Reset(void)
{
	volatile int loop = 0, dummy = 0;

#if (MIDI_STEREO == 1)
	AI_EnableBit(BIT_EXTAMP_IO_SEL);
	AI_ConfigBitAsOutput(PIN_EXTAMP_CTRL);
#elif (MIDI_STEREO == 0)
	AI_ConfigBitAsInput(PIN_EXTAMP_CTRL);
#endif
	
	/* Set SIM_PWCTRL as GPIO5 for YMU765 RST */
	AI_EnableBit(1);
	AI_ConfigBitAsOutput(5);

	/* Reset YMU765 */
	AI_SetBit(5);
	for(loop = 0; loop < 1000; loop++)
		dummy ++;

	/* reset low pulse, duration at least 100us */
	AI_ResetBit(5);
	for(loop = 0; loop < 65535; loop++)
		dummy++;
	
	AI_SetBit(5);
	for(loop = 0; loop < 1000; loop++)
		dummy++;
}

/******************************************************************************
 *
 * Function:
 *		MI_Melody_HpAmpCtrl()
 *
 * Description:
 *		Perform melody chip power management at each states.
 *

⌨️ 快捷键说明

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