⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 masnddva.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
 *
 *		Copyright (C) 2002-2003	YAMAHA CORPORATION. All rights reserved.
 *
 *		Module		: masnddva.c
 *
 *		Description	: DVA module for MA Sound Driver
 *
 *		Version		: 1.0.2 	2003.06.16
 *
 ****************************************************************************/

#include "masnddva.h"

/*--------------------------------------------------------------------------*/
/*   Defines                                                                */
/*--------------------------------------------------------------------------*/
#define	DVA_NUM_CH		16							/* Number of Channnels (== 16)		*/
#define	DVA_NUM_ALT		6							/* Number of Alternate Drums + 1	*/
#define DVA_NUM_FM		32							/* Number of FM slots (== 32)		*/
#define	DVA_NUM_WT		32							/* Number of WT slots (== 32)		*/
#define	DVA_NUM_STM		2							/* Number of STREAM slots (== 2)	*/
#define	DVA_NUM_KEY		128							/* Number of Keys					*/
#define DVA_NUM_MAP		(DVA_NUM_CH*DVA_NUM_KEY)	/* Number of PolyOnMaps				*/

#define DVA_PMAP_FM_ON	0x80
#define DVA_PMAP_WT_ON	0xC0
#define DVA_PMAP_FM_OFF	0x00
#define DVA_PMAP_WT_OFF	0x40

#define DVA_PMAP_MASK	0x7F
#define DVA_PMAP_ONOFF	0x80
#define DVA_PMAP_ON		0x80
#define DVA_PMAP_OFF	0x00

#define DVA_PMAP_SYNTH	0x40
#define DVA_PMAP_FM		0x00
#define DVA_PMAP_WT		0x40

#define DVA_PMAP_NUM	0x3F

/*--------------------------------------------------------------------------*/
/*   Types                                                                  */
/*--------------------------------------------------------------------------*/
typedef	enum _DVACHMODE		{DVA_MONO_CH = 0, DVA_POLY_CH, DVA_DRUM_CH}		DVACHMODE;
typedef	enum _DVASLOTMODE	{DVA_MONO_SLOT = 0, DVA_POLY_SLOT}				DVASLOTMODE;
typedef	enum _DVASYNTH		{DVA_FM_SYNTH = 0, DVA_WT_SYNTH}				DVASYNTH;
typedef	enum _DVASTREAM		{DVA_MONO_STREAM = 0, DVA_STEREO_STREAM}		DVASTREAM;
typedef	enum _DVAALT		{DVA_MA3_ALT = 0, DVA_MA5_ALT}					DVAALT;
typedef	enum _DVANOTEON		{DVA_NOTE_OFF = 0, DVA_NOTE_ON, DVA_NOTE_MUTE}	DVANOTEON;
typedef	enum _DVASTMON		{DVA_STREAM_OFF = 0, DVA_STREAM_ON}				DVASTMON ;

typedef	struct _tagSlotInfo{
	struct _tagSlotInfo*	pNext;
	struct _tagSlotInfo*	pPrev;
	UINT32					dKeyCh;				/* ((NoteOn Key) << 4) + (NoteOn Ch) */
	DVASLOTMODE				Mode;
	DVANOTEON				NoteOn;
	UINT32					dSlotId;
	UINT32					dIndex;
} SLOTINFO, *PSLOTINFO;

typedef	struct _tagChMap{
	DVACHMODE				Mode;
	DVASYNTH				MonoSynth;
	UINT32					dMonoSlot;
	SINT32					sdMonoOn;
} CHMAP, *PCHMAP;

typedef	struct _tagStreamInfo{
	DVASTMON				NoteOn;
	UINT32					dIndex;
	DVASTREAM				Stereo;
} STREAMINFO, *PSTREAMINFO;

typedef	struct _tagDvaGlobals{
	struct _tagSlotInfo		FmSlotInfo[DVA_NUM_FM + 3];
	struct _tagSlotInfo		WtSlotInfo[DVA_NUM_WT + 3];
	struct _tagStreamInfo	StreamSlotInfo[DVA_NUM_STM];
	struct _tagChMap		ChMap[DVA_NUM_CH];
	UINT8					bPolyOnMap[DVA_NUM_MAP];
	SINT32					sdAlt3Map[DVA_NUM_ALT];
	SINT32					sdAlt5Map[DVA_NUM_ALT * DVA_NUM_CH];

	struct _tagSlotInfo*	pFmSlotTop;
	struct _tagSlotInfo*	pWtSlotTop;
	struct _tagSlotInfo*	pFmSlotBottom;
	struct _tagSlotInfo*	pWtSlotBottom;
	struct _tagSlotInfo*	pFmSlotOnTop;
	struct _tagSlotInfo*	pWtSlotOnTop;

	UINT32					dStreamNextID;
	UINT32					dStreamNum;
	DVAALT					DrumAlt;
} DVAGLOBAL, *PDVAGLOBAL;

