📄 masnddrv.c
字号:
#include "pccdef.h"
#include "predef.h"
#include "Masnddrv.h"
#include "table.h"
/***************************************/
/* seciton1 is Exclusize Event process */
/***************************************/
/****************************************************************/
/* Function Name : MaSndDrv_SetVoice */
/* Description : make voice info for RAM note */
/* Note : used as RAM voice info for MaSndDrv_NoteOn */
/* and GetVoiceInfo */
/****************************************************************/
SINT32 MaSndDrv_SetVoice
(
UINT8 bank_no, /* bank number */
UINT8 program_no, /* program number */
UINT32 key, /* key number */
UINT32 ram_adrs /* ram address */
)
{
UINT32 state = 0;
UINT16 bank_prog; /* bank & program number */
UINT32 i;
SINT32 result = MASMW_SUCCESS;
if ((bank_no & 0x7f) >= MA_MAX_RAM_BANK)
return MASMW_ERROR;
if ( program_no > MASMW_MAX_PROGRAM )
return MASMW_ERROR;
if ( ( ( ram_adrs < MA_RAM_START_ADDRESS ) || ( MA_RAM_END_ADDRESS < ram_adrs ) ) )
return MASMW_ERROR;
if ( bank_no < 128 )
{
bank_prog = (UINT16)(((UINT16)bank_no << 7) + (UINT16)program_no);
}
else
{
bank_prog = (UINT16)(((UINT16)(bank_no - 128 + MA_MAX_RAM_BANK) << 7) + (UINT16)program_no);
}
if (ma_voice_index[bank_prog] == 0xff)
{
state = 1;
/*--- 1st Try ----*/
i = (bank_no & 0x80) + program_no;
if ( ma_voice_info[i].ram_adrs == 0xFFFF )
{
state = 1;
ma_voice_info[i].synth = 1;
ma_voice_info[i].key = (UINT16)key;
ma_voice_info[i].ram_adrs = (UINT16)ram_adrs;
ma_voice_index[bank_prog] = (UINT8)i;
}
else
{
for ( i = 0; i < (MA_MAX_REG_VOICE * 2 - 1); i++ )
{
if ( ma_voice_info[i].ram_adrs == 0xFFFF )
{
state = 1;
ma_voice_info[i].synth = 1;
ma_voice_info[i].key = (UINT16)key;
ma_voice_info[i].ram_adrs = (UINT16)ram_adrs;
ma_voice_index[bank_prog] = (UINT8)i;
break;
}
}
}
}
if ( state == 0 )
result = MASMW_ERROR;
return result;
}
/************************************************/
/* seciton2 is Initialization for Event process */
/************************************************/
/******************************************************************/
/* Function Name : MaSndDrv_Create */
/* Descrption : make initialize value for interstate */
/* Note : Allocate Sequencer and Timer1 */
/* set FM Mode (Control Reg #359) */
/* something about Ram data */
/******************************************************************/
SINT32 MaSndDrv_Create
(
UINT8 timebase, /* time base */
UINT8 cnv_mode, /* convert mode */
UINT8 sa_num, /* number of stream audio */
UINT32 *ram_adrs, /* ram address */
UINT32 *ram_size /* ram size */
)
{
UINT16 i;
UINT8 ch; /* channel number */
UINT8 slot_no; /* slot number */
UINT8 fm_ext_num; /* number of FM EXT voices */
UINT32 ch_map; /* bit mapping for channel */
UINT32 fm_map; /* bit mapping for FM voices */
UINT32 wt_map; /* bit mapping for WT voices */
UINT32 rb_map; /* bit mapping for RAM blocks */
UINT32 sa_map; /* bit mapping for Stream Audio */
SINT32 result; /* result of allocate resources */
UINT32 ram_address;
UINT16 base_time;
UINT8 packet[5];
static UINT32 res_map[3] = { 0x00000000, 0x00000001, 0x00000003 };
static UINT32 msk_map[3] = { 0xFFFFFFFF, 0xFFFFFF7F, 0xFFFFFF3F };
if (timebase > 10)
{
timebase = 10;
/*bTimeBaseR = (UINT8)(timebase / 10);*/
}
/* Check time_base */
if ( ( MASMW_MIN_DLY_BASETIME > timebase ) || ( timebase > MASMW_MAX_DLY_BASETIME ) )
return MASMW_ERROR;
/*result = MaResMgr_AllocSequencer( ma_timebase[time_base-1] );*/
base_time = ma_timebase[timebase-1];
packet[0] = (UINT8)( MA_SEQUENCE & 0x7F ); /* address */
packet[1] = (UINT8)( (MA_SEQUENCE >> 7) | 0x80 );
packet[2] = (UINT8)( (base_time >> 7) & 0x7F ); /* data */
packet[3] = (UINT8)( base_time & 0x7F );
packet[4] = (UINT8)( MA_INT_POINT | 0x80 );
result = MaDevDrv_SendDirectPacket( packet, 5 );
if ( result != MASMW_SUCCESS )
{
return result;
}
/*result = MaResMgr_AllocTimer( 2, 0, 100, 1, 0 ); Time #1 */
packet[0] = (UINT8)( MA_TIMER_1_TIME & 0x7F ); /* address */
packet[1] = (UINT8)( (MA_TIMER_1_TIME >> 7) | 0x80 );
packet[2] = (UINT8)( 100 & 0x7F ); /* time count = 100 */
/* mode=1(for sequencer) oneshot=0(continous counting) star=1 */
packet[3] = (UINT8)( 0x5 | 0x80 );
result = MaDevDrv_SendDirectPacket( packet, 4 );
if ( result != MASMW_SUCCESS )
{
return result;
}
fm_ext_num = 0;
if ( ( cnv_mode & 0x20 ) == 0x20 )
{
fm_ext_num = 16; /* 2OP - 32 voices */
}
if( fm_ext_num ==16 )
{
/* set FM Mode 1 (2OP 32vovice) */
packet[0] = (UINT8)( MA_FM_MODE & 0x7F ); /* address */
packet[1] = (UINT8)( (MA_FM_MODE >> 7) | 0x80 );
packet[2] = (UINT8)( 0x81 ); /* data */
MaDevDrv_SendDirectPacket( packet, 3 );
}
else
{
/* set FM Mode 0 (4OP 16vovice) */
packet[0] = (UINT8)( MA_FM_MODE & 0x7F ); /* address */
packet[1] = (UINT8)( (MA_FM_MODE >> 7) | 0x80 );
packet[2] = (UINT8)( 0x80 ); /* data */
MaDevDrv_SendDirectPacket( packet, 3 );
}
/* Initialize volume */
ma_snddrv_info.master_volume = (UINT8)100;
ma_snddrv_info.ctrl_volume = (UINT8)100;
/* Initialize slot_list */
ma_snddrv_info.min_slot[0] = (UINT8)0;
ma_snddrv_info.max_slot[0] = (UINT8)(0 + 16 + fm_ext_num - 1);
ma_snddrv_info.min_slot[1] = (UINT8)32;
ma_snddrv_info.max_slot[1] = (UINT8)(32 + 8 - sa_num - 1);
if ( sa_num != 0 )
{
ma_snddrv_info.min_slot[2] = (UINT8)40;
ma_snddrv_info.max_slot[2] = (UINT8)(40 + sa_num - 1);
}
for ( i = 0; i < 3; i++ )
{
ma_slot_list.top[i] = ma_snddrv_info.min_slot[i];
ma_slot_list.end[i] = ma_snddrv_info.max_slot[i];
}
for ( i = 0; i < 42; i++ )
{
ma_slot_list.next[i] = (UINT8)(i + 1);
}
/* Initialize slot_info */
fm_map = 0x0000FFFF;
wt_map = 0x000000FF & msk_map[sa_num];
rb_map = 0x000000FF & msk_map[sa_num];
sa_map = res_map[sa_num];
ram_address = 0;
for ( i = 0; i < 8; i++ )
{
if ( ( rb_map & (1 << i) ) != 0 )
{
ram_address = i * MA_RAM_BLOCK_SIZE + MA_RAM_START_ADDRESS + 16;
break;
}
}
if ( ( ram_adrs != NULL ) && ( ram_size != NULL ) && ( ram_address != 0 ) )
{
*ram_adrs = ram_address;
*ram_size = 8 * MA_RAM_BLOCK_SIZE - 16;
}
for ( slot_no = 0; slot_no < (16 + fm_ext_num); slot_no++ )
{
if ( ( fm_map & (UINT32)(1 << slot_no) ) != 0 )
{
ma_slot_info[slot_no].ch = 0;
}
}
for ( slot_no = 0; slot_no < (8- sa_num); slot_no++ )
{
if ( ( wt_map & (UINT32)(1 << slot_no) ) != 0 )
{
ma_slot_info[slot_no+32].ch = 0;
}
}
for ( slot_no = 0; slot_no < sa_num; slot_no++ )
{
if ( ( sa_map & (UINT32)(1 << slot_no) ) != 0 )
{
ma_slot_info[slot_no+40].ch = 0;
}
}
/* Initialize channel_info */
for ( ch = 0; ch < MASMW_NUM_CHANNEL; ch++ )
{
ma_channel_info[ch].bank_no = (UINT8)( ( ch == 9 ) ? 128 : 0 );
ma_channel_info[ch].prog_no = (UINT8)0;
ma_channel_info[ch].poly = (UINT8)MA_MODE_POLY; /* Controlled by 0xBn0x7E/0x7F */
ma_channel_info[ch].volume = (UINT8)100;
ma_channel_info[ch].bend_range = (UINT8)2;
ma_channel_info[ch].expression = (UINT8)127;
ma_channel_info[ch].sfx = (UINT8)0;
ma_channel_info[ch].note_on = (UINT8)0;
}
/* Initialize voice info */
for ( i = 0; i < MA_MAX_REG_VOICE*2; i++ )
{
ma_voice_info[i].ram_adrs = (UINT16)0xFFFF;
}
for (ch_map = 0; ch_map < (MA_MAX_RAM_BANK * 2 * 128); ch_map++)
{
ma_voice_index[ch_map] = 0xFF;
}
/* Send initialization data */
result = MaDevDrv_SendDirectRamData( (ram_address - 16), 0, &ma_woodblk[0], 16 );
if ( result != MASMW_SUCCESS )
return result;
result = MaSndDrv_SetVoice( 0, 115, 0, (ram_address - 16) );
if ( result != MASMW_SUCCESS )
return result;
return MASMW_SUCCESS;
}
/*************************************/
/* section3 is Control Event process */
/*************************************/
/**************************************************************/
/* Function Name : MaSndDrv_Nop */
/* Description : Make nop operation */
/* Event type : 0xFF0x00 */
/* Note : NOP_1 process time = 1/64 fs (326ns) */
/* NOP_2 process time = 2fs~3fs (41.7us~62.5us) */
/* Cotrol Event usually use NOP_1 as processing time */
/**************************************************************/
SINT32 MaSndDrv_Nop
(
SINT32 delta_time, /* delta time */
UINT32 type /* NOP type */
)
{
UINT32 num; /* number of packet data */
UINT32 reg_index; /* register index number */
SINT32 result; /* result of function */
/* Make packet data */
num = MakeDeltaTime( &packet_buf[0], delta_time ); /* timer part */
reg_index = (UINT32)( ( type == 0 ) ? MA_NOP_1 : MA_NOP_2 );
packet_buf[num++] = (UINT8)( reg_index & 0x7F ); /* address part */
packet_buf[num++] = (UINT8)( (reg_index >> 7) | 0x80 );
packet_buf[num++] = (UINT8)0x80; /* data part */
if ( delta_time < 0 ) /* direct command */
{
result = MaDevDrv_SendDirectPacket( &packet_buf[0], num );
}
else /* delayed command */
{
result = MaDevDrv_SendDelayedPacket( &packet_buf[0], num );
}
return result;
}
/*****************************************************************/
/* Function Group Name : Channel_vol */
/* Description : make channel volume */
/* Event type : 0xBn0x07... */
/* Member Function: CalcChVolume , MaSndDrv_ChannelVolume . */
/* Note : default vol = 0x64 */
/*****************************************************************/
UINT8 CalcChVolume
(
UINT32 ch /* channel number */
)
{
UINT32 db;
UINT8 volume;
db = (UINT32)db_table[ma_channel_info[ch].volume];
db = (UINT32)( db + db_table[ma_channel_info[ch].expression] );
if ( db > (UINT32)MASMW_MAX_DB )
db = (UINT32)MASMW_MAX_DB;
volume = vol_table[db];
return volume;
}
SINT32 MaSndDrv_ChannelVolume
(
SINT32 delta_time, /* delta time */
UINT32 ch, /* channel number */
UINT32 vol /* volume value */
)
{
UINT8 volume; /* volume */
UINT32 num; /* number of packet data */
UINT32 reg_index; /* register index number */
SINT32 result; /* result of function */
/* updata channel information */
ma_channel_info[ch].volume = (UINT8)(vol & MASMW_MASK_VOLUME);
volume = CalcChVolume( ch );
/* Make packet data and send it */
num = MakeDeltaTime( &packet_buf[0], delta_time );
reg_index = (UINT32)(MA_CHANNEL_VOLUME + ch);
/*MAKE_ADDRESS_PART( seq_id, num, reg_index )*/
packet_buf[num++] = (UINT8)( reg_index & 0x7F );
packet_buf[num++] = (UINT8)( (reg_index >> 7) | 0x80 );
/*MAKE_CHANNEL_VOLUME( seq_id, num, volume )*/
packet_buf[num++] = (UINT8)( (volume & 0x7C) | 0x80 );
if ( delta_time < 0 ) /* direct command */
{
result = MaDevDrv_SendDirectPacket( &packet_buf[0], num );
}
else /* delayed command */
{
result = MaDevDrv_SendDelayedPacket( &packet_buf[0], num );
}
return result;
}
/*******************************************************************/
/* Function Name : MaSndDrv_Panpot */
/* Description : Set panpot of the specificated channel */
/* Event type : 0xBn0x0A... */
/* Note : default value 0x40 */
/*******************************************************************/
SINT32 MaSndDrv_Panpot
(
SINT32 delta_time, /* delta time */
UINT32 ch, /* channel number */
UINT32 pan /* pan */
)
{
UINT32 num; /* number of packet data */
UINT32 reg_index; /* register index number */
SINT32 result; /* result of function */
/* check arguments */
if(( ch > MASMW_MAX_CHANNEL )||( pan > MASMW_MAX_PAN ))
return MASMW_ERROR;
/* Make packet data and send it */
num = MakeDeltaTime( &packet_buf[0], delta_time );
reg_index = (UINT32)(MA_CHANNEL_PANPOT + ch);
/*MAKE_ADDRESS_PART( seq_id, num, reg_index )*/
packet_buf[num++] = (UINT8)( reg_index & 0x7F );
packet_buf[num++] = (UINT8)( (reg_index >> 7) | 0x80 );
/*MAKE_PANPOT( seq_id, num, pan )*/
packet_buf[num++] = (UINT8)( (pan & 0x7C) | 0x80 );
if ( delta_time < 0 ) /* direct command */
{
result = MaDevDrv_SendDirectPacket( &packet_buf[0], num );
}
else /* delayed command */
{
result = MaDevDrv_SendDelayedPacket( &packet_buf[0], num );
}
return result;
}
/****************************************************************/
/* Function Name : MaSndDrv_Expression */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -