📄 masnddrv.c
字号:
else
{
key = drum_key & 0x7F ;
pitch = ma_fm_block_100[key];
}
return pitch;
}
UINT16 GetWtBlockFnum
(
UINT8 ch, /* channel number */
UINT8 key, /* key number */
UINT16 base_fs /* base frequency */
)
{
UINT16 pitch; /* pitch = block&fnum */
UINT16 rate; /* rate */
UINT32 scale; /* scale */
UINT32 block; /* block */
UINT32 fnum = 0; /* f number */
if ( ma_channel_info[ch].bank_no < 128 )
{
switch ( ma_channel_info[ch].prog_no )
{
case 115:
rate = ma_wt_block_50a[key];
break;
case 116:
rate = ma_wt_block_50b[key];
break;
case 117:
rate = ma_wt_block_50c[key];
break;
case 118:
case 119:
rate = ma_wt_block_50[key];
break;
case 122:
case 127:
rate = ma_wt_block_20[key];
break;
case 123:
case 126:
rate = ma_wt_block_5[key];
break;
case 124:
case 125:
rate = ma_wt_block_10[key];
break;
default:
rate = ma_wt_block_100[key];
break;
}
}
else
{
key = (UINT8)60;
rate = ma_wt_block_100[key];
}
scale = base_fs; /* base frequency [Hz] */
/* 1/48[kHz] = 1.0 (0x0400) */
scale *= rate; /* [12.20] = [6.10] * [6.10] */
scale >>= 10; /* [22.10] */
if ( scale > 0x0400 ) scale = 0x0400;
if ( scale < 0x0020 ) scale = 0x0020;
for ( block = 0; block < 6; block++ )
{
fnum = (SINT32)( scale << (5 - block) ) - 1024;
if ( fnum < 1024 )
break;
}
pitch = (UINT16)( ((fnum << 3) & 0x1C00)
| ((block << 7) & 0x0380)
| ( fnum & 0x007F) );
return pitch;
}
UINT8 CalcVoiceVolume
(
UINT32 vol, /* volume value */
UINT32 offset /* offset value */
)
{
UINT32 db;
UINT8 volume;
db = db_table[vol];
db = (UINT32)( db + db_table[ma_snddrv_info.master_volume] );
db = (UINT32)( db + db_table[ma_snddrv_info.ctrl_volume] );
db = (UINT32)(( db >= offset) ? (db - offset) : 0);
if ( db > (UINT32)MASMW_MAX_DB )
db = (UINT32)MASMW_MAX_DB;
volume = vol_table[db];
return volume;
}
UINT32 MakeDeltaTime( UINT8 * packet_ptr, SINT32 delta_time )
{
UINT32 num = 0;
if ( delta_time < 0 ) return num;
while ( ( delta_time > 127 ) && ( num < 2 ) )
{
*(packet_ptr+num) = (UINT8)(delta_time & 0x7F);
delta_time >>= 7;
num++;
}
*(packet_ptr+num) = (UINT8)(delta_time | 0x80 );
return (UINT32)(num+1);
}
SINT32 GetVoiceInfo
(
UINT8 ch, /* channel number */
UINT8 key, /* key number */
PMAVINFO voice_info_ptr /* voice information */
)
{
UINT8 prog;
UINT8 bank_no; /* bank number */
UINT8 prog_no; /* program number */
UINT16 bank_prog; /* bank & program number */
UINT32 type; /* type */
UINT32 i; /* loop counter */
UINT16 result; /* result of function */
bank_no = ma_channel_info[ch].bank_no;
prog_no = (UINT8)( ( bank_no < 128 ) ? ma_channel_info[ch].prog_no : key ) & 0x7F;
if ( bank_no < 128 )
{
type = 0;
bank_prog = (UINT16)(((UINT16)bank_no << 7) + (UINT16)prog_no);
}
else
{
type = MA_MAX_REG_VOICE;
bank_prog = (UINT16)(((UINT16)(bank_no - 128 + MA_MAX_RAM_BANK) << 7) + (UINT16)prog_no);
}
if ( ( bank_no & 0x7f ) < MA_MAX_RAM_BANK )
{
if ( ma_voice_index[bank_prog] != 0xff )
{
/*--- Yes, Voice Info in RAM ---------*/
i = ma_voice_index[bank_prog];
voice_info_ptr->synth = ma_voice_info[i].synth;
voice_info_ptr->key = ma_voice_info[i].key;
voice_info_ptr->address = (UINT16)(ma_voice_info[i].ram_adrs >> 1);
return MASMW_SUCCESS;
}
}
prog = (UINT8)(type + prog_no);
/*result = MaResMgr_GetDefVoiceSynth( (UINT8)(type + prog_no) );*/
if ( prog < 128 )
{
voice_info_ptr->synth = (UINT8)(1);
}
else
{
prog -= 128;
if ( ( prog < MA_MIN_ROM_DRUM ) || ( MA_MAX_ROM_DRUM < prog ) )
{
return MASMW_ERROR;
}
else
{
voice_info_ptr->synth = (UINT8)( ( ( ma_rom_drum_type[prog/16] >> (prog%16) ) & 0x1 ) + 1 );
}
}
if ( type == MA_MAX_REG_VOICE )
{
/*result = MaResMgr_GetDefVoiceKey( (UINT8)(type + prog_no) );*/
if ( prog < 128 )
{
return MASMW_ERROR;
}
else
{
prog -= 128;
if ( ( prog < MA_MIN_ROM_DRUM ) || ( MA_MAX_ROM_DRUM < prog ) )
{
return MASMW_ERROR;
}
else
{
voice_info_ptr->key = (UINT16)ma_rom_drum_key[prog - MA_MIN_ROM_DRUM];
}
}
}
/*result = MaResMgr_GetDefVoiceAddress( (UINT8)(type + prog_no) );*/
if ( prog < 128 )
{
/* melody */
result = (UINT16)( MA_NORMAL_ROM_ADDRESS + ( prog * 16 ) );
voice_info_ptr->address = result >> 1;
}
else
{
prog -= 128;
/* drum */
if ( ( prog < MA_MIN_ROM_DRUM ) || ( MA_MAX_ROM_DRUM < prog ) )
{
return MASMW_ERROR;
}
else
{
result = (UINT16)( MA_DRUM_ROM_ADDRESS + ( ( prog - MA_MIN_ROM_DRUM ) * 16 ) );
voice_info_ptr->address = result >> 1;
}
}
return MASMW_SUCCESS;
}
SINT32 MaSndDrv_NoteOn
(
SINT32 delta_time, /* delta time */
UINT8 ch, /* channel number */
UINT8 key, /* key number */
UINT8 velocity, /* velocity */
SINT32 gatetime, /* gate time */
SINT32 next_dura
)
{
UINT8 j;
UINT8 slot_no; /* slot number */
UINT8 old_ch; /* old channel number */
UINT8 vo_volume; /* voice volume */
UINT32 num; /* number of packet data */
UINT32 reg_index; /* register index */
UINT32 pitch; /* pitch */
SINT32 result; /* result of function */
MAVINFO voice_info; /* voice information */
/* check */
if(( ch > 15 )||( key > 127 )||( velocity > 127 ))
return MASMW_ERROR;
/* get voice information */
result = GetVoiceInfo( ch, key, &voice_info );
if ( result < MASMW_SUCCESS )
{
result = MaSndDrv_Nop( delta_time, 0 );
return result;
}
/* get slot number */
if ( ma_channel_info[ch].poly == MA_MODE_POLY )
{
slot_no = GetSlotList( voice_info.synth-1 );
if ( ( ma_slot_info[slot_no].ch & 0x80 ) != 0 )
{
old_ch = (UINT8)( ( ma_slot_info[slot_no].ch - 1 ) & 0x7F );
ma_channel_info[old_ch].note_on = 0;
}
}
/* set register index value and pitch of slot */
if ( slot_no < 16 )
{
reg_index = (UINT32)(((slot_no - 0) * 6) + MA_FM_VOICE_ADDRESS);
pitch = GetFmBlockFnum( (UINT8)ch, key, voice_info.key );
vo_volume = CalcVoiceVolume( velocity, 0 );
}
else if ( slot_no < 32 )
{
reg_index = (UINT32)(((slot_no - 16) * 6) + MA_EXT_FM_VOICE_ADDRESS);
pitch = GetFmBlockFnum( (UINT8)ch, key, voice_info.key );
vo_volume = CalcVoiceVolume( velocity, 0 );
}
else if ( slot_no < 40 )
{
reg_index = (UINT32)(((slot_no - 32) * 6) + MA_WT_VOICE_ADDRESS);
pitch = GetWtBlockFnum( (UINT8)ch, key, voice_info.key );
vo_volume = CalcVoiceVolume( velocity, (12 << 1) );
}
else
{
result = MaSndDrv_Nop( delta_time, 0 );
return result;
}
printf_uart2("\n ****slot_no = %d, reg_no = %d****", slot_no, reg_index);
// save the NoteOff info
channel[con] = ch;
reg[con] = reg_index;
dura[con] = gatetime;
con++;
// alternate assign process........(drum)
if( delta_time >= pre_time )
{
// NoteOff elap_time = Duration(N) - Gatetime(N-1)
delta_time = delta_time - pre_time;
}
num = MakeDeltaTime( &packet_buf[0], delta_time );
/* update previous gatetime */
pre_time = gatetime;
if ( ma_channel_info[ch].poly == MA_MODE_POLY )
{
if ( ( ma_slot_info[slot_no].ch & 0x80 ) == 0 ) /* new note */
{
old_ch = (UINT8)ch;
}
else
{
old_ch = (UINT8)( ma_slot_info[slot_no].ch - 1 );
}
if ( delta_time <= 0 )
{
/* NOP2 */
/*MAKE_NOP( seq_id, num, (UINT16)MA_NOP_2 )*/
packet_buf[num++] = (UINT8)( (UINT16)MA_NOP_2 & 0x7F );
packet_buf[num++] = (UINT8)( ((UINT16)MA_NOP_2 >> 7) | 0x80 );
packet_buf[num++] = (UINT8)( 0x00 | 0x80 );
/*MAKE_TIMER_PART( seq_id, num, delta_time )*/
if ( delta_time >= 0 )
{
packet_buf[num++] = (UINT8)( 0x80 );
}
}
/* KeyOn */
reg_index += 5;
/*MAKE_ADDRESS_PART( seq_id, num, reg_index )*/
packet_buf[num++] = (UINT8)( reg_index & 0x7F );
packet_buf[num++] = (UINT8)( (reg_index >> 7) | 0x80 );
/*MAKE_RST( seq_id, num, old_ch )*/
packet_buf[num++] = (UINT8)( (0x10 + old_ch) | 0x80 );
/*MAKE_TIMER_PART( seq_id, num, delta_time )*/
if ( delta_time >= 0 )
{
packet_buf[num++] = (UINT8)( 0x80 );
}
/*MAKE_NOP( seq_id, num, (UINT16)MA_NOP_2 )*/
packet_buf[num++] = (UINT8)( (UINT16)MA_NOP_2 & 0x7F );
packet_buf[num++] = (UINT8)( ((UINT16)MA_NOP_2 >> 7) | 0x80 );
packet_buf[num++] = (UINT8)( 0x00 | 0x80 );
/*MAKE_TIMER_PART( seq_id, num, delta_time )*/
if ( delta_time >= 0 )
{
packet_buf[num++] = (UINT8)( 0x80 );
}
reg_index -= 5;
/*MAKE_ADDRESS_PART( seq_id, num, reg_index )*/
packet_buf[num++] = (UINT8)( reg_index & 0x7F );
packet_buf[num++] = (UINT8)( (reg_index >> 7) | 0x80 );
/*MAKE_KEY_ON( seq_id, num, voice_info.address, vo_volume, pitch, ch )*/
packet_buf[num++] = (UINT8)( (voice_info.address >> 7) & 0x7F );
packet_buf[num++] = (UINT8)( voice_info.address & 0x7F );
packet_buf[num++] = (UINT8)( vo_volume & 0x7C );
packet_buf[num++] = (UINT8)( (pitch >> 7) & 0x7F );
packet_buf[num++] = (UINT8)( pitch & 0x7F );
packet_buf[num++] = (UINT8)( (0x40 + ch) | 0x80 );
if( next_dura !=0 )
{
for(j = 0; j < con; j++)
{
if( j != 0)
dura[j] = 0;
if( dura[j] > 127 )
{
packet_buf[num++] = (UINT8)( dura[j] & 0x7F );
packet_buf[num++] = (UINT8)( (dura[j]>>7) | 0x80 );
}
else
packet_buf[num++] = (UINT8)( dura[j] | 0x80 );
if( dura[j] <= 0 )
{
//NOP2
//MAKE_NOP( seq_id, num, MA_NOP_2 )
packet_buf[num++] = (UINT8)( (UINT16)MA_NOP_2 & 0x7F );
packet_buf[num++] = (UINT8)( ((UINT16)MA_NOP_2 >> 7) | 0x80 );
packet_buf[num++] = (UINT8)( 0x00 | 0x80 );
//MAKE_TIMER_PART( seq_id, num, delta_time )
if( dura[j] >= 0 )
{
packet_buf[num++] = (UINT8)( 0x80 );
}
}
//KeyOff
reg[j] += 5;
//MAKE_ADDRESS_PART( seq_id, num, reg_index )
packet_buf[num++] = (UINT8)( reg[j] & 0x7F );
packet_buf[num++] = (UINT8)( (reg[j] >> 7) | 0x80 );
//MAKE_KEY_OFF( seq_id, num, ch )
packet_buf[num++] = (UINT8)( channel[j] | 0x80 );
}
con = 0; //clear Off counter
}
}
/* Send packet data */
if ( delta_time < 0 ) /* direct command */
{
result = MaDevDrv_SendDirectPacket( &packet_buf[0], num );
}
else /* delayed command */
{
result = MaDevDrv_SendDelayedPacket( &packet_buf[0], num );
}
/* update the slot information */
ma_slot_info[slot_no].ch = (UINT8)( (ch + 1) | 0x80 );
ma_slot_info[slot_no].key = key;
return result;
}
/*************************************END**************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -