--- uae/src/audio.c 2018/04/24 16:41:58 1.1.1.2 +++ uae/src/audio.c 2018/04/24 16:47:17 1.1.1.5 @@ -79,7 +79,6 @@ typedef uae_u8 sample8_t; #define DO_CHANNEL(v, c) do { (v) &= audio_channel[c].adk_mask; data += v; } while (0); -/* Templates! I want templates! */ void sample16_handler (void) { BEGIN_BENCH @@ -109,6 +108,62 @@ void sample16_handler (void) check_sound_buffers (); } +void sample16i_handler (void) +{ + unsigned long delta, ratio; + + BEGIN_BENCH + + uae_u32 data0 = audio_channel[0].current_sample; + uae_u32 data1 = audio_channel[1].current_sample; + uae_u32 data2 = audio_channel[2].current_sample; + uae_u32 data3 = audio_channel[3].current_sample; + uae_u32 data0p = audio_channel[0].last_sample; + uae_u32 data1p = audio_channel[1].last_sample; + uae_u32 data2p = audio_channel[2].last_sample; + uae_u32 data3p = audio_channel[3].last_sample; + DO_CHANNEL_1 (data0, 0); + DO_CHANNEL_1 (data1, 1); + DO_CHANNEL_1 (data2, 2); + DO_CHANNEL_1 (data3, 3); + DO_CHANNEL_1 (data0p, 0); + DO_CHANNEL_1 (data1p, 1); + DO_CHANNEL_1 (data2p, 2); + DO_CHANNEL_1 (data3p, 3); + + data0 &= audio_channel[0].adk_mask; + data0p &= audio_channel[0].adk_mask; + data1 &= audio_channel[1].adk_mask; + data1p &= audio_channel[1].adk_mask; + data2 &= audio_channel[2].adk_mask; + data2p &= audio_channel[2].adk_mask; + data3 &= audio_channel[3].adk_mask; + data3p &= audio_channel[3].adk_mask; + + /* linear interpolation and summing up... */ + delta = audio_channel[0].per; + ratio = ((audio_channel[0].evtime % delta) << 8) / delta; + data0 = (data0 * (256 - ratio) + data0p * ratio) >> 8; + delta = audio_channel[1].per; + ratio = ((audio_channel[1].evtime % delta) << 8) / delta; + data0 += (data1 * (256 - ratio) + data1p * ratio) >> 8; + delta = audio_channel[2].per; + ratio = ((audio_channel[2].evtime % delta) << 8) / delta; + data0 += (data2 * (256 - ratio) + data2p * ratio) >> 8; + delta = audio_channel[3].per; + ratio = ((audio_channel[3].evtime % delta) << 8) / delta; + data0 += (data3 * (256 - ratio) + data3p * ratio) >> 8; + + { + uae_u32 data = SBASEVAL16(2) + data0; + FINISH_DATA(16, 2); + PUT_SOUND_WORD (data); + } + END_BENCH + + check_sound_buffers (); +} + void sample8_handler (void) { BEGIN_BENCH @@ -176,6 +231,106 @@ void sample16s_handler (void) check_sound_buffers (); } +void sample16si_handler (void) +{ + unsigned long delta, ratio; + + BEGIN_BENCH + + uae_u32 data0 = audio_channel[0].current_sample; + uae_u32 data1 = audio_channel[1].current_sample; + uae_u32 data2 = audio_channel[2].current_sample; + uae_u32 data3 = audio_channel[3].current_sample; + uae_u32 data0p = audio_channel[0].last_sample; + uae_u32 data1p = audio_channel[1].last_sample; + uae_u32 data2p = audio_channel[2].last_sample; + uae_u32 data3p = audio_channel[3].last_sample; + + DO_CHANNEL_1 (data0, 0); + DO_CHANNEL_1 (data1, 1); + DO_CHANNEL_1 (data2, 2); + DO_CHANNEL_1 (data3, 3); + DO_CHANNEL_1 (data0p, 0); + DO_CHANNEL_1 (data1p, 1); + DO_CHANNEL_1 (data2p, 2); + DO_CHANNEL_1 (data3p, 3); + + data0 &= audio_channel[0].adk_mask; + data0p &= audio_channel[0].adk_mask; + data1 &= audio_channel[1].adk_mask; + data1p &= audio_channel[1].adk_mask; + data2 &= audio_channel[2].adk_mask; + data2p &= audio_channel[2].adk_mask; + data3 &= audio_channel[3].adk_mask; + data3p &= audio_channel[3].adk_mask; + +# if 0 + /* linear interpolation and summing up... */ + delta = audio_channel[0].per; + ratio = ((audio_channel[0].evtime % delta) << 8) / delta; + data0 = (data0 * (256 - ratio) + data0p * ratio) >> 8; + delta = audio_channel[1].per; + ratio = ((audio_channel[1].evtime % delta) << 8) / delta; + data1 = (data1 * (256 - ratio) + data1p * ratio) >> 8; + delta = audio_channel[2].per; + ratio = ((audio_channel[2].evtime % delta) << 8) / delta; + data1 += (data2 * (256 - ratio) + data2p * ratio) >> 8; + delta = audio_channel[3].per; + ratio = ((audio_channel[3].evtime % delta) << 8) / delta; + data0 += (data3 * (256 - ratio) + data3p * ratio) >> 8; +#else + { + struct audio_channel_data *cdp; + int ratio, ratio1; +#define INTERVAL (sample_evtime) + cdp = audio_channel + 0; + ratio1 = cdp->per - cdp->evtime; + ratio = (ratio1 << 12) / INTERVAL; + if (cdp->evtime < sample_evtime || ratio1 >= INTERVAL) + ratio = 4096; + data0 = (data0 * ratio + data0p * (4096 - ratio)) >> 12; + + cdp = audio_channel + 1; + ratio1 = cdp->per - cdp->evtime; + ratio = (ratio1 << 12) / INTERVAL; + if (cdp->evtime < sample_evtime || ratio1 >= INTERVAL) + ratio = 4096; + data1 = (data1 * ratio + data1p * (4096 - ratio)) >> 12; + + cdp = audio_channel + 2; + ratio1 = cdp->per - cdp->evtime; + ratio = (ratio1 << 12) / INTERVAL; + if (cdp->evtime < sample_evtime || ratio1 >= INTERVAL) + ratio = 4096; + data2 = (data2 * ratio + data2p * (4096 - ratio)) >> 12; + + cdp = audio_channel + 3; + ratio1 = cdp->per - cdp->evtime; + ratio = (ratio1 << 12) / INTERVAL; + if (cdp->evtime < sample_evtime || ratio1 >= INTERVAL) + ratio = 4096; + data3 = (data3 * ratio + data3p * (4096 - ratio)) >> 12; + } + data1 += data2; + data0 += data3; +#endif + { + uae_u32 data = SBASEVAL16 (1) + data0; + FINISH_DATA (16, 1); + PUT_SOUND_WORD_RIGHT (data); + } + + { + uae_u32 data = SBASEVAL16 (1) + data1; + FINISH_DATA (16, 1); + PUT_SOUND_WORD_LEFT (data); + } + + END_BENCH + + check_sound_buffers (); +} + void sample8s_handler (void) { BEGIN_BENCH @@ -301,6 +456,7 @@ static void audio_handler (int nr) cdp->evtime = cdp->per; cdp->dat = cdp->nextdat; + cdp->last_sample = cdp->current_sample; cdp->current_sample = (sample8_t)(cdp->dat >> 8); cdp->state = 2; @@ -318,6 +474,7 @@ static void audio_handler (int nr) if (currprefs.produce_sound == 0) cdp->per = 65535; + cdp->last_sample = cdp->current_sample; cdp->current_sample = (sample8_t)(cdp->dat & 0xFF); cdp->evtime = cdp->per; @@ -353,6 +510,7 @@ static void audio_handler (int nr) if ((INTREQR() & (0x80 << nr)) && !cdp->dmaen) { cdp->state = 0; + cdp->last_sample = 0; cdp->current_sample = 0; break; } else { @@ -367,6 +525,7 @@ static void audio_handler (int nr) cdp->intreq2 = 0; cdp->dat = cdp->nextdat; + cdp->last_sample = cdp->current_sample; cdp->current_sample = (sample8_t)(cdp->dat >> 8); if (cdp->dmaen && napnav) @@ -427,6 +586,7 @@ static __inline__ int sound_prefs_change { return (changed_prefs.produce_sound != currprefs.produce_sound || changed_prefs.stereo != currprefs.stereo + || changed_prefs.sound_freq != currprefs.sound_freq || changed_prefs.sound_bits != currprefs.sound_bits); } @@ -436,24 +596,27 @@ void check_prefs_changed_audio (void) return; close_sound (); + currprefs.produce_sound = changed_prefs.produce_sound; currprefs.stereo = changed_prefs.stereo; currprefs.sound_bits = changed_prefs.sound_bits; + currprefs.sound_freq = changed_prefs.sound_freq; - if (currprefs.produce_sound >= 1) { - if (! init_sound ()) { - if (currprefs.produce_sound == -1) { - fprintf (stderr, "Sound is not supported.\n"); - } else { - fprintf (stderr, "Sorry, can't initialize sound.\n"); - currprefs.produce_sound = 0; - } - } else { - last_cycles = cycles - 1; - next_sample_evtime = sample_evtime; - } + if (currprefs.produce_sound < 2) + return; + + if (init_sound ()) { + last_cycles = cycles - 1; + next_sample_evtime = sample_evtime; + return; + } + if (! sound_available) { + fprintf (stderr, "Sound is not supported.\n"); } else { - printf ("Sound system shut down.\n"); + fprintf (stderr, "Sorry, can't initialize sound.\n"); + currprefs.produce_sound = 0; + /* So we don't do this every frame */ + changed_prefs.produce_sound = 0; } } @@ -461,7 +624,7 @@ void update_audio (void) { unsigned long int n_cycles; - if (currprefs.produce_sound == 0) + if (currprefs.produce_sound < 2) return; n_cycles = cycles - last_cycles; @@ -488,7 +651,7 @@ void update_audio (void) audio_channel[2].evtime -= best_evtime; audio_channel[3].evtime -= best_evtime; n_cycles -= best_evtime; - if (next_sample_evtime == 0) { + if (next_sample_evtime == 0 && currprefs.produce_sound > 1) { next_sample_evtime = sample_evtime; (*sample_handler) (); }