/*--------------------------------------------------------------------------*/
/*   Consts                                                                 */
/*--------------------------------------------------------------------------*/
static const UINT32	gdAltDrumKey[128] = {
						0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
						10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
						20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
						30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
						40, 41, 42, 43, 42, 45, 42, 47, 48, 49,
						50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
						60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
						70, 71, 71, 73, 73, 75, 76, 77, 78, 78,
						80, 80, 82, 83, 84, 85, 86, 87, 88, 89,
						90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
						100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
						110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
						120, 121, 122, 123, 124, 125, 126, 127};

static const UINT8	gbIsAltDrum[128] = {
						0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
						0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
						0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
						0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
						0, 0, 1, 0, 1, 0, 1, 0, 0, 0,
						0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
						0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
						0, 2, 2, 3, 3, 0, 0, 0, 4, 4,
						5, 5, 0, 0, 0, 0, 0, 0, 0, 0,
						0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
						0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
						0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
						0, 0, 0, 0, 0, 0, 0, 0};

/*---------------------------------------------------------------------------*/
/*   Globals                                                                 */
/*---------------------------------------------------------------------------*/
static DVAGLOBAL	gDvaInfo;
static PDVAGLOBAL	gpDvaInfo;


/*---------------------------------------------------------------------------*/
/*   Functions (internal use only)                                           */
/*---------------------------------------------------------------------------*/

/****************************************************************************
 *	FmTurnOn
 *
 *	Description:
 *			Turn FM-slot on.
 *	Argument:
 *			pSlot		Slot, should be ON.
 *	Return:
 *			none
 ****************************************************************************/
static void FmTurnOn(PSLOTINFO pSlot)
{
	PSLOTINFO pTerget;

	pSlot->NoteOn = DVA_NOTE_ON;
	
	(pSlot->pPrev)->pNext = pSlot->pNext;
	(pSlot->pNext)->pPrev = pSlot->pPrev;
	
	pTerget = gpDvaInfo->pFmSlotBottom->pPrev;
	pTerget->pNext = pSlot;
	pSlot->pPrev = pTerget;
	pTerget = gpDvaInfo->pFmSlotBottom;
	pTerget->pPrev = pSlot;
	pSlot->pNext = pTerget;
}


/****************************************************************************
 *	FmTurnOff
 *
 *	Description:
 *			Turn FM-slot off.
 *	Argument:
 *			pSlot		Slot, should be OFF.
 *	Return:
 *			none
 ****************************************************************************/
static void FmTurnOff(PSLOTINFO pSlot)
{
	PSLOTINFO pTerget;

	if (pSlot->NoteOn != DVA_NOTE_ON)
	{
		return;
	}

	pSlot->NoteOn = DVA_NOTE_OFF;

	(pSlot->pPrev)->pNext = pSlot->pNext;
	(pSlot->pNext)->pPrev = pSlot->pPrev;

	pTerget = gpDvaInfo->pFmSlotOnTop->pPrev;
	pTerget->pNext = pSlot;
	pSlot->pPrev = pTerget;
	pTerget = gpDvaInfo->pFmSlotOnTop;
	pTerget->pPrev = pSlot;
	pSlot->pNext = pTerget;
}


/****************************************************************************
 *	FmMute
 *
 *	Description:
 *			Kill FM-slot.
 *	Argument:
 *			pSlot		Slot, should be MUTE.
 *	Return:
 *			none
 ****************************************************************************/
static void FmMute(PSLOTINFO pSlot)
{
	PSLOTINFO pTerget;

	pSlot->NoteOn = DVA_NOTE_MUTE;

	(pSlot->pPrev)->pNext = pSlot->pNext;
	(pSlot->pNext)->pPrev = pSlot->pPrev;

	pTerget = gpDvaInfo->pFmSlotTop->pNext;
	pTerget->pPrev = pSlot;
	pSlot->pNext = pTerget;
	pTerget = gpDvaInfo->pFmSlotTop;
	pTerget->pNext = pSlot;
	pSlot->pPrev = pTerget;
}


/****************************************************************************
 *	WtTurnOn
 *
 *	Description:
 *			Turn Wt-slot on.
 *	Argument:
 *			pSlot		Slot, should be ON.
 *	Return:
 *			none
 ****************************************************************************/
static void WtTurnOn(PSLOTINFO pSlot)
{
	PSLOTINFO pTerget;

	pSlot->NoteOn = DVA_NOTE_ON;
	
	(pSlot->pPrev)->pNext = pSlot->pNext;
	(pSlot->pNext)->pPrev = pSlot->pPrev;
	
	pTerget = gpDvaInfo->pWtSlotBottom->pPrev;
	pTerget->pNext = pSlot;
	pSlot->pPrev = pTerget;
	pTerget = gpDvaInfo->pWtSlotBottom;
	pTerget->pPrev = pSlot;
	pSlot->pNext = pTerget;
}


/****************************************************************************
 *	WtTurnOff
 *
 *	Description:
 *			Turn WT-slot off.
 *	Argument:
 *			pSlot		Slot, should be OFF.
 *	Return:
 *			none
 ****************************************************************************/
static void WtTurnOff(PSLOTINFO pSlot)
{
	PSLOTINFO pTerget;

	if (pSlot->NoteOn != DVA_NOTE_ON)
	{
		return;
	}

	pSlot->NoteOn = DVA_NOTE_OFF;

	(pSlot->pPrev)->pNext = pSlot->pNext;
	(pSlot->pNext)->pPrev = pSlot->pPrev;

	pTerget = gpDvaInfo->pWtSlotOnTop->pPrev;
	pTerget->pNext = pSlot;
	pSlot->pPrev = pTerget;
	pTerget = gpDvaInfo->pWtSlotOnTop;
	pTerget->pPrev = pSlot;
	pSlot->pNext = pTerget;
}


/****************************************************************************
 *	WtMute
 *
 *	Description:
 *			Kill WT-slot.
 *	Argument:
 *			pSlot		Slot, should be MUTE.
 *	Return:
 *			none
 ****************************************************************************/
static void WtMute(PSLOTINFO pSlot)
{
	PSLOTINFO pTerget;

	pSlot->NoteOn = DVA_NOTE_MUTE;

	(pSlot->pPrev)->pNext = pSlot->pNext;
	(pSlot->pNext)->pPrev = pSlot->pPrev;

	pTerget = gpDvaInfo->pWtSlotTop->pNext;
	pTerget->pPrev = pSlot;
	pSlot->pNext = pTerget;
	pTerget = gpDvaInfo->pWtSlotTop;
	pTerget->pNext = pSlot;
	pSlot->pPrev = pTerget;
}


/*---------------------------------------------------------------------------*/
/*   Functions                                                               */
/*---------------------------------------------------------------------------*/

/****************************************************************************
 *	MaDva_Initialize
 *
 *	Description:
 *			Initialize DVA module.
 *	Argument:
 *			dAl			Number of AL voices.		(0..1)
 *			dFm			Number of FM voices.		(16/32)
 *			dWt			Number of WT voices.		(6/7/8/16/32)
 *			dStream		Number of STREAM voices.	(0..2)
 *			dAlt		Alternate drum mode.		(0: MA-3, 1:MA-5)
 *	Return:
 *			MASMW_SUCCESS	if Success
 *			MASMW_ERROR		if Error
 ****************************************************************************/
SINT32 MaDva_Initialize(UINT32 dAl, UINT32 dFm, UINT32 dWt, UINT32 dStream, UINT32 dAlt)
{
	UINT32		i;
	PSLOTINFO	pSlot;
	PSTREAMINFO	pStm;
	PCHMAP		pCh;

	if (dAl > 1) return (MASMW_ERROR);
	if ((dFm != 16) && (dFm != 32)) return (MASMW_ERROR);
	if ((dWt != 6) && (dWt != 7) && (dWt != 8) && (dWt != 16) && (dWt != 32)) return (MASMW_ERROR);
	if (dStream > 2) return (MASMW_ERROR);
	if (dAlt > 1) return (MASMW_ERROR);

	gpDvaInfo = &gDvaInfo;
	gpDvaInfo->dStreamNum = dStream;
	gpDvaInfo->DrumAlt = (DVAALT)dAlt;
	
	for (i = 0; i < DVA_NUM_CH; i++)
	{
		pCh = &(gpDvaInfo->ChMap[i]);
		pCh->Mode = DVA_POLY_CH;
		pCh->MonoSynth = DVA_FM_SYNTH;
		pCh->sdMonoOn = 0;
		pCh->dMonoSlot = 0;
	}
	
	for (i = 0; i < DVA_NUM_MAP; i++)
	{
		gpDvaInfo->bPolyOnMap[i] = 0;
	}
	
	for (i = 0; i < DVA_NUM_ALT; i++)
	{
		gpDvaInfo->sdAlt3Map[i] = -1;
	}
	
	for (i = 0; i < DVA_NUM_ALT * DVA_NUM_CH; i++)
	{
		gpDvaInfo->sdAlt5Map[i] = -1;
	}
	
	for (i = 0; i < (DVA_NUM_FM + 3); i++)
	{
		pSlot = &(gpDvaInfo->FmSlotInfo[i]);
		pSlot->dKeyCh = 0;
		pSlot->pPrev = NULL;
		pSlot->pNext = NULL;
		pSlot->Mode = DVA_POLY_SLOT;
		pSlot->NoteOn = DVA_NOTE_MUTE;
		pSlot->dSlotId = 0;
		pSlot->dIndex = i;
	}
	
	pSlot = &(gpDvaInfo->FmSlotInfo[0]);
	pSlot->pPrev = NULL;
	pSlot->pNext = &(gpDvaInfo->FmSlotInfo[1]);
	
	pSlot = &(gpDvaInfo->FmSlotInfo[dFm - dAl + 2]);
	pSlot->pPrev = &(gpDvaInfo->FmSlotInfo[dFm - dAl + 1]);
	pSlot->pNext = NULL;
	
	for (i = 1; i < (dFm - dAl + 2); i++)
	{
		pSlot = &(gpDvaInfo->FmSlotInfo[i]);
		pSlot->pPrev = &(gpDvaInfo->FmSlotInfo[i - 1]);
		pSlot->pNext = &(gpDvaInfo->FmSlotInfo[i + 1]);
		pSlot->dSlotId = i + dAl - 1;
	}
	gpDvaInfo->pFmSlotTop = &(gpDvaInfo->FmSlotInfo[0]);
	gpDvaInfo->pFmSlotOnTop = &(gpDvaInfo->FmSlotInfo[dFm - dAl + 1]);
	gpDvaInfo->pFmSlotBottom = &(gpDvaInfo->FmSlotInfo[dFm - dAl + 2]);
	gpDvaInfo->pFmSlotOnTop->dSlotId = 0;
	
	for (i = 0; i < (DVA_NUM_WT + 3); i++)
	{
		pSlot = &(gpDvaInfo->WtSlotInfo[i]);
		pSlot->dKeyCh = 0;
		pSlot->pPrev = NULL;
		pSlot->pNext = NULL;
		pSlot->Mode = DVA_POLY_SLOT;
		pSlot->NoteOn = DVA_NOTE_MUTE;
		pSlot->dSlotId = 0;
		pSlot->dIndex = i;
	}
	
	pSlot = &(gpDvaInfo->WtSlotInfo[0]);
	pSlot->pPrev = NULL;
	pSlot->pNext = &(gpDvaInfo->WtSlotInfo[1]);
	
	pSlot = &(gpDvaInfo->WtSlotInfo[dWt - dAl + 2]);
	pSlot->pPrev = &(gpDvaInfo->WtSlotInfo[dWt - dAl + 1]);
	pSlot->pNext = NULL;
	
	for (i = 1; i < dWt - dAl + 2; i++)
	{
		pSlot = &(gpDvaInfo->WtSlotInfo[i]);
		pSlot->pPrev = &(gpDvaInfo->WtSlotInfo[i - 1]);
		pSlot->pNext = &(gpDvaInfo->WtSlotInfo[i + 1]);
		pSlot->dSlotId = i + dAl - 1;
	}
	gpDvaInfo->pWtSlotTop = &(gpDvaInfo->WtSlotInfo[0]);
	gpDvaInfo->pWtSlotOnTop = &(gpDvaInfo->WtSlotInfo[dWt - dAl + 1]);
	gpDvaInfo->pWtSlotBottom = &(gpDvaInfo->WtSlotInfo[dWt - dAl + 2]);
	gpDvaInfo->pWtSlotOnTop->dSlotId = 0;
	
	for (i = 0; i < DVA_NUM_STM; i++)
	{
		pStm = &(gpDvaInfo->StreamSlotInfo[i]);
		pStm->NoteOn = DVA_STREAM_OFF;
		pStm->Stereo = DVA_MONO_STREAM;
		pStm->dIndex = i;
	}
	gpDvaInfo->dStreamNextID = 0;
	
	return (MASMW_SUCCESS);
}


/****************************************************************************
 *	MaDva_End
 *
 *	Description:
 *			Treminate DVA module.
 *	Argument:
 *			none
 *	Return:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -