aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorneonloop2021-03-14 18:54:30 +0000
committerneonloop2021-03-14 19:28:36 +0000
commitcc67e49563096e4367881e8bbe4554f1a7d21595 (patch)
tree393883d80d2b417d67a4fb2150dbd37392017802
parent34c62fb129becec9e61a48227d9ed89867cdd470 (diff)
downloadpcsx_rearmed-cc67e49563096e4367881e8bbe4554f1a7d21595.tar.gz
pcsx_rearmed-cc67e49563096e4367881e8bbe4554f1a7d21595.tar.bz2
pcsx_rearmed-cc67e49563096e4367881e8bbe4554f1a7d21595.zip
Adds frameskip based on free audio buffer space
-rw-r--r--frontend/libretro.c12
-rw-r--r--frontend/menu.c7
-rw-r--r--frontend/plugin_lib.c35
-rw-r--r--frontend/plugin_lib.h1
-rw-r--r--plugins/dfsound/alsa.c21
-rw-r--r--plugins/dfsound/nullsnd.c7
-rw-r--r--plugins/dfsound/oss.c28
-rw-r--r--plugins/dfsound/out.h1
-rw-r--r--plugins/dfsound/pulseaudio.c33
-rw-r--r--plugins/dfsound/sdl.c12
-rw-r--r--plugins/gpulib/gpu.c4
11 files changed, 103 insertions, 58 deletions
diff --git a/frontend/libretro.c b/frontend/libretro.c
index 59f1201..e588b8d 100644
--- a/frontend/libretro.c
+++ b/frontend/libretro.c
@@ -151,6 +151,7 @@ static int vout_open(void) { return 0; }
static void vout_close(void) {}
static int snd_init(void) { return 0; }
static void snd_finish(void) {}
+static float snd_capacity(void) { return 0.3; }
static int snd_busy(void) { return 0; }
#define GPU_PEOPS_ODD_EVEN_BIT (1 << 0)
@@ -510,11 +511,12 @@ static void snd_feed(void *buf, int bytes)
void out_register_libretro(struct out_driver *drv)
{
- drv->name = "libretro";
- drv->init = snd_init;
- drv->finish = snd_finish;
- drv->busy = snd_busy;
- drv->feed = snd_feed;
+ drv->name = "libretro";
+ drv->init = snd_init;
+ drv->finish = snd_finish;
+ drv->busy = snd_busy;
+ drv->feed = snd_feed;
+ drv->capacity = snd_capacity;
}
#define RETRO_DEVICE_PSE_STANDARD RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 0)
diff --git a/frontend/menu.c b/frontend/menu.c
index 7bf4080..52e6b98 100644
--- a/frontend/menu.c
+++ b/frontend/menu.c
@@ -93,7 +93,7 @@ typedef enum
} menu_id;
static int last_vout_w, last_vout_h, last_vout_bpp;
-static int cpu_clock, cpu_clock_st, volume_boost, frameskip;
+static int cpu_clock, cpu_clock_st, volume_boost, frameskip, frameskip_type;
static char last_selected_fname[MAXPATHLEN];
static int config_save_counter, region, in_type_sel1, in_type_sel2;
static int psx_clock;
@@ -325,6 +325,7 @@ static void menu_sync_config(void)
spu_config.iVolume = 768 + 128 * volume_boost;
pl_rearmed_cbs.frameskip = frameskip - 1;
+ pl_rearmed_cbs.frameskip_type = frameskip_type;
pl_timing_prepare(Config.PsxType);
}
@@ -337,6 +338,7 @@ static void menu_set_defconfig(void)
g_gamma = 100;
volume_boost = 0;
frameskip = 0;
+ frameskip_type = 0;
analog_deadzone = 50;
soft_scaling = 1;
soft_filter = 0;
@@ -424,6 +426,7 @@ static const struct {
CE_INTVAL_N("adev0_is_nublike", in_adev_is_nublike[0]),
CE_INTVAL_N("adev1_is_nublike", in_adev_is_nublike[1]),
CE_INTVAL_V(frameskip, 3),
+ CE_INTVAL(frameskip_type),
CE_INTVAL_P(thread_rendering),
CE_INTVAL_P(gpu_peops.iUseDither),
CE_INTVAL_P(gpu_peops.dwActFixes),
@@ -1611,6 +1614,7 @@ static int mh_restore_defaults(int id, int keys)
static const char *men_region[] = { "Auto", "NTSC", "PAL", NULL };
static const char *men_frameskip[] = { "Auto", "Off", "1", "2", "3", NULL };
+static const char *men_fs_type[] = { "Time", "Audio", NULL };
/*
static const char *men_confirm_save[] = { "OFF", "writes", "loads", "both", NULL };
static const char h_confirm_save[] = "Ask for confirmation when overwriting save,\n"
@@ -1625,6 +1629,7 @@ static menu_entry e_menu_options[] =
// mee_range ("Save slot", 0, state_slot, 0, 9),
// mee_enum_h ("Confirm savestate", 0, dummy, men_confirm_save, h_confirm_save),
mee_enum_h ("Frameskip", 0, frameskip, men_frameskip, h_frameskip),
+ mee_enum ("Frameskip type", 0, frameskip_type, men_fs_type),
mee_onoff ("Show FPS", 0, g_opts, OPT_SHOWFPS),
mee_enum ("Region", 0, region, men_region),
mee_range ("CPU clock", MA_OPT_CPU_CLOCKS, cpu_clock, 20, 5000),
diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c
index eee255b..6c5b296 100644
--- a/frontend/plugin_lib.c
+++ b/frontend/plugin_lib.c
@@ -33,6 +33,8 @@
#include "../libpcsxcore/new_dynarec/new_dynarec.h"
#include "../libpcsxcore/psxmem_map.h"
#include "../plugins/dfinput/externals.h"
+#include "../plugins/dfsound/out.h"
+
#define HUD_HEIGHT 10
@@ -702,17 +704,34 @@ void pl_frame_limit(void)
tv_expect.tv_usec = usadj << 10;
}
- if (!(g_opts & OPT_NO_FRAMELIM) && diff > frame_interval) {
- // yay for working usleep on pandora!
- //printf("usleep %d\n", diff - frame_interval / 2);
- usleep(diff - frame_interval);
+ if (!(g_opts & OPT_NO_FRAMELIM)) {
+ if (pl_rearmed_cbs.frameskip && pl_rearmed_cbs.frameskip_type == 1) {
+ while (out_current && out_current->capacity() < 0.1) {
+ usleep(500);
+ }
+ } else {
+ if (diff > frame_interval) {
+ // yay for working usleep on pandora!
+ //printf("usleep %d\n", diff - frame_interval / 2);
+ usleep(diff - frame_interval);
+ }
+ }
}
+
if (pl_rearmed_cbs.frameskip) {
- if (diff < -frame_interval)
- pl_rearmed_cbs.fskip_advice = 1;
- else if (diff >= 0)
- pl_rearmed_cbs.fskip_advice = 0;
+ if (pl_rearmed_cbs.frameskip_type == 1) {
+ if (out_current->capacity() > 0.5) {
+ pl_rearmed_cbs.fskip_advice = 1;
+ } else {
+ pl_rearmed_cbs.fskip_advice = 0;
+ }
+ } else {
+ if (diff < -frame_interval)
+ pl_rearmed_cbs.fskip_advice = 1;
+ else if (diff >= 0)
+ pl_rearmed_cbs.fskip_advice = 0;
+ }
// recompilation is not that fast and may cause frame skip on
// loading screens and such, resulting in flicker or glitches
diff --git a/frontend/plugin_lib.h b/frontend/plugin_lib.h
index 71dfcb5..841eeb9 100644
--- a/frontend/plugin_lib.h
+++ b/frontend/plugin_lib.h
@@ -69,6 +69,7 @@ struct rearmed_cbs {
void *gles_display, *gles_surface;
// gpu options
int frameskip;
+ int frameskip_type;
int fskip_advice;
unsigned int *gpu_frame_count;
unsigned int *gpu_hcnt;
diff --git a/plugins/dfsound/alsa.c b/plugins/dfsound/alsa.c
index 6b9f83e..9873655 100644
--- a/plugins/dfsound/alsa.c
+++ b/plugins/dfsound/alsa.c
@@ -166,20 +166,22 @@ static void alsa_finish(void)
}
}
-// GET BYTES BUFFERED
-static int alsa_busy(void)
-{
+static float alsa_capacity(void) {
int l;
- if (handle == NULL) // failed to open?
- return 1;
+ if (handle == NULL) return 0;
+ if (buffer_size == 0) return 0;
+
l = snd_pcm_avail(handle);
if (l < 0) return 0;
- if (l < buffer_size / 2) // can we write in at least the half of fragments?
- l = 1; // -> no? wait
- else l = 0; // -> else go on
- return l;
+ return (float)l / buffer_size;
+}
+
+// GET BYTES BUFFERED
+static int alsa_busy(void)
+{
+ return alsa_capacity() < 0.5;
}
// FEED SOUND DATA
@@ -219,4 +221,5 @@ void out_register_alsa(struct out_driver *drv)
drv->finish = alsa_finish;
drv->busy = alsa_busy;
drv->feed = alsa_feed;
+ drv->capacity = alsa_capacity;
}
diff --git a/plugins/dfsound/nullsnd.c b/plugins/dfsound/nullsnd.c
index d8714df..ba6e51a 100644
--- a/plugins/dfsound/nullsnd.c
+++ b/plugins/dfsound/nullsnd.c
@@ -11,6 +11,12 @@ static void none_finish(void)
{
}
+// GET BUFFER AVAILABLE
+static float none_capacity(void)
+{
+ return 0.3;
+}
+
// GET BYTES BUFFERED
static int none_busy(void)
{
@@ -29,4 +35,5 @@ void out_register_none(struct out_driver *drv)
drv->finish = none_finish;
drv->busy = none_busy;
drv->feed = none_feed;
+ drv->capacity = none_capacity;
}
diff --git a/plugins/dfsound/oss.c b/plugins/dfsound/oss.c
index 6b1cb4a..67ba4c9 100644
--- a/plugins/dfsound/oss.c
+++ b/plugins/dfsound/oss.c
@@ -128,25 +128,26 @@ static void oss_finish(void)
}
////////////////////////////////////////////////////////////////////////
-// GET BUFFERED STATUS
+// GET BUFFER AVAILABLE
////////////////////////////////////////////////////////////////////////
-static int oss_busy(void)
+static float oss_capacity(void)
{
audio_buf_info info;
- unsigned long l;
- if(oss_audio_fd == -1) return 1;
- if(ioctl(oss_audio_fd,SNDCTL_DSP_GETOSPACE,&info)==-1)
- l=0;
- else
- {
- if(info.fragments<(info.fragstotal>>1)) // can we write in at least the half of fragments?
- l=1; // -> no? wait
- else l=0; // -> else go on
- }
+ if(oss_audio_fd == -1) return 0;
+ if(ioctl(oss_audio_fd,SNDCTL_DSP_GETOSPACE,&info)==-1) return 0;
+ if(info.fragstotal == 0) return 0;
+ return (float)info.fragments / info.fragstotal;
+}
- return l;
+////////////////////////////////////////////////////////////////////////
+// GET BUFFERED STATUS
+////////////////////////////////////////////////////////////////////////
+
+static int oss_busy(void)
+{
+ return oss_capacity() < 0.5;
}
////////////////////////////////////////////////////////////////////////
@@ -186,4 +187,5 @@ void out_register_oss(struct out_driver *drv)
drv->finish = oss_finish;
drv->busy = oss_busy;
drv->feed = oss_feed;
+ drv->capacity = oss_capacity;
}
diff --git a/plugins/dfsound/out.h b/plugins/dfsound/out.h
index e4878a8..2dcd226 100644
--- a/plugins/dfsound/out.h
+++ b/plugins/dfsound/out.h
@@ -7,6 +7,7 @@ struct out_driver {
void (*finish)(void);
int (*busy)(void);
void (*feed)(void *data, int bytes);
+ float (*capacity)(void);
};
extern struct out_driver *out_current;
diff --git a/plugins/dfsound/pulseaudio.c b/plugins/dfsound/pulseaudio.c
index 8ffd58f..0f4e32e 100644
--- a/plugins/dfsound/pulseaudio.c
+++ b/plugins/dfsound/pulseaudio.c
@@ -288,34 +288,32 @@ static void pulse_finish(void)
}
////////////////////////////////////////////////////////////////////////
-// GET BYTES BUFFERED
+// GET BUFFER AVAILABLE
////////////////////////////////////////////////////////////////////////
-static int pulse_busy(void)
+static float pulse_capacity(void)
{
int free_space;
if ((device.mainloop == NULL) || (device.api == NULL) || ( device.context == NULL) || (device.stream == NULL))
- return 1;
+ return 0;
pa_threaded_mainloop_lock (device.mainloop);
free_space = pa_stream_writable_size (device.stream);
pa_threaded_mainloop_unlock (device.mainloop);
+ if (free_space == 0) return 0;
- //fprintf (stderr, "Free space: %d\n", free_space);
- //fprintf (stderr, "Used space: %d\n", maxlength - free_space);
- if (free_space < mixlen * 3)
- {
- // Don't buffer anymore, just play
- //fprintf (stderr, "Not buffering.\n");
- return 1;
- }
- else
- {
- // Buffer some sound
- //fprintf (stderr, "Buffering.\n");
- return 0;
- }
+ return (float)free_space / mixlen;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+// GET BYTES BUFFERED
+////////////////////////////////////////////////////////////////////////
+
+static int pulse_busy(void)
+{
+ return pulse_capacity() < 0.33;
}
////////////////////////////////////////////////////////////////////////
@@ -346,4 +344,5 @@ void out_register_pulse(struct out_driver *drv)
drv->finish = pulse_finish;
drv->busy = pulse_busy;
drv->feed = pulse_feed;
+ drv->capacity = pulse_capacity;
}
diff --git a/plugins/dfsound/sdl.c b/plugins/dfsound/sdl.c
index ce92b6e..5a5ca51 100644
--- a/plugins/dfsound/sdl.c
+++ b/plugins/dfsound/sdl.c
@@ -103,17 +103,20 @@ static void sdl_finish(void) {
pSndBuffer = NULL;
}
-static int sdl_busy(void) {
+static float sdl_capacity(void) {
int size;
- if (pSndBuffer == NULL) return 1;
+ if (pSndBuffer == NULL) return 0;
+ if (iBufSize == 0) return 0;
size = iReadPos - iWritePos;
if (size <= 0) size += iBufSize;
- if (size < iBufSize / 2) return 1;
+ return (float)size / iBufSize;
+}
- return 0;
+static int sdl_busy(void) {
+ return sdl_capacity() < 0.5;
}
static void sdl_feed(void *pSound, int lBytes) {
@@ -140,4 +143,5 @@ void out_register_sdl(struct out_driver *drv)
drv->finish = sdl_finish;
drv->busy = sdl_busy;
drv->feed = sdl_feed;
+ drv->capacity = sdl_capacity;
}
diff --git a/plugins/gpulib/gpu.c b/plugins/gpulib/gpu.c
index ed37b71..cffb97d 100644
--- a/plugins/gpulib/gpu.c
+++ b/plugins/gpulib/gpu.c
@@ -97,7 +97,9 @@ static noinline void decide_frameskip(void)
gpu.frameskip.frame_ready = 1;
}
- if (!gpu.frameskip.active && *gpu.frameskip.advice)
+ if (gpu.frameskip.set < 0 && gpu.frameskip.cnt < 2 && *gpu.frameskip.advice)
+ gpu.frameskip.active = 1;
+ else if (!gpu.frameskip.active && *gpu.frameskip.advice)
gpu.frameskip.active = 1;
else if (gpu.frameskip.set > 0 && gpu.frameskip.cnt < gpu.frameskip.set)
gpu.frameskip.active = 1;