/* 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; }
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); }