📄 masnddva.c
字号:
/****************************************************************************
*
* 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 + -