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

📄 masnddrv.c

📁 YAMAHA的铃音芯片的测试程序
💻 C
📖 第 1 页 / 共 4 页
字号:
#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 + -