?? mamidcnv.c
字號:
/****************************************************************************
*
* Copyright (C) 2002-2003 YAMAHA CORPORATION. All rights reserved.
*
* Module : mamidcnv.c
*
* Description : SMF/GML Stream Converter Module.
*
* Version : 1.1.2 2003.07.09
*
****************************************************************************/
#include "mamidcnv.h"
/*--------------------------------------------------------------------------*/
/* Defines */
/*--------------------------------------------------------------------------*/
#define SMF_TIMEBASE_SHIFT 2 /* */
#define SMF_TIMEBASE (1L<<SMF_TIMEBASE_SHIFT) /* [ms] */
#define MAX_SMF_MESSAGES 256 /* */
#define MAX_SMF_TRACKS 32 /* Should be <= 32 */
#define SMF_MAX_GAIN 76 /* - 6[dB] : 90 */
/* -18[dB] : 45 */
#define MINIMUM_LENGTH (20)
#define MELODY_MAP (0)
#define DRUM_MAP (1)
#define NUM_OF_MAPS (2)
/*--------------------------------------------------------------------------*/
/* Types */
/*--------------------------------------------------------------------------*/
typedef struct _tagMidChInfo
{
UINT32 dBank; /* BankH&L (0x00:00..0x7F7F) */
UINT32 dCurrBank; /* BankH&L (0x00:00..0x7F7F) */
UINT32 dProg; /* ProgramChange (0..127) */
UINT32 dVolume; /* ChannelVolume (0..127) */
UINT32 dExpression; /* Expression (0..127) */
UINT32 dModulation; /* Modulation (0..127) */
UINT32 dPitchBend; /* PitchBendH (0..127) */
UINT32 dBendRange; /* CurrentBendRange (0..24) */
UINT32 dPreBendRange; /* LatestBendRange (0..24) */
UINT32 dPanpot; /* Panpot (0..127) */
UINT32 dHold1; /* Hold1 (0..127) */
UINT32 dMode; /* 0:MONO, 1:POLY */
UINT32 dRPN; /* RPN (0x00:00..0xFF7F) */
UINT32 dMipMute; /* Mute switch (1:mute) */
UINT32 dKeyCon; /* 0:Melady, 1:OFF, 2:ON */
UINT32 dLedSync; /* 0:OFF, 1:ON */
UINT32 dVibSync; /* 0:OFF, 1:ON */
UINT32 dFineTune; /* 0..0x3FFF */
UINT32 dCoaseTune; /* 0..0x7F */
} MIDCHINFO, *PMIDCHINFO;
typedef struct _tagMIDPACKET
{
SINT32 sdDeltaTime;
UINT32 dMsgID;
UINT32 dP1;
UINT32 dP2;
UINT32 dP3;
} MIDPACKET, *PMIDPACKET;
typedef struct _tagTrack
{
UINT32 dSmfCmd; /* CMD @ now */
UINT32 dSize; /* [byte] 0 measns nothing in it. */
UINT8* pbBase; /* NULL measns nothing in it. */
UINT32 dOffset; /* offset byte */
SINT32 sdTicks; /* */
} TRACKINFO, *PTRACKINFO;
typedef struct _tagOrderList
{
struct _tagOrderList* pPrev;
struct _tagOrderList* pNext;
UINT32 dTrack;
UINT32 dTicks;
} ORDERLIST, *PORDERLIST;
typedef struct _tagMidInfo
{
UINT32 dTimeResolution; /* 0..0x7fff */
UINT8* pbTitle; /* */
UINT32 dSizeTitle; /* */
UINT8* pbCopyright; /* */
UINT32 dSizeCopyright; /* */
UINT32 dNumOfTracks; /* 1..32 */
UINT32 dSmfFormat; /* 0..1 */
UINT32 dSetupBar; /* 0:No, 1:Yes */
UINT32 dStart; /* Index after SetupBar */
UINT32 dVibNoteVoice; /* 0:No, 1:Yes */
SINT32 sdTotalTicks; /* Total ticks */
SINT32 sdDataEndTime; /* (22.10)[ms] */
SINT32 sdDelta; /* (22.10)[ms] */
UINT32 dEndFlag; /* */
TRACKINFO TrackInfo[MAX_SMF_TRACKS];
struct _tagOrderList* pTopOrderList;
struct _tagOrderList* pDoneOrderList;
struct _tagOrderList* pBottomOrderList;
ORDERLIST OrderList[MAX_SMF_TRACKS + 3];
MIDCHINFO ChInfo[16]; /* */
UINT32 dValid; /* 0:none, 1:Valid */
UINT8 bVoiceMap[NUM_OF_MAPS][128];/* 0:Empty, 1:Valid */
} MIDINFO, *PMIDINFO;
typedef struct _tagMidGlobals
{
SINT32 sdSeqID; /* Sequence ID */
SINT32 sdFileID; /* File ID */
UINT32 dEnable; /* 0:disable */
UINT32 dSetup; /* 1: Just after seek */
UINT32 dRamBase; /* */
UINT32 dRamOffset; /* */
UINT32 dRamSize; /* */
MIDINFO DataInfo[2]; /* */
SINT32 sdSeekTime; /* [ms] */
SINT32 sdLastMsgTime; /* (22.10)[ms] */
SINT32 sdSmfCurrentTicks; /* Ticks @ now */
SINT32 sdSmfCurrentTime; /* (22.10)[ms] */
SINT32 sdSmfDataEndTime; /* (22.10)[ms] */
SINT32 sdSmfEndTime; /* (22.10)[ms] */
SINT32 sdSmfDelta; /* (22.10)[ms] */
UINT32 dMaxGain; /* MaxGain (0..127) */
UINT32 dMasterVolume; /* MsaterVolume (0..127) */
UINT32 dHoldMsgs; /* Number of messages in Q */
UINT32 dHoldPtrR; /* Pointer for Read */
MIDPACKET MsgBuffer[MAX_SMF_MESSAGES]; /* Message Q */
UINT32 dMuteFlag; /* 0:Normal, 1:MUTE */
UINT32 dSyncNoteCh; /* 0..15 */
UINT32 dSyncNoteKey; /* 0..127, 255:OFF */
UINT32 dVibNote; /* 0:No VibiNote, 1:Yes,VibNote */
} MIDGLOBAL, *PMIDGLOBAL;
/*--------------------------------------------------------------------------*/
/* Consts */
/*--------------------------------------------------------------------------*/
#include "mamid4opvoice.h"
/*---------------------------------------------------------------------------*/
/* Globals */
/*---------------------------------------------------------------------------*/
static MIDGLOBAL gMidInfo;
static PMIDGLOBAL gpMidInfo;
/*---------------------------------------------------------------------------*/
/* Functions (internal use only) */
/*---------------------------------------------------------------------------*/
/****************************************************************************
* InitializeOrderList(PMIDINFO pI)
*
* Description:
* Initialize OrderList.
* Param:
* pI ... pointer to the data info
* Return:
* none
****************************************************************************/
static void InitializeOrderList(PMIDINFO pI)
{
UINT32 i;
for (i = 1; i <= MAX_SMF_TRACKS + 1; i++)
{
pI->OrderList[i].pPrev = &pI->OrderList[i - 1];
pI->OrderList[i].pNext = &pI->OrderList[i + 1];
pI->OrderList[i].dTrack = 0xFF;
pI->OrderList[i].dTicks = 0xFFFFFFFFL;
}
pI->OrderList[0].pPrev = NULL;
pI->OrderList[0].pNext = &pI->OrderList[1];
pI->OrderList[MAX_SMF_TRACKS + 2].pPrev = &pI->OrderList[MAX_SMF_TRACKS + 1];
pI->OrderList[MAX_SMF_TRACKS + 2].pNext = NULL;
pI->pTopOrderList = &pI->OrderList[0];
pI->pDoneOrderList = &pI->OrderList[1];
pI->pBottomOrderList = &pI->OrderList[MAX_SMF_TRACKS + 2];
}
/****************************************************************************
* SortOrderList(PMIDINFO pI)
*
* Description:
* Sort OrderList. (Ascending order)
* Param:
* pI ... pointer to the data info
* Return:
* none
****************************************************************************/
static void SortOrderList(PMIDINFO pI)
{
PORDERLIST pSlot;
PORDERLIST pTerget;
pSlot = (pI->pTopOrderList)->pNext;
(pSlot->pPrev)->pNext = pSlot->pNext;
(pSlot->pNext)->pPrev = pSlot->pPrev;
pSlot->dTicks = ((UINT32)pI->TrackInfo[pSlot->dTrack].sdTicks << 5) + pSlot->dTrack;
pTerget = pSlot->pNext;
while (pTerget != pI->pDoneOrderList)
{
if (pSlot->dTicks <= pTerget->dTicks) break;
pTerget = pTerget->pNext;
}
(pTerget->pPrev)->pNext = pSlot;
pSlot->pPrev = pTerget->pPrev;
pTerget->pPrev = pSlot;
pSlot->pNext = pTerget;
}
/****************************************************************************
* InsertOrderList(PMIDINFO pI, UINT32 dTrack, SINT32 sdTicks)
*
* Description:
* Add item to the top of the list.
* Param:
* pI ... pointer to the data info
* Return:
* none
****************************************************************************/
static void InsertOrderList(PMIDINFO pI, UINT32 dTrack, SINT32 sdTicks)
{
PORDERLIST pTerget;
if (pI->dNumOfTracks == 1) return;
if (((pI->dEndFlag >> dTrack) & 0x01) == 0) return;
pTerget = pI->pDoneOrderList->pNext;
if (pTerget == pI->pBottomOrderList) return;
pI->pDoneOrderList->pNext = pTerget->pNext;
(pTerget->pNext)->pPrev = pI->pDoneOrderList;
pTerget->dTrack = dTrack;
pTerget->dTicks = ((UINT32)sdTicks << 5) + dTrack;
pTerget->pPrev = pI->pTopOrderList;
pTerget->pNext = (pI->pTopOrderList)->pNext;
((pI->pTopOrderList)->pNext)->pPrev = pTerget;
(pI->pTopOrderList)->pNext = pTerget;
SortOrderList(pI);
}
/****************************************************************************
* RemoveFromOrderList(PMIDINFO pI)
*
* Description:
* delete Item from the top of the list.
* Param:
* pI ... pointer to the data info
* Return:
* none
****************************************************************************/
static void RemoveFromOrderList(PMIDINFO pI)
{
PORDERLIST pSlot;
PORDERLIST pTerget;
pSlot = (pI->pTopOrderList)->pNext;
(pSlot->pPrev)->pNext = pSlot->pNext;
(pSlot->pNext)->pPrev = pSlot->pPrev;
pTerget = pI->pBottomOrderList;
(pTerget->pPrev)->pNext = pSlot;
pSlot->pPrev = pTerget->pPrev;
pTerget->pPrev = pSlot;
pSlot->pNext = pTerget;
}
/****************************************************************************
* GetTrackTime(PMIDINFO pI, UINT32 dTrack)
*
* Description:
* Get the 1st DT from the list.
* Param:
* pI ... pointer to the data info
* bTrack ... #Track
* Return:
* 0 : NoError, < 0 : Error code
****************************************************************************/
static SINT32 GetTrackTime(PMIDINFO pI, UINT32 dTrack)
{
UINT32 dTemp;
SINT32 dTime;
PTRACKINFO pMt;
if (((pI->dEndFlag >> dTrack) & 0x01) == 0) return (-1);
pMt = &(pI->TrackInfo[dTrack]);
dTime = 0;
do
{
if (pMt->dOffset >= pMt->dSize)
{
pI->dEndFlag &= ~(1L << dTrack);
return (-1);
}
dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
dTime = (dTime << 7) + (dTemp & 0x7f);
} while (dTemp >= 0x80);
pMt->sdTicks += dTime;
return (0);
}
/****************************************************************************
* UpdateTrackTime(PMIDINFO pI, UINT32 dTrack)
*
* Description:
* Update the 1st DT on the Track and OrderList
* Param:
* pI ... pointer to the data info
* bTrack ... #Track
* Return:
* 0 : NoError, < 0 : Error code
****************************************************************************/
static SINT32 UpdateTrackTime(PMIDINFO pI, UINT32 dTrack)
{
UINT32 dTemp;
SINT32 dTime;
PTRACKINFO pMt;
if (pI->dNumOfTracks == 1)
{
/* Single track */
if (((pI->dEndFlag >> dTrack) & 0x01) == 0)
{
return (-1);
}
pMt = &(pI->TrackInfo[dTrack]);
dTime = 0;
do
{
if (pMt->dOffset >= pMt->dSize)
{
pI->dEndFlag &= ~(1L << dTrack);
return (-1);
}
dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
dTime = (dTime << 7) + (dTemp & 0x7f);
} while (dTemp >= 0x80);
pMt->sdTicks += dTime;
}
else
{
/* Multi track */
if (((pI->dEndFlag >> dTrack) & 0x01) == 0)
{
RemoveFromOrderList(pI);
return (-1);
}
pMt = &(pI->TrackInfo[dTrack]);
dTime = 0;
do
{
if (pMt->dOffset >= pMt->dSize)
{
pI->dEndFlag &= ~(1L << dTrack);
RemoveFromOrderList(pI);
return (-1);
}
dTemp = (UINT32)pMt->pbBase[pMt->dOffset++];
dTime = (dTime << 7) + (dTemp & 0x7f);
} while (dTemp >= 0x80);
pMt->sdTicks += dTime;
SortOrderList(pI);
}
return (0);
}
/****************************************************************************
* ResetTimeInfo(PMIDINFO pI)
*
* Description:
* Reset time info
* Param:
* pI ... pointer to the data info
* Return:
* none
****************************************************************************/
static void ResetTimeInfo(PMIDINFO pI)
{
SINT32 sdTrack;
PTRACKINFO pMt;
pI->dEndFlag = 0;
for (sdTrack = 0; sdTrack < (SINT32)pI->dNumOfTracks; sdTrack++)
{
pMt = &(pI->TrackInfo[sdTrack]);
pMt->dSmfCmd = 0;
pMt->dOffset = 0;
pMt->sdTicks = 0;
if (pMt->dSize > 0) pI->dEndFlag |= (1L << sdTrack);
}
InitializeOrderList(pI);
for (sdTrack = 0; sdTrack < (SINT32)pI->dNumOfTracks; sdTrack++)
{
GetTrackTime(pI, (UINT32)sdTrack);
pMt = &(pI->TrackInfo[sdTrack]);
InsertOrderList(pI, (UINT32)sdTrack, pMt->sdTicks);
}
}
/****************************************************************************
* GetLeastTimeTrack(PMIDINFO pI)
*
* Description:
* Get the track@LeasetTime
* Param:
* pI ... pointer to the setup storage
* Return:
* 0 : NoError, < 0 : Error
****************************************************************************/
static SINT32 GetLeastTimeTrack(PMIDINFO pI)
{
PORDERLIST pTerget;
pTerget = (pI->pTopOrderList)->pNext;
if (pTerget == pI->pBottomOrderList) return (-1);
return ((SINT32)pTerget->dTrack);
}
/****************************************************************************
* GetSMFInfo(PMIDINFO pI)
*
* Description:
* Get SMF info from the file
* Param:
* pI ... pointer to the setup storage
* Return:
* 0 : NoError, < 0 : Error
****************************************************************************/
static SINT32 GetSMFInfo(PMIDINFO pI)
{
UINT32 dCmd;
UINT32 dCmd2;
UINT32 dSize;
UINT32 dTemp;
UINT32 dTime;
SINT32 sdTotalTicks;
SINT32 sdCurrentTime;
SINT32 sdDelta;
PMIDCHINFO pCh;
UINT32 dCh;
UINT32 dSetup; /* bit0:beat@0, bit1:tempo@0, bit2:GmOn@0, bit3:tempo@1 */
PTRACKINFO pMt;
SINT32 sdTr;
static UINT32 dBank[16];
static UINT32 dCurrBank[16];
MASMFCNV_DBGMSG(("MaMidCnv : GetSMFInfo\n"));
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -