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

📄 adpcm.c

📁 著名ARC模拟器源码,包括多个平台
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* bail if we're not playing anything */	if (audio_sample_rate == 0)		return;	/* range check the numbers */	if (num >= num_voices)	{#ifdef RAINE_DEBUG	  fprintf(stderr,"error: ADPCM_stop() called with channel = %d, but only %d channels allocated\n", num, num_voices);#endif	  return;	}	/* update the ADPCM voice */	stream_update(voice->stream, 0);	/* stop playback */	voice->playing = 0;}/**********************************************************************************************     ADPCM_setvol -- change volume on an ADPCM data channel***********************************************************************************************/void ADPCM_setvol(int num, int vol){	struct ADPCMVoice *voice = &adpcm[num];	/* bail if we're not playing anything */	if (audio_sample_rate == 0)		return;	/* range check the numbers */	if (num >= num_voices)	{#ifdef RAINE_DEBUG	  fprintf(stderr,"error: ADPCM_setvol() called with channel = %d, but only %d channels allocated\n", num, num_voices);#endif	  return;	}	/* update the ADPCM voice */	stream_update(voice->stream, 0);	voice->volume = vol;}/**********************************************************************************************     ADPCM_playing -- returns true if an ADPCM data channel is still playing***********************************************************************************************/int ADPCM_playing(int num){	struct ADPCMVoice *voice = &adpcm[num];	/* bail if we're not playing anything */	if (audio_sample_rate == 0)		return 0;	/* range check the numbers */	if (num >= num_voices)	{#ifdef RAINE_DEBUG	  fprintf(stderr,"error: ADPCM_playing() called with channel = %d, but only %d channels allocated\n", num, num_voices);#endif	  return 0;	}	/* update the ADPCM voice */	stream_update(voice->stream, 0);	return voice->playing;}/********************************************************************************************** * *	OKIM 6295 ADPCM chip: * *	Command bytes are sent: * *		1xxx xxxx = start of 2-byte command sequence, xxxxxxx is the sample number to trigger *		abcd vvvv = second half of command; one of the abcd bits is set to indicate which voice *		            the v bits seem to be volumed * *		0abc d000 = stop playing; one or more of the abcd bits is set to indicate which voice(s) * *	Status is read: * *		???? abcd = one bit per voice, set to 0 if nothing is playing, or 1 if it is active ************************************************************************************************/static int okim6295_command[MAX_OKIM6295];static int okim6295_base[MAX_OKIM6295][MAX_OKIM6295_VOICES];/**********************************************************************************************     OKIM6295_sh_start -- start emulation of an OKIM6295-compatible chip***********************************************************************************************/int OKIM6295_sh_start(const struct OKIM6295interface *intf){	char stream_name[40];	int i;	/* reset the ADPCM system */	num_voices = intf->num * MAX_OKIM6295_VOICES;	compute_tables();	/* initialize the voices */	//memset(adpcm, 0, sizeof(adpcm));	for (i = 0; i < num_voices; i++)	{		int chip = i / MAX_OKIM6295_VOICES;		int voice = i % MAX_OKIM6295_VOICES;		/* reset the OKI-specific parameters */		okim6295_command[chip] = -1;		okim6295_base[chip][voice] = 0;		/* generate the name and create the stream */		sprintf(stream_name, "M6295 #%d (voice %d)", chip, voice);#ifndef __RAINE__		adpcm[i].stream = stream_init(stream_name, intf->mixing_level[chip], audio_sample_rate, i, adpcm_update);#else				adpcm[i].stream = stream_init(stream_name, audio_sample_rate, 16,i, adpcm_update);#endif		if (adpcm[i].stream == -1){		  return 1;		}		/* volume setup */		stream_set_volume(adpcm[i].stream,intf->mixing_level[chip]); // don't know if mixing_level is right here...		/* initialize the rest of the structure */		if (intf->region[chip]) // If we have the info...		  adpcm[i].base = adpcm[i].region_base = load_region[intf->region[chip]];		adpcm[i].volume = 255;		adpcm[i].signal = -2;		if (audio_sample_rate)		  adpcm[i].source_step = (UINT32)((double)intf->frequency[chip] * (double)FRAC_ONE / (double)audio_sample_rate);	}	/* success */	return 0;}/**********************************************************************************************     OKIM6295_sh_stop -- stop emulation of an OKIM6295-compatible chip***********************************************************************************************/void OKIM6295_sh_stop(void){}/**********************************************************************************************     OKIM6295_sh_update -- update emulation of an OKIM6295-compatible chip***********************************************************************************************/void OKIM6295_sh_update(void){}/**********************************************************************************************     OKIM6295_set_bank_base -- set the base of the bank for a given voice on a given chip***********************************************************************************************/void OKIM6295_set_bank_base(int which, int channel, int base){	struct ADPCMVoice *voice = &adpcm[which * MAX_OKIM6295_VOICES + channel];	/* handle the all voice case */	if (channel == ALL_VOICES)	{		int i;		for (i = 0; i < MAX_OKIM6295_VOICES; i++)			OKIM6295_set_bank_base(which, i, base);		return;	}	/* update the stream and set the new base */	stream_update(voice->stream, 0);	okim6295_base[which][channel] = base;}/**********************************************************************************************     OKIM6295_set_frequency -- dynamically adjusts the frequency of a given ADPCM voice***********************************************************************************************/void OKIM6295_set_frequency(int which, int channel, int frequency){	struct ADPCMVoice *voice = &adpcm[which * MAX_OKIM6295_VOICES + channel];	/* handle the all voice case */	if (channel == ALL_VOICES)	{		int i;		for (i = 0; i < MAX_OKIM6295_VOICES; i++)			OKIM6295_set_frequency(which, i, frequency);		return;	}	/* update the stream and set the new base */	stream_update(voice->stream, 0);	if (audio_sample_rate)		voice->source_step = (UINT32)((double)frequency * (double)FRAC_ONE / (double)audio_sample_rate);}/**********************************************************************************************     OKIM6295_status_r -- read the status port of an OKIM6295-compatible chip***********************************************************************************************/static int OKIM6295_status_r(int num){	int i, result;	/* range check the numbers */	if (num >= num_voices / MAX_OKIM6295_VOICES)	{#ifdef RAINE_DEBUG	  fprintf(stderr,"error: OKIM6295_status_r() called with chip = %d, but only %d chips allocated\n",num, num_voices / MAX_OKIM6295_VOICES);#endif	  return 0x0f;	}	/* set the bit to 1 if something is playing on a given channel */	result = 0;	for (i = 0; i < MAX_OKIM6295_VOICES; i++)	{		struct ADPCMVoice *voice = &adpcm[num * MAX_OKIM6295_VOICES + i];		/* update the stream */		stream_update(voice->stream, 0);		/* set the bit if it's playing */		if (voice->playing)			result |= 1 << i;	}	return result;}/**********************************************************************************************     OKIM6295_data_w -- write to the data port of an OKIM6295-compatible chip***********************************************************************************************/static void OKIM6295_data_w(int num, int data){  /* range check the numbers */  if (num >= num_voices / MAX_OKIM6295_VOICES)    {#ifdef RAINE_DEBUG      fprintf(stderr,"error: OKIM6295_data_w() called with chip = %d, but only %d chips allocated\n", num, num_voices / MAX_OKIM6295_VOICES);#endif      return;    }    /* if a command is pending, process the second half */  if (okim6295_command[num] != -1)    {      int temp = data >> 4, i, start, stop;      unsigned char *base;      /* determine which voice(s) (voice is set by a 1 bit in the upper 4 bits of the second byte) */      for (i = 0; i < MAX_OKIM6295_VOICES; i++, temp >>= 1)	if (temp & 1)	  {	    struct ADPCMVoice *voice = &adpcm[num * MAX_OKIM6295_VOICES + i];	    				/* update the stream */	    stream_update(voice->stream, 0);	    				/* determine the start/stop positions */	    base = &voice->region_base[okim6295_base[num][i] + okim6295_command[num] * 8];	    start = (base[0] << 16) + (base[1] << 8) + base[2];	    stop = (base[3] << 16) + (base[4] << 8) + base[5];				/* set up the voice to play this sample */	    if (start < 0x40000 && stop < 0x40000)	      {		voice->playing = 1;		voice->base = &voice->region_base[okim6295_base[num][i] + start];		voice->sample = 0;		voice->count = 2 * (stop - start + 1);				/* also reset the ADPCM parameters */		voice->signal = -2;		voice->step = 0;		voice->volume = volume_table[data & 0x0f];	      }	    				/* invalid samples go here */	    else	      {#ifdef RAINE_DEBUG		fprintf(stderr,"OKIM6295: requested to play invalid sample %02x\n",okim6295_command[num]);#endif		voice->playing = 0;				}			}		/* reset the command */		okim6295_command[num] = -1;	}	/* if this is the start of a command, remember the sample number for next time */	else if (data & 0x80)	{		okim6295_command[num] = data & 0x7f;	}	/* otherwise, see if this is a silence command */	else	{	  int temp = data >> 3, i;	  /* determine which voice(s) (voice is set by a 1 bit in bits 3-6 of the command */	  for (i = 0; i < 4; i++, temp >>= 1)	    if (temp & 1)	      {		struct ADPCMVoice *voice = &adpcm[num * MAX_OKIM6295_VOICES + i];						/* update the stream, then turn it off */		stream_update(voice->stream, 0);		voice->playing = 0;	      }	}}/**********************************************************************************************     OKIM6295_status_0_r -- generic status read functions     OKIM6295_status_1_r***********************************************************************************************/READ_HANDLER( OKIM6295_status_0_r ){  return OKIM6295_status_r(0);}READ_HANDLER( OKIM6295_status_1_r ){	return OKIM6295_status_r(1);}/**********************************************************************************************     OKIM6295_data_0_w -- generic data write functions     OKIM6295_data_1_w***********************************************************************************************/WRITE_HANDLER( OKIM6295_data_0_w ){  OKIM6295_data_w(0, data);}WRITE_HANDLER( OKIM6295_data_1_w ){	OKIM6295_data_w(1, data);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -