📄 masnddrv.c
字号:
/****************************************************************************
* *
* Copyright (C) 2001-2003 YAMAHA CORPORATION. All rights reserved. *
* *
* Module : masnddrv.c *
* *
* Description : MA Sound Driver *
* *
* Version : 1.3.15.4 2003.04.04 *
* *
****************************************************************************/
#include "masnddrv.h"
#include "matable.h"
static MASNDDRVINFO ma_snddrv_info[MASMW_NUM_SEQTYPE];
static MACHINFO ma_channel_info[MASMW_NUM_CHANNEL];
static MAVOICEINFO ma_voice_info[MASMW_NUM_VOICEINFO][MA_MAX_REG_VOICE*2];
static UINT8 ma_voice_index[MA_MAX_RAM_BANK*2*128]; /* (Bank[16+16]) * Prog */
/* index of ma_voice_info */
/* NULL if index = 0xff */
static MASTREAMINFO ma_stream_info[MASMW_NUM_SEQTYPE][MA_MAX_REG_STREAM];
static MASLOTINFO ma_slot_info[MASMW_MAX_SLOT];
static MASLOTLIST ma_slot_list[MASMW_NUM_SEQTYPE];
static MALEDINFO ma_led_info;
static MAMTRINFO ma_mtr_info;
static MA_SEQBUFINFO ma_seqbuf_info;
SINT32 (* ma_srm_cnv[MASMW_NUM_SEQTYPE])( void );
static UINT32 ma_pos_count[MASMW_NUM_SEQTYPE];
static UINT8 ma_control_sequencer[MASMW_NUM_SEQTYPE];
static SINT32 MaSndDrv_Nop ( SINT32 sid, SINT32 dt, UINT32 tp, UINT32 p2, UINT32 p3 );
static SINT32 MaSndDrv_UserEvent ( SINT32 sid, SINT32 dt, UINT32 vl, UINT32 p2, UINT32 p3 );
static SINT32 MaSndDrv_NoteOn ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 key, UINT32 vel );
static SINT32 MaSndDrv_NoteOnMa2 ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 key, UINT32 vel );
static SINT32 MaSndDrv_NoteOnMa2Ex ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 key, UINT32 vel );
static SINT32 MaSndDrv_NoteOff ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 key, UINT32 p3 );
static SINT32 MaSndDrv_NoteOffMa2 ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 key, UINT32 p3 );
static SINT32 MaSndDrv_NoteOffMa2Ex ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 key, UINT32 p3 );
static SINT32 MaSndDrv_ProgramChange ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 bkn, UINT32 prg );
static SINT32 MaSndDrv_ModulationDepth ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 dph, UINT32 p3 );
static SINT32 MaSndDrv_ChannelVolume ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 vol, UINT32 p3 );
static SINT32 MaSndDrv_Panpot ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 pan, UINT32 p3 );
static SINT32 MaSndDrv_Expression ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 vol, UINT32 p3 );
static SINT32 MaSndDrv_Hold1 ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 val, UINT32 p3 );
static SINT32 MaSndDrv_AllSoundOff ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 p2, UINT32 p3 );
static SINT32 MaSndDrv_ResetAllControllers ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 p2, UINT32 p3 );
static SINT32 MaSndDrv_AllNoteOff ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 p2, UINT32 p3 );
static SINT32 MaSndDrv_MonoModeOn ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 p2, UINT32 p3 );
static SINT32 MaSndDrv_PolyModeOn ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 p2, UINT32 p3 );
static SINT32 MaSndDrv_PitchBend ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 val, UINT32 p3 );
static SINT32 MaSndDrv_BendRange ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 rng, UINT32 p3 );
static SINT32 MaSndDrv_StreamOn ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 wid, UINT32 vel );
static SINT32 MaSndDrv_StreamOff ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 wid, UINT32 p3 );
static SINT32 MaSndDrv_StreamSlave ( SINT32 sid, SINT32 dt, UINT32 ch, UINT32 wid, UINT32 vel );
static SINT32 MaSndDrv_StreamPanpot ( SINT32 sid, SINT32 dt, UINT32 wv, UINT32 pan, UINT32 p3 );
static SINT32 MaSndDrv_MasterVolume ( SINT32 sid, SINT32 dt, UINT32 vl, UINT32 p2, UINT32 p3 );
static SINT32 MaSndDrv_SystemOn ( SINT32 sid, SINT32 dt, UINT32 p1, UINT32 p2, UINT32 p3 );
static SINT32 MaSndDrv_LedOn ( SINT32 sid, SINT32 dt, UINT32 p1, UINT32 p2, UINT32 p3 );
static SINT32 MaSndDrv_LedOff ( SINT32 sid, SINT32 dt, UINT32 p1, UINT32 p2, UINT32 p3 );
static SINT32 MaSndDrv_MotorOn ( SINT32 sid, SINT32 dt, UINT32 p1, UINT32 p2, UINT32 p3 );
static SINT32 MaSndDrv_MotorOff ( SINT32 sid, SINT32 dt, UINT32 p1, UINT32 p2, UINT32 p3 );
static SINT32 MaSndDrv_StreamSeek ( SINT32 sid, SINT32 dt, UINT32 p1, UINT32 p2, UINT32 p3 );
static SINT32 (* ma_snddrv_command[])( SINT32 sid, SINT32 dt, UINT32 p1, UINT32 p2, UINT32 p3 ) =
{
MaSndDrv_NoteOn, /* 0 */
MaSndDrv_NoteOnMa2, /* 1 */
MaSndDrv_NoteOnMa2Ex, /* 2 */
MaSndDrv_NoteOff, /* 3 */
MaSndDrv_NoteOffMa2, /* 4 */
MaSndDrv_NoteOffMa2Ex, /* 5 */
MaSndDrv_ProgramChange, /* 6 */
MaSndDrv_ModulationDepth, /* 7 */
MaSndDrv_ChannelVolume, /* 8 */
MaSndDrv_Panpot, /* 9 */
MaSndDrv_Expression, /* 10 */
MaSndDrv_Hold1, /* 11 */
MaSndDrv_AllSoundOff, /* 12 */
MaSndDrv_ResetAllControllers, /* 13 */
MaSndDrv_AllNoteOff, /* 14 */
MaSndDrv_MonoModeOn, /* 15 */
MaSndDrv_PolyModeOn, /* 16 */
MaSndDrv_PitchBend, /* 17 */
MaSndDrv_BendRange, /* 18 */
MaSndDrv_StreamOn, /* 19 */
MaSndDrv_StreamOff, /* 20 */
MaSndDrv_StreamSlave, /* 21 */
MaSndDrv_StreamPanpot, /* 22 */
MaSndDrv_MasterVolume, /* 23 */
MaSndDrv_SystemOn, /* 24 */
MaSndDrv_LedOn, /* 25 */
MaSndDrv_LedOff, /* 26 */
MaSndDrv_MotorOn, /* 27 */
MaSndDrv_MotorOff, /* 28 */
MaSndDrv_UserEvent, /* 29 */
MaSndDrv_Nop, /* 30 */
MaSndDrv_StreamSeek /* 31 */
};
static UINT8 packet_buf[MASMW_NUM_SEQTYPE][256];
extern void machdep_memcpy( UINT8 *d, UINT8 *s, UINT32 size );
/*--------------------------------------------------------------------------*/
/****************************************************************************
* SendDelayedPacket
*
* Description:
* Send the delayed packet.
* Argument:
* packet_ptr pointer to the packet data
* packet_size size of the packet data
* Return:
* 0 success
* 1 save to queue
*
****************************************************************************/
static SINT32 SendDelayedPacket
(
UINT8 * packet_ptr, /* pointer to the packet */
UINT32 packet_size /* size of the packet */
)
{
MASNDDRV_DBGMSG(("SendDelayedPacket: ptr=%p sz=%ld\n", packet_ptr, packet_size));
if ( ( ma_seqbuf_info.buf_size < packet_size ) || ( ma_seqbuf_info.queue_flag == 1 ) )
{
machdep_memcpy( &ma_seqbuf_info.queue[ma_seqbuf_info.queue_wptr], packet_ptr, packet_size );
ma_seqbuf_info.queue_flag = 1;
ma_seqbuf_info.queue_size += packet_size;
ma_seqbuf_info.queue_wptr += packet_size;
return 1;
}
if ( ma_seqbuf_info.buf_ptr == NULL ) return MASMW_ERROR;
machdep_memcpy( ma_seqbuf_info.buf_ptr, packet_ptr, packet_size );
ma_seqbuf_info.buf_ptr += packet_size;
ma_seqbuf_info.buf_size -= packet_size;
ma_seqbuf_info.wrote_size += packet_size;
return MASMW_SUCCESS;
}
/****************************************************************************
* GetVoiceInfo
*
* Description:
* Return the voice information.
* Arguments:
* seq_id sequence id (0..1)
* ch channel number (0..15)
* key key number (0..127)
* voice_info_ptr 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 seq_id, /* sequence id */
UINT32 ch, /* channel number */
UINT32 key, /* key number */
PMAVINFO voice_info_ptr /* voice information */
)
{
UINT8 bank_no; /* bank number */
UINT8 prog_no; /* program number */
UINT16 bank_prog; /* bank & program number */
UINT32 type; /* type */
UINT32 i; /* loop counter */
SINT32 result; /* result of function */
MASMW_ASSERT( seq_id <= MASMW_SEQTYPE_DIRECT );
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[seq_id][i].synth;
voice_info_ptr->key = ma_voice_info[seq_id][i].key;
voice_info_ptr->address = (UINT16)(ma_voice_info[seq_id][i].ram_adrs >> 1);
return MASMW_SUCCESS;
}
}
if ( ma_snddrv_info[seq_id].drum_type != 0 )
{
if ( bank_no >= 128 )
{
if ( ( prog_no < MA_MIN_GML1_DRUM ) || ( MA_MAX_GML1_DRUM < prog_no ) )
{
return MASMW_ERROR;
}
}
}
result = MaResMgr_GetDefVoiceSynth( (UINT8)(type + prog_no) );
if ( result <= 0 )
return MASMW_ERROR;
else
voice_info_ptr->synth = (UINT8)result;
if ( type == MA_MAX_REG_VOICE )
{
result = MaResMgr_GetDefVoiceKey( (UINT8)(type + prog_no) );
if ( result <= 0 )
return MASMW_ERROR;
else
voice_info_ptr->key = (UINT16)result;
}
result = MaResMgr_GetDefVoiceAddress( (UINT8)(type + prog_no) );
if ( result <= 0 )
return MASMW_ERROR;
else
voice_info_ptr->address = (UINT16)(result >> 1);
return MASMW_SUCCESS;
}
/****************************************************************************
* CalcChVolume
*
* Description:
* Calculate the channel volume.
* Arguments:
* ch channnel number (0..15)
* Return:
* Channel volume value.
*
****************************************************************************/
static 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;
}
/****************************************************************************
* CalcVoiceVolume
*
* Description:
* Calculate the channel volume.
* Arguments:
* seq_id sequence id (0..2)
* vol volume (0..127)
* offset offset value
* Return:
* volume value of slot (0..127).
*
****************************************************************************/
static UINT8 CalcVoiceVolume
(
SINT32 seq_id, /* sequence id */
UINT32 vol, /* volume value */
UINT32 offset /* offset value */
)
{
UINT32 db;
UINT8 volume;
db = db_table[vol];
db = (UINT32)( db + db_table[ma_snddrv_info[seq_id].master_volume] );
db = (UINT32)( db + db_table[ma_snddrv_info[seq_id].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;
}
/****************************************************************************
* MakeDeltaTime
*
* Description:
*
* Arguments:
* packet_ptr
* delta_time
* Return:
*
*
****************************************************************************/
static 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);
}
/****************************************************************************
* GetSlotList
*
* Description:
* Return slot number from slot list for note on.
* Arguments:
* seq_id sequence id (0..2)
* synth_type type of synthesize (0..2)
* Return:
* slot number (0..15/31, 32..39, 40..41)
*
****************************************************************************/
static UINT32 GetSlotList
(
SINT32 seq_id, /* sequence id */
UINT32 synth_type /* synth type */
)
{
UINT8 top_slot;
UINT8 end_slot;
top_slot = ma_slot_list[seq_id].top[synth_type];
end_slot = ma_slot_list[seq_id].end[synth_type];
ma_slot_list[seq_id].next[end_slot] = top_slot;
ma_slot_list[seq_id].top[synth_type] = ma_slot_list[seq_id].next[top_slot];
ma_slot_list[seq_id].end[synth_type] = top_slot;
ma_slot_list[seq_id].next[top_slot] = (UINT8)(ma_snddrv_info[seq_id].max_slot[synth_type] + 1);
return top_slot;
}
/****************************************************************************
* SearchSlotList
*
* Description:
* Return slot number from slot list for note off.
* Arguments:
* seq_id sequence id (0..2)
* synth_type type of synthesize (0..2)
* ch channel number (0..15)
* key key number (0..127)
* Return:
* slot number (0..15/31, 32..39, 40..41, 255)
*
****************************************************************************/
static UINT32 SearchSlotList
(
SINT32 seq_id, /* sequence id */
UINT32 synth_type, /* synth type */
UINT32 ch, /* channel number */
UINT32 key /* key number */
)
{
UINT32 slot_no; /* slot number */
UINT32 min_slot; /* minimum slot number */
UINT32 max_slot; /* maximum slot number */
UINT32 i; /* loop counter */
min_slot = ma_snddrv_info[seq_id].min_slot[synth_type];
max_slot = ma_snddrv_info[seq_id].max_slot[synth_type];
slot_no = ma_slot_list[seq_id].top[synth_type];
for ( i = min_slot; i <= max_slot; i++ )
{
if ( ma_slot_info[slot_no].ch == (ch + 0x81) )
{
if ( ma_slot_info[slot_no].key == key )
{
return slot_no;
}
}
slot_no = ma_slot_list[seq_id].next[slot_no];
}
return 0xFF;
}
/****************************************************************************
* RemakeSlotList
*
* Description:
* Return slot number from slot list for note off.
* Arguments:
* synth_type type of synthesize (0..2)
* Return:
* None
*
****************************************************************************/
static void RemakeSlotList
(
SINT32 seq_id, /* sequence id */
UINT32 synth_type, /* synth type */
UINT32 slot_no, /* slot number */
UINT32 type /* type */
)
{
UINT32 prv_slot;
UINT32 nxt_slot;
UINT32 temp = 0;
UINT32 flag = 0;
UINT32 min_slot;
UINT32 max_slot;
UINT32 i;
min_slot = ma_snddrv_info[seq_id].min_slot[synth_type];
max_slot = ma_snddrv_info[seq_id].max_slot[synth_type];
prv_slot = nxt_slot = ma_slot_list[seq_id].top[synth_type];
for ( i = min_slot; i <= max_slot; i++ )
{
if ( flag == 0 )
{
if ( ma_slot_info[nxt_slot].ch > type )
{
if ( nxt_slot == ma_slot_list[seq_id].top[synth_type] )
{
ma_slot_list[seq_id].top[synth_type] = (UINT8)slot_no;
}
else
{
ma_slot_list[seq_id].next[prv_slot] = (UINT8)slot_no;
}
temp = ma_slot_list[seq_id].next[slot_no];
ma_slot_list[seq_id].next[slot_no] = (UINT8)nxt_slot;
flag = 1;
}
}
if ( flag == 1 )
{
if ( ma_slot_list[seq_id].next[nxt_slot] == slot_no )
{
if ( slot_no == ma_slot_list[seq_id].end[synth_type] )
{
ma_slot_list[seq_id].end[synth_type] = (UINT8)nxt_slot;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -