示例#1
0
文件: audio.c 项目: dv1/ion_player
/* update_audio() emulates actions of audio state machine since it was last
   time called. One can assume it is called at least once per horizontal
   line and possibly more often. */
void update_audio (void)
{
    /* Number of cycles that has passed since last call to update_audio() */
    unsigned long n_cycles = cycles - last_audio_cycles;

    while (n_cycles > 0) {
	unsigned long best_evtime = n_cycles + 1;
	int i;
	unsigned long rounded;
	float f;

	for (i = 0; i < 4; i++) {
	    if (audio_channel[i].state != 0 && best_evtime > audio_channel[i].evtime)
		best_evtime = audio_channel[i].evtime;
	}

	/* next_sample_evtime >= 0 so floor() behaves as expected */
	rounded = floorf(next_sample_evtime);
	if ((next_sample_evtime - rounded) >= 0.5)
	    rounded++;

	if (best_evtime > rounded)
	    best_evtime = rounded;

	if (best_evtime > n_cycles)
	    best_evtime = n_cycles;
	
	/* Decrease time-to-wait counters */
	next_sample_evtime -= best_evtime;

	/* sample_prehandler makes it possible to compute effects with
	   accuracy of one bus cycle. sample_handler is only called when
	   a sample is outputted. */
	if (sample_prehandler != NULL)
	    sample_prehandler(best_evtime);

	for (i = 0; i < 4; i++)
	    audio_channel[i].evtime -= best_evtime;

	n_cycles -= best_evtime;

	/* Test if new sample needs to be outputted */
	if (rounded == best_evtime) {
	    /* Before the following addition, next_sample_evtime is in range
	       [-0.5, 0.5) */
	    next_sample_evtime += sample_evtime_interval;
	    (*sample_handler) ();
	}

	/* Call audio state machines if needed */
	for (i = 0; i < 4; i++) {
	    if (audio_channel[i].evtime == 0 && audio_channel[i].state != 0)
		audio_handler(i);
	}
    }

    last_audio_cycles = cycles - n_cycles;
}
示例#2
0
文件: audio.cpp 项目: Bith76/iUAE
void update_audio (void)
{
    unsigned long int n_cycles;
	
    uae4all_prof_start(4);
    n_cycles = get_cycles () - last_cycles;
	for (;;) {
#ifdef __arm__
		asm(".align 4");
#endif	
		register unsigned long int best_evtime = n_cycles + 1;
		//int addr = (int)audio_channel_evtime;
		//AUDIO_PREFETCH(addr);

		// CHECK_STATE
		if (best_evtime > audio_channel_evtime[0]) 
			best_evtime = audio_channel_evtime[0]; 
		if (best_evtime > audio_channel_evtime[1]) 
			best_evtime = audio_channel_evtime[1]; 
		if (best_evtime > audio_channel_evtime[2]) 
			best_evtime = audio_channel_evtime[2];
		if (best_evtime > audio_channel_evtime[3])
			best_evtime = audio_channel_evtime[3];

		if (best_evtime > next_sample_evtime)
			best_evtime = next_sample_evtime;
		if (best_evtime > n_cycles)
			break;
			
		// SUB_EVTIME
		next_sample_evtime -= best_evtime;
		audio_channel_evtime[0] -= best_evtime;
		audio_channel_evtime[1] -= best_evtime;
		audio_channel_evtime[2] -= best_evtime;
		audio_channel_evtime[3] -= best_evtime;
		n_cycles -= best_evtime;
		
		/*
		addr = (int)&audio_channel_current_sample;
		AUDIO_PREFETCH(addr);
		addr = (int)&audio_channel_vol;
		AUDIO_PREFETCH(addr);
		addr = (int)&audio_channel_adk_mask;
		AUDIO_PREFETCH(addr);
		 */
		
		// IF_SAMPLE
		if (!next_sample_evtime) {
			next_sample_evtime = scaled_sample_evtime;
			register uae_u32 d0 = audio_channel_current_sample[0];
			register uae_u32 d1 = audio_channel_current_sample[1];
			register uae_u32 d2 = audio_channel_current_sample[2];
			register uae_u32 d3 = audio_channel_current_sample[3];
			d0 *= audio_channel_vol[0];
			d1 *= audio_channel_vol[1];
			d2 *= audio_channel_vol[2];
			d3 *= audio_channel_vol[3];
			d0 &= audio_channel_adk_mask[0];
			d1 &= audio_channel_adk_mask[1];
			d2 &= audio_channel_adk_mask[2];
			d3 &= audio_channel_adk_mask[3];
			*(uae_u16 *)sndbufpt = d0+d1+d2+d3;
			sndbufpt = (uae_u16 *)(((uae_u8 *)sndbufpt) + 2);
			if ((unsigned)sndbufpt - (unsigned)render_sndbuff >= SNDBUFFER_LEN) {
				finish_sound_buffer ();
			}
		}
		
		// RUN_HANDLERS
		for (int i=0; i < 4; i++) {
			if (!audio_channel_evtime[i])
				audio_handler(i);
		}
		/*
		if (!audio_channel_evtime[0])
			audio_handler_0();
		if (!audio_channel_evtime[1])
			audio_handler_1();
		if (!audio_channel_evtime[2])
			audio_handler_2();
		if (!audio_channel_evtime[3])
			audio_handler_3();
		 */
	}
	
	last_cycles = get_cycles () - n_cycles;
	
    uae4all_prof_end(4);
}