📄 mammfcnv.c
字号:
/*********************************************************************************
* Check_Initial
*
* Description:
* SMAF data load (error check and regist)
* Argument:
* psLoad pointer to load information structure
* Return:
* nothing
********************************************************************************/
static void Check_Initial(
PLOADINFO psLoad
)
{
UINT8 i;
/* Initialize Load information structure */
psLoad->pbMmmd = NULL;
psLoad->dMmmdSize = 0;
psLoad->dCrc = MMF_CRC_NULL;
psLoad->dSmafType = MMF_SMAF_TYPE_NULL;
psLoad->dPlayTime = 0;
psLoad->dStartTime = 0;
psLoad->dTimeBase = 0;
psLoad->pfnGetByte = NULL;
psLoad->sOption_Info.pbCnti = NULL;
psLoad->sOption_Info.dCntiSize = 0;
psLoad->sOption_Info.pbOpda = NULL;
psLoad->sOption_Info.dOpdaSize = 0;
for( i = 0; i < MMF_MAX_TRACK_NUM; i++) {
psLoad->sTrack_Info[i].pbMtr = NULL;
psLoad->sTrack_Info[i].dMtrSize = 0;
psLoad->sTrack_Info[i].pbMspi = NULL;
psLoad->sTrack_Info[i].dMspiSize = 0;
psLoad->sTrack_Info[i].pbMtsu = NULL;
psLoad->sTrack_Info[i].dMtsuSize = 0;
psLoad->sTrack_Info[i].pbMtsq = NULL;
psLoad->sTrack_Info[i].dMtsqSize = 0;
psLoad->sTrack_Info[i].pbMtsp = NULL;
psLoad->sTrack_Info[i].dMtspSize = 0;
psLoad->sTrack_Info[i].pbMthv = NULL;
psLoad->sTrack_Info[i].dMthvSize = 0;
psLoad->sTrack_Info[i].dPlayTime = 0;
psLoad->sTrack_Info[i].dTimeBase = 0;
psLoad->sTrack_Info[i].dStartPoint = MMF_STSP_OFFSET_NULL;
psLoad->sTrack_Info[i].dStopPoint = MMF_STSP_OFFSET_NULL;
psLoad->sTrack_Info[i].dStartTick = MMF_STSP_TIME_NULL;
psLoad->sTrack_Info[i].dStopTick = MMF_STSP_TIME_NULL;
}
for( i = 0; i < MMF_MAX_PHRASE_INFO; i++) {
psLoad->sPhrase_Info[i].dStartPoint = MMF_STSP_OFFSET_NULL;
psLoad->sPhrase_Info[i].dStopPoint = MMF_STSP_OFFSET_NULL;
psLoad->sPhrase_Info[i].dStartTick = MMF_STSP_TIME_NULL;
psLoad->sPhrase_Info[i].dStopTick = MMF_STSP_TIME_NULL;
}
psLoad->sHV_Info.pbVoice = NULL;
psLoad->sHV_Info.dVoiceSize = 0;
psLoad->sHV_Info.pbScript = NULL;
psLoad->sHV_Info.dScriptSize = 0;
psLoad->sHV_Info.bHvChannel = MMF_HV_CHANNEL_NULL;
}
/*********************************************************************************
* get_timebase
*
* Description:
* get time base (data value -> msec/tick)
* Argument:
* bData time base (data value)
* Return:
* >=0 success(time base (msec/tick))
* < 0 error code
********************************************************************************/
static SINT32 get_timebase(
UINT8 bData
)
{
switch( bData ) {
case 0x02: return 4; /* 4[msec/tick] */
case 0x03: return 5; /* 5[msec/tick] */
case 0x10: return 10; /* 10[msec/tick] */
case 0x11: return 20; /* 20[msec/tick] */
case 0x12: return 40; /* 40[msec/tick] */
case 0x13: return 50; /* 50[msec/tick] */
default: return MMF_FUNC_ERROR; /* Time Base Error */
}
}
/*********************************************************************************
* MTR_Check
*
* Description:
* score track chunk check (header information and chunk construction)
* Argument:
* psTrack pointer to track information structure
* bSmafType SMAF type
* Return:
* 0 success
* < 0 error code
********************************************************************************/
static SINT32 MTR_Check(
PTRACKINFO psTrack,
UINT8 bSmafType
)
{
SINT32 sdResult, sdChunkSize;
UINT32 dSize, dIndex;
UINT8* pbBuf;
UINT32 dChunkID, dChunkNo;
/* Check Format Type */
switch (bSmafType) {
case MMF_SMAF_TYPE_MA1 :
case MMF_SMAF_TYPE_MA2 :
if (psTrack->pbMtr[0] != 0x00) {
return MMF_ERR_CHUNK;
}
break;
case MMF_SMAF_TYPE_MA3 :
if ((psTrack->pbMtr[0] != 0x01) && (psTrack->pbMtr[0] != 0x02)) {
return MMF_ERR_CHUNK;
}
break;
case MMF_SMAF_TYPE_MA5 :
if (psTrack->pbMtr[0] != 0x02) {
return MMF_ERR_CHUNK;
}
break;
}
/* Check Sequence Type */
if (psTrack->pbMtr[1] != 0x00) {
return MMF_ERR_CHUNK;
}
/* Check Time Base */
if (psTrack->pbMtr[2] != psTrack->pbMtr[3]) {
return MMF_ERR_CHUNK;
}
sdResult = get_timebase(psTrack->pbMtr[2]);
if (sdResult == MMF_FUNC_ERROR) {
return MMF_ERR_CHUNK;
}
psTrack->dTimeBase = (UINT32)sdResult;
/* Check sub chunk disposition */
if ((bSmafType == MMF_SMAF_TYPE_MA1) || (bSmafType == MMF_SMAF_TYPE_MA2))
dIndex = MMF_MINIMUM_TRACKSIZE2;
else
dIndex = MMF_MINIMUM_TRACKSIZE3;
pbBuf = psTrack->pbMtr;
dSize = psTrack->dMtrSize;
while (dSize > (dIndex + MMF_CHUNK_HEADER_SIZE)) {
sdChunkSize = malib_NextChunk(&pbBuf[dIndex], (dSize-dIndex),
MALIB_CHUNK_PHASE_MTRSUB, &dChunkID, &dChunkNo);
if (sdChunkSize < 0) {
return MMF_ERR_CHUNK;
}
dIndex += MMF_CHUNK_HEADER_SIZE;
switch (dChunkID) {
case MALIB_CHUNKCODE_MSPI :
psTrack->pbMspi = &(pbBuf[dIndex]);
psTrack->dMspiSize = sdChunkSize;
break;
case MALIB_CHUNKCODE_MTSU :
psTrack->pbMtsu = &(pbBuf[dIndex]);
psTrack->dMtsuSize = sdChunkSize;
break;
case MALIB_CHUNKCODE_MTSQ :
psTrack->pbMtsq = &(pbBuf[dIndex]);
psTrack->dMtsqSize = sdChunkSize;
break;
case MALIB_CHUNKCODE_MTSP :
psTrack->pbMtsp = &(pbBuf[dIndex]);
psTrack->dMtspSize = sdChunkSize;
break;
case MALIB_CHUNKCODE_MTHV :
psTrack->pbMthv = &(pbBuf[dIndex]);
psTrack->dMthvSize = sdChunkSize;
break;
default :
break;
}
dIndex += sdChunkSize;
}
if ((psTrack->pbMtsq == NULL) ||
(psTrack->dMtsqSize == 0)) {
return MMF_ERR_SLENGTH;
}
return MMF_FUNC_SUCCESS;
}
/*********************************************************************************
* ATR_Check
*
* Description:
* audio track chunk check (header information and chunk construction)
* Argument:
* psTrack pointer to track information structure
* Return:
* 0 success
* < 0 error code
********************************************************************************/
static SINT32 ATR_Check(
PTRACKINFO psTrack
)
{
SINT32 sdResult, sdChunkSize;
UINT32 dSize, dIndex;
UINT8* pbBuf;
UINT32 dChunkID, dChunkNo;
UINT8 fbWave;
/* Check Format Type */
if (psTrack->pbMtr[0] != 0x00) {
return MMF_ERR_CHUNK;
}
/* Check Sequence Type */
if (psTrack->pbMtr[1] != 0x00) {
return MMF_ERR_CHUNK;
}
/* Check Wave Type */
if (((psTrack->pbMtr[2] != 0x10) && (psTrack->pbMtr[2] != 0x11)) ||
((psTrack->pbMtr[3] & 0xF0) != 0x00)) {
return MMF_ERR_CHUNK;
}
/* Check Time Base */
if (psTrack->pbMtr[4] != psTrack->pbMtr[5]) {
return MMF_ERR_CHUNK;
}
sdResult = get_timebase(psTrack->pbMtr[4]);
if (sdResult == MMF_FUNC_ERROR) {
return MMF_ERR_CHUNK;
}
psTrack->dTimeBase = (UINT32)sdResult;
pbBuf = psTrack->pbMtr;
dSize = psTrack->dMtrSize;
dIndex = 6;
fbWave = MMF_MA2_VOICE_NULL;
/* Check sub chunk disposition */
while (dSize > (dIndex + MMF_CHUNK_HEADER_SIZE)) {
sdChunkSize = malib_NextChunk(&pbBuf[dIndex], (dSize-dIndex),
MALIB_CHUNK_PHASE_ATRSUB, &dChunkID, &dChunkNo);
if (sdChunkSize < 0) {
return MMF_ERR_CHUNK;
}
dIndex += MMF_CHUNK_HEADER_SIZE;
switch (dChunkID) {
case MALIB_CHUNKCODE_ASPI :
psTrack->pbMspi = &(pbBuf[dIndex]);
psTrack->dMspiSize = sdChunkSize;
break;
case MALIB_CHUNKCODE_ATSQ :
psTrack->pbMtsq = &(pbBuf[dIndex]);
psTrack->dMtsqSize = sdChunkSize;
break;
case MALIB_CHUNKCODE_AWA :
if ((0x01 <= dChunkNo) && (dChunkNo <= 0x3E))
fbWave = MMF_MA2_VOICE_FOUND;
break;
default :
break;
}
dIndex += sdChunkSize;
}
if ((psTrack->pbMtsq == NULL) ||
(psTrack->dMtsqSize == 0) ||
(fbWave == MMF_MA2_VOICE_NULL)) {
return MMF_ERR_SLENGTH;
}
return MMF_FUNC_SUCCESS;
}
/*********************************************************************************
* MspI_Check
*
* Description:
* seek & phrase info chunk check (get phrase information)
* Argument:
* psTrack pointer to track information structure
* psPhrase pointer to phrase information structure
* Return:
* 0 success
* < 0 error code
********************************************************************************/
static void MspI_Check(
PTRACKINFO psTrack,
PPHRASEINFO psPhrase
)
{
UINT8* pbBuf;
UINT32 dSize, dIndex;
UINT16 wTag;
if (psTrack->pbMspi == NULL)
return;
pbBuf = psTrack->pbMspi;
dSize = psTrack->dMspiSize;
dIndex = 0;
while (dSize >= dIndex + MMF_PHRAZE_SIZE_A) {
wTag = (UINT16)((((UINT16)pbBuf[dIndex]) << 8) + (UINT16)pbBuf[dIndex+1]);
switch (wTag) {
case MMF_TAG_STARTPOINT : /* start point */
psTrack->dStartPoint = get_4byte(&(pbBuf[dIndex + 3]));
dIndex += MMF_PHRAZE_SIZE_A;
break;
case MMF_TAG_STOPPOINT : /* stop point */
psTrack->dStopPoint = get_4byte(&(pbBuf[dIndex + 3]));
dIndex += MMF_PHRAZE_SIZE_A;
break;
case MMF_TAG_PHRASE_A : /* A melody */
if (dSize < dIndex + MMF_PHRAZE_SIZE_B)
return ;
psPhrase[0].dStartPoint = get_4byte(&(pbBuf[dIndex + 3]));
psPhrase[0].dStopPoint = get_4byte(&(pbBuf[dIndex + 7]));
dIndex += MMF_PHRAZE_SIZE_B;
break;
case MMF_TAG_PHRASE_B : /* B melody */
if (dSize < dIndex + MMF_PHRAZE_SIZE_B)
return ;
psPhrase[1].dStartPoint = get_4byte(&(pbBuf[dIndex + 3]));
psPhrase[1].dStopPoint = get_4byte(&(pbBuf[dIndex + 7]));
dIndex += MMF_PHRAZE_SIZE_B;
break;
case MMF_TAG_PHRASE_E : /* Ending */
if (dSize < dIndex + MMF_PHRAZE_SIZE_B)
return ;
psPhrase[2].dStartPoint = get_4byte(&(pbBuf[dIndex + 3]));
psPhrase[2].dStopPoint = get_4byte(&(pbBuf[dIndex + 7]));
dIndex += MMF_PHRAZE_SIZE_B;
break;
case MMF_TAG_PHRASE_I : /* Intro */
if (dSize < dIndex + MMF_PHRAZE_SIZE_B)
return ;
psPhrase[3].dStartPoint = get_4byte(&(pbBuf[dIndex + 3]));
psPhrase[3].dStopPoint = get_4byte(&(pbBuf[dIndex + 7]));
dIndex += MMF_PHRAZE_SIZE_B;
break;
case MMF_TAG_PHRASE_K : /* Interlude */
if (dSize < dIndex + MMF_PHRAZE_SIZE_B)
return ;
psPhrase[4].dStartPoint = get_4byte(&(pbBuf[dIndex + 3]));
psPhrase[4].dStopPoint = get_4byte(&(pbBuf[dIndex + 7]));
dIndex += MMF_PHRAZE_SIZE_B;
break;
case MMF_TAG_PHRASE_R : /* Refrain */
if (dSize < dIndex + MMF_PHRAZE_SIZE_B)
return ;
psPhrase[5].dStartPoint = get_4byte(&(pbBuf[dIndex + 3]));
psPhrase[5].dStopPoint = get_4byte(&(pbBuf[dIndex + 7]));
dIndex += MMF_PHRAZE_SIZE_B;
break;
case MMF_TAG_PHRASE_S : /* Bridge */
if (dSize < dIndex + MMF_PHRAZE_SIZE_B)
return ;
psPhrase[6].dStartPoint = get_4byte(&(pbBuf[dIndex + 3]));
psPhrase[6].dStopPoint = get_4byte(&(pbBuf[dIndex + 7]));
dIndex += MMF_PHRAZE_SIZE_B;
break;
default :
return;
}
}
return;
}
/*********************************************************************************
* ST_SP_Check
*
* Description:
* track chunk check (offset of start point and stop point)
* Argument:
* psTrack pointer to track information structure
* Return:
* 0 success
* < 0 error code
********************************************************************************/
static SINT32 ST_SP_Check(
PTRACKINFO psTrack
)
{
UINT32 dStart, dStop, dSize;
dSize = psTrack->dMtsqSize;
if (psTrack->dStartPoint == MMF_STSP_OFFSET_NULL)
dStart = 0;
else
dStart = psTrack->dStartPoint;
if (psTrack->dStopPoint == MMF_STSP_OFFSET_NULL)
dStop = dSize;
else
dStop = psTrack->dStopPoint;
if ((dStart >= dStop) || (dStart > dSize) || (dStop > dSize))
return MMF_ERR_CHUNK;
return MMF_FUNC_SUCCESS;
}
/*********************************************************************************
* Mtsu_Check2
*
* Description:
* track chunk check (existence voice parameter)
* Argument:
* psTrack pointer to track information structure
* bSmafType SMAF type
* Return:
* 0 success
* < 0 error code
********************************************************************************/
static SINT32 Mtsu_Check2(
PTRACKINFO psTrack,
UINT8 bSmafType
)
{
UINT8* pbBuf;
UINT32 dSize, dIndex;
if (psTrack->pbMtsu == NULL) {
return MMF_MA2_VOICE_NOTFOUND;
}
pbBuf = psTrack->pbMtsu;
dSize = psTrack->dMtsuSize;
dIndex = 0;
while (dSize > dIndex + 20) {
if ((pbBuf[dIndex] != 0xFF) || (pbBuf[dIndex + 1] != 0xF0)) {
return MMF_MA2_VOICE_NOTFOUND;
}
if (pbBuf[dIndex + 3] == 0x43) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -