📄 malib.c
字号:
/* Update */
pPhrChk->pbVoice += dwSkip;
pPhrChk->dwVoiceSize -= (UINT32)(MALIB_SIZE_OF_CHUNKHEADER + dwSkip);
}
}
for(i = dwNumofVoice; i < MALIB_MAX_PHRASE_VOICES; i++)
{
/* Set ProgNo=0 as default voice to un-set voices */
pVi = &(pPi->VocInfo[i]);
pVi->bBankNo = 0;
pVi->bProgNo = 0;
}
/* Update */
pPhrChk->pbPhrase += dwSize;
pPhrChk->dwPhraseSize -= (UINT32)(dwSize + MALIB_SIZE_OF_CHUNKHEADER);
return (0L);
}
/*=============================================================================
// Function Name : UINT32 PhrChk_SequenceChunkCheck(PPHRCHECK pPhrChk)
//
// Description : Check SMAF/Phrase Sequence chunk
//
// Argument : pPhrChk ... Pointer to the checking result
//
// Return : 0 NoError
// !0 Error
//
=============================================================================*/
static UINT32 PhrChk_SequenceChunkCheck(
MALIB_PPHRCHECK pPhrChk
)
{
UINT8* pbSeq;
UINT8 bData0;
UINT8 bData1;
UINT8 bSize;
UINT32 dwRemain;
UINT32 dwSize;
UINT32 dwDuration;
UINT32 dwPlayTime;
MALIB_PPHRINFO pPi = pPhrChk->pPhrInfo;
/* Get Size */
dwSize = _get4b(&(pPhrChk->pbPhrase));
/* Check Size */
if(pPhrChk->dwPhraseSize < (UINT32)(MALIB_SIZE_OF_CHUNKHEADER + dwSize))
{
pPhrChk->wErrStatus |= MALIB_PHRASE_DATA_SIZE;
return (1L);
}
/* Remember position and size */
pPi->pbSequenceChunk = pPhrChk->pbPhrase;
pPi->dwSequenceChunkSize = dwSize;
/* Get play back time */
pbSeq = pPi->pbSequenceChunk;
dwRemain = pPi->dwSequenceChunkSize;
dwPlayTime = 0L;
while(dwRemain)
{
/* Check Size!! */
if(dwRemain < 3L) { /* minimam command */
pPhrChk->wErrStatus |= MALIB_PHRASE_DATA_SIZE;
return (1L);
}
/* Duration 1 or 2byte */
dwDuration = (UINT32)*(pbSeq++);
dwRemain--;
if(dwDuration & 0x80) {
dwDuration = (UINT32)((((dwDuration & 0x7F) << 7) + (UINT32)*(pbSeq++)) + 128);
dwRemain--;
}
/* Update play back time */
dwPlayTime += dwDuration;
/* Event */
bData0 = *(pbSeq++);
dwRemain--;
switch (bData0)
{
case 0x00:
/* Control Message */
if(dwRemain < 1L) {
pPhrChk->wErrStatus |= MALIB_PHRASE_DATA_SIZE;
return (1L);
}
bData1 = *(pbSeq++);
dwRemain--;
if((bData1 & 0x30) == 0x30) { /* 3byte */
if(dwRemain < 1L) {
pPhrChk->wErrStatus |= MALIB_PHRASE_DATA_SIZE;
return (1L);
}
pbSeq++;
dwRemain--;
}
else { /* 2byte */
}
break;
case 0xFF:
/* Exclusive Message or NOP */
if(dwRemain < 1L) {
pPhrChk->wErrStatus |= MALIB_PHRASE_DATA_SIZE;
return (1L);
}
bData1 = *(pbSeq++);
dwRemain--;
if(bData1 == 0xF0) {
if(dwRemain < 1L) {
pPhrChk->wErrStatus |= MALIB_PHRASE_DATA_SIZE;
return (1L);
}
bSize = *(pbSeq++);
dwRemain--;
if(dwRemain < (UINT32)bSize) {
pPhrChk->wErrStatus |= MALIB_PHRASE_DATA_SIZE;
return (1L);
}
else {
pbSeq += (UINT32)bSize;
dwRemain -= (UINT32)bSize;
}
}
else { /* NOP */
}
break;
default:
/* Note Message */
/* Gatetime 1 or 2byte */
dwDuration = (UINT32)*(pbSeq++);
dwRemain--;
if(dwDuration & 0x80) {
if(dwRemain < 1) {
pPhrChk->wErrStatus |= MALIB_PHRASE_DATA_SIZE;
return (1L);
}
dwDuration = (UINT32)((((dwDuration & 0x7F) << 7) + (UINT32)*(pbSeq++)) + 128);
dwRemain--;
}
break;
}
}
pPi->dwPlayTime = dwPlayTime;
if(pPi->dwPlayTime <= MALIB_MIN_PHRASE_DATA_LENGTH) {
pPhrChk->wErrStatus |= MALIB_PHRASE_DATA_SHORTLEN;
return (1L);
}
/* Update */
pPhrChk->pbPhrase += dwSize;
pPhrChk->dwPhraseSize -= (UINT32)(dwSize + MALIB_SIZE_OF_CHUNKHEADER);
return (0L);
}
/*=============================================================================
// Function Name : UINT32 PhrChk_PhraseBody(PPHRCHECK pPhrChk)
//
// Description : Check SMAF/Phrase "MMMG" chunk body
//
// Argument : pPhrChk ... Pointer to the checking result
//
// Return : 0 NoError
// !0 Error
//
=============================================================================*/
static UINT32 PhrChk_PhraseBody(
MALIB_PPHRCHECK pPhrChk
)
{
UINT8 bFound;
UINT8 bTmp;
UINT32 dwSize;
UINT32 dwSkip;
static UINT8 bChunkName0[5] = "INFO";
static UINT8 bChunkName1[5] = "VOIC";
static UINT8 bChunkName2[5] = "SEQU";
/* Get Size */
dwSize = _get4b(&(pPhrChk->pbBuffer));
/* Check Size */
if(pPhrChk->dwSize < (UINT32)(MALIB_SIZE_OF_CHUNKHEADER + dwSize + MALIB_SIZE_OF_CRC))
{
pPhrChk->wErrStatus |= MALIB_PHRASE_DATA_SIZE;
return (1L);
}
pPhrChk->pbPhrase = pPhrChk->pbBuffer;
pPhrChk->dwPhraseSize = dwSize;
if(pPhrChk->bMode & MALIB_CHKMODE_ENABLE)
{
/* Check Version */
bTmp = _get1b(&(pPhrChk->pbPhrase));
if(bTmp != MALIB_PHRASE_VERSION) {
pPhrChk->wErrStatus |= MALIB_PHRASE_DATA_VERSION;
return (1L);
}
/* Check Timer base */
bTmp = _get1b(&(pPhrChk->pbPhrase));
if(bTmp != MALIB_PHRASE_TIMEBASE) {
pPhrChk->wErrStatus |= MALIB_PHRASE_DATA_TIMEBASE;
return (1L);
}
} else {
pPhrChk->pbPhrase += 2L; /* Skip */
}
pPhrChk->dwPhraseSize -= 2L;
/* Search "INFO", "VOIC", "SEQU" Chunk */
bFound = 0x00;
while(pPhrChk->dwPhraseSize > (UINT32)(MALIB_SIZE_OF_CHUNKHEADER))
{
/**/
if(PhrChk_CompareID(bChunkName0, pPhrChk->pbPhrase, 0xFFFFFFFF) == 0L)
{
pPhrChk->pbPhrase += 4L;
if(PhrChk_InfoChunkBody(pPhrChk) != 0L) {
return (1L);
}
}
/**/
else if(PhrChk_CompareID(bChunkName1, pPhrChk->pbPhrase, 0xFFFFFFFF) == 0L)
{
pPhrChk->pbPhrase += 4L;
if(PhrChk_VoiceChunkCheck(pPhrChk) != 0L) {
return (1L);
}
}
/**/
else if(PhrChk_CompareID(bChunkName2, pPhrChk->pbPhrase, 0xFFFFFFFF) == 0L)
{
bFound = 0x01;
pPhrChk->pbPhrase += 4L;
if(PhrChk_SequenceChunkCheck(pPhrChk) != 0L) {
return (1L);
}
}
/* other chunk!! */
else
{
/* Skip Chunk */
pPhrChk->pbPhrase += 4L;
dwSkip = _get4b(&(pPhrChk->pbPhrase));
/* Check Size */
if(pPhrChk->dwPhraseSize < (UINT32)(MALIB_SIZE_OF_CHUNKHEADER + dwSkip))
{
pPhrChk->wErrStatus |= MALIB_PHRASE_DATA_SIZE;
return (1L);
}
/* Update */
pPhrChk->pbPhrase += dwSkip;
pPhrChk->dwPhraseSize -= (UINT32)(dwSkip + MALIB_SIZE_OF_CHUNKHEADER);
}
}
if(bFound == 0x00) {
pPhrChk->wErrStatus |= MALIB_PHRASE_DATA_CHUNK;
return (1L);
}
/* Update */
pPhrChk->pbBuffer = pPhrChk->pbPhrase;
pPhrChk->dwSize -= (UINT32)(dwSize + MALIB_SIZE_OF_CHUNKHEADER);
return (0L);
}
/*=============================================================================
// Function Name : SINT32 smafpharse_checker
//
// Description : Check SMAF/Phrase
//
// Argument : psPCA ... Pointer to the checking result
//
// Return : data length(msec) or error code
//
=============================================================================*/
SINT32 smafpharse_checker(
MALIB_PPHRCHECK pPCA
)
{
UINT8 bFound;
UINT32 dwSize;
static UINT8 bChunkName[5] = "MMMG";
/* Check Header & CRC */
if(PhrChk_OverallChunkCheck(pPCA) != 0L) return pPCA->wErrStatus;
/* Check Contents Info Chunk */
if(PhrChk_CntiInfoChunkCheck(pPCA) != 0L) return pPCA->wErrStatus;
/* Check Option Data Chunk */
if(PhrChk_OptionDataChunkCheck(pPCA) != 0L) return pPCA->wErrStatus;
/* check only contetns infomation */
if(pPCA->bMode & MALIB_CHKMODE_CNTIONLY) return pPCA->wErrStatus;
/* Phrase Check */
bFound = 0x00;
while(pPCA->dwSize > (UINT32)(MALIB_SIZE_OF_CHUNKHEADER + MALIB_SIZE_OF_CRC))
{
/* Search "MMMG" Chunk */
if(PhrChk_CompareID(bChunkName, pPCA->pbBuffer, 0xFFFFFFFF) != 0L)
{
/* Skip Chunk */
pPCA->pbBuffer += 4L;
dwSize = _get4b(&(pPCA->pbBuffer));
/* Check Size */
if(pPCA->dwSize < (UINT32)(MALIB_SIZE_OF_CHUNKHEADER + dwSize + MALIB_SIZE_OF_CRC))
return MALIB_PHRASE_DATA_SIZE;
/* Update */
pPCA->pbBuffer += dwSize;
pPCA->dwSize -= dwSize;
}
/* Found "MMMG" Chunk!! */
else
{
bFound = 0x01;
pPCA->pbBuffer += 4L;
if(PhrChk_PhraseBody(pPCA) != 0L) return pPCA->wErrStatus;
break; /* Support only the first "MMMG" Chunk */
}
}
/* Not found "MMMG" Chunk */
if(bFound == 0x00) return MALIB_PHRASE_DATA_CHUNK;
return MALIB_PHRASE_DATA_NOERROR;
}
/*=============================================================================
// Function Name : SINT32 malib_smafphrase_checker
//
// Description : Check SMAF/Phrase
//
// Argument : pBuffer ... Pointer to the data
// dwSize ... Data size
// psPCA ... Pointer to the checking result
//
// Return : data length(msec) or error code
//
=============================================================================*/
SINT32 malib_smafphrase_checker(
UINT8* pbBuf,
UINT32 dwSize,
void* pvPCA
)
{
SINT32 sdResult;
MALIB_PPHRCHECK pPCA;
if (pvPCA == NULL) pPCA = malib_PhrChk_Initialize(pbBuf, dwSize);
else pPCA = (MALIB_PPHRCHECK)pvPCA;
sdResult = smafpharse_checker(pPCA);
if (sdResult != MALIB_PHRASE_DATA_NOERROR) {
if(sdResult & MALIB_PHRASE_DATA_SIZE) return (MASMW_ERROR_CHUNK_SIZE);
if(sdResult & MALIB_PHRASE_DATA_CLASS) return (MASMW_ERROR_CONTENTS_CLASS);
if(sdResult & MALIB_PHRASE_DATA_TYPE) return (MASMW_ERROR_CONTENTS_TYPE);
if(sdResult & MALIB_PHRASE_DATA_CHUNK) return (MASMW_ERROR_CHUNK);
if(sdResult & MALIB_PHRASE_DATA_SHORTLEN) return (MASMW_ERROR_SHORT_LENGTH);
return (MASMW_ERROR_FILE);
}
else return (SINT32)(pPCA->pPhrInfo->dwPlayTime * MALIB_PHRASE_TIMEBASE);
}
/*=============================================================================
// Function Name : SINT32 NextChunk(UINT8 state, UINT8* pBuff,
// UINT32 remain, UINT16* chunk)
//
// Description : Get Chunk Name and Size
//
// Argument : state : check status
// pBuff : pointer to the data
// remain : size of the data
// chunk : chunk id
//
// Return : >= 0 : NoError(Chunk Size),
// < 0 : Error
=============================================================================*/
static SINT32 NextChunk(UINT8 state, UINT8 *pBuff, UINT32 remain,
UINT16 *chunk)
{
UINT32 dwChunkID;
UINT32 dwChunkSize;
if(remain <= 8)
return -1;
dwChunkID = ((UINT32)(*pBuff << 24) | (UINT32)(*(pBuff+1) << 16) |
(UINT32)(*(pBuff+2) << 8 ) | (UINT32)(*(pBuff+3)));
remain -= 4;
switch(dwChunkID){
case 0x4D4D4D44: /* File Chunk */
if(state != 0) /* status Check */
return -1;
*chunk = 0x0001;
break;
case 0x434E5449: /* Contents Info Chunk */
if(state != 1) /* status Check */
return -1;
*chunk = 0x0002;
break;
case 0x4F504441: /* Optional Data Chunk */
if(state != 2) /* status Check */
return -1;
*chunk = 0x0003;
break;
case 0x4D535452: /* Master Track Chunk */
if(state != 2) /* status Check */
return -1;
*chunk = 0x0007;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -