--- uae/src/audio.c 2018/04/24 16:47:17 1.1.1.5 +++ uae/src/audio.c 2018/04/24 16:48:32 1.1.1.6 @@ -108,7 +108,7 @@ void sample16_handler (void) check_sound_buffers (); } -void sample16i_handler (void) +void sample16i_rh_handler (void) { unsigned long delta, ratio; @@ -164,6 +164,83 @@ void sample16i_handler (void) check_sound_buffers (); } +void sample16i_crux_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; + + { + struct audio_channel_data *cdp; + int ratio, ratio1; +#define INTERVAL (sample_evtime * 3) + 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; + data0 += data1; + { + 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 @@ -231,7 +308,7 @@ void sample16s_handler (void) check_sound_buffers (); } -void sample16si_handler (void) +void sample16si_crux_handler (void) { unsigned long delta, ratio; @@ -264,25 +341,10 @@ void sample16si_handler (void) 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) +#define INTERVAL (sample_evtime * 3) cdp = audio_channel + 0; ratio1 = cdp->per - cdp->evtime; ratio = (ratio1 << 12) / INTERVAL; @@ -313,7 +375,69 @@ void sample16si_handler (void) } 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 sample16si_rh_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; + 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; { uae_u32 data = SBASEVAL16 (1) + data0; FINISH_DATA (16, 1); @@ -375,6 +499,14 @@ void sample16s_handler (void) { sample16_handler(); } +void sample16si_crux_handler (void) +{ + sample16i_crux_handler(); +} +void sample16si_rh_handler (void) +{ + sample16i_rh_handler(); +} #endif static uae_u8 int2ulaw (int ch) @@ -582,7 +714,7 @@ void audio_reset (void) next_sample_evtime = sample_evtime; } -static __inline__ int sound_prefs_changed (void) +STATIC_INLINE int sound_prefs_changed (void) { return (changed_prefs.produce_sound != currprefs.produce_sound || changed_prefs.stereo != currprefs.stereo @@ -592,32 +724,42 @@ static __inline__ int sound_prefs_change void check_prefs_changed_audio (void) { - if (! sound_available || ! sound_prefs_changed ()) - return; + if (sound_available && sound_prefs_changed ()) { + close_sound (); - 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 < 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 { - 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; + 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 >= 2) { + if (init_sound ()) { + last_cycles = cycles - 1; + next_sample_evtime = sample_evtime; + } else + if (! sound_available) { + fprintf (stderr, "Sound is not supported.\n"); + } else { + 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; + } + } } + /* Select the right interpolation method. */ + if (sample_handler == sample16_handler + || sample_handler == sample16i_crux_handler + || sample_handler == sample16i_rh_handler) + sample_handler = (currprefs.sound_interpol == 0 ? sample16_handler + : currprefs.sound_interpol == 1 ? sample16i_rh_handler + : sample16i_crux_handler); + else if (sample_handler == sample16s_handler + || sample_handler == sample16si_crux_handler + || sample_handler == sample16si_rh_handler) + sample_handler = (currprefs.sound_interpol == 0 ? sample16s_handler + : currprefs.sound_interpol == 1 ? sample16si_rh_handler + : sample16si_crux_handler); } void update_audio (void)