📄 masnddrv.c
字号:
static UINT32 GetMa5FmPitch(UINT32 dBank, UINT32 dProg, UINT32 dKey)
{
UINT32 dIndex;
UINT32 dFnum;
dIndex = (dBank & 0x80) + dProg;
dFnum = (gpdMa5FmRate[dIndex])[dKey & MASNDDRV_MASK_KEY];
return (dFnum);
}
/****************************************************************************
* GetMa3WtPitch
*
* Description:
* Calc Block&Fnum. (WT/MA-3)
* Argument:
* dFs Base Freq[Hz] (1..48000)
* dBank NoteOn Bank# (0..255)
* dProg NoteOn Prog# (0..127)
* dKey RealKey (0..127)
* Return:
* (BLOCK << 10) + FNUM
****************************************************************************/
static UINT32 GetMa3WtPitch(UINT32 dFs, UINT32 dBank, UINT32 dProg, UINT32 dKey)
{
UINT32 dIndex;
UINT32 dMaScale;
UINT32 dKeyScale;
UINT32 dBlock;
UINT32 dFnum;
dIndex = (dBank & 0x80) + dProg;
dMaScale = ((dFs * 0x0800L) / 48000L + 1L) >> 1;
dKeyScale = (gpdMa3WtRate[dIndex])[dKey & MASNDDRV_MASK_KEY];
dMaScale = (dMaScale * dKeyScale) >> 10;
if (dMaScale < 0x0400L)
{
if (dMaScale > 0x0020)
{
dBlock = gdBlockTable[dMaScale >> 5];
dFnum = (dMaScale << (5 - dBlock)) & 0x3FF;
}
else
{
dBlock = 0;
dFnum = 1;
}
}
else
{
dBlock = 5;
dFnum = 0;
}
dFnum += dBlock << 10;
if (dFnum == 0) dFnum = 1;
return (dFnum);
}
/****************************************************************************
* GetMa5WtPitch
*
* Description:
* Calc Block&Fnum. (WT/MA-5)
* Argument:
* dFs Base Freq[Hz] (1..48000)
* dBank NoteOn Bank# (0..255)
* dProg NoteOn Prog# (0..127)
* dKey RealKey (0..127)
* Return:
* (BLOCK << 10) + FNUM
****************************************************************************/
static UINT32 GetMa5WtPitch(UINT32 dFs, UINT32 dBank, UINT32 dProg, UINT32 dKey)
{
UINT32 dIndex;
UINT32 dMaScale;
UINT32 dKeyScale;
UINT32 dBlock;
UINT32 dFnum;
dIndex = (dBank & 0x80) + dProg;
dMaScale = ((dFs * 0x10000L) / 24000L + 1L) >> 1;
dKeyScale = (gpdMa5WtRate[dIndex])[dKey & MASNDDRV_MASK_KEY];
dMaScale = dMaScale * dKeyScale;
if (dMaScale < 0x80000000L)
{
if (dMaScale > 0x04000000L)
{
dIndex = (dMaScale + (1L << 15)) >> 16;
dBlock = gdBlockTable[dIndex >> 10];
dFnum = (dIndex >> dBlock) & 0x3FF;
}
else
{
dBlock = 0;
dFnum = 1;
}
}
else
{
dBlock = 5;
dFnum = 0;
}
dFnum += dBlock << 10;
if (dFnum == 0) dFnum = 1;
return (dFnum);
}
/*--------------------------------------------------------------------------*
Functions
*--------------------------------------------------------------------------*/
/****************************************************************************
* UpdataStreamStatus
*
* Description:
* Update stream playing status
* Argument:
* none
* Return:
* 0 success
* 1 error
*
****************************************************************************/
static SINT32 UpdateStreamStatus(void)
{
PMASNDDRVSTMCTRLINFO psStreamCtrlInfo;
psStreamCtrlInfo = &gpMaSndDrvInfo->sStreamCtrlInfo;
/* ch #1 */
if( psStreamCtrlInfo->dType[1]!=0 )
{
switch( psStreamCtrlInfo->dType[1] )
{
/* mono OFF */
case 0x01:
/* mono#1 Off */
psStreamCtrlInfo->dStreamStatus &= ~(MASNDDRV_STMSTAT_MONO1);
break;
/* mono ON */
case 0x81:
/* stereo Off */
psStreamCtrlInfo->dStreamStatus &= ~(MASNDDRV_STMSTAT_STEREO);
/* mono#1 On */
psStreamCtrlInfo->dStreamStatus |= MASNDDRV_STMSTAT_MONO1;
/* save waveId */
psStreamCtrlInfo->dWaveId[1] = psStreamCtrlInfo->dRamVal[1];
break;
}
}
/* ch #0 */
if( psStreamCtrlInfo->dType[0]!=0 )
{
switch( psStreamCtrlInfo->dType[0] )
{
/* mono OFF */
case 0x01:
/* mono#0 Off */
psStreamCtrlInfo->dStreamStatus &= ~(MASNDDRV_STMSTAT_MONO0);
break;
/* stereo OFF */
case 0x02:
/* stereo Off */
psStreamCtrlInfo->dStreamStatus &= ~(MASNDDRV_STMSTAT_STEREO);
break;
/* mono ON */
case 0x81:
/* stereo Off */
psStreamCtrlInfo->dStreamStatus &= ~(MASNDDRV_STMSTAT_STEREO);
/* mono#0 On */
psStreamCtrlInfo->dStreamStatus |= MASNDDRV_STMSTAT_MONO0;
/* save waveId */
psStreamCtrlInfo->dWaveId[0] = psStreamCtrlInfo->dRamVal[0];
break;
/* stereo ON */
case 0x82:
/* mono#0/mono#1 Off */
psStreamCtrlInfo->dStreamStatus &= ~(MASNDDRV_STMSTAT_MONO0|MASNDDRV_STMSTAT_MONO1);
/* stereo On */
psStreamCtrlInfo->dStreamStatus |= MASNDDRV_STMSTAT_STEREO;
/* save waveId */
psStreamCtrlInfo->dWaveId[0] = psStreamCtrlInfo->dRamVal[0];
break;
}
}
return MASMW_SUCCESS;
}
/****************************************************************************
* SendDelayedPacket
*
* Description:
* Send the delayed packet.
* Argument:
* pbPacket pointer to the packet data
* dPacketSize size of the packet data
* Return:
* 0 success
* 1 save to queue
* < 0 error code
*
****************************************************************************/
static SINT32 SendDelayedPacket
(
UINT8 * pbPacket, /* pointer to the packet */
UINT32 dPacketSize /* size of the packet */
)
{
PMASNDDRVSEQBUFINFO psSeqbufInfo;
MASNDDRV_DBGMSG(("SendDelayedPacket: ptr=%p sz=%ld\n", pbPacket, dPacketSize));
psSeqbufInfo = &gpMaSndDrvInfo->sSeqbufInfo;
if ( ( psSeqbufInfo->dBufSize < dPacketSize ) || ( psSeqbufInfo->bQueueFlag == 1 ) )
{
machdep_memcpy( &(psSeqbufInfo->bQueue[psSeqbufInfo->dQueueWPtr]), pbPacket, dPacketSize );
psSeqbufInfo->bQueueFlag = 1;
psSeqbufInfo->dQueueSize += dPacketSize;
psSeqbufInfo->dQueueWPtr += dPacketSize;
return 1;
}
/* write a packet to the soft buffer */
if ( psSeqbufInfo->pbBufPtr == NULL ) return MASMW_ERROR;
machdep_memcpy( psSeqbufInfo->pbBufPtr, pbPacket, dPacketSize );
psSeqbufInfo->pbBufPtr += dPacketSize;
psSeqbufInfo->dBufSize -= dPacketSize;
psSeqbufInfo->dWroteSize += dPacketSize;
return MASMW_SUCCESS;
}
/****************************************************************************
* GetVoiceInfo
*
* Description:
* Return the voice information.
* Arguments:
* sdSeqId sequence id (0..1)
* dCh channel number (0..15)
* dKey key number (0..127)
* psVoiceInfo pointer to the voice information
* Return:
* voice information:
* key number or base frequency (48[KHz] = 1.0[0x0400])
* internal RAM address
* type of synthesize (1:FM, 2:WT)
*
****************************************************************************/
static SINT32 GetVoiceInfo
(
SINT32 sdSeqId, /* sequence id */
UINT32 dCh, /* channel number */
UINT32 dKey, /* key number */
PMASNDDRVVINFO psVoiceInfo /* voice information */
)
{
UINT32 dBankNo; /* bank number */
UINT32 dProgNo; /* program number */
UINT32 dBankProg; /* bank & program number */
UINT32 dType; /* type */
UINT32 i; /* loop counter */
SINT32 sdResult; /* result of function */
MASMW_ASSERT( sdSeqId <= MASMW_SEQTYPE_DIRECT );
dBankNo = (UINT32)gpMaSndDrvInfo->sChInfo[dCh].bBankNo;
dProgNo = (UINT32)( ( ( dBankNo < 128 ) ? gpMaSndDrvInfo->sChInfo[dCh].bProgNo : dKey ) & MASNDDRV_MASK_PROGRAM );
if ( dBankNo < 128 )
{
dType = 0;
dBankProg = (dBankNo << 7) + dProgNo;
}
else
{
dType = MASNDDRV_MAX_REG_VOICE;
dBankProg = ((dBankNo - 128 + MASNDDRV_MAX_RAM_BANK) << 7) + dProgNo;
}
if ( ( dBankNo & 0x7f ) < MASNDDRV_MAX_RAM_BANK )
{
if ( gpMaSndDrvInfo->bVoiceIndex[dBankProg] != 0xff )
{
/*--- Yes, Voice Info in RAM ---------*/
i = gpMaSndDrvInfo->bVoiceIndex[dBankProg];
psVoiceInfo->bSynth = gpMaSndDrvInfo->sVoiceInfo[sdSeqId][i].bSynth;
psVoiceInfo->wKey = gpMaSndDrvInfo->sVoiceInfo[sdSeqId][i].wKey;
psVoiceInfo->wAddress = (UINT16)(gpMaSndDrvInfo->sVoiceInfo[sdSeqId][i].wRamAdrs >> 1);
return MASMW_SUCCESS;
}
}
if ( gpMaSndDrvInfo->sSndDrvInfo[sdSeqId].bDrumType != 0 )
{
if ( dBankNo >= 128 )
{
if ( ( dProgNo < MASNDDRV_MIN_GML1_DRUM ) || ( MASNDDRV_MAX_GML1_DRUM < dProgNo ) )
{
return MASMW_ERROR;
}
}
}
sdResult = MaResMgr_GetDefVoiceSynth( dType + dProgNo );
if ( sdResult <= 0 )
return MASMW_ERROR;
else
psVoiceInfo->bSynth = (UINT8)sdResult;
if ( dType == MASNDDRV_MAX_REG_VOICE )
{
sdResult = MaResMgr_GetDefVoiceKey( dType + dProgNo );
if ( sdResult <= 0 )
return MASMW_ERROR;
else
psVoiceInfo->wKey = (UINT16)sdResult;
}
sdResult = MaResMgr_GetDefVoiceAddress( dType + dProgNo );
if ( sdResult <= 0 )
return MASMW_ERROR;
else
psVoiceInfo->wAddress = (UINT16)(sdResult >> 1);
return MASMW_SUCCESS;
}
/****************************************************************************
* CalcChVolume
*
* Description:
* Calculate the channel volume.
* Arguments:
* dCh channnel number (0..15)
* Return:
* Channel volume value.
*
****************************************************************************/
static UINT32 CalcChVolume
(
UINT32 dCh /* channel number */
)
{
UINT32 dDb;
UINT32 dVolume;
dDb = (UINT32)db_table[gpMaSndDrvInfo->sChInfo[dCh].bVolume];
dDb = (UINT32)( dDb + db_table[gpMaSndDrvInfo->sChInfo[dCh].bExpression] );
if ( dDb > (UINT32)MASNDDRV_MAX_DB ) dDb = (UINT32)MASNDDRV_MAX_DB;
dVolume = vol_table[dDb];
return dVolume;
}
/****************************************************************************
* CalcVoiceVolume
*
* Description:
* Calculate the channel volume.
* Arguments:
* sdSeqId sequence id (0..2)
* dVol volume (0..127)
* dOffset offset value
* Return:
* volume value of slot (0..127).
*
****************************************************************************/
static UINT32 CalcVoiceVolume
(
SINT32 sdSeqId, /* sequence id */
UINT32 dVol, /* volume value */
UINT32 dOffset /* offset value */
)
{
UINT32 dDb;
UINT32 dVolume;
dDb = db_table[dVol];
dDb = dDb + db_table[gpMaSndDrvInfo->sSndDrvInfo[sdSeqId].bMasterVolume];
dDb = ( dDb >= dOffset) ? (dDb - dOffset) : 0;
if ( dDb > MASNDDRV_MAX_DB ) dDb = MASNDDRV_MAX_DB;
dVolume = vol_table[dDb];
return dVolume;
}
/****************************************************************************
* MakeDeltaTime
*
* Description:
* make packet of delta time part
* Arguments:
* pbPacket
* sdDeltaTime
* Return:
* number of packet
*
****************************************************************************/
static UINT32 MakeDeltaTime( UINT8 * pbPacket, SINT32 sdDeltaTime )
{
UINT32 dNum = 0;
if ( sdDeltaTime < 0 ) return dNum;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -