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

📄 masnddrv.c

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