📄 melody_env.c
字号:
/**
* 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 + -