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 + -
显示快捷键?